jenkins-bot has submitted this change and it was merged. Change subject: Suppress newlines before category links ......................................................................
Suppress newlines before category links * itwiki:Melampyrum now RTs without semantic errors because the duplicate args category links no longer ends up on a new line. * http://localhost:8000/enwiki/Taiko?oldid=665356368 now renders as expected as well. * Parsoid now renders enwiki:User:SSastry_%28WMF%29/Category_Test identically to the PHP parser output. The list tests will not RT back the newlines because of newline suppression in list context. RTing of that test case will not be supported (see parser tests). * We continue to treat category links as SOL-transparent, because that is their "true nature" in scenarios where newlines aren't stripped (when found at start of text -- they aren't usually, but that is besides the point). * Added 2 new parser tests that spec this newline-stripping behavior. * Updated wt2html output of 1 parser test. This will no longer wt2wt now because we are not really suppressing the newlines. I am not interested in adding special cases for rting this edge case. An alternative would be to actually suppress the newlines in parse output using some special meta-tag like mw:Placeholder or mw:SuppressNewlines or something that is not editable but can be deleted. Bug: T2087 Bug: T95988 Change-Id: I507dcefcca5a4ee22fb9f9bf0cfe678f14d64991 --- M lib/ext.core.TokenStreamPatcher.js M tests/parserTests-blacklist.js M tests/parserTests.txt 3 files changed, 118 insertions(+), 11 deletions(-) Approvals: Arlolra: Looks good to me, approved jenkins-bot: Verified diff --git a/lib/ext.core.TokenStreamPatcher.js b/lib/ext.core.TokenStreamPatcher.js index e27cc71..69be60c 100644 --- a/lib/ext.core.TokenStreamPatcher.js +++ b/lib/ext.core.TokenStreamPatcher.js @@ -18,6 +18,7 @@ // define some constructor shortcuts var CommentTk = defines.CommentTk; +var NlTk = defines.NlTk; var TagTk = defines.TagTk; var SelfclosingTagTk = defines.SelfclosingTagTk; var EndTagTk = defines.EndTagTk; @@ -34,8 +35,8 @@ // FIXME: At this point, it probably deserves a refactor. coreutil.inherits(TokenStreamPatcher, TemplateHandler); -TokenStreamPatcher.prototype.anyRank = 2.001; -TokenStreamPatcher.prototype.nlRank = 2.002; +TokenStreamPatcher.prototype.nlRank = 2.001; +TokenStreamPatcher.prototype.anyRank = 2.002; TokenStreamPatcher.prototype.endRank = 2.003; TokenStreamPatcher.prototype.register = function() { @@ -56,12 +57,15 @@ this.wikiTableNesting = 0; this.srcOffset = 0; this.sol = true; + this.tokenBuf = []; }; TokenStreamPatcher.prototype.onNewline = function(token) { + this.manager.env.log("trace/tsp", this.manager.pipelineId, function() { return JSON.stringify(token); } ); this.srcOffset = (token.dataAttribs.tsr || [null, null])[1]; this.sol = true; - return {tokens: [token]}; + this.tokenBuf.push(token); + return {tokens: []}; }; TokenStreamPatcher.prototype.onEnd = function(token) { @@ -135,6 +139,14 @@ var tokens = [token]; switch (token.constructor) { case String: + // While we are buffering newlines to suppress them + // in case we see a category, buffer all intervening + // white-space as well. + if (this.tokenBuf.length > 0 && /^\s*$/.test(token)) { + this.tokenBuf.push(token); + return {tokens: []}; + } + // TRICK #1: // Attempt to match "{|" after a newline and convert // it to a table token. @@ -164,8 +176,48 @@ break; case SelfclosingTagTk: - if (token.name === "meta" && token.dataAttribs.stx !== "html") { + if (token.name === 'meta' && token.dataAttribs.stx !== 'html') { this.srcOffset = (token.dataAttribs.tsr || [null, null])[1]; + // If we have buffered newlines, we might very well encounter + // a category link, so continue buffering. + if (this.tokenBuf.length > 0 && token.name === 'meta' && + token.getAttribute('typeof') === 'mw:Transclusion') { + this.tokenBuf.push(token); + return {tokens: []}; + } + } else if (token.name === 'link' && + token.getAttribute('rel') === 'mw:PageProp/Category') { + // Replace buffered newline & whitespace tokens with mw:EmptyLine + // meta-tokens. This tunnels them through the rest of the transformations + // without affecting them. During HTML building, they are expanded + // back to newlines / whitespace. + var n = this.tokenBuf.length; + if (n > 0) { + var i = 0; + while (i < n && this.tokenBuf[i].constructor !== SelfclosingTagTk) { + i++; + } + + var toks = [ + new SelfclosingTagTk("meta", + [new KV('typeof', 'mw:EmptyLine')], { + tokens: this.tokenBuf.slice(0, i) + }) + ]; + if (i < n) { + toks.push(this.tokenBuf[i]); + if (i + 1 < n) { + toks.push(new SelfclosingTagTk("meta", + [new KV('typeof', 'mw:EmptyLine')], { + tokens: this.tokenBuf.slice(i + 1) + }) + ); + } + } + tokens = toks.concat(tokens); + this.tokenBuf = []; + } + this.clearSOL(); } else { this.clearSOL(); } @@ -203,6 +255,11 @@ break; } + // Emit buffered newlines (and a transclusion meta-token, if any) + if (this.tokenBuf.length > 0) { + tokens = this.tokenBuf.concat(tokens); + this.tokenBuf = []; + } return {tokens: tokens}; }; diff --git a/tests/parserTests-blacklist.js b/tests/parserTests-blacklist.js index 3ee3c06..c97e1a6 100644 --- a/tests/parserTests-blacklist.js +++ b/tests/parserTests-blacklist.js @@ -186,7 +186,7 @@ add("wt2html", "Category with template", "<link typeof=\"mw:ExpandedAttrs\" about=\"#mwt2\" rel=\"mw:PageProp/Category\" href=\"./Category:Foo\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Foo\"},\"sa\":{\"href\":\"Category:{{echo|Foo}}\"},\"dsr\":[0,25,null,null]}' data-mw='{\"attribs\":[[{\"txt\":\"href\"},{\"html\":\"Category:<span about=\\\"#mwt1\\\" typeof=\\\"mw:Transclusion\\\" data-parsoid=\\\"{&quot;pi&quot;:[[{&quot;k&quot;:&quot;1&quot;,&quot;spc&quot;:[&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;]}]],&quot;dsr&quot;:[11,23,null,null]}\\\" data-mw=\\\"{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;Foo&quot;}},&quot;i&quot;:0}}]}\\\">Foo</span>\"}]]}'/>"); add("wt2html", "Category with template in sort key", "<link rel=\"mw:PageProp/Category\" href=\"./Category:Foo#Bar\" about=\"#mwt2\" typeof=\"mw:ExpandedAttrs\" data-parsoid='{\"stx\":\"piped\",\"a\":{\"href\":\"./Category:Foo\"},\"sa\":{\"href\":\"Category:Foo\"},\"dsr\":[0,29,null,null]}' data-mw='{\"attribs\":[[{\"txt\":\"mw:sortKey\"},{\"html\":\"<span about=\\\"#mwt1\\\" typeof=\\\"mw:Transclusion\\\" data-parsoid=\\\"{&quot;pi&quot;:[[{&quot;k&quot;:&quot;1&quot;,&quot;spc&quot;:[&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;]}]],&quot;dsr&quot;:[15,27,null,null]}\\\" data-mw=\\\"{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;Bar&quot;}},&quot;i&quot;:0}}]}\\\">Bar</span>\"}]]}'/>"); add("wt2html", "Category with template in sort key and title", "<link typeof=\"mw:ExpandedAttrs\" about=\"#mwt4\" rel=\"mw:PageProp/Category\" href=\"./Category:Foo#Bar\" data-parsoid='{\"stx\":\"piped\",\"a\":{\"href\":\"./Category:Foo\"},\"sa\":{\"href\":\"Category:{{echo|Foo}}\"},\"dsr\":[0,38,null,null]}' data-mw='{\"attribs\":[[{\"txt\":\"href\"},{\"html\":\"Category:<span about=\\\"#mwt1\\\" typeof=\\\"mw:Transclusion\\\" data-parsoid=\\\"{&quot;pi&quot;:[[{&quot;k&quot;:&quot;1&quot;,&quot;spc&quot;:[&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;]}]],&quot;dsr&quot;:[11,23,null,null]}\\\" data-mw=\\\"{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;Foo&quot;}},&quot;i&quot;:0}}]}\\\">Foo</span>\"}],[{\"txt\":\"mw:sortKey\"},{\"html\":\"<span about=\\\"#mwt2\\\" typeof=\\\"mw:Transclusion\\\" data-parsoid=\\\"{&quot;pi&quot;:[[{&quot;k&quot;:&quot;1&quot;,&quot;spc&quot;:[&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;]}]],&quot;dsr&quot;:[24,36,null,null]}\\\" data-mw=\\\"{&quot;parts&quot;:[{&quot;template&quot;:{&quot;target&quot;:{&quot;wt&quot;:&quot;echo&quot;,&quot;href&quot;:&quot;./Template:Echo&quot;},&quot;params&quot;:{&quot;1&quot;:{&quot;wt&quot;:&quot;Bar&quot;}},&quot;i&quot;:0}}]}\\\">Bar</span>\"}]]}'/>"); -add("wt2html", "Category / paragraph interactions", "<p data-parsoid='{\"dsr\":[0,24,0,0]}'>Foo <link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[4,20,null,null]}'/> Bar</p>\n\n<p data-parsoid='{\"dsr\":[26,50,0,0]}'>Foo <link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[30,46,null,null]}'/>\nBar</p>\n\n<p data-parsoid='{\"dsr\":[52,76,0,0]}'>Foo\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[56,72,null,null]}'/>\nBar</p>\n\n<p data-parsoid='{\"dsr\":[78,81,0,0]}'>Foo</p>\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[82,98,null,null]}'/><pre data-parsoid='{\"dsr\":[98,102,1,0]}'>Bar</pre>\n\n<p data-parsoid='{\"dsr\":[104,163,0,0]}'>Foo\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[108,124,null,null]}'/>\n <link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[126,142,null,null]}'/>\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[143,159,null,null]}'/>\nBar</p>\n\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[165,181,null,null]}'/>\n <link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[183,199,null,null]}'/>\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[200,216,null,null]}'/>\n\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[218,234,null,null]}'/>\n <link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[236,261,null,null],\"pi\":[[{\"k\":\"1\",\"spc\":[\"\",\"\",\"\",\"\"]}]]}' data-mw='{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"[[Category:Baz]]\"}},\"i\":0}}]}'/>\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[262,278,null,null]}'/>"); +add("wt2html", "Category / paragraph interactions", "<p data-parsoid='{\"dsr\":[0,24,0,0]}'>Foo <link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[4,20,null,null]}'/> Bar</p>\n\n<p data-parsoid='{\"dsr\":[26,50,0,0]}'>Foo <link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[30,46,null,null]}'/>\nBar</p>\n\n<p data-parsoid='{\"dsr\":[52,76,0,0]}'>Foo\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[56,72,null,null]}'/>\nBar</p>\n\n<p data-parsoid='{\"dsr\":[78,102,0,0]}'>Foo\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[82,98,null,null]}'/> Bar</p>\n\n<p data-parsoid='{\"dsr\":[104,261,0,0]}'>Foo\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[108,124,null,null]}'/>\n <link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[126,142,null,null]}'/>\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[143,159,null,null]}'/>\nBar\n\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[165,181,null,null]}'/>\n <link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[183,199,null,null]}'/>\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[200,216,null,null]}'/>\n\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[218,234,null,null]}'/>\n <link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[236,261,null,null],\"pi\":[[{\"k\":\"1\",\"spc\":[\"\",\"\",\"\",\"\"]}]]}' data-mw='{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"[[Category:Baz]]\"}},\"i\":0}}]}'/></p>\n<link rel=\"mw:PageProp/Category\" href=\"./Category:Baz\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Category:Baz\"},\"sa\":{\"href\":\"Category:Baz\"},\"dsr\":[262,278,null,null]}'/>"); add("wt2html", "Short headings with trailing space should match behavior of Parser::doHeadings (bug 19910)", "<p data-parsoid='{\"dsr\":[0,100,0,0]}'>=== \nThe line above must have a trailing space!\n=== <!--\n--> <!-- -->\nBut just in case it doesn't...</p>"); add("wt2html", "Header with space, plus and underscore as entity", "<p data-parsoid='{\"dsr\":[0,34,0,0]}'>Id should not contain + for spaces</p>\n\n<h2 data-parsoid='{\"dsr\":[36,60,2,2]}'> Space between Text </h2>\n<p data-parsoid='{\"dsr\":[61,70,0,0]}'>section 1</p>\n\n<h2 data-parsoid='{\"dsr\":[72,111,2,2]}'> Space-Entity<span typeof=\"mw:Entity\" data-parsoid='{\"src\":\"&#32;\",\"srcContent\":\" \",\"dsr\":[87,92,null,null]}'> </span>between<span typeof=\"mw:Entity\" data-parsoid='{\"src\":\"&#32;\",\"srcContent\":\" \",\"dsr\":[99,104,null,null]}'> </span>Text </h2>\n<p data-parsoid='{\"dsr\":[112,121,0,0]}'>section 2</p>\n\n<h2 data-parsoid='{\"dsr\":[123,146,2,2]}'> Plus+between+Text </h2>\n<p data-parsoid='{\"dsr\":[147,156,0,0]}'>section 3</p>\n\n<h2 data-parsoid='{\"dsr\":[158,196,2,2]}'> Plus-Entity<span typeof=\"mw:Entity\" data-parsoid='{\"src\":\"&#43;\",\"srcContent\":\"+\",\"dsr\":[172,177,null,null]}'>+</span>between<span typeof=\"mw:Entity\" data-parsoid='{\"src\":\"&#43;\",\"srcContent\":\"+\",\"dsr\":[184,189,null,null]}'>+</span>Text </h2>\n<p data-parsoid='{\"dsr\":[197,206,0,0]}'>section 4</p>\n\n<h2 data-parsoid='{\"dsr\":[208,237,2,2]}'> Underscore_between_Text </h2>\n<p data-parsoid='{\"dsr\":[238,247,0,0]}'>section 5</p>\n\n<h2 data-parsoid='{\"dsr\":[249,293,2,2]}'> Underscore-Entity<span typeof=\"mw:Entity\" data-parsoid='{\"src\":\"&#95;\",\"srcContent\":\"_\",\"dsr\":[269,274,null,null]}'>_</span>between<span typeof=\"mw:Entity\" data-parsoid='{\"src\":\"&#95;\",\"srcContent\":\"_\",\"dsr\":[281,286,null,null]}'>_</span>Text </h2>\n<p data-parsoid='{\"dsr\":[294,303,0,0]}'>section 6</p>\n\n<p data-parsoid='{\"dsr\":[305,501,0,0]}'><a rel=\"mw:WikiLink\" href=\"./Main%20Page#Space_between_Text\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Main%20Page#Space_between_Text\"},\"sa\":{\"href\":\"#Space between Text\"},\"dsr\":[305,328,2,2]}'>#Space between Text</a>\n<a rel=\"mw:WikiLink\" href=\"./Main%20Page#Space-Entity_between_Text\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Main%20Page#Space-Entity_between_Text\"},\"sa\":{\"href\":\"#Space-Entity&#32;between&#32;Text\"},\"dsr\":[329,367,2,2]}'>#Space-Entity between Text</a>\n<a rel=\"mw:WikiLink\" href=\"./Main%20Page#Plus+between+Text\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Main%20Page#Plus+between+Text\"},\"sa\":{\"href\":\"#Plus+between+Text\"},\"dsr\":[368,390,2,2]}'>#Plus+between+Text</a>\n<a rel=\"mw:WikiLink\" href=\"./Main%20Page#Plus-Entity+between+Text\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Main%20Page#Plus-Entity+between+Text\"},\"sa\":{\"href\":\"#Plus-Entity&#43;between&#43;Text\"},\"dsr\":[391,428,2,2]}'>#Plus-Entity+between+Text</a>\n<a rel=\"mw:WikiLink\" href=\"./Main%20Page#Underscore_between_Text\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Main%20Page#Underscore_between_Text\"},\"sa\":{\"href\":\"#Underscore_between_Text\"},\"dsr\":[429,457,2,2]}'>#Underscore_between_Text</a>\n<a rel=\"mw:WikiLink\" href=\"./Main%20Page#Underscore-Entity_between_Text\" data-parsoid='{\"stx\":\"simple\",\"a\":{\"href\":\"./Main%20Page#Underscore-Entity_between_Text\"},\"sa\":{\"href\":\"#Underscore-Entity&#95;between&#95;Text\"},\"dsr\":[458,501,2,2]}'>#Underscore-Entity_between_Text</a></p>"); add("wt2html", "Single-line or multiline-comments can follow headings", "<h2 data-parsoid='{\"dsr\":[0,7,2,2]}'>foo</h2><!---->\n<h2 data-parsoid='{\"dsr\":[15,22,2,2]}'>bar</h2><!--c1-->\n<h2 data-parsoid='{\"dsr\":[32,39,2,2]}'>baz</h2><!--\nc2\nc3-->"); @@ -425,6 +425,7 @@ add("wt2wt", "Templates: Indent-Pre: 1f: Wrapping should be based on expanded content", "{{echo| }}a\n\n{{echo|\n }}a\n\n{{echo|\n b}}\n\n{{echo|a\n }}b\n\n{{echo|a\n}}\n b\n"); add("wt2wt", "Templates: Handle comments in the target", "{{echo\n<!-- should be ignored -->\n|foo}}\n\n{{echo<!-- should be ignored -->\n|foo}}\n\n{{echo<!-- should be ignored -->|foo}}\n\n{{echo|foo}}"); add("wt2wt", "4. Indent-Pre and extension tags", " a <gallery>\n File:foobar.jpg\n </gallery>\n"); +add("wt2wt", "7b. Indent-pre and category links", " [[Category:foo]] a\n [[Category:foo]] {{echo|b}}\n"); add("wt2wt", "Definition lists: self-closed tag", ";one<br />two : two-line fun"); add("wt2wt", "Definition Lists: colons occurring in tags", ";a:b\n;'''a:b'''\n;<i>a:b</i>\n;<span>a:b</span>\n;<div>a:b</div>\n;<div>a\n:b\n;{{echo|a:b}}\n;{{echo|''a:b''}}\n;;;''a:b''\n"); add("wt2wt", "BUG 289: \">\"-token in bracketed URL", "[http://www.example.com/ <hello> stuff]\n"); @@ -1825,6 +1826,7 @@ add("selser", "5a. White-space in indent-pre [[2,0,4]]", " d3ppdqvqzdxi529a<br />\n 82567nb6q9hbmx6r"); add("selser", "5a. White-space in indent-pre [[2,0,0]]", " 9blj98gpz0py14ia<br />\n \n \n b"); add("selser", "5a. White-space in indent-pre [[0,2,0]]", " am3m3vd8oxzu84cxr<br />\n \n \n b"); +add("selser", "7b. Indent-pre and category links [2]", "yml0m6jz2j32qpvi\n [[Category:foo]] a\n [[Category:foo]] {{echo|b}}"); add("selser", "Definition lists: self-closed tag [2]", "x14l42v2vh392j4i\n;one<br/>two : two-line fun"); add("selser", "Definition lists: self-closed tag [1]", ";one<br/>two : two-line fun"); add("selser", "Definition lists: self-closed tag [[[4,2,4,0],[2]]]", ";hfmudey4je6u5wmi18aco6b1yahy3nmi<br/>199ekjza5e7phkt9 :b3ubf9dln2x7ds4i two-line fun"); @@ -2227,9 +2229,7 @@ add("selser", "Render invalid page names as plain text (bug 51090) [2,4,3]", "x280lbt0x9smunmi\n\n[[./../foo|bar]]\n[[foo�|bar]]\n[[foo/.|bar]]\n[[foo/..|bar]]\n[[foo~~~bar]]\n[[foo>bar]]\n[[foo[bar]]\n[[.]]\n[[..]]\n[[foo././bar]]\n\n9zekc2ruir0h33di\n"); add("selser", "Render invalid page names as plain text (bug 51090) [2,0,3]", "uy7lbslcu8mvaemi\n\n[[./../foo|bar]]\n[[foo�|bar]]\n[[foo/.|bar]]\n[[foo/..|bar]]\n[[foo~~~bar]]\n[[foo>bar]]\n[[foo[bar]]\n[[.]]\n[[..]]\n[[foo././bar]]\n"); add("selser", "Render invalid page names as plain text (bug 51090) [2,0,[2,0,0,0,4,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,3,0,2]]", "ixtw0uq17iqtcsor\n\n[[./../foo|bar]]\n[[foo�|bar]]\n[[foo/.|bar]]\n[[foo/..|bar]]\n[[foo~~~bar]]\n[[foo>bar]]\n[[foo[bar]]\n[[.]]\n[[..]]\n[[foo././bar]]\n\ncjgyt6cnj124kj4i[[{{echo|./../foo}}|bar]]\n[[{{echo|foo/.}}4i3f1qev8b5u3di{{echo|foo/..}}t26yvjmagszl4n29{{echo|foo~~~~bar}}]]\n[[{{echo|foo>bar}}3vx6jfw5gbvs4i{{echo|foo././bar}}]]\n[[{{echo|foo{bar}}]]\n[[{{echo|foo}bar}}]]\n[[{{echo|foo[bar}}]]\n[[{{echo|foo]bar}}{{echo|foo<bar}}<nowiki>3vz7g6pd5lzhncdi]]</nowiki>"); -add("selser", "Category / paragraph interactions [[0,3,2],0,2,4,[3,2,0],0,[2],3,0,[3],0,[3,3,4,1,4,2,3],0,3,4,0,4,3,0,0,2,0,0,0]", "Foo 83zrad4tpxxkcsor Bar\n\nysekf8brayr885mi\n\nFoo [[Category:Baz]]\nBar\n\nduknjpcnvnyzxgvi\n\nhroyapi5paqhncdi[[Category:Baz]]\nBar\n\nmsiv1cjc1q8e61orFoo\n[[Category:Baz]] \n\nljrvpzob03tedn29[[Category:Baz]]6bqrn9ug03npcik95jcarnywu55klnmi[[Category:Baz]]\n\nik3u2lqitfomkj4i[[Category:Baz]]\nn8wwykwa78f72e29\n\n[[Category:Baz]]\n9dl89xg0l57phkt9\n {{echo|[[Category:Baz]]}}\n[[Category:Baz]]"); -add("selser", "Category / paragraph interactions [4,0,0,0,[4,1,0],3,3,0,0,0,2,[2,0,0,1,3,0,0],0,1,3,0,2,0,2,0,0,0,4,2]", "y2ksxygpidn7y14i\n\nFoo [[Category:Baz]]\nBar\n\ntqcbbea7bmiy66r[[Category:Baz]]\nBar\n[[Category:Baz]] Bar\nc42dqedyb3u6usor\n\ndjmvd61k80kymn29Foo\n[[Category:Baz]]\n [[Category:Baz]][[Category:Baz]]\nBar\n\n[[Category:Baz]]\n [[Category:Baz]]\nvyv3u18bgs4z33di\n[[Category:Baz]]\ne98vfkx1eqld6lxr\n\n[[Category:Baz]]\n {{echo|[[Category:Baz]]}}\nviznyhgcd9muz0k9\n\nd830mwe1qg1oflxr[[Category:Baz]]"); -add("selser", "Category / paragraph interactions [1,0,1,0,1,0,1,0,0,0,2,[4,0,0,0,0,4,0],3,0,4,0,0,1,4,4,0,0,3,0]", "Foo [[Category:Baz]] Bar\n\nFoo [[Category:Baz]]\nBar\n\nFoo\n[[Category:Baz]]\nBar\n\nFoo\n[[Category:Baz]] Bar\nqyq2tw4tbcjfko6r\n\n8rsqjn6ahwoecdi[[Category:Baz]]\n [[Category:Baz]]\n7qub38k3od0od2t9\nBar\n\n[[Category:Baz]]\njml3cn3gxdt5ipb9[[Category:Baz]]\n[[Category:Baz]]\n7www48dkmtg74x6r\n\nfddlp7i37zwr8uxr\n {{echo|[[Category:Baz]]}}[[Category:Baz]]"); +add("selser", "Category / paragraph interactions [3,2,1,3,0,4,1,2,1,3,0]", "x7ixp2jr6ir4quxr\n\nFoo [[Category:Baz]]\nBar\n\nFoo\n[[Category:Baz]]\nBar\n\nwvsxizohr6hia4i\n\nFoo\n[[Category:Baz]] Bar\n\nykmlq9svazzd7vi\n\nFoo\n[[Category:Baz]]\n [[Category:Baz]]\n[[Category:Baz]]\nBar\n\n[[Category:Baz]]\n [[Category:Baz]]\n[[Category:Baz]]\n\n[[Category:Baz]]\n {{echo|[[Category:Baz]]}}\n[[Category:Baz]]"); add("selser", "Section headings with TOC [3,4,0,0,3,2,[3],3,0,4,3,3,0]", "px8b3ng5n4lpu8fr\n\n=== Subheadline 1 ===\np64mngpetwfm9529\n\n======<nowiki/>======\n\n== Headline 2 ==\nzvfwz386e7xbhuxr\n\n===Another headline==="); add("selser", "Handling of sections up to level 6 and beyond [1,2,1,2,1,0,[3],2,2,4,[2],4,0,0,1,0,0,3,1]", "= Level 1 Heading=\n7e043zzvvtzf47vi\n\n== Level 2 Heading==\n0pp0pcwrmkakyb9\n\n=== Level 3 Heading===\n====<nowiki/>====\n253vnq49otg9zfr\nmncpvxste96vquxr\n\n===== Level 5 Heading=====\n91qmbb1e2vlpu8fr\n\n======ohqkkrlkoqi79zfr Level 6 Heading======\n6hv8gbhdqngn9udi\n\n======= Level 7 Heading=======\n======<nowiki>== Level 8 Heading==</nowiki>======\n========= Level 9 Heading=========\n======<nowiki>==== Level 10 Heading====</nowiki>======"); add("selser", "Handling of sections up to level 6 and beyond [1,0,1,0,0,3,2,3,0,0,4,0,[4],0,1,0,0,4,0]", "= Level 1 Heading=\n== Level 2 Heading==\n=== Level 3 Heading===\n6fs6ykhv45nrk9\n\n==== Level 4 Heading====\n===== Level 5 Heading=====\njkvm1xjd1mw2vs4i\n\n======lrcthal0ujwnrk9======\n======<nowiki>== Level 8 Heading==</nowiki>======\n========= Level 9 Heading=========\n6uicqh73ey5bfbt9\n\n========== Level 10 Heading=========="); diff --git a/tests/parserTests.txt b/tests/parserTests.txt index 1a9fb3f..2396c33 100644 --- a/tests/parserTests.txt +++ b/tests/parserTests.txt @@ -3245,9 +3245,8 @@ [[Category:foo]] a [[Category:foo]] {{echo|b}} !! html -<pre> -<link rel="mw:PageProp/Category" href="./Category:Foo"> a -<link rel="mw:PageProp/Category" href="./Category:Foo"> <span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b"}},"i":0}}]}'>b</span></pre> +<pre><link rel="mw:PageProp/Category" href="./Category:Foo"> a + <link rel="mw:PageProp/Category" href="./Category:Foo"> <span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"b"}},"i":0}}]}'>b</span></pre> !! end !! test @@ -13676,6 +13675,57 @@ </p> !! end +## The whitespace on the empty line is part of the test. Please do not delete +!! test +1. Categories and newlines: All preceding newlines should be suppressed (courtesy bug 87) +!! options +parsoid=wt2html,wt2wt +!! wikitext +This + +[[Category:Foo]] and this should be part of same paragraph (not an indent-pre) + +{{echo|[[Category:Foo]] and so should this!}} +!! html +<p>This and this should be part of same paragraph (not an indent-pre) and so should this! +</p> +!! html/parsoid +<p>This + +<link rel="mw:PageProp/Category" href="./Category:Foo"/> and this should be part of same paragraph (not an indent-pre) + +<link rel="mw:PageProp/Category" href="./Category:Foo" about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[Category:Foo]] and so should this!"}},"i":0}}]}'/><span about="#mwt1"> and so should this!</span></p> +!! end + +## Parsoid will not try to wt2wt this while preserving newlines because +## it suppresses excess newlines within list items -- and we don't want to +## introduce a special case just for categories, which is, in reality somewhat +## odd behavior -- categories are unlikely to be used in list items like this +## in top-level pages and are only likely to show up in template-generated +## list items where this RT-ing is a non-issue. +## +## The whitespace on the empty line is part of the test. Please do not delete +!! test +2. Categories and newlines: All preceding newlines should be suppressed (courtesy bug 87) +!! options +parsoid=wt2html +!! wikitext +* This + +[[Category:Foo]] and this should be part of the same list item +* So should this + +{{echo|[[Category:Foo]] and this should be part of the same list item}} +!! html +<ul><li>This and this should be part of the same list item</li> +<li>So should this and this should be part of the same list item</li></ul> +!! html/parsoid +<ul> +<li>This <link rel="mw:PageProp/Category" href="./Category:Foo"/> and this should be part of the same list item</li> +<li>So should this <link rel="mw:PageProp/Category" href="Category:Foo" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"[[Category:Foo]] and this should be part of the same list item"}},"i":0}}]}'/><span> and this should be part of the same list item</span></li> +</ul> +!! end + !! test Parsoid: Serialize link to category page with colon escape !! options -- To view, visit https://gerrit.wikimedia.org/r/216136 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I507dcefcca5a4ee22fb9f9bf0cfe678f14d64991 Gerrit-PatchSet: 9 Gerrit-Project: mediawiki/services/parsoid Gerrit-Branch: master Gerrit-Owner: Subramanya Sastry <[email protected]> Gerrit-Reviewer: Arlolra <[email protected]> Gerrit-Reviewer: Catrope <[email protected]> Gerrit-Reviewer: Cscott <[email protected]> Gerrit-Reviewer: Esanders <[email protected]> Gerrit-Reviewer: GWicke <[email protected]> Gerrit-Reviewer: Jforrester <[email protected]> Gerrit-Reviewer: Subramanya Sastry <[email protected]> Gerrit-Reviewer: Tim Starling <[email protected]> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list [email protected] https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits
