diff --git a/js/BitmapParser.js b/js/BitmapParser.js index 1aaffe1fa..fb072fdb3 100644 --- a/js/BitmapParser.js +++ b/js/BitmapParser.js @@ -9,6 +9,17 @@ Compiles bitmap images into JavaScript functions that render them in HTML /*jslint node: true */ "use strict"; +var utils = require("./Utils.js"); + +var BitmapRenderer = function(handlerCode) { + /*jslint evil: true */ + this.handler = eval(handlerCode); +}; + +BitmapRenderer.prototype.render = function(tiddler,store) { + return this.handler(tiddler,store,utils); +}; + // The parse tree is degenerate var BitmapParseTree = function() { this.dependencies = []; @@ -16,7 +27,7 @@ var BitmapParseTree = function() { BitmapParseTree.prototype.compile = function(type) { if(type === "text/html") { - return "(function (tiddler,store,utils) {return '';})"; + return new BitmapRenderer("(function (tiddler,store,utils) {return '';})"); } else { return null; } diff --git a/js/JavaScriptParseTree.js b/js/JavaScriptParseTree.js index 17463c089..fc660f9ec 100644 --- a/js/JavaScriptParseTree.js +++ b/js/JavaScriptParseTree.js @@ -28,7 +28,11 @@ var JavaScriptParseTree = function(tree) { // Render the entire JavaScript tree object to JavaScript source code JavaScriptParseTree.prototype.render = function() { var output = []; - this.renderSubTree(output,this.tree); + if(this.tree instanceof Array) { + this.renderSubTree(output,this.tree); + } else { + this.renderNode(output,this.tree); + } var r = output.join(""); return r; }; diff --git a/js/SVGParser.js b/js/SVGParser.js index 754bd21fe..c0bdbc873 100644 --- a/js/SVGParser.js +++ b/js/SVGParser.js @@ -9,6 +9,17 @@ Compiles SVG images into JavaScript functions that render them in HTML /*jslint node: true */ "use strict"; +var utils = require("./Utils.js"); + +var SVGRenderer = function(handlerCode) { + /*jslint evil: true */ + this.handler = eval(handlerCode); +}; + +SVGRenderer.prototype.render = function(tiddler,store) { + return this.handler(tiddler,store,utils); +}; + // The parse tree is degenerate var SVGParseTree = function() { this.dependencies = []; @@ -16,7 +27,7 @@ var SVGParseTree = function() { SVGParseTree.prototype.compile = function(type) { if(type === "text/html") { - return "(function (tiddler,store,utils) {return '';})"; + return new SVGRenderer("(function (tiddler,store,utils) {return '';})"); } else { return null; } diff --git a/js/WikiStore.js b/js/WikiStore.js index 349986071..f283d613a 100755 --- a/js/WikiStore.js +++ b/js/WikiStore.js @@ -301,30 +301,25 @@ WikiStore.prototype.parseTiddler = function(title) { }; /* -Compiles a block of text of a specified type into a JavaScript function that renders the text in a particular MIME type +Compiles a block of text of a specified type into a renderer that renders the text in a particular MIME type */ WikiStore.prototype.compileText = function(type,text,targetType) { - /*jslint evil: true */ var tree = this.parseText(type,text); - return eval(tree.compile(targetType)); + return tree.compile(targetType); }; /* Compiles a JavaScript function that renders a tiddler in a particular MIME type */ WikiStore.prototype.compileTiddler = function(title,type) { - /*jslint evil: true */ var tiddler = this.getTiddler(title), renderers = this.getCacheForTiddler(title,"renderers",function() { return {}; }); if(tiddler) { if(!renderers[type]) { - var tree = this.parseTiddler(title), - text = tree.compile(type); - // Add a source URL to help debugging (see http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/) - text += "//@ sourceURL=" + encodeURIComponent(title) + "-" + type; - renderers[type] = eval(text); + var tree = this.parseTiddler(title); + renderers[type] = tree.compile(type); } return renderers[type]; } else { @@ -337,8 +332,8 @@ Render a block of text of a specified type into a particular MIME type */ WikiStore.prototype.renderText = function(type,text,targetType,asTitle) { var tiddler = this.getTiddler(asTitle), - fn = this.compileText(type,text,targetType); - return fn(tiddler,this,utils); + renderer = this.compileText(type,text,targetType); + return renderer.render(tiddler,this); }; /* @@ -348,17 +343,17 @@ store.renderTiddler("text/html",templateTitle,tiddlerTitle) */ WikiStore.prototype.renderTiddler = function(targetType,title,asTitle) { var tiddler = this.getTiddler(title), - fn = this.compileTiddler(title,targetType), + renderer = this.compileTiddler(title,targetType), renditions = this.getCacheForTiddler(title,"renditions",function() { return {}; }); if(tiddler) { if(asTitle) { var asTiddler = this.getTiddler(asTitle); - return fn(asTiddler,this,utils); + return renderer.render(asTiddler,this); } else { if(!renditions[targetType]) { - renditions[targetType] = fn(tiddler,this,utils); + renditions[targetType] = renderer.render(tiddler,this); } return renditions[targetType]; } diff --git a/js/WikiTextParseTree.js b/js/WikiTextParseTree.js index 7d0af3ef1..1e50dd3e9 100644 --- a/js/WikiTextParseTree.js +++ b/js/WikiTextParseTree.js @@ -9,7 +9,8 @@ A container for the parse tree generated by parsing wikitext /*jslint node: true */ "use strict"; -var ArgParser = require("./ArgParser.js").ArgParser, +var WikiTextRenderer = require("./WikiTextRenderer.js").WikiTextRenderer, + ArgParser = require("./ArgParser.js").ArgParser, utils = require("./Utils.js"); // Intialise the parse tree object @@ -22,22 +23,26 @@ var WikiTextParseTree = function(tree,dependencies,store) { // Compile the parse tree into a JavaScript function that returns the required // representation of the tree WikiTextParseTree.prototype.compile = function(type,treenode) { + /*jslint evil: true */ treenode = treenode || this.tree; - var output = []; + var renderer = new WikiTextRenderer(), + renderStep = {}, + renderStepIndex = renderer.addRenderStep(renderStep), + output = []; if(type === "text/html") { - this.compileSubTreeHtml(output,treenode); + this.compileSubTreeHtml(output,renderer,treenode); } else if(type === "text/plain") { - this.compileSubTreePlain(output,treenode); + this.compileSubTreePlain(output,renderer,treenode); } else { return null; } - // And then wrap the javascript tree and render it back into JavaScript code + // Create the parse tree for the rendering step function definition var parseTree = this.store.jsParser.createTree( [ { type: "Function", name: null, - params: ["tiddler","store","utils"], // These are the parameters passed to the tiddler function; must match the invocation in WikiStore.renderTiddler() + params: ["tiddler","renderer","store","utils"], // These are the parameters passed to the tiddler function; must match the invocation in WikiStore.renderTiddler() elements: [ { type: "ReturnStatement", @@ -61,11 +66,13 @@ WikiTextParseTree.prototype.compile = function(type,treenode) { ] } ]); - var r = parseTree.render(); - return r; + renderStep.step = renderStepIndex; + renderStep.dependencies = []; + renderStep.handler = eval(parseTree.render()); + return renderer; }; -WikiTextParseTree.prototype.pushString = function(output,s) { +var pushString = function(output,s) { var last = output[output.length-1]; if(output.length > 0 && last.type === "StringLiterals") { last.value.push(s); @@ -77,66 +84,80 @@ WikiTextParseTree.prototype.pushString = function(output,s) { } }; -WikiTextParseTree.prototype.compileMacroCall = function(output,type,node) { +WikiTextParseTree.prototype.compileMacroCall = function(output,renderer,type,node) { + /*jslint evil: true */ var name = node.name, params = node.params, macro = this.store.macros[name], p, - n; + n, + renderStep = {}, + renderStepIndex = renderer.addRenderStep(renderStep); + // Check for errors if(!macro) { - this.pushString(output,"{{** Unknown macro '" + name + "' **}}"); + pushString(output,"{{** Unknown macro '" + name + "' **}}"); return; } if(macro.types.indexOf(type) === -1) { - this.pushString(output,"{{** Macro '" + name + "' cannot render to MIME type '" + type + "'**}}"); + pushString(output,"{{** Macro '" + name + "' cannot render to MIME type '" + type + "'**}}"); return; } + // Compose the macro call as a render function var macroCall = { - type: "FunctionCall", - name: { - base: { - base: { - base: { - name: "store", - type: "Variable"}, - name: "macros", - type: "PropertyAccess"}, + type: "Function", + name: null, + params: ["tiddler","renderer","store","utils"], // These are the parameters passed to the tiddler function; must match the invocation in WikiStore.renderTiddler() + elements: [ { + type: "ReturnStatement", + value: { + type: "FunctionCall", name: { + base: { + base: { + base: { + name: "store", + type: "Variable"}, + name: "macros", + type: "PropertyAccess"}, + name: { + type: "StringLiteral", + value: name}, + type: "PropertyAccess"}, + name: "handler", + type: "PropertyAccess"}, + "arguments": [ { type: "StringLiteral", - value: name}, - type: "PropertyAccess"}, - name: "handler", - type: "PropertyAccess"}, - "arguments": [ { - type: "StringLiteral", - value: type - },{ - type: "Variable", - name: "tiddler" - },{ - type: "Variable", - name: "store" - },{ - type: "ObjectLiteral", - properties: [] - }] + value: type + },{ + type: "Variable", + name: "tiddler" + },{ + type: "Variable", + name: "store" + },{ + type: "ObjectLiteral", + properties: [] + }] + }}] }; + // Slot the parameters into the macro call for(p in params) { if(params[p].type === "string") { n = {type: "StringLiteral", value: params[p].value}; } else { n = this.store.jsParser.parse(params[p].value).tree.elements[0]; } - macroCall["arguments"][3].properties.push({ + macroCall.elements[0].value["arguments"][3].properties.push({ type: "PropertyAssignment", name: p, value: n }); } + // Compile any child nodes if(node.children) { var subOutput = []; - this.compileSubTreeHtml(subOutput,node.children); - macroCall["arguments"].push({ + this.compileSubTreeHtml(subOutput,renderer,node.children); + macroCall.elements[0].value["arguments"].push({ type: "FunctionCall", name: { type: "PropertyAccess", @@ -152,86 +173,108 @@ WikiTextParseTree.prototype.compileMacroCall = function(output,type,node) { }] }); } + renderStep.step = renderStepIndex; + renderStep.dependencies = node.dependencies; + renderStep.handler = eval(this.store.jsParser.createTree(macroCall).render()); var wrapperTag = macro.wrapperTag || "div"; if(type === "text/html") { - this.pushString(output,utils.stitchElement(wrapperTag,{ - "data-tw-macro": name + pushString(output,utils.stitchElement(wrapperTag,{ + "data-tw-macro": name, + "data-tw-render-step": renderStepIndex })); } - output.push(macroCall); + output.push({ + type: "FunctionCall", + name: { + base: { + name: "renderer", + type: "Variable"}, + name: "render", + type: "PropertyAccess"}, + "arguments": [ { + type: "Variable", + name: "tiddler" + },{ + type: "Variable", + name: "store" + },{ + type: "NumericLiteral", + value: renderStepIndex + }] + }); if(type === "text/html") { - this.pushString(output,""); + pushString(output,""); } }; -WikiTextParseTree.prototype.compileElementHtml = function(output,element,options) { +WikiTextParseTree.prototype.compileElementHtml = function(output,renderer,element,options) { options = options || {}; - this.pushString(output,utils.stitchElement(element.type,element.attributes,{ + pushString(output,utils.stitchElement(element.type,element.attributes,{ selfClosing: options.selfClosing })); if(!options.selfClosing) { if(element.children) { - this.compileSubTreeHtml(output,element.children); + this.compileSubTreeHtml(output,renderer,element.children); } - this.pushString(output,""); + pushString(output,""); } }; -WikiTextParseTree.prototype.compileSubTreeHtml = function(output,tree) { +WikiTextParseTree.prototype.compileSubTreeHtml = function(output,renderer,tree) { for(var t=0; t"); } + output.push(utils.stitchElement("span",null, + {classNames: ["treeNode","splitLabel"]})); + output.push(utils.stitchElement("span",{"data-tw-treenode-type": "renderStepDependencies"},{ + content: "dependencies", + classNames: ["splitLabelLeft"] + })); + output.push(utils.stitchElement("span",null,{ + content: utils.htmlEncode(node.dependencies === null ? "*" : node.dependencies.join(", ")), + classNames: ["splitLabelRight"] + })); + output.push(""); if(node.children) { utils.renderObject(output,type,node.children,customTemplates); } diff --git a/js/WikiTextParser.js b/js/WikiTextParser.js index 348a4c2ae..c5254554e 100644 --- a/js/WikiTextParser.js +++ b/js/WikiTextParser.js @@ -83,6 +83,18 @@ WikiTextParser.prototype.addDependency = function(dependency) { } }; +WikiTextParser.prototype.addDependencies = function(dependencies) { + if(dependencies === null) { + this.dependencies = null; + } else if(this.dependencies !== null){ + for(var t=0; t"); + output.push(utils.stitchElement("span",null, + {classNames: ["treeNode","splitLabel"]})); + output.push(utils.stitchElement("span",{"data-tw-treenode-type": "renderStepHandler"},{ + content: "handler", + classNames: ["splitLabelLeft"] + })); + output.push(utils.stitchElement("code",null,{ + content: utils.htmlEncode(node.handler.toString()).replace(/\n/g,"
"), + classNames: ["splitLabelRight"] + })); + output.push(""); + return true; + } + return false; + } + ]; + utils.renderObject(output,type,this.renderSteps,customTemplates); + return output.join(""); +}; + +exports.WikiTextRenderer = WikiTextRenderer; + +})(); diff --git a/js/WikiTextRules.js b/js/WikiTextRules.js index 68a3335fa..c1ee92c0b 100755 --- a/js/WikiTextRules.js +++ b/js/WikiTextRules.js @@ -105,24 +105,29 @@ var enclosedTextHelper = function(w) { var parseMacroCall = function(w,name,paramString) { var macro = w.store.macros[name], - params = {}; + params = {}, + dependencies = []; if(macro) { if(macro.dependentAll) { - w.addDependency(null); + dependencies = null; } var args = new ArgParser(paramString,{defaultName: "anon"}), insertParam = function(param,name,arg) { + if(param.dependentAll) { + dependencies = null; + } if(param.type === "tiddler") { - w.addDependency(arg.evaluated ? null : arg.string); + if(arg.evaluated) { + dependencies = null; + } else if(dependencies !== null) { + dependencies.push(arg.string); + } } params[name] = {type: arg.evaluated ? "eval" : "string", value: arg.string}; }; for(var m in macro.params) { var param = macro.params[m], arg; - if(param.dependentAll) { - w.addDependency(null); - } if("byPos" in param && args.byPos[param.byPos]) { arg = args.byPos[param.byPos].v; insertParam(param,m,arg); @@ -137,7 +142,8 @@ var parseMacroCall = function(w,name,paramString) { } } } - return {type: "macro", name: name, params: params}; + w.addDependencies(dependencies); + return {type: "macro", name: name, params: params, dependencies: dependencies}; }; var rules = [ @@ -467,16 +473,19 @@ var rules = [ children: [{ type: "text", value: "" - }]}, + }], + dependencies: []}, text = lookaheadMatch[1]; if(lookaheadMatch[3]) { // Pretty bracketted link var link = lookaheadMatch[3]; e.params.target.value = link; + e.dependencies.push(link); w.addDependency(link); } else { // Simple bracketted link e.params.target.value = text; + e.dependencies.push(text); w.addDependency(text); } e.children[0].value = text; @@ -511,7 +520,10 @@ var rules = [ children: [{ type: "text", value: w.source.substring(w.matchStart,w.nextMatch) - }]}; + }], + dependencies: [ + w.matchText + ]}; w.addDependency(w.matchText); w.output.push(link); } else { @@ -531,7 +543,10 @@ var rules = [ children: [{ type: "text", value: w.source.substring(w.matchStart,w.nextMatch) - }]}; + }], + dependencies: [ + w.matchText + ]}; w.addDependency(w.matchText); w.output.push(e); } @@ -562,8 +577,10 @@ var rules = [ image.params.text = {type: "string", value: lookaheadMatch[3]}; } image.params.src.value = lookaheadMatch[4]; + image.dependencies = [lookaheadMatch[4]]; if(lookaheadMatch[5]) { link.params.target.value = lookaheadMatch[5]; + link.dependencies = [lookaheadMatch[5]]; w.output.push(link); } else { w.output.push(image); diff --git a/js/macros/info.js b/js/macros/info.js index 785fcdf8e..01e5961f8 100644 --- a/js/macros/info.js +++ b/js/macros/info.js @@ -25,9 +25,7 @@ exports.macro = { return "Parse tree: " + parseTree.toString(type); //break; case "compiled": - return "Compiled as: " + utils.stitchElement("pre",null,{ - content: encoder(parseTree.compile(type)) - }); + return "Compiled as: " + parseTree.compile(type).toString(type); //break; case "dependencies": if(parseTree.dependencies === null) { diff --git a/js/macros/list.js b/js/macros/list.js index 65d5a0e1e..aff019ab8 100644 --- a/js/macros/list.js +++ b/js/macros/list.js @@ -61,11 +61,11 @@ exports.macro = { if(tiddlers.length === 0) { return params.emptyMessage ? encoder(params.emptyMessage) : ""; } else { - var fn = store.compileText(templateType,templateText,type); + var renderer = store.compileText(templateType,templateText,type); pushTag(""); diff --git a/readme.md b/readme.md index bf98c2468..3567c715a 100644 --- a/readme.md +++ b/readme.md @@ -1,12 +1,12 @@ -

