Subramanya Sastry has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/72858


Change subject: (Bug 50841): First pass reducing scope of nowiki tags
......................................................................

(Bug 50841): First pass reducing scope of nowiki tags

* This still feels a little crude, but does the job for now.

* One failing html2html test is because of a quirk of how we
  normalize newlines while comparing output.

Additional tests:

------------
[subbu@earth lib] echo "[[foo]] [[bar]] [[baz]] [[foobar]] [[moobar]]" | node 
parse --html2wt

<nowiki>[[foo]] [[bar]] [[baz]]</nowiki> <nowiki>[[foobar]] [[moobar]]</nowiki>
------------
[subbu@earth lib] echo "Links in wikitext are written like this: [[foo]] How 
magical\!\!" | node parse --html2wt

Links in wikitext are written like this: <nowiki>[[foo]]</nowiki> How magical!!
------------
[subbu@earth lib] echo 'Hello my [[name]]*(see below) is Julian and I live in 
the city of Rochester, New York\nwith my friend Sandy; we write [[books]].' | 
node parse --html2wt

Hello my <nowiki>[[name]]</nowiki>*(see below) is Julian and I live in the city
of Rochester, New York with my friend Sandy; we write 
<nowiki>[[books]]</nowiki>.
------------
[subbu@earth lib] echo 'Hello my [[name]]*(see below) is Julian and I live in 
the city of Rochester, New York to \n* escape with my friend Sandy; we write 
[[books]].' | node parse --html2wt

Hello my <nowiki>[[name]]</nowiki><nowiki>*(see below) is Julian and I live in 
the city of Rochester, New York to
* escape with my friend Sandy; we write </nowiki> <nowiki>[[books]].</nowiki>
------------

Change-Id: Iac2cf7470bb566372fd856250fbbeef2e37e4156
---
M js/lib/mediawiki.WikitextSerializer.js
M js/tests/parserTests-blacklist.js
2 files changed, 87 insertions(+), 11 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Parsoid 
refs/changes/58/72858/1

diff --git a/js/lib/mediawiki.WikitextSerializer.js 
b/js/lib/mediawiki.WikitextSerializer.js
index 4a56fde..74ee942 100644
--- a/js/lib/mediawiki.WikitextSerializer.js
+++ b/js/lib/mediawiki.WikitextSerializer.js
@@ -539,9 +539,84 @@
 // Make sure the initialState is never modified
 Util.deepFreeze( WSP.initialState );
 
