1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-11-10 20:09:57 +00:00

Experimental support for client-side builds

These changes allow tiddlywiki.js to cook it's own components into a
skeletal new-school client-side TiddlyWiki.
This commit is contained in:
Jeremy Ruston 2011-12-13 12:30:09 +00:00
parent f112048682
commit 8ed8772b82
22 changed files with 468 additions and 51 deletions

29
copyright.txt Normal file
View File

@ -0,0 +1,29 @@
TiddlyWiki created by Jeremy Ruston, (jeremy [at] jermolene [dot] com)
Copyright (c) Jeremy Ruston 2004-2007
Copyright (c) UnaMesa Association 2007-2011
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
Neither the name of the UnaMesa Association nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

View File

@ -1,8 +1,7 @@
(function(){ /*\
title: js/ArgParser.js
/* Parse a space-separated string of name:value parameters. Values can be quoted with single quotes, double quotes, double square brackets, or double curly braces.
Parse a space-separated string of name:value parameters. Values can be quoted with single quotes, double quotes,
double square brackets, or double curly braces.
The parameters are returned in a structure that can be referenced like this: The parameters are returned in a structure that can be referenced like this:
@ -17,7 +16,8 @@ Options and their defaults are:
noNames: false, noNames: false,
cascadeDefaults: false cascadeDefaults: false
*/ \*/
(function(){
/*jslint node: true */ /*jslint node: true */
"use strict"; "use strict";

View File

@ -1,8 +1,10 @@
(function(){ /*\
title: js/FileRetriever.js
/*
FileRetriever can asynchronously retrieve files from HTTP URLs or the local file system FileRetriever can asynchronously retrieve files from HTTP URLs or the local file system
*/
\*/
(function(){
/*jslint node: true */ /*jslint node: true */
"use strict"; "use strict";

82
js/Main.js Normal file
View File

@ -0,0 +1,82 @@
/*\
title: js/Main.js
This is the main() function in the browser
\*/
(function(){
/*jslint node: true */
"use strict";
var WikiStore = require("./WikiStore.js").WikiStore,
Tiddler = require("./Tiddler.js").Tiddler,
tiddlerInput = require("./TiddlerInput.js"),
tiddlerOutput = require("./TiddlerOutput.js"),
TextProcessors = require("./TextProcessors.js").TextProcessors,
WikiTextProcessor = require("./WikiTextProcessor.js").WikiTextProcessor,
TiddlerConverters = require("./TiddlerConverters.js").TiddlerConverters;
var textProcessors = new TextProcessors(),
tiddlerConverters = new TiddlerConverters(),
store = new WikiStore({
textProcessors: textProcessors
}),
t;
// Register the wikitext processor
textProcessors.registerTextProcessor("text/x-tiddlywiki",new WikiTextProcessor({
textProcessors: textProcessors
}));
// Register the standard tiddler serializers and deserializers
tiddlerInput.register(tiddlerConverters);
tiddlerOutput.register(tiddlerConverters);
// Add the shadow tiddlers that are built into TiddlyWiki
var shadowShadowStore = new WikiStore({
textProcessors: textProcessors,
shadowStore: null
}),
shadowShadows = [
{title: "StyleSheet", text: ""},
{title: "MarkupPreHead", text: ""},
{title: "MarkupPostHead", text: ""},
{title: "MarkupPreBody", text: ""},
{title: "MarkupPostBody", text: ""},
{title: "TabTimeline", text: "<<timeline>>"},
{title: "TabAll", text: "<<list all>>"},
{title: "TabTags", text: "<<allTags excludeLists>>"},
{title: "TabMoreMissing", text: "<<list missing>>"},
{title: "TabMoreOrphans", text: "<<list orphans>>"},
{title: "TabMoreShadowed", text: "<<list shadowed>>"},
{title: "AdvancedOptions", text: "<<options>>"},
{title: "PluginManager", text: "<<plugins>>"},
{title: "SystemSettings", text: ""},
{title: "ToolbarCommands", text: "|~ViewToolbar|closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|\n|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|"},
{title: "WindowTitle", text: "<<tiddler SiteTitle>> - <<tiddler SiteSubtitle>>"},
{title: "DefaultTiddlers", text: "[[GettingStarted]]"},
{title: "MainMenu", text: "[[GettingStarted]]"},
{title: "SiteTitle", text: "My TiddlyWiki"},
{title: "SiteSubtitle", text: "a reusable non-linear personal web notebook"},
{title: "SiteUrl", text: ""},
{title: "SideBarOptions", text: '<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "options \u00bb" "Change TiddlyWiki advanced options">>'},
{title: "SideBarTabs", text: '<<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "More lists" TabMore>>'},
{title: "TabMore", text: '<<tabs txtMoreTab "Missing" "Missing tiddlers" TabMoreMissing "Orphans" "Orphaned tiddlers" TabMoreOrphans "Shadowed" "Shadowed tiddlers" TabMoreShadowed>>'}
];
store.shadows.shadows = shadowShadowStore;
for(t=0; t<shadowShadows.length; t++) {
shadowShadowStore.addTiddler(new Tiddler(shadowShadows[t]));
}
// Load the tiddlers built into the TiddlyWiki document
var storeArea = document.getElementById("storeArea"),
tiddlers = tiddlerConverters.deserialize("(DOM)",storeArea);
for(t=0; t<tiddlers.length; t++) {
store.addTiddler(new Tiddler(tiddlers[t]));
}
// Render HelloThere
$("<div/>").html(store.renderTiddler("text/html","HelloThere")).appendTo("body");
})();

View File

@ -1,6 +1,7 @@
(function(){ /*\
title: js/Recipe.js
/* FileRetriever can asynchronously retrieve files from HTTP URLs or the local file system
Recipe processing is in four parts: Recipe processing is in four parts:
@ -32,7 +33,8 @@ At this point tiddlers are placed in the store so that they can be referenced by
4) Finally, the template is processed by replacing the markers with the text of the associated tiddlers 4) Finally, the template is processed by replacing the markers with the text of the associated tiddlers
*/ \*/
(function(){
/*jslint node: true */ /*jslint node: true */
"use strict"; "use strict";
@ -224,7 +226,8 @@ Recipe.tiddlerOutputMapper = {
jsdeprecated: "javascript", jsdeprecated: "javascript",
jquery: "javascript", jquery: "javascript",
shadow: "shadow", shadow: "shadow",
title: "title" title: "title",
jsmodule: "jsmodule"
}; };
Recipe.tiddlerOutputter = { Recipe.tiddlerOutputter = {
@ -269,6 +272,16 @@ Recipe.tiddlerOutputter = {
}, },
title: function(out,tiddlers) { title: function(out,tiddlers) {
out.push(this.store.renderTiddler("text/plain","WindowTitle")); out.push(this.store.renderTiddler("text/plain","WindowTitle"));
},
jsmodule: function(out,tiddlers) {
// JavaScript modules are output as a special script tag
for(var t=0; t<tiddlers.length; t++) {
var title = tiddlers[t],
tid = this.store.getTiddler(title);
out.push("<" + "script type=\"application/x-js-module\" title=\"" + title + "\">");
out.push(tid.fields.text);
out.push("</" + "script>");
}
} }
}; };

View File

@ -1,3 +1,7 @@
/*\
title: js/TextProcessors.js
\*/
(function(){ (function(){
/*jslint node: true */ /*jslint node: true */

View File

@ -1,6 +1,5 @@
(function(){ /*\
title: js/Tiddler.js
/*
Tiddlers are an immutable dictionary of name:value pairs called fields. Values can be a string, an array Tiddlers are an immutable dictionary of name:value pairs called fields. Values can be a string, an array
of strings, or a date. The only field that is required is the `title` field, but useful tiddlers also of strings, or a date. The only field that is required is the `title` field, but useful tiddlers also
@ -21,7 +20,8 @@ The hashmap(s) can specify the "modified" and "created" fields as strings in YY
format or as JavaScript date objects. The "tags" field can be given as a JavaScript array of strings or format or as JavaScript date objects. The "tags" field can be given as a JavaScript array of strings or
as a TiddlyWiki quoted string (eg, "one [[two three]]"). as a TiddlyWiki quoted string (eg, "one [[two three]]").
*/ \*/
(function(){
/*jslint node: true */ /*jslint node: true */
"use strict"; "use strict";
@ -49,6 +49,21 @@ var Tiddler = function(/* tiddler,fields */) {
} }
}; };
Tiddler.standardFields = {
title: { type: "string"},
modifier: { type: "string"},
modified: { type: "date"},
creator: { type: "string"},
created: { type: "date"},
tags: { type: "tags"},
type: { type: "string"},
text: { type: "string"}
}
Tiddler.isStandardField = function(name) {
return name in Tiddler.standardFields;
};
Tiddler.prototype.hasTag = function(tag) { Tiddler.prototype.hasTag = function(tag) {
if(this.tags) { if(this.tags) {
for(var t=0; t<this.tags.length; t++) { for(var t=0; t<this.tags.length; t++) {

View File

@ -1,3 +1,7 @@
/*\
title: js/TiddlerConverters.js
\*/
(function(){ (function(){
/*jslint node: true */ /*jslint node: true */

View File

@ -1,13 +1,16 @@
(function(){ /*\
title: js/TiddlerInput.js
/*
Functions concerned with parsing representations of tiddlers Functions concerned with parsing representations of tiddlers
*/
\*/
(function(){
/*jslint node: true */ /*jslint node: true */
"use strict"; "use strict";
var utils = require("./Utils.js"), var utils = require("./Utils.js"),
Tiddler = require("./Tiddler.js").Tiddler,
util = require("util"); util = require("util");
var tiddlerInput = exports; var tiddlerInput = exports;
@ -88,6 +91,16 @@ var inputTiddlerPlain = function(text,fields) {
return [fields]; return [fields];
}; };
var inputTiddlerJavaScript = function(text,fields) {
var headerCommentRegExp = /^\/\*\\\n((?:^[^\n]*\n)+?)(^\\\*\/$\n?)/mg,
match = headerCommentRegExp.exec(text);
fields.text = text;
if(match) {
fields = parseMetaDataBlock(match[1],fields);
}
return [fields];
};
var inputTiddlerDiv = function(text,fields) { var inputTiddlerDiv = function(text,fields) {
return [parseTiddlerDiv(text,fields)]; return [parseTiddlerDiv(text,fields)];
}; };
@ -157,12 +170,52 @@ var inputTiddlyWiki = function(text,fields) {
return results; return results;
}; };
// Given a reference to a DOM node, return the tiddlers stored in the immediate child nodes
var inputTiddlerDOM = function(node) {
var extractTiddler = function(node) {
var e = node.firstChild;
while(e && e.nodeName.toLowerCase() !== "pre") {
e = e.nextSibling;
}
if(e && node.hasAttribute("title")) {
var i,
attrs = node.attributes,
tiddler = {
text: utils.htmlDecode(e.innerHTML)
};
for(i=attrs.length-1; i >= 0; i--) {
if(attrs[i].specified) {
var value = attrs[i].value,
name = attrs[i].name;
if(!Tiddler.isStandardField(name)) {
value = utils.unescapeLineBreaks(value);
}
tiddler[name] = value;
}
}
return tiddler;
} else {
return null;
}
},
t,tiddlers = [];
for(t = 0; t < node.childNodes.length; t++) {
var tiddler = extractTiddler(node.childNodes[t]);
if(tiddler) {
tiddlers.push(tiddler);
}
}
return tiddlers;
};
tiddlerInput.register = function(tiddlerConverters) { tiddlerInput.register = function(tiddlerConverters) {
tiddlerConverters.registerDeserializer(".txt","text/plain",inputTiddlerPlain); tiddlerConverters.registerDeserializer(".txt","text/plain",inputTiddlerPlain);
tiddlerConverters.registerDeserializer(".js","application/javascript",inputTiddlerJavaScript);
tiddlerConverters.registerDeserializer(".tiddler","application/x-tiddler-html-div",inputTiddlerDiv); tiddlerConverters.registerDeserializer(".tiddler","application/x-tiddler-html-div",inputTiddlerDiv);
tiddlerConverters.registerDeserializer(".tid","application/x-tiddler",inputTiddler); tiddlerConverters.registerDeserializer(".tid","application/x-tiddler",inputTiddler);
tiddlerConverters.registerDeserializer(".json","application/json",inputTiddlerJSON); tiddlerConverters.registerDeserializer(".json","application/json",inputTiddlerJSON);
tiddlerConverters.registerDeserializer(".tiddlywiki","application/x-tiddlywiki",inputTiddlyWiki); tiddlerConverters.registerDeserializer(".tiddlywiki","application/x-tiddlywiki",inputTiddlyWiki);
tiddlerConverters.registerDeserializer("(DOM)","(DOM)",inputTiddlerDOM);
}; };
})(); })();

View File

@ -1,8 +1,10 @@
(function(){ /*\
title: js/TiddlerOutput.js
/*
Functions concerned with parsing representations of tiddlers Functions concerned with parsing representations of tiddlers
*/
\*/
(function(){
/*jslint node: true */ /*jslint node: true */
"use strict"; "use strict";

View File

@ -1,17 +1,18 @@
(function(){ /*\
title: js/Utils.js
/*
Various static utility functions. Various static utility functions.
This file is a bit of a dumping ground; the expectation is that most of these functions will be refactored. This file is a bit of a dumping ground; the expectation is that most of these functions will be refactored.
*/
\*/
(function(){
/*jslint node: true */ /*jslint node: true */
"use strict"; "use strict";
var utils = exports; var utils = exports;
utils.deepCopy = function(v) { utils.deepCopy = function(v) {
var r,t; var r,t;
if(v instanceof Array) { if(v instanceof Array) {
@ -30,7 +31,6 @@ utils.deepCopy = function(v) {
return r; return r;
}; };
// Pad a string to a certain length with zeros // Pad a string to a certain length with zeros
utils.zeroPad = function(n,d) utils.zeroPad = function(n,d)
{ {
@ -186,4 +186,8 @@ utils.entityDecode = function(s) {
utils.htmlEntities = {quot:34, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 }; utils.htmlEntities = {quot:34, amp:38, apos:39, lt:60, gt:62, nbsp:160, iexcl:161, cent:162, pound:163, curren:164, yen:165, brvbar:166, sect:167, uml:168, copy:169, ordf:170, laquo:171, not:172, shy:173, reg:174, macr:175, deg:176, plusmn:177, sup2:178, sup3:179, acute:180, micro:181, para:182, middot:183, cedil:184, sup1:185, ordm:186, raquo:187, frac14:188, frac12:189, frac34:190, iquest:191, Agrave:192, Aacute:193, Acirc:194, Atilde:195, Auml:196, Aring:197, AElig:198, Ccedil:199, Egrave:200, Eacute:201, Ecirc:202, Euml:203, Igrave:204, Iacute:205, Icirc:206, Iuml:207, ETH:208, Ntilde:209, Ograve:210, Oacute:211, Ocirc:212, Otilde:213, Ouml:214, times:215, Oslash:216, Ugrave:217, Uacute:218, Ucirc:219, Uuml:220, Yacute:221, THORN:222, szlig:223, agrave:224, aacute:225, acirc:226, atilde:227, auml:228, aring:229, aelig:230, ccedil:231, egrave:232, eacute:233, ecirc:234, euml:235, igrave:236, iacute:237, icirc:238, iuml:239, eth:240, ntilde:241, ograve:242, oacute:243, ocirc:244, otilde:245, ouml:246, divide:247, oslash:248, ugrave:249, uacute:250, ucirc:251, uuml:252, yacute:253, thorn:254, yuml:255, OElig:338, oelig:339, Scaron:352, scaron:353, Yuml:376, fnof:402, circ:710, tilde:732, Alpha:913, Beta:914, Gamma:915, Delta:916, Epsilon:917, Zeta:918, Eta:919, Theta:920, Iota:921, Kappa:922, Lambda:923, Mu:924, Nu:925, Xi:926, Omicron:927, Pi:928, Rho:929, Sigma:931, Tau:932, Upsilon:933, Phi:934, Chi:935, Psi:936, Omega:937, alpha:945, beta:946, gamma:947, delta:948, epsilon:949, zeta:950, eta:951, theta:952, iota:953, kappa:954, lambda:955, mu:956, nu:957, xi:958, omicron:959, pi:960, rho:961, sigmaf:962, sigma:963, tau:964, upsilon:965, phi:966, chi:967, psi:968, omega:969, thetasym:977, upsih:978, piv:982, ensp:8194, emsp:8195, thinsp:8201, zwnj:8204, zwj:8205, lrm:8206, rlm:8207, ndash:8211, mdash:8212, lsquo:8216, rsquo:8217, sbquo:8218, ldquo:8220, rdquo:8221, bdquo:8222, dagger:8224, Dagger:8225, bull:8226, hellip:8230, permil:8240, prime:8242, Prime:8243, lsaquo:8249, rsaquo:8250, oline:8254, frasl:8260, euro:8364, image:8465, weierp:8472, real:8476, trade:8482, alefsym:8501, larr:8592, uarr:8593, rarr:8594, darr:8595, harr:8596, crarr:8629, lArr:8656, uArr:8657, rArr:8658, dArr:8659, hArr:8660, forall:8704, part:8706, exist:8707, empty:8709, nabla:8711, isin:8712, notin:8713, ni:8715, prod:8719, sum:8721, minus:8722, lowast:8727, radic:8730, prop:8733, infin:8734, ang:8736, and:8743, or:8744, cap:8745, cup:8746, int:8747, there4:8756, sim:8764, cong:8773, asymp:8776, ne:8800, equiv:8801, le:8804, ge:8805, sub:8834, sup:8835, nsub:8836, sube:8838, supe:8839, oplus:8853, otimes:8855, perp:8869, sdot:8901, lceil:8968, rceil:8969, lfloor:8970, rfloor:8971, lang:9001, rang:9002, loz:9674, spades:9824, clubs:9827, hearts:9829, diams:9830 };
utils.unescapeLineBreaks = function(s) {
return s.replace(/\\n/mg,"\n").replace(/\\b/mg," ").replace(/\\s/mg,"\\").replace(/\r/mg,"");
};
})(); })();

View File

@ -1,3 +1,7 @@
/*\
title: js/WikiStore.js
\*/
(function(){ (function(){
/*jslint node: true */ /*jslint node: true */

View File

@ -1,8 +1,5 @@
(function(){ /*\
title: js/WikiTextParser.js
/*
WikiTextParser.js
Parses a block of tiddlywiki-format wiki text into a parse tree object. Parses a block of tiddlywiki-format wiki text into a parse tree object.
@ -23,7 +20,8 @@ Text nodes are:
{type: "text", value: "string of text node"} {type: "text", value: "string of text node"}
*/ \*/
(function(){
/*jslint node: true */ /*jslint node: true */
"use strict"; "use strict";

View File

@ -1,3 +1,7 @@
/*\
title: js/WikiTextProcessor.js
\*/
(function(){ (function(){
/*jslint node: true */ /*jslint node: true */
@ -8,7 +12,11 @@ var WikiTextRules = require("./WikiTextRules.js"),
/* /*
Creates a new instance of the wiki text processor with the specified options. The Creates a new instance of the wiki text processor with the specified options. The
options are a hashmap of optional members as follows: options are a hashmap of mandatory members as follows:
textProcessors: The TextProcessors object to use to parse any cascaded content (eg transclusion)
Planned:
enableRules: An array of names of wiki text rules to enable. If not specified, all rules are available enableRules: An array of names of wiki text rules to enable. If not specified, all rules are available
extraRules: An array of additional rule handlers to add extraRules: An array of additional rule handlers to add
@ -16,6 +24,7 @@ options are a hashmap of optional members as follows:
extraMacros: An array of additional macro handlers to add extraMacros: An array of additional macro handlers to add
*/ */
var WikiTextProcessor = function(options) { var WikiTextProcessor = function(options) {
this.textProcessors = options.textProcessors;
this.rules = WikiTextRules.rules; this.rules = WikiTextRules.rules;
var pattern = []; var pattern = [];
for(var n=0; n<this.rules.length; n++) { for(var n=0; n<this.rules.length; n++) {

View File

@ -1,14 +1,13 @@
(function(){ /*\
title: js/WikiTextRenderer.js
/* \*/
Wiki text macro implementation (function(){
*/
/*jslint node: true */ /*jslint node: true */
"use strict"; "use strict";
var ArgParser = require("./ArgParser.js").ArgParser, var ArgParser = require("./ArgParser.js").ArgParser,
WikiTextParserModule = require("./WikiTextParser.js"),
utils = require("./Utils.js"), utils = require("./Utils.js"),
util = require("util"); util = require("util");
@ -169,16 +168,17 @@ WikiTextRenderer.macros = {
}, },
tiddler: { tiddler: {
handler: function(macroNode) { handler: function(macroNode) {
var args = new ArgParser(macroNode.params,{defaultName:"name"}), var args = new ArgParser(macroNode.params,{defaultName:"name",cascadeDefaults:true}),
targetTitle = args.getValueByName("name",null), targetTitle = args.getValueByName("name",null),
withTokens = args.getValuesByName("with",[]), withTokens = args.getValuesByName("with",[]),
tiddler = this.store.getTiddler(targetTitle),
text = this.store.getTiddlerText(targetTitle,""), text = this.store.getTiddlerText(targetTitle,""),
t; t;
for(t=0; t<withTokens.length; t++) { for(t=0; t<withTokens.length; t++) {
var placeholderRegExp = new RegExp("\\$"+(t+1),"mg"); var placeholderRegExp = new RegExp("\\$"+(t+1),"mg");
text = text.replace(placeholderRegExp,withTokens[t]); text = text.replace(placeholderRegExp,withTokens[t]);
} }
var parseTree = new WikiTextParserModule.WikiTextParser(text,this.parser.processor); var parseTree = this.parser.processor.textProcessors.parse(tiddler.fields.type,text);
for(t=0; t<parseTree.children.length; t++) { for(t=0; t<parseTree.children.length; t++) {
macroNode.output.push(parseTree.children[t]); macroNode.output.push(parseTree.children[t]);
} }

View File

@ -1,3 +1,7 @@
/*\
title: js/WikiTextRules.js
\*/
(function(){ (function(){
/*jslint node: true */ /*jslint node: true */

View File

@ -56,7 +56,9 @@ var textProcessors = new TextProcessors(),
currSwitch = 0; currSwitch = 0;
textProcessors.registerTextProcessor("text/x-tiddlywiki",new WikiTextProcessor({})); textProcessors.registerTextProcessor("text/x-tiddlywiki",new WikiTextProcessor({
textProcessors: textProcessors
}));
// Register the standard tiddler serializers and deserializers // Register the standard tiddler serializers and deserializers
tiddlerInput.register(tiddlerConverters); tiddlerInput.register(tiddlerConverters);
tiddlerOutput.register(tiddlerConverters); tiddlerOutput.register(tiddlerConverters);

122
tiddlywiki5/BootLoader.js Normal file
View File

@ -0,0 +1,122 @@
(function() {
/*jslint node: true */
"use strict";
/*
A hashmap containing hashmaps about each module:
{
module1: {
text: "<text of module1>",
executed: true
},
module2: {
text: "<text of module2>"
}
}
*/
var modules = {};
/*
The built in modules
*/
var builtInModules = {
util: {
},
path: {
},
fs: {
},
url: {
},
http: {
},
https: {
}
};
/*
Given the absolute path of a srcModule, and a relative reference to a dstModule, return the fully resolved module name
*/
function resolveModuleName(srcModule,dstModule) {
var src = srcModule.split("/"),
dst = dstModule.split("/"),
c;
// If the destination starts with / or ./ then it's a reference to an ordinary module
if(dstModule.substr(0,1) === "/" || dstModule.substr(0,2) === "./" ) {
// Remove the filename part of the src path
src.splice(src.length-1,1);
// Process the destination path bit by bit
while(dst.length > 0) {
c = dst.shift();
switch(c) {
case ".": // Ignore dots
break;
case "..": // Slice off the last src directory for a double dot
src.splice(src.length-1,1);
break;
default: // Copy everything else across
src.push(c);
break;
}
}
return src.join("/");
} else {
// If there was no / or ./ then it's a built in module
return dstModule;
}
}
function executeModule(name) {
var require = function(filepath) {
return executeModule(resolveModuleName(name,filepath));
},
exports = {},
module = modules[name];
if(!module) {
throw new Error("Cannot find module named '" + name + "'");
}
if(module.executed) {
return module.exports;
} else {
// This way of executing modules isn't perfect. Everything that is in scope here is available to the
// scripts, so this mechanism should only be used for trusted code
var script = "(function (require,exports){" + modules[name].text + "})(require,exports);"
eval(script);
module.executed = true;
module.exports = exports;
return exports;
}
}
function findModules(childNodes) {
// Iterate using the DOM directly; jQuery methods seem to bypass comment nodes
childNodes = childNodes || document.childNodes;
for(var t=0; t<childNodes.length; t++) {
var node = childNodes[t];
if(node.nodeName.toLowerCase() === "script" && node.type === "application/x-js-module") {
modules[node.title] = {text: node.textContent};
} else if(childNodes[t].childNodes.length > 0) {
findModules(childNodes[t].childNodes);
}
}
}
$(function() {
// Start with the embedded JavaScript modules
for(var t in builtInModules) {
modules[t] = builtInModules;
}
// Add any modules packed into script tags in the page
findModules();
// Execute the main module
executeModule("js/Main.js");
})
})();

View File

@ -0,0 +1,24 @@
template: tiddlywiki5.template.html
copyright: ../copyright.txt
jslib: ../test/tiddlywiki.2.6.5/source/tiddlywiki/jquery/jquery.js
jsmodule: ../js/ArgParser.js
jsmodule: ../js/FileRetriever.js
jsmodule: ../js/Utils.js
jsmodule: ../js/Tiddler.js
jsmodule: ../js/TiddlerConverters.js
jsmodule: ../js/TiddlerInput.js
jsmodule: ../js/TiddlerOutput.js
jsmodule: ../js/WikiStore.js
jsmodule: ../js/TextProcessors.js
jsmodule: ../js/WikiTextProcessor.js
jsmodule: ../js/WikiTextParser.js
jsmodule: ../js/WikiTextRules.js
jsmodule: ../js/WikiTextRenderer.js
jsmodule: ../js/Main.js
jsboot: BootLoader.js
recipe: ../test/tiddlywiki.2.6.5/source/tiddlywiki.com/tiddlywiki-com-ref/split.recipe
recipe: ../test/tiddlywiki.2.6.5/source/tiddlywiki.com/tiddlywiki-com/split.recipe

View File

@ -0,0 +1,32 @@
<!doctype html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="copyright" content="
&lt;!--@@copyright@@--&gt;
" />
<title>
<!--@@title@@-->
</title>
<style id="styleArea" type="text/css">
<!--@@style@@-->
</style>
</head>
<body>
<noscript>
<!--@@noscript@@-->
</noscript>
<div id="shadowArea" style="display:none;">
<!--@@shadow@@-->
</div>
<div id="storeArea" style="display:none;">
<!--@@tiddler@@-->
</div>
<script id="jsLibArea" type="text/javascript">
<!--@@jslib@@-->
</script>
<!--@@jsmodule@@-->
<script id="jsBootArea" type="text/javascript">
<!--@@jsboot@@-->
</script>
</body>
</html>

12
tw5.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/sh
# build TiddlyWiki5
# create a temporary directory if it doesn't already exist
mkdir -p tmp
mkdir -p tmp/tw5
node tiddlywiki.js --recipe $PWD/tiddlywiki5/tiddlywiki5.recipe --savewiki tmp/tw5 || exit 1
# open the result
open -a /Applications/Google\ Chrome.app tmp/tw5/index.html

View File

@ -35,7 +35,9 @@ var testdirectory = process.argv[2],
titles = [], titles = [],
f,t,extname,basename; f,t,extname,basename;
textProcessors.registerTextProcessor("text/x-tiddlywiki",new WikiTextProcessor({})); textProcessors.registerTextProcessor("text/x-tiddlywiki",new WikiTextProcessor({
textProcessors: textProcessors
}));
tiddlerInput.register(tiddlerConverters); tiddlerInput.register(tiddlerConverters);
for(f=0; f<files.length; f++) { for(f=0; f<files.length; f++) {