diff --git a/core/modules/parsers/parseutils.js b/core/modules/parsers/parseutils.js index 30bc39509..99ccbb40a 100644 --- a/core/modules/parsers/parseutils.js +++ b/core/modules/parsers/parseutils.js @@ -381,3 +381,44 @@ exports.parseAttribute = function(source,pos) { node.end = pos; return node; }; + +/* +Serialize a parsed attribute node +*/ +exports.serializeAttribute = function(node,options) { + options = options || {}; + if(!node || typeof node !== "object" || !node.name || !node.type) { + return null; + } + // If name is number, means it is a positional attribute and name is omitted + var positional = parseInt(node.name) >= 0, + // `=` in a widget and might be `:` in a macro + assign = positional ? "" : (options.assignmentSymbol || "="), + attributeString = positional ? "" : node.name; + if(node.type === "string") { + if(node.value === "true") { + return attributeString; + } + attributeString += assign + '"' + node.value + '"'; + } else if(node.type === "filtered") { + attributeString += assign + "{{{" + node.filter + "}}}"; + } else if(node.type === "indirect") { + attributeString += assign + "{{" + node.textReference + "}}"; + } else if(node.type === "substituted") { + attributeString += assign + "`" + node.rawValue + "`"; + } else if(node.type === "macro") { + if(node.value && typeof node.value === "object" && node.value.type === "macrocall") { + var params = node.value.params.map(function(param) { + return param.value; + }).join(" "); + attributeString += assign + "<<" + node.value.name + " " + params + ">>"; + } else { + // Unsupported macro structure + return null; + } + } else { + // Unsupported type + return null; + } + return attributeString; +}; diff --git a/core/modules/parsers/wikiparser/rules/codeblock.js b/core/modules/parsers/wikiparser/rules/codeblock.js index bdecd65be..ca84e24aa 100644 --- a/core/modules/parsers/wikiparser/rules/codeblock.js +++ b/core/modules/parsers/wikiparser/rules/codeblock.js @@ -53,3 +53,7 @@ exports.parse = function() { } }]; }; + +exports.serialize = function(tree,serialize) { + return "```" + tree.attributes.language.value + "\n" + tree.attributes.code.value + "\n```\n\n"; +} diff --git a/core/modules/parsers/wikiparser/rules/codeinline.js b/core/modules/parsers/wikiparser/rules/codeinline.js index 5606ba478..a9dadad27 100644 --- a/core/modules/parsers/wikiparser/rules/codeinline.js +++ b/core/modules/parsers/wikiparser/rules/codeinline.js @@ -51,3 +51,7 @@ exports.parse = function() { }] }]; }; + +exports.serialize = function(tree,serialize) { + return "`" + serialize(tree.children) + "`"; +} diff --git a/core/modules/parsers/wikiparser/rules/commentblock.js b/core/modules/parsers/wikiparser/rules/commentblock.js index 96d3deb3d..9a953be08 100644 --- a/core/modules/parsers/wikiparser/rules/commentblock.js +++ b/core/modules/parsers/wikiparser/rules/commentblock.js @@ -22,7 +22,7 @@ Note that the syntax for comments is simplified to an opening " + +Some text + + + +More text \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/CommentInline.tid b/editions/test/tiddlers/tests/data/serialize/CommentInline.tid new file mode 100644 index 000000000..2d0e98513 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/CommentInline.tid @@ -0,0 +1,5 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/CommentInline +type: text/vnd.tiddlywiki + +This is some text with an inline comment and some more text. \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/Conditional.tid b/editions/test/tiddlers/tests/data/serialize/Conditional.tid new file mode 100644 index 000000000..4540e6eb4 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/Conditional.tid @@ -0,0 +1,21 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/Conditional +type: text/vnd.tiddlywiki + +This is a <%if [{something}] %>Elephant<%elseif [{else}] %>Pelican<%else%>Crocodile<%endif%> <%if [{something}] %>Elephant<%else%>Crocodile<%endif%> + +<%if [{$:/info/url/protocol}match[file:]]%> + Loaded from a file URI +<%elseif [{$:/info/url/protocol}match[https:]]%> + Loaded from an HTTPS URI +<%elseif [{$:/info/url/protocol}match[http:]]%> + Loaded from an HTTP URI +<%else%> + Loaded from an unknown protocol +<%endif%> + +Plain text in next paragraph. + +<%if [{$:/info/url/protocol}match[file:]]%> + Hidden. +<%endif%> diff --git a/editions/test/tiddlers/tests/data/serialize/Dash.tid b/editions/test/tiddlers/tests/data/serialize/Dash.tid new file mode 100644 index 000000000..b0a7ddc55 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/Dash.tid @@ -0,0 +1,7 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/Dash +type: text/vnd.tiddlywiki + +This is an en-dash: -- + +This is an em-dash: --- \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/Entity.tid b/editions/test/tiddlers/tests/data/serialize/Entity.tid new file mode 100644 index 000000000..d8891e4ed --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/Entity.tid @@ -0,0 +1,5 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/Entity +type: text/vnd.tiddlywiki + +This is a copyright symbol: © \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/ExtLink.tid b/editions/test/tiddlers/tests/data/serialize/ExtLink.tid new file mode 100644 index 000000000..de966452f --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/ExtLink.tid @@ -0,0 +1,7 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/ExtLink +type: text/vnd.tiddlywiki + +An external link: https://www.tiddlywiki.com/ + +A suppressed external link: ~http://www.tiddlyspace.com/ \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/FilteredTranscludeBlock.tid b/editions/test/tiddlers/tests/data/serialize/FilteredTranscludeBlock.tid new file mode 100644 index 000000000..b1c526d9d --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/FilteredTranscludeBlock.tid @@ -0,0 +1,13 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/FilteredTranscludeBlock +type: text/vnd.tiddlywiki + +{{{ [tag[docs]] }}} + +{{{ [tag[docs]] |tooltip}}} + +{{{ [tag[docs]] ||TemplateTitle}}} + +{{{ [tag[docs]] |tooltip||TemplateTitle}}} + +{{{ [tag[docs]] }}width:40;height:50;}.class.class diff --git a/editions/test/tiddlers/tests/data/serialize/FilteredTranscludeInline.tid b/editions/test/tiddlers/tests/data/serialize/FilteredTranscludeInline.tid new file mode 100644 index 000000000..8b3155882 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/FilteredTranscludeInline.tid @@ -0,0 +1,5 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/FilteredTranscludeInline +type: text/vnd.tiddlywiki + +{{{ [tag[docs]] }}} {{{ [tag[docs]] |tooltip}}} {{{ [tag[docs]] ||TemplateTitle}}} {{{ [tag[docs]] |tooltip||TemplateTitle}}} {{{ [tag[docs]] }}width:40;height:50;}.class.class \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/FunctionDefinition.tid b/editions/test/tiddlers/tests/data/serialize/FunctionDefinition.tid new file mode 100644 index 000000000..3585564a9 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/FunctionDefinition.tid @@ -0,0 +1,15 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/FunctionDefinition +type: text/vnd.tiddlywiki + +\function name(param:"defaultvalue", param2:"defaultvalue") +definition text +\end + +\procedure name(param:"defaultvalue", param2:"defaultvalue") +definition text +\end + +\widget $mywidget(param:"defaultvalue", param2:"defaultvalue") +definition text +\end \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/HardLineBreaks.tid b/editions/test/tiddlers/tests/data/serialize/HardLineBreaks.tid new file mode 100644 index 000000000..b6ea0b985 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/HardLineBreaks.tid @@ -0,0 +1,12 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/HardLineBreaks +type: text/vnd.tiddlywiki + +""" +This is some text +That is set like +It is a Poem +When it is +Clearly +Not +""" diff --git a/editions/test/tiddlers/tests/data/serialize/Heading.tid b/editions/test/tiddlers/tests/data/serialize/Heading.tid new file mode 100644 index 000000000..34152e50a --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/Heading.tid @@ -0,0 +1,29 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/Heading +type: text/vnd.tiddlywiki + +! Heading 1 + +!! Heading 2 + +!!! Heading 3 + +!!!! Heading 4 + +!!!!! Heading 5 + +!!!!!! Heading 6 + +! AAA + +!! AAA + +!!! AAA + +!!!! AAA + +!!!!! AAA + +!!!!!! AAA + +AAA diff --git a/editions/test/tiddlers/tests/data/serialize/Html.tid b/editions/test/tiddlers/tests/data/serialize/Html.tid new file mode 100644 index 000000000..76b86d570 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/Html.tid @@ -0,0 +1,15 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/Html +type: text/vnd.tiddlywiki + + + +<$slider target="MyTiddler"> +This is a widget invocation + + +<$list filter="[tag[ExampleTag]sort[title]]"/> + +Plain text in next paragraph. \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/Image.tid b/editions/test/tiddlers/tests/data/serialize/Image.tid new file mode 100644 index 000000000..8641df4cb --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/Image.tid @@ -0,0 +1,10 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/Image +type: text/vnd.tiddlywiki + +[img[https://tiddlywiki.com/fractalveg.jpg]] +[img width="23" height="24" [https://tiddlywiki.com/fractalveg.jpg]] +[img width={{!!width}} height={{!!height}} [https://tiddlywiki.com/fractalveg.jpg]] +[img[Description of image|https://tiddlywiki.com/fractalveg.jpg]] +[img[TiddlerTitle]] +[img[Description of image|TiddlerTitle]] \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/Import.tid b/editions/test/tiddlers/tests/data/serialize/Import.tid new file mode 100644 index 000000000..e467de534 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/Import.tid @@ -0,0 +1,6 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/Import +type: text/vnd.tiddlywiki + +\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]] +\import [[$:/core/ui/PageMacros]] \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/ItalicEmphasis.tid b/editions/test/tiddlers/tests/data/serialize/ItalicEmphasis.tid new file mode 100644 index 000000000..a06ca62ce --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/ItalicEmphasis.tid @@ -0,0 +1,5 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/ItalicEmphasis +type: text/vnd.tiddlywiki + +This is //italic// text \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/List.tid b/editions/test/tiddlers/tests/data/serialize/List.tid new file mode 100644 index 000000000..d25397799 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/List.tid @@ -0,0 +1,40 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/List +type: text/vnd.tiddlywiki + +* This is an unordered list +* It has two items + +# This is a numbered list +## With a subitem +# And a third item + +; This is a term that is being defined +: This is the definition of that term + +#** One +#* Two +#** Three +#**** Four +#**# Five +#**## Six +## Seven +### Eight +## Nine + +* List item one +*.active List item two has the class `active` +* List item three + +# AAA +## [[BBB]] +### CCC +# AAA +## CCC +## DDD +## EEE +# BBB +## FF `/` FFF +## FFF +## GGG +## diff --git a/editions/test/tiddlers/tests/data/serialize/MacroCallBlock.tid b/editions/test/tiddlers/tests/data/serialize/MacroCallBlock.tid new file mode 100644 index 000000000..4bd30d451 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/MacroCallBlock.tid @@ -0,0 +1,9 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/MacroCallBlock +type: text/vnd.tiddlywiki + +<> + +<<.def "macro calls">> + +<> diff --git a/editions/test/tiddlers/tests/data/serialize/MacroCallInline.tid b/editions/test/tiddlers/tests/data/serialize/MacroCallInline.tid new file mode 100644 index 000000000..09127dce0 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/MacroCallInline.tid @@ -0,0 +1,5 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/MacroCallInline +type: text/vnd.tiddlywiki + +These are macro calls in a line: <> and <<.def "macro calls">> <> diff --git a/editions/test/tiddlers/tests/data/serialize/MacroDef.tid b/editions/test/tiddlers/tests/data/serialize/MacroDef.tid new file mode 100644 index 000000000..132ee7053 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/MacroDef.tid @@ -0,0 +1,9 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/MacroDef +type: text/vnd.tiddlywiki + +\define name(param:defaultvalue,param2:defaultvalue) +definition text, including $param$ markers +\end + +\define lingo-base() $:/language/ControlPanel/Basics/ diff --git a/editions/test/tiddlers/tests/data/serialize/Parameters.tid b/editions/test/tiddlers/tests/data/serialize/Parameters.tid new file mode 100644 index 000000000..5b107a73d --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/Parameters.tid @@ -0,0 +1,5 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/Parameters +type: text/vnd.tiddlywiki + +\parameters(param:defaultvalue,param2:defaultvalue) \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/ParserMode.tid b/editions/test/tiddlers/tests/data/serialize/ParserMode.tid new file mode 100644 index 000000000..b4c31b66b --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/ParserMode.tid @@ -0,0 +1,9 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/ParserMode +type: text/vnd.tiddlywiki + +\parsermode block + +\parsermode inline + +Test. \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/PrettyExtLink.tid b/editions/test/tiddlers/tests/data/serialize/PrettyExtLink.tid new file mode 100644 index 000000000..1b4002b94 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/PrettyExtLink.tid @@ -0,0 +1,6 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/PrettyExtLink +type: text/vnd.tiddlywiki + +[ext[https://tiddlywiki.com/fractalveg.jpg]] +[ext[Tooltip|https://tiddlywiki.com/fractalveg.jpg]] \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/PrettyLink.tid b/editions/test/tiddlers/tests/data/serialize/PrettyLink.tid new file mode 100644 index 000000000..8c7afbc7f --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/PrettyLink.tid @@ -0,0 +1,6 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/PrettyLink +type: text/vnd.tiddlywiki + +[[Introduction]] +[[Link description|TiddlerTitle]] \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/QuoteBlock.tid b/editions/test/tiddlers/tests/data/serialize/QuoteBlock.tid new file mode 100644 index 000000000..a2f698846 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/QuoteBlock.tid @@ -0,0 +1,7 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/QuoteBlock +type: text/vnd.tiddlywiki + +<<` around this list will also have the class `myClass` +* List item 2 +@@ + +@@font-size:1.5em; +@@.coloured-text.coloured-bg +* Block content +* With custom style and classes +@@ \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/StyleBlock2.tid b/editions/test/tiddlers/tests/data/serialize/StyleBlock2.tid new file mode 100644 index 000000000..cdd31254e --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/StyleBlock2.tid @@ -0,0 +1,13 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/StyleBlock2 +type: text/vnd.tiddlywiki + +@@width:100px; +@@.myFirstClass.mySecondClass.myThirdClass +This is a paragraph +@@ + +@@background-color:lightcyan; +* Item one +* Item two +@@ \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/StyleInline.tid b/editions/test/tiddlers/tests/data/serialize/StyleInline.tid new file mode 100644 index 000000000..c491767f5 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/StyleInline.tid @@ -0,0 +1,7 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/StyleInline +type: text/vnd.tiddlywiki + +@@.myClass This is some text with a class@@ +@@background-color:red; This is some text with a background colour@@ +@@width:100px;.myClass This is some text with a class and a width@@ \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/SubscriptEmphasis.tid b/editions/test/tiddlers/tests/data/serialize/SubscriptEmphasis.tid new file mode 100644 index 000000000..b39d7f6d5 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/SubscriptEmphasis.tid @@ -0,0 +1,5 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/SubscriptEmphasis +type: text/vnd.tiddlywiki + +This is ,,subscript,, text \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/SuperscriptEmphasis.tid b/editions/test/tiddlers/tests/data/serialize/SuperscriptEmphasis.tid new file mode 100644 index 000000000..9683f9e54 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/SuperscriptEmphasis.tid @@ -0,0 +1,5 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/SuperscriptEmphasis +type: text/vnd.tiddlywiki + +This is ^^superscript^^ text \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/SysLink.tid b/editions/test/tiddlers/tests/data/serialize/SysLink.tid new file mode 100644 index 000000000..fdbc982fe --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/SysLink.tid @@ -0,0 +1,6 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/SysLink +type: text/vnd.tiddlywiki + +$:TiddlerTitle +~$:TiddlerTitle \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/Table.tid b/editions/test/tiddlers/tests/data/serialize/Table.tid new file mode 100644 index 000000000..bd92db4bc --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/Table.tid @@ -0,0 +1,11 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/Table +type: text/vnd.tiddlywiki + +|!|!Alpha|!Beta|!Gamma|!Delta| +|!One||||| +|!Two||||| +|!Three||||| + +|cell one|cell two| +|cell three|cell four| diff --git a/editions/test/tiddlers/tests/data/serialize/TranscludeBlock.tid b/editions/test/tiddlers/tests/data/serialize/TranscludeBlock.tid new file mode 100644 index 000000000..344171af0 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/TranscludeBlock.tid @@ -0,0 +1,21 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/TranscludeBlock +type: text/vnd.tiddlywiki + +{{MyTiddler}} + +{{MyTiddler||TemplateTitle}} + +{{||TemplateTitle}} + +{{MyTiddler|Parameter}} + +{{MyTiddler||TemplateTitle|Parameter|SecondParameter}} + +{{MyTiddler!!field}} + +{{!!field}} + +{{MyTiddler##index}} + +{{##index}} \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/TranscludeInline.tid b/editions/test/tiddlers/tests/data/serialize/TranscludeInline.tid new file mode 100644 index 000000000..df20658cf --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/TranscludeInline.tid @@ -0,0 +1,5 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/TranscludeInline +type: text/vnd.tiddlywiki + +{{MyTiddler}} {{MyTiddler||TemplateTitle}} \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/TypedBlock1.tid b/editions/test/tiddlers/tests/data/serialize/TypedBlock1.tid new file mode 100644 index 000000000..06362d062 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/TypedBlock1.tid @@ -0,0 +1,15 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/TypedBlock1 +type: text/vnd.tiddlywiki + +$$$text/vnd.tiddlywiki > text/plain +This is ''some'' wikitext +$$$ + +$$$text/unknown +Some plain text, which will not be //formatted//. + +$$$text/vnd.tiddlywiki > text/html +This is ''some'' wikitext +$$$ + diff --git a/editions/test/tiddlers/tests/data/serialize/TypedBlock2.tid b/editions/test/tiddlers/tests/data/serialize/TypedBlock2.tid new file mode 100644 index 000000000..082ca533a --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/TypedBlock2.tid @@ -0,0 +1,19 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/TypedBlock2 +type: text/vnd.tiddlywiki + +$$$.js +This will be rendered as JavaScript +$$$ + +$$$.svg + + + +$$$ + +$$$image/svg+xml + + + +$$$ \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/UnderscoreEmphasis.tid b/editions/test/tiddlers/tests/data/serialize/UnderscoreEmphasis.tid new file mode 100644 index 000000000..73dc6425c --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/UnderscoreEmphasis.tid @@ -0,0 +1,5 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/UnderscoreEmphasis +type: text/vnd.tiddlywiki + +This is __underscore__ text \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/WikiLink.tid b/editions/test/tiddlers/tests/data/serialize/WikiLink.tid new file mode 100644 index 000000000..18b04caf1 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/WikiLink.tid @@ -0,0 +1,7 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/WikiLink +type: text/vnd.tiddlywiki + +AWikiLink +AnotherLink +~SuppressedLink \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/serialize/WikiLinkPrefix.tid b/editions/test/tiddlers/tests/data/serialize/WikiLinkPrefix.tid new file mode 100644 index 000000000..982ed9071 --- /dev/null +++ b/editions/test/tiddlers/tests/data/serialize/WikiLinkPrefix.tid @@ -0,0 +1,5 @@ +tags: $:/tags/wikitext-serialize-test-spec +title: Serialize/WikiLinkPrefix +type: text/vnd.tiddlywiki + +~SuppressedLink \ No newline at end of file diff --git a/editions/test/tiddlers/tests/data/transclude/Parameterised-ParseTreeNodes.tid b/editions/test/tiddlers/tests/data/transclude/Parameterised-ParseTreeNodes.tid index 916e2abfb..fc0d785f8 100644 --- a/editions/test/tiddlers/tests/data/transclude/Parameterised-ParseTreeNodes.tid +++ b/editions/test/tiddlers/tests/data/transclude/Parameterised-ParseTreeNodes.tid @@ -26,4 +26,4 @@ title: TiddlerOne + title: ExpectedResult -

[{"type":"element","tag":"p","children":[{"type":"text","text":"This is a block","start":68,"end":83}],"start":68,"end":83}]

[{"type":"text","text":"This is inline","start":136,"end":152}]

\ No newline at end of file +

[{"type":"element","tag":"p","children":[{"type":"text","text":"This is a block","start":68,"end":83}],"start":68,"end":83,"rule":"parseblock"}]

[{"type":"text","text":"This is inline","start":136,"end":152}]

\ No newline at end of file diff --git a/editions/test/tiddlers/tests/test-html-parser.js b/editions/test/tiddlers/tests/test-html-parser.js index 9fc108235..c6c160bb3 100644 --- a/editions/test/tiddlers/tests/test-html-parser.js +++ b/editions/test/tiddlers/tests/test-html-parser.js @@ -24,7 +24,7 @@ describe("HTML tag new parser tests", function() { null ); expect($tw.utils.parseWhiteSpace("p ",1)).toEqual( - { type : 'whitespace', start : 1, end : 3 } + { type : "whitespace", start : 1, end : 3 } ); }); @@ -33,7 +33,7 @@ describe("HTML tag new parser tests", function() { null ); expect($tw.utils.parseTokenString("p= ",1,"=")).toEqual( - { type : 'token', value : '=', start : 1, end : 2 } + { type : "token", value : "=", start : 1, end : 2 } ); }); @@ -42,10 +42,10 @@ describe("HTML tag new parser tests", function() { null ); expect($tw.utils.parseTokenRegExp("p=' ",1,/(=(?:'|"))/g).match[0]).toEqual( - '=\'' + "='" ); expect($tw.utils.parseTokenRegExp("p=blah ",2,/([^\s>]+)/g).match[0]).toEqual( - 'blah' + "blah" ); }); @@ -54,40 +54,40 @@ describe("HTML tag new parser tests", function() { null ); expect($tw.utils.parseStringLiteral("p='blah' ",2)).toEqual( - { type : 'string', start : 2, value : 'blah', end : 8 } + { type : "string", start : 2, value : "blah", end : 8 } ); expect($tw.utils.parseStringLiteral("p='' ",2)).toEqual( - { type : 'string', start : 2, value : '', end : 4 } + { type : "string", start : 2, value : "", end : 4 } ); expect($tw.utils.parseStringLiteral("p=\"blah' ",2)).toEqual( null ); expect($tw.utils.parseStringLiteral("p=\"\" ",2)).toEqual( - { type : 'string', start : 2, value : '', end : 4 } + { type : "string", start : 2, value : "", end : 4 } ); }); it("should parse macro parameters", function() { expect($tw.utils.parseMacroParameter("me",0)).toEqual( - { type : 'macro-parameter', start : 0, value : 'me', end : 2 } + { type : "macro-parameter", start : 0, value : "me", end : 2 } ); expect($tw.utils.parseMacroParameter("me:one",0)).toEqual( - { type : 'macro-parameter', start : 0, value : 'one', name : 'me', end : 6 } + { type : "macro-parameter", start : 0, value : "one", name : "me", end : 6 } ); expect($tw.utils.parseMacroParameter("me:'one two three'",0)).toEqual( - { type : 'macro-parameter', start : 0, value : 'one two three', name : 'me', end : 18 } + { type : "macro-parameter", start : 0, value : "one two three", name : "me", end : 18 } ); expect($tw.utils.parseMacroParameter("'one two three'",0)).toEqual( - { type : 'macro-parameter', start : 0, value : 'one two three', end : 15 } + { type : "macro-parameter", start : 0, value : "one two three", end : 15 } ); expect($tw.utils.parseMacroParameter("me:[[one two three]]",0)).toEqual( - { type : 'macro-parameter', start : 0, value : 'one two three', name : 'me', end : 20 } + { type : "macro-parameter", start : 0, value : "one two three", name : "me", end : 20 } ); expect($tw.utils.parseMacroParameter("[[one two three]]",0)).toEqual( - { type : 'macro-parameter', start : 0, value : 'one two three', end : 17 } + { type : "macro-parameter", start : 0, value : "one two three", end : 17 } ); expect($tw.utils.parseMacroParameter("myparam>",0)).toEqual( - { type : 'macro-parameter', start : 0, value : 'myparam>', end : 8 } + { type : "macro-parameter", start : 0, value : "myparam>", end : 8 } ); }); @@ -96,22 +96,22 @@ describe("HTML tag new parser tests", function() { null ); expect($tw.utils.parseMacroInvocation("<>",0)).toEqual( - { type : 'macrocall', start : 0, params : [ ], name : 'mymacro', end : 11 } + { type : "macrocall", start : 0, params : [ ], name : "mymacro", end : 11 } ); expect($tw.utils.parseMacroInvocation("<>",0)).toEqual( - { type : 'macrocall', start : 0, params : [ { type : 'macro-parameter', start : 9, value : 'one', end : 13 }, { type : 'macro-parameter', start : 13, value : 'two', end : 17 }, { type : 'macro-parameter', start : 17, value : 'three', end : 23 } ], name : 'mymacro', end : 25 } + { type : "macrocall", start : 0, params : [ { type : "macro-parameter", start : 9, value : "one", end : 13 }, { type : "macro-parameter", start : 13, value : "two", end : 17 }, { type : "macro-parameter", start : 17, value : "three", end : 23 } ], name : "mymacro", end : 25 } ); expect($tw.utils.parseMacroInvocation("<>",0)).toEqual( - { type : 'macrocall', start : 0, params : [ { type : 'macro-parameter', start : 9, value : 'one', name : 'p', end : 15 }, { type : 'macro-parameter', start : 15, value : 'two', name : 'q', end : 21 }, { type : 'macro-parameter', start : 21, value : 'three', end : 27 } ], name : 'mymacro', end : 29 } + { type : "macrocall", start : 0, params : [ { type : "macro-parameter", start : 9, value : "one", name : "p", end : 15 }, { type : "macro-parameter", start : 15, value : "two", name : "q", end : 21 }, { type : "macro-parameter", start : 21, value : "three", end : 27 } ], name : "mymacro", end : 29 } ); expect($tw.utils.parseMacroInvocation("<>",0)).toEqual( - { type : 'macrocall', start : 0, params : [ { type : 'macro-parameter', start : 9, value : 'one two three', end : 25 } ], name : 'mymacro', end : 27 } + { type : "macrocall", start : 0, params : [ { type : "macro-parameter", start : 9, value : "one two three", end : 25 } ], name : "mymacro", end : 27 } ); expect($tw.utils.parseMacroInvocation("<>",0)).toEqual( - { type : 'macrocall', start : 0, params : [ { type : 'macro-parameter', start : 9, value : 'one two three', name : 'r', end : 27 } ], name : 'mymacro', end : 29 } + { type : "macrocall", start : 0, params : [ { type : "macro-parameter", start : 9, value : "one two three", name : "r", end : 27 } ], name : "mymacro", end : 29 } ); expect($tw.utils.parseMacroInvocation("<>",0)).toEqual( - { type : 'macrocall', start : 0, params : [ { type : 'macro-parameter', start : 9, value : 'two', name : 'one', end : 17 }, { type : 'macro-parameter', start : 17, value : 'four and five', name : 'three', end : 39 } ], name : 'myMacro', end : 41 } + { type : "macrocall", start : 0, params : [ { type : "macro-parameter", start : 9, value : "two", name : "one", end : 17 }, { type : "macro-parameter", start : 17, value : "four and five", name : "three", end : 39 } ], name : "myMacro", end : 41 } ); }); @@ -120,56 +120,87 @@ describe("HTML tag new parser tests", function() { null ); expect($tw.utils.parseAttribute("p='blah' ",0)).toEqual( - { type : 'string', start : 0, name : 'p', value : 'blah', end : 8 } + { type : "string", start : 0, name : "p", value : "blah", end : 8 } ); expect($tw.utils.parseAttribute("p=\"blah\" ",0)).toEqual( - { type : 'string', start : 0, name : 'p', value : 'blah', end : 8 } + { type : "string", start : 0, name : "p", value : "blah", end : 8 } ); expect($tw.utils.parseAttribute("p=\"bl\nah\" ",0)).toEqual( - { type : 'string', start : 0, name : 'p', value : 'bl\nah', end : 9 } + { type : "string", start : 0, name : "p", value : "bl\nah", end : 9 } ); expect($tw.utils.parseAttribute("p={{{blah}}} ",0)).toEqual( - { type : 'filtered', start : 0, name : 'p', filter : 'blah', end : 12 } + { type : "filtered", start : 0, name : "p", filter : "blah", end : 12 } ); expect($tw.utils.parseAttribute("p={{{bl\nah}}} ",0)).toEqual( - { type : 'filtered', start : 0, name : 'p', filter : 'bl\nah', end : 13 } + { type : "filtered", start : 0, name : "p", filter : "bl\nah", end : 13 } ); expect($tw.utils.parseAttribute("p={{{ [{$:/layout}] }}} ",0)).toEqual( - { type : 'filtered', start : 0, name : 'p', filter : ' [{$:/layout}] ', end : 23 } + { type : "filtered", start : 0, name : "p", filter : " [{$:/layout}] ", end : 23 } ); expect($tw.utils.parseAttribute("p={{blah}} ",0)).toEqual( - { type : 'indirect', start : 0, name : 'p', textReference : 'blah', end : 10 } + { type : "indirect", start : 0, name : "p", textReference : "blah", end : 10 } ); expect($tw.utils.parseAttribute("p=blah ",0)).toEqual( - { type : 'string', start : 0, name : 'p', value : 'blah', end : 6 } + { type : "string", start : 0, name : "p", value : "blah", end : 6 } ); expect($tw.utils.parseAttribute("p =blah ",0)).toEqual( - { type : 'string', start : 0, name : 'p', value : 'blah', end : 7 } + { type : "string", start : 0, name : "p", value : "blah", end : 7 } ); expect($tw.utils.parseAttribute("p= blah ",0)).toEqual( - { type : 'string', start : 0, name : 'p', value : 'blah', end : 7 } + { type : "string", start : 0, name : "p", value : "blah", end : 7 } ); expect($tw.utils.parseAttribute("p = blah ",0)).toEqual( - { type : 'string', start : 0, name : 'p', value : 'blah', end : 8 } + { type : "string", start : 0, name : "p", value : "blah", end : 8 } ); expect($tw.utils.parseAttribute("p = >blah ",0)).toEqual( - { type : 'string', value : 'true', start : 0, name : 'p', end : 4 } + { type : "string", value : "true", start : 0, name : "p", end : 4 } ); expect($tw.utils.parseAttribute(" attrib1>",0)).toEqual( - { type : 'string', value : 'true', start : 0, name : 'attrib1', end : 8 } + { type : "string", value : "true", start : 0, name : "attrib1", end : 8 } ); expect($tw.utils.parseAttribute("p=`blah` ",1)).toEqual(null); expect($tw.utils.parseAttribute("p=`blah` ",0)).toEqual( - { start: 0, name: 'p', type: 'substituted', rawValue: 'blah', end: 8 } + { start: 0, name: "p", type: "substituted", rawValue: "blah", end: 8 } ); expect($tw.utils.parseAttribute("p=```blah``` ",0)).toEqual( - { start: 0, name: 'p', type: 'substituted', rawValue: 'blah', end: 12 } + { start: 0, name: "p", type: "substituted", rawValue: "blah", end: 12 } ); expect($tw.utils.parseAttribute("p=`Hello \"There\"`",0)).toEqual( - { start: 0, name: 'p', type: 'substituted', rawValue: 'Hello "There"', end: 17 } + { start: 0, name: "p", type: "substituted", rawValue: 'Hello "There"', end: 17 } ); }); + + describe("serializeAttribute", function () { + it("should serialize string attributes", function () { + expect($tw.utils.serializeAttribute({ type: "string", name: "p", value: "blah" })).toBe('p="blah"'); + expect($tw.utils.serializeAttribute({ type: "string", name: "p", value: "true" })).toBe("p"); + }); + + it("should serialize filtered attributes", function () { + expect($tw.utils.serializeAttribute({ type: "filtered", name: "p", filter: "blah" })).toBe("p={{{blah}}}"); + }); + + it("should serialize indirect attributes", function () { + expect($tw.utils.serializeAttribute({ type: "indirect", name: "p", textReference: "blah" })).toBe("p={{blah}}"); + }); + + it("should serialize substituted attributes", function () { + expect($tw.utils.serializeAttribute({ type: "substituted", name: "p", rawValue: "blah" })).toBe("p=`blah`"); + }); + + it("should return null for unsupported types", function () { + expect($tw.utils.serializeAttribute({ type: "unknown", name: "p", value: "blah" })).toBeNull(); + }); + + it("should return null for invalid input", function () { + expect($tw.utils.serializeAttribute(null)).toBeNull(); + expect($tw.utils.serializeAttribute({})).toBeNull(); + expect($tw.utils.serializeAttribute({ type: "string" })).toBeNull(); + expect($tw.utils.serializeAttribute({ name: "p" })).toBeNull(); + }); + }); + it("should parse HTML tags", function() { expect(parser.parseTag("",1)).toEqual( null @@ -178,52 +209,52 @@ describe("HTML tag new parser tests", function() { null ); expect(parser.parseTag("",0)).toEqual( - { type : 'element', start : 0, attributes : { }, orderedAttributes: [ ], tag : 'mytag', end : 7 } + { type : "element", start : 0, attributes : { }, orderedAttributes: [ ], tag : "mytag", end : 7 } ); expect(parser.parseTag("",0)).toEqual( - { type : 'element', start : 0, attributes : { attrib1 : { type : 'string', value : 'true', start : 6, name : 'attrib1', end : 14 } }, orderedAttributes: [ { start: 6, name: 'attrib1', type: 'string', value: 'true', end: 14 } ], tag : 'mytag', end : 15 } + { type : "element", start : 0, attributes : { attrib1 : { type : "string", value : "true", start : 6, name : "attrib1", end : 14 } }, orderedAttributes: [ { start: 6, name: "attrib1", type: "string", value: "true", end: 14 } ], tag : "mytag", end : 15 } ); expect(parser.parseTag("",0)).toEqual( - { type : 'element', start : 0, attributes : { attrib1 : { type : 'string', value : 'true', start : 6, name : 'attrib1', end : 14 } }, orderedAttributes: [ { start: 6, name: 'attrib1', type: 'string', value: 'true', end: 14 } ], tag : 'mytag', isSelfClosing : true, end : 16 } + { type : "element", start : 0, attributes : { attrib1 : { type : "string", value : "true", start : 6, name : "attrib1", end : 14 } }, orderedAttributes: [ { start: 6, name: "attrib1", type: "string", value: "true", end: 14 } ], tag : "mytag", isSelfClosing : true, end : 16 } ); expect(parser.parseTag("<$view field=\"title\" format=\"link\"/>",0)).toEqual( - { type : 'view', start : 0, attributes : { field : { start : 6, name : 'field', type : 'string', value : 'title', end : 20 }, format : { start : 20, name : 'format', type : 'string', value : 'link', end : 34 } }, orderedAttributes: [ { start: 6, name: 'field', type: 'string', value: 'title', end: 20 }, { start: 20, name: 'format', type: 'string', value: 'link', end: 34 } ], tag : '$view', isSelfClosing : true, end : 36 } + { type : "view", start : 0, attributes : { field : { start : 6, name : "field", type : "string", value : "title", end : 20 }, format : { start : 20, name : "format", type : "string", value : "link", end : 34 } }, orderedAttributes: [ { start: 6, name: "field", type: "string", value: "title", end: 20 }, { start: 20, name: "format", type: "string", value: "link", end: 34 } ], tag : "$view", isSelfClosing : true, end : 36 } ); expect(parser.parseTag("",0)).toEqual( - { type : 'element', start : 0, attributes : { attrib1 : { type : 'string', start : 6, name : 'attrib1', value : 'something', end : 26 } }, orderedAttributes: [ { start: 6, name: 'attrib1', type: 'string', value: 'something', end: 26 } ], tag : 'mytag', end : 27 } + { type : "element", start : 0, attributes : { attrib1 : { type : "string", start : 6, name : "attrib1", value : "something", end : 26 } }, orderedAttributes: [ { start: 6, name: "attrib1", type: "string", value: "something", end: 26 } ], tag : "mytag", end : 27 } ); expect(parser.parseTag("",0)).toEqual( - { type : 'element', start : 0, attributes : { attrib1 : { type : 'string', start : 15, name : 'attrib1', value : 'something', end : 34 } }, orderedAttributes: [ { start: 6, name: 'attrib1', type: 'string', value: 'true', end: 15 }, { start: 15, name: 'attrib1', type: 'string', value: 'something', end: 34 } ], tag : 'mytag', end : 35 } + { type : "element", start : 0, attributes : { attrib1 : { type : "string", start : 15, name : "attrib1", value : "something", end : 34 } }, orderedAttributes: [ { start: 6, name: "attrib1", type: "string", value: "true", end: 15 }, { start: 15, name: "attrib1", type: "string", value: "something", end: 34 } ], tag : "mytag", end : 35 } ); expect(parser.parseTag("",0)).toEqual( - { type : 'element', start : 0, attributes : { attrib1 : { type : 'string', start : 34, name : 'attrib1', value : 'else', end : 49 } }, orderedAttributes: [ { start: 6, name: 'attrib1', type: 'string', value: 'true', end: 15 }, { start: 15, name: 'attrib1', type: 'string', value: 'something', end: 34 }, { start: 34, name: 'attrib1', type: 'string', value: 'else', end: 49 } ], tag : 'mytag', end : 50 } + { type : "element", start : 0, attributes : { attrib1 : { type : "string", start : 34, name : "attrib1", value : "else", end : 49 } }, orderedAttributes: [ { start: 6, name: "attrib1", type: "string", value: "true", end: 15 }, { start: 15, name: "attrib1", type: "string", value: "something", end: 34 }, { start: 34, name: "attrib1", type: "string", value: "else", end: 49 } ], tag : "mytag", end : 50 } ); expect(parser.parseTag("<$mytag attrib1='something' attrib2=else thing>",0)).toEqual( - { type : 'mytag', start : 0, attributes : { attrib1 : { type : 'string', start : 7, name : 'attrib1', value : 'something', end : 27 }, attrib2 : { type : 'string', start : 27, name : 'attrib2', value : 'else', end : 40 }, thing : { type : 'string', start : 40, name : 'thing', value : 'true', end : 46 } }, orderedAttributes: [ { start: 7, name: 'attrib1', type: 'string', value: 'something', end: 27 }, { start: 27, name: 'attrib2', type: 'string', value: 'else', end: 40 }, { start: 40, name: 'thing', type: 'string', value: 'true', end: 46 } ], tag : '$mytag', end : 47 } + { type : "mytag", start : 0, attributes : { attrib1 : { type : "string", start : 7, name : "attrib1", value : "something", end : 27 }, attrib2 : { type : "string", start : 27, name : "attrib2", value : "else", end : 40 }, thing : { type : "string", start : 40, name : "thing", value : "true", end : 46 } }, orderedAttributes: [ { start: 7, name: "attrib1", type: "string", value: "something", end: 27 }, { start: 27, name: "attrib2", type: "string", value: "else", end: 40 }, { start: 40, name: "thing", type: "string", value: "true", end: 46 } ], tag : "$mytag", end : 47 } ); expect(parser.parseTag("< $mytag attrib1='something' attrib2=else thing>",0)).toEqual( null ); expect(parser.parseTag("<$mytag attrib3=<>>",0)).toEqual( - { type : 'mytag', start : 0, attributes : { attrib3 : { type : 'macro', start : 7, name : 'attrib3', value : { type : 'macrocall', start : 16, params : [ { type : 'macro-parameter', start : 25, value : 'two', name : 'one', end : 33 }, { type : 'macro-parameter', start : 33, value : 'four and five', name : 'three', end : 55 } ], name : 'myMacro', end : 57 }, end : 57 } }, orderedAttributes: [ { type : 'macro', start : 7, name : 'attrib3', value : { type : 'macrocall', start : 16, params : [ { type : 'macro-parameter', start : 25, value : 'two', name : 'one', end : 33 }, { type : 'macro-parameter', start : 33, value : 'four and five', name : 'three', end : 55 } ], name : 'myMacro', end : 57 }, end : 57 } ], tag : '$mytag', end : 58 } + { type : "mytag", start : 0, attributes : { attrib3 : { type : "macro", start : 7, name : "attrib3", value : { type : "macrocall", start : 16, params : [ { type : "macro-parameter", start : 25, value : "two", name : "one", end : 33 }, { type : "macro-parameter", start : 33, value : "four and five", name : "three", end : 55 } ], name : "myMacro", end : 57 }, end : 57 } }, orderedAttributes: [ { type : "macro", start : 7, name : "attrib3", value : { type : "macrocall", start : 16, params : [ { type : "macro-parameter", start : 25, value : "two", name : "one", end : 33 }, { type : "macro-parameter", start : 33, value : "four and five", name : "three", end : 55 } ], name : "myMacro", end : 57 }, end : 57 } ], tag : "$mytag", end : 58 } ); expect(parser.parseTag("<$mytag attrib1='something' attrib2=else thing attrib3=<>>",0)).toEqual( - { type : 'mytag', start : 0, attributes : { attrib1 : { type : 'string', start : 7, name : 'attrib1', value : 'something', end : 27 }, attrib2 : { type : 'string', start : 27, name : 'attrib2', value : 'else', end : 40 }, thing : { type : 'string', start : 40, name : 'thing', value : 'true', end : 47 }, attrib3 : { type : 'macro', start : 47, name : 'attrib3', value : { type : 'macrocall', start : 55, params : [ { type : 'macro-parameter', start : 64, value : 'two', name : 'one', end : 72 }, { type : 'macro-parameter', start : 72, value : 'four and five', name : 'three', end : 94 } ], name : 'myMacro', end : 96 }, end : 96 } }, orderedAttributes: [ { type : 'string', start : 7, name : 'attrib1', value : 'something', end : 27 }, { type : 'string', start : 27, name : 'attrib2', value : 'else', end : 40 }, { type : 'string', start : 40, name : 'thing', value : 'true', end : 47 }, { type : 'macro', start : 47, name : 'attrib3', value : { type : 'macrocall', start : 55, params : [ { type : 'macro-parameter', start : 64, value : 'two', name : 'one', end : 72 }, { type : 'macro-parameter', start : 72, value : 'four and five', name : 'three', end : 94 } ], name : 'myMacro', end : 96 }, end : 96 } ], tag : '$mytag', end : 97 } + { type : "mytag", start : 0, attributes : { attrib1 : { type : "string", start : 7, name : "attrib1", value : "something", end : 27 }, attrib2 : { type : "string", start : 27, name : "attrib2", value : "else", end : 40 }, thing : { type : "string", start : 40, name : "thing", value : "true", end : 47 }, attrib3 : { type : "macro", start : 47, name : "attrib3", value : { type : "macrocall", start : 55, params : [ { type : "macro-parameter", start : 64, value : "two", name : "one", end : 72 }, { type : "macro-parameter", start : 72, value : "four and five", name : "three", end : 94 } ], name : "myMacro", end : 96 }, end : 96 } }, orderedAttributes: [ { type : "string", start : 7, name : "attrib1", value : "something", end : 27 }, { type : "string", start : 27, name : "attrib2", value : "else", end : 40 }, { type : "string", start : 40, name : "thing", value : "true", end : 47 }, { type : "macro", start : 47, name : "attrib3", value : { type : "macrocall", start : 55, params : [ { type : "macro-parameter", start : 64, value : "two", name : "one", end : 72 }, { type : "macro-parameter", start : 72, value : "four and five", name : "three", end : 94 } ], name : "myMacro", end : 96 }, end : 96 } ], tag : "$mytag", end : 97 } ); }); it("should find and parse HTML tags", function() { expect(parser.findNextTag("",1)).toEqual( - { type : 'element', start : 11, attributes : { }, orderedAttributes: [ ], tag : 'mytag', end : 18 } + { type : "element", start : 11, attributes : { }, orderedAttributes: [ ], tag : "mytag", end : 18 } ); expect(parser.findNextTag("something else ",0)).toEqual( null ); expect(parser.findNextTag("<> ",0)).toEqual( - { type : 'element', start : 1, attributes : { other : { type : 'string', value : 'true', start : 6, name : 'other', end : 13 }, stuff : { type : 'string', value : 'true', start : 13, name : 'stuff', end : 18 } }, orderedAttributes: [ { type : 'string', value : 'true', start : 6, name : 'other', end : 13 }, { type : 'string', value : 'true', start : 13, name : 'stuff', end : 18 } ], tag : 'some', end : 19 } + { type : "element", start : 1, attributes : { other : { type : "string", value : "true", start : 6, name : "other", end : 13 }, stuff : { type : "string", value : "true", start : 13, name : "stuff", end : 18 } }, orderedAttributes: [ { type : "string", value : "true", start : 6, name : "other", end : 13 }, { type : "string", value : "true", start : 13, name : "stuff", end : 18 } ], tag : "some", end : 19 } ); expect(parser.findNextTag("<> ",2)).toEqual( - { type : 'element', start : 21, attributes : { }, orderedAttributes: [ ], tag : 'mytag', end : 28 } + { type : "element", start : 21, attributes : { }, orderedAttributes: [ ], tag : "mytag", end : 28 } ); }); diff --git a/editions/test/tiddlers/tests/test-wikitext-parser.js b/editions/test/tiddlers/tests/test-wikitext-parser.js index c35ad1dce..cc4574895 100644 --- a/editions/test/tiddlers/tests/test-wikitext-parser.js +++ b/editions/test/tiddlers/tests/test-wikitext-parser.js @@ -23,87 +23,87 @@ describe("WikiText parser tests", function() { it("should parse tags", function() { expect(parse("
")).toEqual( - [ { type : 'element', tag : 'p', start : 0, end : 4, children : [ { type : 'element', tag : 'br', start : 0, end : 4, openTagStart: 0, openTagEnd: 4, rule: 'html', isBlock : false, attributes : { }, orderedAttributes: [ ] } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start : 0, end : 4, children : [ { type : "element", tag : "br", start : 0, end : 4, openTagStart: 0, openTagEnd: 4, rule: "html", isBlock : false, attributes : { }, orderedAttributes: [ ] } ] } ] ); expect(parse("
")).toEqual( - [ { type : 'element', tag : 'p', start : 0, end : 5, children : [ { type : 'text', text : '
', start : 0, end : 5 } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start : 0, end : 5, children : [ { type : "text", text : "
", start : 0, end : 5 } ] } ] ); expect(parse("
")).toEqual( - [ { type : 'element', tag : 'p', start : 0, end : 5, children : [ { type : 'element', tag : 'div', start : 0, end : 5, openTagStart: 0, openTagEnd: 5, closeTagStart: 5, closeTagEnd: 5, rule: 'html', isBlock : false, attributes : { }, orderedAttributes: [ ], children : [ ] } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start : 0, end : 5, children : [ { type : "element", tag : "div", start : 0, end : 5, openTagStart: 0, openTagEnd: 5, closeTagStart: 5, closeTagEnd: 5, rule: "html", isBlock : false, attributes : { }, orderedAttributes: [ ], children : [ ] } ] } ] ); expect(parse("
")).toEqual( - [ { type : 'element', tag : 'p', start : 0, end : 6, children : [ { type : 'element', tag : 'div', isSelfClosing : true, isBlock : false, attributes : { }, orderedAttributes: [ ], start : 0, end : 6, rule: 'html' } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start : 0, end : 6, children : [ { type : "element", tag : "div", isSelfClosing : true, isBlock : false, attributes : { }, orderedAttributes: [ ], start : 0, end : 6, rule: "html" } ] } ] ); expect(parse("
")).toEqual( - [ { type : 'element', tag : 'p', start : 0, end : 11, children : [ { type : 'element', tag : 'div', isBlock : false, attributes : { }, orderedAttributes: [ ], children : [ ], start : 0, end : 11, openTagStart: 0, openTagEnd: 5, closeTagStart: 5, closeTagEnd: 11, rule: 'html' } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start : 0, end : 11, children : [ { type : "element", tag : "div", isBlock : false, attributes : { }, orderedAttributes: [ ], children : [ ], start : 0, end : 11, openTagStart: 0, openTagEnd: 5, closeTagStart: 5, closeTagEnd: 11, rule: "html" } ] } ] ); expect(parse("
some text
")).toEqual( - [ { type : 'element', tag : 'p', start : 0, end : 20, children : [ { type : 'element', tag : 'div', openTagStart: 0, openTagEnd: 5, closeTagStart: 14, closeTagEnd: 20, rule: 'html', isBlock : false, attributes : { }, orderedAttributes: [ ], children : [ { type : 'text', text : 'some text', start : 5, end : 14 } ], start : 0, end : 20 } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start : 0, end : 20, children : [ { type : "element", tag : "div", openTagStart: 0, openTagEnd: 5, closeTagStart: 14, closeTagEnd: 20, rule: "html", isBlock : false, attributes : { }, orderedAttributes: [ ], children : [ { type : "text", text : "some text", start : 5, end : 14 } ], start : 0, end : 20 } ] } ] ); expect(parse("
some text
")).toEqual( - [ { type : 'element', tag : 'p', start : 0, end : 30, children : [ { type : 'element', tag : 'div', isBlock : false, attributes : { attribute : { type : 'string', value : 'true', start : 4, end : 14, name: 'attribute' } }, orderedAttributes: [ { type : 'string', value : 'true', start : 4, end : 14, name: 'attribute' } ], children : [ { type : 'text', text : 'some text', start : 15, end : 24 } ], start : 0, end : 30, openTagStart: 0, openTagEnd: 15, closeTagStart: 24, closeTagEnd: 30, rule: 'html' } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start : 0, end : 30, children : [ { type : "element", tag : "div", isBlock : false, attributes : { attribute : { type : "string", value : "true", start : 4, end : 14, name: "attribute" } }, orderedAttributes: [ { type : "string", value : "true", start : 4, end : 14, name: "attribute" } ], children : [ { type : "text", text : "some text", start : 15, end : 24 } ], start : 0, end : 30, openTagStart: 0, openTagEnd: 15, closeTagStart: 24, closeTagEnd: 30, rule: "html" } ] } ] ); expect(parse("
some text
")).toEqual( - [ { type : 'element', tag : 'p', start : 0, end : 38, children : [ { type : 'element', tag : 'div', openTagStart: 0, openTagEnd: 23, closeTagStart: 32, closeTagEnd: 38, rule: 'html', isBlock : false, attributes : { attribute : { type : 'string', name: 'attribute', value : 'value', start: 4, end: 22 } }, orderedAttributes: [ { type: 'string', name: 'attribute', value : 'value', start: 4, end: 22 } ], children : [ { type : 'text', text : 'some text', start : 23, end : 32 } ], start : 0, end : 38 } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start : 0, end : 38, children : [ { type : "element", tag : "div", openTagStart: 0, openTagEnd: 23, closeTagStart: 32, closeTagEnd: 38, rule: "html", isBlock : false, attributes : { attribute : { type : "string", name: "attribute", value : "value", start: 4, end: 22 } }, orderedAttributes: [ { type: "string", name: "attribute", value : "value", start: 4, end: 22 } ], children : [ { type : "text", text : "some text", start : 23, end : 32 } ], start : 0, end : 38 } ] } ] ); expect(parse("
some text
")).toEqual( - [ { type : 'element', tag : 'p', start: 0, end: 47, children : [ { type : 'element', tag : 'div', isBlock : false, attributes : { attribute : { type : 'indirect', name: 'attribute', textReference : 'TiddlerTitle', start : 4, end : 31 } }, orderedAttributes: [ { type : 'indirect', name: 'attribute', textReference : 'TiddlerTitle', start : 4, end : 31 } ], children : [ { type : 'text', text : 'some text', start : 32, end : 41 } ], start : 0, end : 47, openTagStart: 0, openTagEnd: 32, closeTagStart: 41, closeTagEnd: 47, rule: 'html' } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start: 0, end: 47, children : [ { type : "element", tag : "div", isBlock : false, attributes : { attribute : { type : "indirect", name: "attribute", textReference : "TiddlerTitle", start : 4, end : 31 } }, orderedAttributes: [ { type : "indirect", name: "attribute", textReference : "TiddlerTitle", start : 4, end : 31 } ], children : [ { type : "text", text : "some text", start : 32, end : 41 } ], start : 0, end : 47, openTagStart: 0, openTagEnd: 32, closeTagStart: 41, closeTagEnd: 47, rule: "html" } ] } ] ); expect(parse("<$reveal state='$:/temp/search' type='nomatch' text=''>")).toEqual( - [ { type : 'element', tag : 'p', start: 0, end: 55, children : [ { type : 'reveal', tag: '$reveal', rule: 'html', attributes : { state : { start : 8, name : 'state', type : 'string', value : '$:/temp/search', end : 31 }, type : { start : 31, name : 'type', type : 'string', value : 'nomatch', end : 46 }, text : { start : 46, name : 'text', type : 'string', value : '', end : 54 } }, orderedAttributes: [ { start : 8, name : 'state', type : 'string', value : '$:/temp/search', end : 31 }, { start : 31, name : 'type', type : 'string', value : 'nomatch', end : 46 }, { start : 46, name : 'text', type : 'string', value : '', end : 54 } ], start: 0, end : 55, openTagStart: 0, openTagEnd: 55, closeTagStart: 55, closeTagEnd: 55, isBlock : false, children : [ ] } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start: 0, end: 55, children : [ { type : "reveal", tag: "$reveal", rule: "html", attributes : { state : { start : 8, name : "state", type : "string", value : "$:/temp/search", end : 31 }, type : { start : 31, name : "type", type : "string", value : "nomatch", end : 46 }, text : { start : 46, name : "text", type : "string", value : "", end : 54 } }, orderedAttributes: [ { start : 8, name : "state", type : "string", value : "$:/temp/search", end : 31 }, { start : 31, name : "type", type : "string", value : "nomatch", end : 46 }, { start : 46, name : "text", type : "string", value : "", end : 54 } ], start: 0, end : 55, openTagStart: 0, openTagEnd: 55, closeTagStart: 55, closeTagEnd: 55, isBlock : false, children : [ ] } ] } ] ); expect(parse("
some text
")).toEqual( - [ { type : 'element', tag : 'p', start: 0, end: 54, children : [ { type : 'element', tag : 'div', rule: 'html', isBlock : false, attributes : { attribute : { type : 'indirect', name : 'attribute', textReference : 'TiddlerTitle!!field', start : 4, end : 38 } }, orderedAttributes: [ { type : 'indirect', name : 'attribute', textReference : 'TiddlerTitle!!field', start : 4, end : 38 } ], children : [ { type : 'text', text : 'some text', start : 39, end : 48 } ], start : 0, end : 54, openTagStart: 0, openTagEnd: 39, closeTagStart: 48, closeTagEnd: 54 } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start: 0, end: 54, children : [ { type : "element", tag : "div", rule: "html", isBlock : false, attributes : { attribute : { type : "indirect", name : "attribute", textReference : "TiddlerTitle!!field", start : 4, end : 38 } }, orderedAttributes: [ { type : "indirect", name : "attribute", textReference : "TiddlerTitle!!field", start : 4, end : 38 } ], children : [ { type : "text", text : "some text", start : 39, end : 48 } ], start : 0, end : 54, openTagStart: 0, openTagEnd: 39, closeTagStart: 48, closeTagEnd: 54 } ] } ] ); expect(parse("
some text
")).toEqual( - [ { type : 'element', tag : 'p', start: 0, end: 55, children : [ { type : 'element', tag : 'div', rule: 'html', isBlock : false, attributes : { attribute : { type : 'indirect', name : 'attribute', textReference : 'Tiddler Title!!field', start : 4, end : 39 } }, orderedAttributes: [ { type : 'indirect', name : 'attribute', textReference : 'Tiddler Title!!field', start : 4, end : 39 } ], children : [ { type : 'text', text : 'some text', start : 40, end : 49 } ], start : 0, end : 55, openTagStart: 0, openTagEnd: 40, closeTagStart: 49, closeTagEnd: 55 } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start: 0, end: 55, children : [ { type : "element", tag : "div", rule: "html", isBlock : false, attributes : { attribute : { type : "indirect", name : "attribute", textReference : "Tiddler Title!!field", start : 4, end : 39 } }, orderedAttributes: [ { type : "indirect", name : "attribute", textReference : "Tiddler Title!!field", start : 4, end : 39 } ], children : [ { type : "text", text : "some text", start : 40, end : 49 } ], start : 0, end : 55, openTagStart: 0, openTagEnd: 40, closeTagStart: 49, closeTagEnd: 55 } ] } ] ); expect(parse("
\n\nsome text
")).toEqual( - [ { type : 'element', start : 0, attributes : { attribute : { start : 4, name : 'attribute', type : 'indirect', textReference : 'TiddlerTitle!!field', end : 38 } }, orderedAttributes: [ { start : 4, name : 'attribute', type : 'indirect', textReference : 'TiddlerTitle!!field', end : 38 } ], tag : 'div', rule: 'html', end : 56, openTagStart: 0, openTagEnd: 39, closeTagStart: 50, closeTagEnd: 56, isBlock : true, children : [ { type : 'element', tag : 'p', start : 41, end : 50, children : [ { type : 'text', text : 'some text', start : 41, end : 50 } ] } ] } ] + [ { type : "element", start : 0, attributes : { attribute : { start : 4, name : "attribute", type : "indirect", textReference : "TiddlerTitle!!field", end : 38 } }, orderedAttributes: [ { start : 4, name : "attribute", type : "indirect", textReference : "TiddlerTitle!!field", end : 38 } ], tag : "div", rule: "html", end : 56, openTagStart: 0, openTagEnd: 39, closeTagStart: 50, closeTagEnd: 56, isBlock : true, children : [ { type : "element", tag : "p", rule: "parseblock", start : 41, end : 50, children : [ { type : "text", text : "some text", start : 41, end : 50 } ] } ] } ] ); expect(parse("
\n\nsome text
")).toEqual( - [ { type : 'element', tag : 'p', start: 0, end: 67, children : [ { type : 'element', start : 0, end: 67, openTagStart: 0, openTagEnd: 5, closeTagStart: 61, closeTagEnd: 67, attributes : { }, orderedAttributes: [ ], tag : 'div', rule: 'html', isBlock : false, children : [ { type : 'element', start : 5, attributes : { attribute : { start : 9, name : 'attribute', type : 'indirect', textReference : 'TiddlerTitle!!field', end : 43 } }, orderedAttributes: [ { start : 9, name : 'attribute', type : 'indirect', textReference : 'TiddlerTitle!!field', end : 43 } ], tag : 'div', end : 61, openTagStart: 5, openTagEnd: 44, closeTagStart: 55, closeTagEnd: 61, rule: 'html', isBlock : true, children : [ { type : 'element', tag : 'p', start : 46, end : 55, children : [ { type : 'text', text : 'some text', start : 46, end : 55 } ] } ] } ] } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start: 0, end: 67, children : [ { type : "element", start : 0, end: 67, openTagStart: 0, openTagEnd: 5, closeTagStart: 61, closeTagEnd: 67, attributes : { }, orderedAttributes: [ ], tag : "div", rule: "html", isBlock : false, children : [ { type : "element", start : 5, attributes : { attribute : { start : 9, name : "attribute", type : "indirect", textReference : "TiddlerTitle!!field", end : 43 } }, orderedAttributes: [ { start : 9, name : "attribute", type : "indirect", textReference : "TiddlerTitle!!field", end : 43 } ], tag : "div", end : 61, openTagStart: 5, openTagEnd: 44, closeTagStart: 55, closeTagEnd: 61, rule: "html", isBlock : true, children : [ { type : "element", tag : "p", rule: "parseblock", start : 46, end : 55, children : [ { type : "text", text : "some text", start : 46, end : 55 } ] } ] } ] } ] } ] ); expect(parse("
\n\n!some heading
")).toEqual( - [ { type : 'element', tag : 'p', start: 0, end: 71, children : [ { type : 'element', start : 0, end: 71, openTagStart: 0, openTagEnd: 5, closeTagStart: 71, closeTagEnd: 71, attributes : { }, orderedAttributes: [ ], tag : 'div', rule: 'html', isBlock : false, children : [ { type : 'element', start : 5, attributes : { attribute : { start : 9, name : 'attribute', type : 'indirect', textReference : 'TiddlerTitle!!field', end : 43 } }, orderedAttributes: [ { start : 9, name : 'attribute', type : 'indirect', textReference : 'TiddlerTitle!!field', end : 43 } ], tag : 'div', end : 71, openTagStart: 5, openTagEnd: 44, closeTagStart: 71, closeTagEnd: 71, rule: 'html', isBlock : true, children : [ { type : 'element', tag : 'h1', start: 46, end: 71, rule: 'heading', attributes : { class : { type : 'string', value : '', start: 47, end: 47 } }, children : [ { type : 'text', text : 'some heading
', start : 47, end : 71 } ] } ] } ] } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start: 0, end: 71, children : [ { type : "element", start : 0, end: 71, openTagStart: 0, openTagEnd: 5, closeTagStart: 71, closeTagEnd: 71, attributes : { }, orderedAttributes: [ ], tag : "div", rule: "html", isBlock : false, children : [ { type : "element", start : 5, attributes : { attribute : { start : 9, name : "attribute", type : "indirect", textReference : "TiddlerTitle!!field", end : 43 } }, orderedAttributes: [ { start : 9, name : "attribute", type : "indirect", textReference : "TiddlerTitle!!field", end : 43 } ], tag : "div", end : 71, openTagStart: 5, openTagEnd: 44, closeTagStart: 71, closeTagEnd: 71, rule: "html", isBlock : true, children : [ { type : "element", tag : "h1", start: 46, end: 71, rule: "heading", attributes : { class : { type : "string", value : "", start: 47, end: 47 } }, children : [ { type : "text", text : "some heading", start : 47, end : 71 } ] } ] } ] } ] } ] ); expect(parse("
\n!some heading
")).toEqual( - [ { type : 'element', tag : 'p', start: 0, end: 70, children : [ { type : 'element', start : 0, end: 70, openTagStart: 0, openTagEnd: 5, closeTagStart: 64, closeTagEnd: 70, attributes : { }, orderedAttributes: [ ], tag : 'div', rule: 'html', isBlock : false, children : [ { type : 'element', start : 5, attributes : { attribute : { start : 9, name : 'attribute', type : 'indirect', textReference : 'TiddlerTitle!!field', end : 43 } }, orderedAttributes: [ { start : 9, name : 'attribute', type : 'indirect', textReference : 'TiddlerTitle!!field', end : 43 } ], tag : 'div', end : 64, openTagStart: 5, openTagEnd: 44, closeTagStart: 58, closeTagEnd: 64, rule: 'html', isBlock : false, children : [ { type : 'text', text : '\n!some heading', start : 44, end : 58 } ] } ] } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start: 0, end: 70, children : [ { type : "element", start : 0, end: 70, openTagStart: 0, openTagEnd: 5, closeTagStart: 64, closeTagEnd: 70, attributes : { }, orderedAttributes: [ ], tag : "div", rule: "html", isBlock : false, children : [ { type : "element", start : 5, attributes : { attribute : { start : 9, name : "attribute", type : "indirect", textReference : "TiddlerTitle!!field", end : 43 } }, orderedAttributes: [ { start : 9, name : "attribute", type : "indirect", textReference : "TiddlerTitle!!field", end : 43 } ], tag : "div", end : 64, openTagStart: 5, openTagEnd: 44, closeTagStart: 58, closeTagEnd: 64, rule: "html", isBlock : false, children : [ { type : "text", text : "\n!some heading", start : 44, end : 58 } ] } ] } ] } ] ); // Regression test for issue (#3306) expect(parse("
\n\nSome text
")).toEqual( - [ { type : 'element', tag : 'p', start: 0, end: 48, children : [ { type : 'element', start : 0, end: 48, openTagStart: 0, openTagEnd: 5, closeTagStart: 42, closeTagEnd: 48, attributes : { }, orderedAttributes: [ ], tag : 'div', rule: 'html', isBlock : false, children : [ { type : 'element', start : 5, attributes : { }, orderedAttributes: [ ], tag : 'span', end : 42, openTagStart: 5, openTagEnd: 11, closeTagStart: 35, closeTagEnd: 42, rule: 'html', isBlock : false, children : [ { type : 'element', start : 11, attributes : { }, orderedAttributes: [ ], tag : 'span', end : 35, openTagStart: 11, openTagEnd: 17, closeTagStart: 28, closeTagEnd: 35, rule: 'html', isBlock : true, children : [ { type : 'element', tag : 'p', start : 19, end : 28, children : [ { type : 'text', text : 'Some text', start : 19, end : 28 } ] } ] } ] } ] } ] } ] + [ { type : "element", tag : "p", rule: "parseblock", start: 0, end: 48, children : [ { type : "element", start : 0, end: 48, openTagStart: 0, openTagEnd: 5, closeTagStart: 42, closeTagEnd: 48, attributes : { }, orderedAttributes: [ ], tag : "div", rule: "html", isBlock : false, children : [ { type : "element", start : 5, attributes : { }, orderedAttributes: [ ], tag : "span", end : 42, openTagStart: 5, openTagEnd: 11, closeTagStart: 35, closeTagEnd: 42, rule: "html", isBlock : false, children : [ { type : "element", start : 11, attributes : { }, orderedAttributes: [ ], tag : "span", end : 35, openTagStart: 11, openTagEnd: 17, closeTagStart: 28, closeTagEnd: 35, rule: "html", isBlock : true, children : [ { type : "element", tag : "p", rule: "parseblock", start : 19, end : 28, children : [ { type : "text", text : "Some text", start : 19, end : 28 } ] } ] } ] } ] } ] } ] ); }); @@ -111,7 +111,12 @@ describe("WikiText parser tests", function() { it("should parse macro definitions", function() { expect(parse("\\define myMacro()\nnothing\n\\end\n")).toEqual( - [{"type":"set","attributes":{"name":{"name":"name","type":"string","value":"myMacro"},"value":{"name":"value","type":"string","value":"nothing"}},"children":[],"params":[],"isMacroDefinition":true,"orderedAttributes":[{"name":"name","type":"string","value":"myMacro"},{"name":"value","type":"string","value":"nothing"}],"start":0,"end":30,"rule":"macrodef"}] + [{"type":"set","attributes":{"name":{"name":"name","type":"string","value":"myMacro"},"value":{"name":"value","type":"string","value":"nothing"}},"children":[],"params":[],"isMacroDefinition":true,"isBlock":false,"orderedAttributes":[{"name":"name","type":"string","value":"myMacro"},{"name":"value","type":"string","value":"nothing"}],"start":0,"end":30,"rule":"macrodef"}] + + ); + expect(parse("\\define myMacro() nothing\n\n")).toEqual( + + [{"type":"set","attributes":{"name":{"name":"name","type":"string","value":"myMacro"},"value":{"name":"value","type":"string","value":"nothing"}},"children":[],"params":[],"isMacroDefinition":true,"isBlock":true,"orderedAttributes":[{"name":"name","type":"string","value":"myMacro"},{"name":"value","type":"string","value":"nothing"}],"start":0,"end":25,"rule":"macrodef"}] ); }); @@ -182,7 +187,7 @@ describe("WikiText parser tests", function() { it("should parse comment in pragma area. Comment will be invisible", function() { expect(parse("\n\\define aMacro()\nnothing\n\\end\n")).toEqual( - [{"type":"set","attributes":{"name":{"name":"name","type":"string","value":"aMacro"},"value":{"name":"value","type":"string","value":"nothing"}},"children":[],"params":[],"isMacroDefinition":true,"orderedAttributes":[{"name":"name","type":"string","value":"aMacro"},{"name":"value","type":"string","value":"nothing"}],"start":32,"end":61,"rule":"macrodef"}] + [{"type":"void","children":[{"type":"set","attributes":{"name":{"name":"name","type":"string","value":"aMacro"},"value":{"name":"value","type":"string","value":"nothing"}},"children":[],"params":[],"isMacroDefinition":true,"isBlock":false,"orderedAttributes":[{"name":"name","type":"string","value":"aMacro"},{"name":"value","type":"string","value":"nothing"}],"start":32,"end":61,"rule":"macrodef"}],"text":"","start":0,"end":31,"rule":"commentblock"}] ); }); @@ -190,12 +195,12 @@ describe("WikiText parser tests", function() { it("should block mode filtered transclusions", function() { expect(parse("{{{ filter }}}")).toEqual( - [ { type: 'list', attributes: { filter: { type: 'string', value: ' filter ', start: 3, end: 11 } }, isBlock: true, start: 0, end: 14, rule: "filteredtranscludeblock" } ] + [ { type: "list", attributes: { filter: { type: "string", value: " filter ", start: 3, end: 11 } }, isBlock: true, start: 0, end: 14, rule: "filteredtranscludeblock" } ] ); expect(parse("{{{ fil\nter }}}")).toEqual( - [ { type: 'list', attributes: { filter: { type: 'string', value: ' fil\nter ', start: 3, end: 12 } }, isBlock: true, start: 0, end: 15, rule: "filteredtranscludeblock" } ] + [ { type: "list", attributes: { filter: { type: "string", value: " fil\nter ", start: 3, end: 12 } }, isBlock: true, start: 0, end: 15, rule: "filteredtranscludeblock" } ] ); }); @@ -203,38 +208,38 @@ describe("WikiText parser tests", function() { it("should parse inline macro calls", function() { expect(parse("<><><><>")).toEqual( - [{"type":"element","tag":"p","children":[{"type":"transclude","start":0,"end":8,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"}]},{"type":"transclude","start":8,"end":16,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"paul"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"paul"}]},{"type":"transclude","start":16,"end":26,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"george"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"george"}]},{"type":"transclude","start":26,"end":35,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"ringo"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"ringo"}]}],"start":0,"end":35}] + [{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"transclude","start":0,"end":8,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"}]},{"type":"transclude","start":8,"end":16,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"paul"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"paul"}]},{"type":"transclude","start":16,"end":26,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"george"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"george"}]},{"type":"transclude","start":26,"end":35,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"ringo"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"ringo"}]}],"start":0,"end":35}] ); expect(parse("text <>")).toEqual( - [{"type":"element","tag":"p","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":92,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"},"one":{"name":"one","type":"string","value":"val1","start":11,"end":20},"two":{"name":"two","type":"string","value":"val \"2\"","start":20,"end":35},"three":{"name":"three","type":"string","value":"val '3'","start":35,"end":52},"four":{"name":"four","type":"string","value":"val 4\"5'","start":52,"end":73},"five":{"name":"five","type":"string","value":"val 5","start":73,"end":89}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"one","type":"string","value":"val1","start":11,"end":20},{"name":"two","type":"string","value":"val \"2\"","start":20,"end":35},{"name":"three","type":"string","value":"val '3'","start":35,"end":52},{"name":"four","type":"string","value":"val 4\"5'","start":52,"end":73},{"name":"five","type":"string","value":"val 5","start":73,"end":89}]}],"start":0,"end":92}] + [{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":92,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"},"one":{"name":"one","type":"string","value":"val1","start":11,"end":20},"two":{"name":"two","type":"string","value":"val \"2\"","start":20,"end":35},"three":{"name":"three","type":"string","value":"val '3'","start":35,"end":52},"four":{"name":"four","type":"string","value":"val 4\"5'","start":52,"end":73},"five":{"name":"five","type":"string","value":"val 5","start":73,"end":89}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"one","type":"string","value":"val1","start":11,"end":20},{"name":"two","type":"string","value":"val \"2\"","start":20,"end":35},{"name":"three","type":"string","value":"val '3'","start":35,"end":52},{"name":"four","type":"string","value":"val 4\"5'","start":52,"end":73},{"name":"five","type":"string","value":"val 5","start":73,"end":89}]}],"start":0,"end":92}] ); expect(parse("ignored << carrots <>")).toEqual( - [{"type":"element","tag":"p","children":[{"type":"text","text":"ignored << carrots ","start":0,"end":19},{"type":"transclude","start":19,"end":27,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"}]}],"start":0,"end":27}] + [{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"ignored << carrots ","start":0,"end":19},{"type":"transclude","start":19,"end":27,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"}]}],"start":0,"end":27}] ); expect(parse("text <<>")).toEqual( - [{"type":"element","tag":"p","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":14,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":">")).toEqual( - [{"type":"element","tag":"p","children":[{"type":"text","text":"before\n","start":0,"end":7},{"type":"transclude","start":7,"end":15,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"}]}],"start":0,"end":15}] + [{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"before\n","start":0,"end":7},{"type":"transclude","start":7,"end":15,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"}]}],"start":0,"end":15}] ); // A single space will cause it to be inline expect(parse("<> ")).toEqual( - [{"type":"element","tag":"p","children":[{"type":"transclude","start":0,"end":8,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"}]},{"type":"text","text":" ","start":8,"end":9}],"start":0,"end":9}] + [{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"transclude","start":0,"end":8,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"}]},{"type":"text","text":" ","start":8,"end":9}],"start":0,"end":9}] ); expect(parse("text <>' >>")).toEqual( - [{"type":"element","tag":"p","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":34,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"outie"},"one":{"name":"one","type":"string","value":"my <>","start":12,"end":31}},"orderedAttributes":[{"name":"$variable","type":"string","value":"outie"},{"name":"one","type":"string","value":"my <>","start":12,"end":31}]}],"start":0,"end":34}] + [{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"text","text":"text ","start":0,"end":5},{"type":"transclude","start":5,"end":34,"rule":"macrocallinline","attributes":{"$variable":{"name":"$variable","type":"string","value":"outie"},"one":{"name":"one","type":"string","value":"my <>","start":12,"end":31}},"orderedAttributes":[{"name":"$variable","type":"string","value":"outie"},{"name":"one","type":"string","value":"my <>","start":12,"end":31}]}],"start":0,"end":34}] ); @@ -243,7 +248,7 @@ describe("WikiText parser tests", function() { it("should parse block macro calls", function() { expect(parse("<>\n<>\r\n<>\n<>")).toEqual( - [ { type: 'transclude', start: 0, rule: 'macrocallblock', attributes: { $variable: { name: "$variable", type: "string", value: "john" }}, orderedAttributes: [ { name: "$variable", type: "string", value: "john" }], end: 8, isBlock: true }, { type: 'transclude', start: 9, rule: 'macrocallblock', attributes: { $variable: { name: "$variable", type: "string", value: "paul" }}, orderedAttributes: [ { name: "$variable", type: "string", value: "paul" }], end: 17, isBlock: true }, { type: 'transclude', start: 19, rule: 'macrocallblock', attributes: { $variable: { name: "$variable", type: "string", value: "george" }}, orderedAttributes: [ { name: "$variable", type: "string", value: "george" }], end: 29, isBlock: true }, { type: 'transclude', start: 30, rule: 'macrocallblock', attributes: { $variable: { name: "$variable", type: "string", value: "ringo" }}, orderedAttributes: [ { name: "$variable", type: "string", value: "ringo" }], end: 39, isBlock: true } ] + [ { type: "transclude", start: 0, rule: "macrocallblock", attributes: { $variable: { name: "$variable", type: "string", value: "john" }}, orderedAttributes: [ { name: "$variable", type: "string", value: "john" }], end: 8, isBlock: true }, { type: "transclude", start: 9, rule: "macrocallblock", attributes: { $variable: { name: "$variable", type: "string", value: "paul" }}, orderedAttributes: [ { name: "$variable", type: "string", value: "paul" }], end: 17, isBlock: true }, { type: "transclude", start: 19, rule: "macrocallblock", attributes: { $variable: { name: "$variable", type: "string", value: "george" }}, orderedAttributes: [ { name: "$variable", type: "string", value: "george" }], end: 29, isBlock: true }, { type: "transclude", start: 30, rule: "macrocallblock", attributes: { $variable: { name: "$variable", type: "string", value: "ringo" }}, orderedAttributes: [ { name: "$variable", type: "string", value: "ringo" }], end: 39, isBlock: true } ] ); expect(parse("<>")).toEqual( @@ -253,17 +258,17 @@ describe("WikiText parser tests", function() { ); expect(parse("<< carrots\n\n<>")).toEqual( - [ { type: 'element', tag: 'p', start : 0, end : 10, children: [ { type: 'text', text: '<< carrots', start : 0, end : 10 } ] }, { type: 'transclude', start: 12, rule: 'macrocallblock', attributes: { $variable: {name: "$variable", type:"string", value: "john"} }, orderedAttributes: [ {name: "$variable", type:"string", value: "john"} ], end: 20, isBlock: true } ] + [ { type: "element", tag: "p", rule: "parseblock", start : 0, end : 10, children: [ { type: "text", text: "<< carrots", start : 0, end : 10 } ] }, { type: "transclude", start: 12, rule: "macrocallblock", attributes: { $variable: {name: "$variable", type:"string", value: "john"} }, orderedAttributes: [ {name: "$variable", type:"string", value: "john"} ], end: 20, isBlock: true } ] ); expect(parse("before\n\n<>")).toEqual( - [ { type: 'element', tag: 'p', start : 0, end : 6, children: [ { type: 'text', text: 'before', start : 0, end : 6 } ] }, { type: 'transclude', start: 8, rule: 'macrocallblock', attributes: { $variable: {name: "$variable", type:"string", value: "john"} }, orderedAttributes: [ {name: "$variable", type:"string", value: "john"} ], end: 16, isBlock: true } ] + [ { type: "element", tag: "p", rule: "parseblock", start : 0, end : 6, children: [ { type: "text", text: "before", start : 0, end : 6 } ] }, { type: "transclude", start: 8, rule: "macrocallblock", attributes: { $variable: {name: "$variable", type:"string", value: "john"} }, orderedAttributes: [ {name: "$variable", type:"string", value: "john"} ], end: 16, isBlock: true } ] ); expect(parse("<>\nafter")).toEqual( - [ { type: 'transclude', start: 0, rule: 'macrocallblock', attributes: { $variable: {name: "$variable", type:"string", value: "john"} }, orderedAttributes: [ {name: "$variable", type:"string", value: "john"} ], end: 8, isBlock: true }, { type: 'element', tag: 'p', start: 9, end: 14, children: [ { type: 'text', text: 'after', start: 9, end: 14 } ] } ] + [ { type: "transclude", start: 0, rule: "macrocallblock", attributes: { $variable: {name: "$variable", type:"string", value: "john"} }, orderedAttributes: [ {name: "$variable", type:"string", value: "john"} ], end: 8, isBlock: true }, { type: "element", tag: "p", rule: "parseblock", start: 9, end: 14, children: [ { type: "text", text: "after", start: 9, end: 14 } ] } ] ); expect(parse("<>")).toEqual( @@ -273,7 +278,7 @@ describe("WikiText parser tests", function() { ); expect(parse("<>' >>")).toEqual( - [ { type: 'transclude', start: 0, rule: 'macrocallblock', attributes: { $variable: {name: "$variable", type:"string", value: "outie"}, one: {name: "one", type:"string", value: "my <>", start: 7, end: 26} }, orderedAttributes: [ {name: "$variable", type:"string", value: "outie"}, {name: "one", type:"string", value: "my <>", start: 7, end: 26} ], end: 29, isBlock: true } ] + [ { type: "transclude", start: 0, rule: "macrocallblock", attributes: { $variable: {name: "$variable", type:"string", value: "outie"}, one: {name: "one", type:"string", value: "my <>", start: 7, end: 26} }, orderedAttributes: [ {name: "$variable", type:"string", value: "outie"}, {name: "one", type:"string", value: "my <>", start: 7, end: 26} ], end: 29, isBlock: true } ] ); }); @@ -291,7 +296,7 @@ describe("WikiText parser tests", function() { ); expect(parse("<>>")).toEqual( - [{"type":"element","tag":"p","children":[{"type":"transclude","start":0,"end":14,"rule":"macrocallinline","attributes":{"0":{"name":"0","type":"string","value":"param","start":6,"end":12},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"param","start":6,"end":12}]},{"type":"text","text":">","start":14,"end":15}],"start":0,"end":15}] + [{"type":"element","tag":"p",rule:"parseblock","children":[{"type":"transclude","start":0,"end":14,"rule":"macrocallinline","attributes":{"0":{"name":"0","type":"string","value":"param","start":6,"end":12},"$variable":{"name":"$variable","type":"string","value":"john"}},"orderedAttributes":[{"name":"$variable","type":"string","value":"john"},{"name":"0","type":"string","value":"param","start":6,"end":12}]},{"type":"text","text":">","start":14,"end":15}],"start":0,"end":15}] ); // equals signs should be allowed @@ -306,7 +311,7 @@ describe("WikiText parser tests", function() { it("should parse horizontal rules", function() { expect(parse("---Not a rule\n\n----\n\nBetween\n\n---")).toEqual( - [ { type : 'element', tag : 'p', start : 0, end : 13, children : [ { type : 'entity', entity : '—', start: 0, end: 3, rule: 'dash' }, { type : 'text', text : 'Not a rule', start : 3, end : 13 } ] }, { type : 'element', tag : 'hr', start: 15, end: 20, rule: 'horizrule' }, { type : 'element', tag : 'p', start : 21, end : 28, children : [ { type : 'text', text : 'Between', start : 21, end : 28 } ] }, { type : 'element', tag : 'hr', start: 30, end: 33, rule: 'horizrule' } ] + [ { type : "element", tag : "p", rule: "parseblock", start : 0, end : 13, children : [ { type : "entity", entity : "—", start: 0, end: 3, rule: "dash" }, { type : "text", text : "Not a rule", start : 3, end : 13 } ] }, { type : "element", tag : "hr", start: 15, end: 20, rule: "horizrule" }, { type : "element", tag : "p", rule: "parseblock", start : 21, end : 28, children : [ { type : "text", text : "Between", start : 21, end : 28 } ] }, { type : "element", tag : "hr", start: 30, end: 33, rule: "horizrule" } ] ); @@ -315,7 +320,7 @@ describe("WikiText parser tests", function() { it("should parse hard linebreak areas", function() { expect(parse("\"\"\"Something\nin the\nway she moves\n\"\"\"\n\n")).toEqual( - [ { type : 'element', tag : 'p', children : [ { type : 'text', text : 'Something', start : 3, end : 12, rule: 'hardlinebreaks' }, { type : 'element', tag : 'br', rule: 'hardlinebreaks', start: 12, end: 13 }, { type : 'text', text : 'in the', start : 13, end : 19, rule: 'hardlinebreaks' }, { type : 'element', tag : 'br', rule: 'hardlinebreaks', start: 19, end: 20 }, { type : 'text', text : 'way she moves', start : 20, end : 33, rule: 'hardlinebreaks' }, { type : 'element', tag : 'br', rule: 'hardlinebreaks', start: 33, end: 34 } ], start : 0, end : 37 } ] + [ { type : "element", tag : "p", rule: "parseblock", children : [ { type : "text", text : "Something", start : 3, end : 12, rule: "hardlinebreaks", isRuleStart: true }, { type : "element", tag : "br", rule: "hardlinebreaks", start: 12, end: 13 }, { type : "text", text : "in the", start : 13, end : 19, rule: "hardlinebreaks" }, { type : "element", tag : "br", rule: "hardlinebreaks", start: 19, end: 20 }, { type : "text", text : "way she moves", start : 20, end : 33, rule: "hardlinebreaks" }, { type : "element", tag : "br", rule: "hardlinebreaks", start: 33, end: 34, isRuleEnd: true } ], start : 0, end : 37 } ] ); diff --git a/editions/test/tiddlers/tests/test-wikitext-serialize.js b/editions/test/tiddlers/tests/test-wikitext-serialize.js new file mode 100644 index 000000000..e9c6f97cf --- /dev/null +++ b/editions/test/tiddlers/tests/test-wikitext-serialize.js @@ -0,0 +1,18 @@ +/*\ +title: test-wikitext-serialize.js +type: application/javascript +tags: [[$:/tags/test-spec]] + +Tests the wikitext inverse-rendering from Wiki AST. + +\*/ + +describe("WikiAST serialization unit tests", function () { + var cases = $tw.wiki.filterTiddlers("[all[shadows+tiddlers]tag[$:/tags/wikitext-serialize-test-spec]]"); + $tw.utils.each(cases, function (title) { + it("should serialize correctly for " + title, function () { + var serialized = $tw.utils.serializeParseTree($tw.wiki.parseTiddler(title).tree).trimEnd(); + expect(serialized).toBe($tw.wiki.getTiddlerText(title).trimEnd()); + }); + }); +});