Welcome to TiddlyWiki5

Welcome to TiddlyWiki5, an interactive wiki written in JavaScript to run in the browser or under node.js. It is a reboot of TiddlyWiki (http://www.tiddlywiki.com/), the now venerable, reusable non-linear personal web notebook first released in 2004.

TiddlyWiki is based on the idea of making information more useful by modelling it in the smallest meaningful semantic units, referred to as "tiddlers". Structure comes from links, tags, and stories (sequences of tiddlers). Tiddlers use a wikitext notation that concisely represents a wide range of text formatting and hypertext features.

TiddlyWiki has earned an enduring place as a tool that people love using for its rich, interactive interface to manipulate complex data with structure that doesn't easily fit into conventional tools like spreadsheets or wordprocessors. Because people can use it without needing any complicated server infrastructure, and because it is open source, it has bought unprecedented freedom to people to keep their precious information under their own control. TiddlyWiki was originally created by JeremyRuston and is now a thriving open source project with a busy Community of independent developers.

Usage

TiddlyWiki5 can be used on the command line to perform an extensive set of operations based on RecipeFiles, TiddlerFiles and TiddlyWikiFiles.

Usage:
+

Welcome to TiddlyWiki5

Welcome to TiddlyWiki5, an interactive wiki written in JavaScript to run in the browser or under node.js. It is a reboot of TiddlyWiki (http://www.tiddlywiki.com/), the now venerable, reusable non-linear personal web notebook first released in 2004.

TiddlyWiki is based on the idea of making information more useful by modelling it in the smallest meaningful semantic units, referred to as "tiddlers". Structure comes from links, tags, and stories (sequences of tiddlers). Tiddlers use a wikitext notation that concisely represents a wide range of text formatting and hypertext features.

TiddlyWiki has earned an enduring place as a tool that people love using for its rich, interactive interface to manipulate complex data with structure that doesn't easily fit into conventional tools like spreadsheets or wordprocessors. Because people can use it without needing any complicated server infrastructure, and because it is open source, it has bought unprecedented freedom to people to keep their precious information under their own control. TiddlyWiki was originally created by JeremyRuston and is now a thriving open source project with a busy Community of independent developers.

Usage

TiddlyWiki5 can be used on the command line to perform an extensive set of operations based on RecipeFiles, TiddlerFiles and TiddlyWikiFiles.

Usage:
node tiddlywiki.js <options> -
The command line options are processed sequentially from left to right. Processing pauses during long operations, like loading a recipe file and all the subrecipes and tiddlers that it references. The following options are available:
--recipe <filepath>Loads a specfied .recipe file
--load <filepath>Load additional tiddlers from 2.x.x TiddlyWiki files (.html), .tiddler, .tid, .json or other files
--savewiki <dirpath>Saves all the loaded tiddlers as a single file TiddlyWiki called index.html and an RSS feed called index.xml in a new directory of the specified name
--savetiddler <title> <filename> [<type>]Save an individual tiddler as a specified MIME type, defaults to text/html
--savetiddlers <outdir>Saves all the loaded tiddlers as .tid files in the specified directory
--servewiki <port>Serve the cooked TiddlyWiki over HTTP at /
--servetiddlers <port>Serve individual tiddlers over HTTP at /tiddlertitle
--wikitest <dir>Run wikification tests against the tiddlers in the given directory
--dumpstoreDump the TiddlyWiki store in JSON format
--dumprecipeDump the current recipe in JSON format
--verboseverbose output, useful for debugging

Examples

This example loads the tiddlers from a TiddlyWiki HTML file and makes them available over HTTP:
+
The command line options are processed sequentially from left to right. Processing pauses during long operations, like loading a recipe file and all the subrecipes and tiddlers that it references. The following options are available:
--recipe <filepath>Loads a specfied .recipe file
--load <filepath>Load additional tiddlers from 2.x.x TiddlyWiki files (.html), .tiddler, .tid, .json or other files
--savewiki <dirpath>Saves all the loaded tiddlers as a single file TiddlyWiki called index.html and an RSS feed called index.xml in a new directory of the specified name
--savetiddler <title> <filename> [<type>]Save an individual tiddler as a specified MIME type, defaults to text/html
--savetiddlers <outdir>Saves all the loaded tiddlers as .tid files in the specified directory
--servewiki <port>Serve the cooked TiddlyWiki over HTTP at /
--servetiddlers <port>Serve individual tiddlers over HTTP at /tiddlertitle
--wikitest <dir>Run wikification tests against the tiddlers in the given directory
--dumpstoreDump the TiddlyWiki store in JSON format
--dumprecipeDump the current recipe in JSON format
--verboseverbose output, useful for debugging

Examples

This example loads the tiddlers from a TiddlyWiki HTML file and makes them available over HTTP:
node tiddlywiki.js --load mywiki.html --servewiki 127.0.0.1:8000 -
This example cooks a TiddlyWiki from a recipe:
+
This example cooks a TiddlyWiki from a recipe:
node tiddlywiki.js --recipe tiddlywiki.com/index.recipe --savewiki tmp/ -
This example ginsus a TiddlyWiki into its constituent tiddlers:
+
This example ginsus a TiddlyWiki into its constituent tiddlers:
node tiddlywiki.js --load mywiki.html --savetiddlers tmp/tiddlers -

Notes

--servewiki and --servertiddlers are for different purposes and should not be used together. The former is for TiddlyWiki core developers who want to be able to edit the TiddlyWiki source files in a text editor and view the results in the browser by clicking refresh; it is slow because it reloads all the TiddlyWiki JavaScript files each time the page is loaded. The latter is for experimenting with the new wikification engine.

--wikitest looks for *.tid files in the specified folder. It then wikifies the tiddlers to both "text/plain" and "text/html" format and checks the results against the content of the *.html and *.txt files in the same directory.

Testing

test.sh contains a simple test script that cooks the main tiddlywiki.com recipe and compares it with the results of the old build process (ie, running cook.rb and then opening the file in a browser and performing a 'save changes' operation). It also runs a series of wikifications tests that work off the data in test/wikitests/.

Planned WikiText Features

It is proposed to extend the existing TiddlyWiki wikitext syntax with the following extensions

  1. Addition of **bold** character formatting
  2. Addition of `backtick for code` character formatting
  3. Addition of WikiCreole-style forced line break, e.g. force\\linebreak
  4. Addition of WikiCreole-style headings, e.g. ==Heading
  5. Addition of WikiCreole-style headings in tables, e.g. |=|=table|=header|
  6. Addition of white-listed HTML tags intermixed with wikitext
  7. Addition of WikiCreole-style pretty links, e.g. [[description -> link]]
  8. Addition of multiline macros, e.g.
<<myMacro
+

Notes

--servewiki and --servertiddlers are for different purposes and should not be used together. The former is for TiddlyWiki core developers who want to be able to edit the TiddlyWiki source files in a text editor and view the results in the browser by clicking refresh; it is slow because it reloads all the TiddlyWiki JavaScript files each time the page is loaded. The latter is for experimenting with the new wikification engine.

--wikitest looks for *.tid files in the specified folder. It then wikifies the tiddlers to both "text/plain" and "text/html" format and checks the results against the content of the *.html and *.txt files in the same directory.

Testing

test.sh contains a simple test script that cooks the main tiddlywiki.com recipe and compares it with the results of the old build process (ie, running cook.rb and then opening the file in a browser and performing a 'save changes' operation). It also runs a series of wikifications tests that work off the data in test/wikitests/.

Planned WikiText Features

It is proposed to extend the existing TiddlyWiki wikitext syntax with the following extensions

  1. Addition of **bold** character formatting
  2. Addition of `backtick for code` character formatting
  3. Addition of WikiCreole-style forced line break, e.g. force\\linebreak
  4. Addition of WikiCreole-style headings, e.g. ==Heading
  5. Addition of WikiCreole-style headings in tables, e.g. |=|=table|=header|
  6. Addition of white-listed HTML tags intermixed with wikitext
  7. Addition of WikiCreole-style pretty links, e.g. [[description -> link]]
  8. Addition of multiline macros, e.g.
<<myMacro
 param1: Parameter value
 param2: value
 "unnamed parameter"
@@ -15,4 +15,4 @@ A multiline parameter that can go on for as long as it likes
 and contain linebreaks.
 ))
 >>
-


This readme file was automatically generated by TiddlyWiki5
\ No newline at end of file +


This readme file was automatically generated by TiddlyWiki5
\ No newline at end of file diff --git a/tiddlywiki5/styles.css b/tiddlywiki5/styles.css index fc93dc877..955fd1a49 100644 --- a/tiddlywiki5/styles.css +++ b/tiddlywiki5/styles.css @@ -102,7 +102,7 @@ a.tw-tiddlylink-missing { margin-right: 5px; padding: 3px 5px 3px; border-radius: 3px; - background-color: #cca; + background-color: #fcf; } .splitLabel { diff --git a/tiddlywiki5/tiddlers/SimpleTemplate.tid b/tiddlywiki5/tiddlers/SimpleTemplate.tid index 709de5689..09f82db3e 100644 --- a/tiddlywiki5/tiddlers/SimpleTemplate.tid +++ b/tiddlywiki5/tiddlers/SimpleTemplate.tid @@ -7,4 +7,5 @@ modifier: JeremyRuston <> <>}}} {{body{ <>}}} +<> <> \ No newline at end of file