-function escapedText(text) {
-       var match = 
text.match(/^((?:.*?|[\r\n]+[^\r\n]|[~]{3,5})*?)((?:\r?\n)*)$/);
-       return ["<nowiki>", match[1], "</nowiki>", match[2]].join('');
+function escapedText(text, fullWrap) {
+       // Full-wrapping is enabled in the following cases:
+       // * text is a "small" string
+       // * text has url triggers (RFC, ISBN, etc.)
+       // * is being escaped within context-specific handlers
+
+       var match = 
text.match(/^((?:.*?|[\r\n]+[^\r\n]|[~]{3,5})*?)((?:\r?\n)*)$/),
+               text = match[1],
+               nls = match[2],
+               maxRun = 20;
+
+       if (fullWrap || text.length < maxRun) {
+               return ["<nowiki>", text, "</nowiki>", nls].join('');
+       } else {
+               // For now, only optimize "[[..]]", "{{..}}", "{{{..}}}" 
scenarios
+               // Splitting on white-space, "=", ' chars can split html tags
+               // in the middle and create ugly nowiki escaping output.
+               var pieces = text.split(/(\[\[|\]\]|\{\{\{|\{\{|\}\}\}|\}\})/g),
+                       n = pieces.length,
+                       buf = n === 1 ?  ["<nowiki>", text, "</nowiki>"] : [];
+
+               if (n > 1) {
+                       var openTag = null,
+                               openNowiki = false,
+                               currentRun = 0,
+                               closingWtTagMap = { "[[" : "]]", "{{" : "}}", 
"{{{": "}}}" };
+
+                       for (var i = 0; i < n; i++) {
+                               var p = pieces[i];
+                               if (!openTag) {
+                                       if (p in closingWtTagMap) {
+                                               openTag = p;
+                                               if (!openNowiki) {
+                                                       buf.push("<nowiki>");
+                                                       openNowiki = true;
+                                               }
+                                       } else if (!openNowiki &&
+                                               (
+                                                       // [..], <..>, '', ~~~~
+                                                       
p.match(/\[[^\[\]]\]|<[^<>]*>|''|~{3,5}/) ||
+                                                       // If in SOL (previous 
piece ended in a \n), or after a \n,
+                                                       // \s+ (indent-pre), = 
(headings), *#;: (lists), {| |}, |, ||, |-, |+, ! (tables)
+                                                       p.match(/\n([ 
\t]+[^\s]+|[=:;#\*]|\s*(\{\||\|\}|\|[\|\-\+]?|!))/) ||
+                                                       ((i === 0 || 
pieces[i-1].match(/\n$/)) && p.match(/^([ 
\t]+[^\s]+|=:;#\*|\s*(\{\||\|\}|\|[\|\-\+]?|!))/))
+                                               ))
+                                       {
+                                               buf.push("<nowiki>");
+                                               openNowiki = true;
+                                       }
+                               } else {
+                                       if (p === closingWtTagMap[openTag]) {
+                                               openTag = null;
+                                       }
+                               }
+
+                               buf.push(p);
+
+                               // If:
+                               // - we are in the middle of an open <nowiki>,
+                               // - we are not in the middle of an open tag,
+                               // - and will except max-run length on the next 
piece
+                               // close the current nowiki.
+                               currentRun += p.length;
+                               if (!openTag && openNowiki && (i < n-1 && 
pieces[i+1].length + currentRun >= maxRun)) {
+                                       buf.push("</nowiki>");
+                                       openNowiki = false;
+                                       currentRun = 0;
+                               }
+                       }
+
+                       if (openNowiki) {
+                               buf.push("</nowiki>");
+                       }
+               }
+
+               buf.push(nls);
+               return buf.join('');
+       }
 }
 
 WSP.tokenizeStr = function(state, str, sol) {
@@ -587,7 +662,7 @@
        var wteHandler = state.wteHandlerStack.last();
        if (wteHandler && wteHandler(state, text, opts)) {
                // console.warn("---EWT:F2---");
-               return escapedText(text);
+               return escapedText(text, true);
        }
 
        // Template and template-arg markers are escaped unconditionally!
@@ -595,7 +670,7 @@
        // of whether we are in template arg context or not.
        if (text.match(/\{\{\{|\{\{|\}\}\}|\}\}/)) {
                // console.warn("---EWT:F3---");
-               return escapedText(text);
+               return escapedText(text, fullCheckNeeded);
        }
 
        // Escape quotes that come after I/B nodes that can be reparsed
@@ -604,7 +679,7 @@
                var prev = opts.node && opts.node.previousSibling ? 
opts.node.previousSibling.nodeName : '';
                if (prev === 'I' || prev === 'B') {
                        // console.warn("---EWT:F3b---");
-                       return escapedText(text);
+                       return escapedText(text, true);
                }
        }
 
@@ -639,7 +714,7 @@
        // So, we always conservatively escape text with ' ' in sol posn.
        if (sol && text.match(/(^|\n)[ \t]+[^\s]+/)) {
                // console.warn("---EWT:F6---");
-               return escapedText(text);
+               return escapedText(text, fullCheckNeeded);
        }
 
        // escape nowiki tags
@@ -652,11 +727,11 @@
        // hasWikitextTokens check
        if (this.wteHandlers.hasWikitextTokens(state, sol, text) || hasTildes) {
                // console.warn("---EWT:DBG1---");
-               return escapedText(text);
+               return escapedText(text, fullCheckNeeded);
        } else if (state.onSOL) {
                if (text.match(/(^|\n)=+[^\n=]+=+[ \t]*\n/)) {
                        // console.warn("---EWT:DBG2a---");
-                       return escapedText(text);
+                       return escapedText(text, fullCheckNeeded);
                } else if (text.match(/(^|\n)=+[^\n=]+=+[ \t]*$/)) {
                        /* 
---------------------------------------------------------------
                         * '$' is only specific to 'text' and not the entire 
line.
@@ -687,7 +762,7 @@
                                DU.isText(nonSepSibling) && 
nonSepSibling.nodeValue.match(/^\s*\n/))
                        {
                                // console.warn("---EWT:DBG2b---");
-                               return escapedText(text);
+                               return escapedText(text, fullCheckNeeded);
                        } else {
                                // console.warn("---EWT:DBG2c---");
                                return text;
@@ -742,7 +817,7 @@
                                this.wteHandlers.hasWikitextTokens(state, sol, 
cl.text + text, true))
                {
                        // console.warn("---EWT:DBG4---");
-                       return escapedText(text);
+                       return escapedText(text, fullCheckNeeded);
                } else {
                        // console.warn("---EWT:DBG5---");
                        return text;
diff --git a/js/tests/parserTests-blacklist.js 
b/js/tests/parserTests-blacklist.js
index 8d05fe7..6be02af 100644
--- a/js/tests/parserTests-blacklist.js
+++ b/js/tests/parserTests-blacklist.js
@@ -848,6 +848,7 @@
 add("html2html", "Template as link source");
 add("html2html", "Template infinite loop");
 add("html2html", "Template with targets containing wikilinks");
+add("html2html", "msgnw keyword");
 add("html2html", "Self-closed noinclude, includeonly, onlyinclude tags");
 add("html2html", "Bug 6563: Edit link generation for section shown by 
<includeonly>");
 add("html2html", "Bug 6563: Section extraction for section shown by 
<includeonly>");

-- 
To view, visit https://gerrit.wikimedia.org/r/72858
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iac2cf7470bb566372fd856250fbbeef2e37e4156
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Parsoid
Gerrit-Branch: master
Gerrit-Owner: Subramanya Sastry <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to