<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://bradleymonk.com/wiki/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3ATextCleaner.js</id>
	<title>MediaWiki:TextCleaner.js - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://bradleymonk.com/wiki/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3ATextCleaner.js"/>
	<link rel="alternate" type="text/html" href="https://bradleymonk.com/wiki/index.php?title=MediaWiki:TextCleaner.js&amp;action=history"/>
	<updated>2026-04-09T16:54:04Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://bradleymonk.com/wiki/index.php?title=MediaWiki:TextCleaner.js&amp;diff=407&amp;oldid=prev</id>
		<title>Monakhos: Created page with &quot;// &lt;source lang=&quot;javascript&quot;&gt; /*   Wikitext sanitation for MediaWiki     Author: User:Lupo, January 2008   License: Quadruple licensed GFDL, GPL, LGPL and Creative Commons...&quot;</title>
		<link rel="alternate" type="text/html" href="https://bradleymonk.com/wiki/index.php?title=MediaWiki:TextCleaner.js&amp;diff=407&amp;oldid=prev"/>
		<updated>2013-01-12T08:16:47Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;// &amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt; /*   Wikitext sanitation for MediaWiki     Author: &lt;a href=&quot;/wiki/index.php?title=User:Lupo&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;User:Lupo (page does not exist)&quot;&gt;User:Lupo&lt;/a&gt;, January 2008   License: Quadruple licensed GFDL, GPL, LGPL and Creative Commons...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;// &amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
  Wikitext sanitation for MediaWiki&lt;br /&gt;
 &lt;br /&gt;
  Author: [[User:Lupo]], January 2008&lt;br /&gt;
  License: Quadruple licensed GFDL, GPL, LGPL and Creative Commons Attribution 3.0 (CC-BY-3.0)&lt;br /&gt;
 &lt;br /&gt;
  Choose whichever license of these you like best :-)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var TextCleaner =&lt;br /&gt;
{&lt;br /&gt;
  &lt;br /&gt;
  imgNamespaceNames : null,&lt;br /&gt;
&lt;br /&gt;
  // This function attempts to construct well-formed wikitext from input that may contain&lt;br /&gt;
  // possibly broken wikitext.&lt;br /&gt;
  //&lt;br /&gt;
  // Note: even just a half-baked sanitation of wikitext is hyper-complex due to the presence&lt;br /&gt;
  // of templates, and due to the fact that image thumbnail captions may themselves contain&lt;br /&gt;
  // links. This implementation catches the most common errors (such as forgetting to close a&lt;br /&gt;
  // template or a link), and even some more elaborate ones. With enough malice, this sanitation&lt;br /&gt;
  // can still be broken by user input such that the result is not well-formed wikitext as the&lt;br /&gt;
  // parser at the servers would like to have it. (It&amp;#039;s still possible that the result is broken&lt;br /&gt;
  // wikitext, if the input was broken wikitext. But it never transforms well-formed wikitext&lt;br /&gt;
  // into broken wikitext.)&lt;br /&gt;
  //&lt;br /&gt;
  // If &amp;#039;only_thumbs&amp;#039; is true, all [[Image: links are changed to [[:Image:, unless the original&lt;br /&gt;
  // image link was a thumbnail or had a width smaller than 300px specified.&lt;br /&gt;
  //&lt;br /&gt;
  // WARNING: do *not* attempt to use this to process large texts (e.g., a whole article). It is&lt;br /&gt;
  // probably rather inefficient due to the many substrings that are generated. This function is&lt;br /&gt;
  // primarily intended to be used to clean up user input in forms, which are typically rather&lt;br /&gt;
  // short.&lt;br /&gt;
  sanitizeWikiText : function (input, only_thumbs)&lt;br /&gt;
  {&lt;br /&gt;
    if (input.search (/[\][}{]|&amp;lt;nowiki(\s[^&amp;gt;]*)?&amp;gt;|&amp;lt;\!--/) &amp;lt; 0) return input;&lt;br /&gt;
    // No critical characters&lt;br /&gt;
    &lt;br /&gt;
    if (!TextCleaner.imgNamespaceNames) {&lt;br /&gt;
      TextCleaner.imgNamespaceNames = [];&lt;br /&gt;
      if (wgNamespaceIds) {&lt;br /&gt;
        for (name in wgNamespaceIds) {&lt;br /&gt;
          if (wgNamespaceIds[name] == 6) // Image namespace&lt;br /&gt;
            TextCleaner.imgNamespaceNames[TextCleaner.imgNamespaceNames.length] = name;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      // Make sure that we have the two canonical names&lt;br /&gt;
      TextCleaner.imgNamespaceNames[TextCleaner.imgNamespaceNames.length] = &amp;#039;Image&amp;#039;;&lt;br /&gt;
      TextCleaner.imgNamespaceNames[TextCleaner.imgNamespaceNames.length] = &amp;#039;File&amp;#039;;&lt;br /&gt;
      // If your Wiki does not have wgNamespaceIds, add aliases or localized namespace names here!&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var consumed       = new Array (0, 0);&lt;br /&gt;
    // For image captions. Image caption may contain links, and may even contain images.&lt;br /&gt;
    // The current MediaWiki parser actually allows this only once. For deeper recursions,&lt;br /&gt;
    // it fails. But here, it&amp;#039;s actually easier to implement no limit.&lt;br /&gt;
 &lt;br /&gt;
    var base_regexp    =&lt;br /&gt;
      new RegExp&lt;br /&gt;
            (   &amp;quot;[\\x01\\x02\\x03\\x04[\\]\\|\\x05\\x06\\x07\\x08]&amp;quot;&lt;br /&gt;
              + &amp;quot;|\&amp;lt;nowiki(\\s[^&amp;gt;]*)?\&amp;gt;|\&amp;lt;\!--&amp;quot;&lt;br /&gt;
            , &amp;quot;i&amp;quot;); // Ignore case&lt;br /&gt;
    var nowiki_regexp  = new RegExp (&amp;quot;\&amp;lt;\\/nowiki(\\s[^&amp;gt;]*)?\&amp;gt;|\&amp;lt;\!--&amp;quot;, &amp;quot;i&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    var allow_only_thumbs = only_thumbs;&lt;br /&gt;
&lt;br /&gt;
    function sanitize&lt;br /&gt;
      (s, with_links, caption_level, allow_thumbs, break_at_pipe, with_tables, with_galleries)&lt;br /&gt;
    {&lt;br /&gt;
      if (!s || s.length == 0) {&lt;br /&gt;
        if (caption_level &amp;gt; 0) {&lt;br /&gt;
          if (consumed.length &amp;lt; caption_level)&lt;br /&gt;
            consumed.push (0);&lt;br /&gt;
          else&lt;br /&gt;
            consumed[caption_level-1] = 0;&lt;br /&gt;
        }&lt;br /&gt;
        return s;&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      var result         = &amp;quot;&amp;quot;;&lt;br /&gt;
      var initial_length = s.length;&lt;br /&gt;
      var get_out        = false;&lt;br /&gt;
      var in_nowiki      = false;&lt;br /&gt;
      var endings        = null;&lt;br /&gt;
      // Stack recording template and table nesting&lt;br /&gt;
      var next;&lt;br /&gt;
      &lt;br /&gt;
      function push_end (val)&lt;br /&gt;
      {&lt;br /&gt;
        if (endings == null) {&lt;br /&gt;
          endings = new Array (1);&lt;br /&gt;
          endings[0] = val;&lt;br /&gt;
        } else {&lt;br /&gt;
          endings[endings.length] = val;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      function pop_end ()&lt;br /&gt;
      {&lt;br /&gt;
        if (endings == null) return null; // Shouldn&amp;#039;t happen&lt;br /&gt;
        var result;&lt;br /&gt;
        if (endings.length == 1) {&lt;br /&gt;
          result = endings[0];&lt;br /&gt;
          endings = null;&lt;br /&gt;
        } else {&lt;br /&gt;
          result = endings[endings.length -1];&lt;br /&gt;
          endings.length = endings.length - 1;&lt;br /&gt;
        }&lt;br /&gt;
        return result;&lt;br /&gt;
      }&lt;br /&gt;
          &lt;br /&gt;
      regexp = base_regexp;&lt;br /&gt;
      while (s.length &amp;gt; 0 &amp;amp;&amp;amp; !get_out) {&lt;br /&gt;
        next = s.search (regexp);&lt;br /&gt;
      &lt;br /&gt;
        if (next &amp;lt; 0) {&lt;br /&gt;
          result = result + s;&lt;br /&gt;
          break;&lt;br /&gt;
        }&lt;br /&gt;
        var ch = s.charAt (next);&lt;br /&gt;
        var i  = -1;&lt;br /&gt;
        var j  = -1;&lt;br /&gt;
        var k  = -1;&lt;br /&gt;
        switch (ch) {&lt;br /&gt;
          case &amp;#039;&amp;lt;&amp;#039;:&lt;br /&gt;
            // Nowiki or HTML comment. Must be closed.&lt;br /&gt;
            if (s.charAt (next+1) == &amp;#039;!&amp;#039;) {&lt;br /&gt;
              // HTML comment. Cannot be nested.&lt;br /&gt;
              i = s.indexOf (&amp;#039;--\&amp;gt;&amp;#039;, next+3);&lt;br /&gt;
              if (i &amp;lt; 0) {&lt;br /&gt;
                result = result + s + &amp;#039;--\&amp;gt;&amp;#039;;&lt;br /&gt;
                s = &amp;quot;&amp;quot;;&lt;br /&gt;
              } else {&lt;br /&gt;
                result = result + s.substring (0, i + 3);&lt;br /&gt;
                s = s.substring (i+3);&lt;br /&gt;
              }&lt;br /&gt;
            } else if (s.charAt (next+1) == &amp;#039;n&amp;#039;) {&lt;br /&gt;
              // Nowiki may contain HTML comments!&lt;br /&gt;
              in_nowiki = true;&lt;br /&gt;
              regexp = nowiki_regexp;&lt;br /&gt;
              result = result + s.substring (0, next + 7);&lt;br /&gt;
              s = s.substring (next + 7);&lt;br /&gt;
            } else {&lt;br /&gt;
              // End of nowiki. Searched for and found only if in_nowiki == true&lt;br /&gt;
              in_nowiki = false;&lt;br /&gt;
              regexp = base_regexp;&lt;br /&gt;
              i = s.indexOf (&amp;#039;&amp;gt;&amp;#039;, next+1); // End of tag&lt;br /&gt;
              result = result + s.substring (0, i+1);&lt;br /&gt;
              s = s.substring (i+1);&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
          case &amp;#039;\x05&amp;#039;:&lt;br /&gt;
            // Table start&lt;br /&gt;
            if (!with_tables) {&lt;br /&gt;
              result  = result + s.substring (0, next);&lt;br /&gt;
              get_out = true;&lt;br /&gt;
              break;&lt;br /&gt;
            }&lt;br /&gt;
            // Fall through&lt;br /&gt;
          case &amp;#039;\x07&amp;#039;:&lt;br /&gt;
            if (ch == &amp;#039;\x07&amp;#039; &amp;amp;&amp;amp; !with_galleries) {&lt;br /&gt;
              result = result + s.substring (0, next);&lt;br /&gt;
              get_out = true;&lt;br /&gt;
              break;&lt;br /&gt;
            }&lt;br /&gt;
          case &amp;#039;\x01&amp;#039;:&lt;br /&gt;
            // Start of template, table, or gallery&lt;br /&gt;
            result = result + s.substring (0, next+1);&lt;br /&gt;
            push_end (String.fromCharCode(ch.charCodeAt (0)+1).charAt (0));&lt;br /&gt;
            s = s.substring (next+1);&lt;br /&gt;
            break;&lt;br /&gt;
          case &amp;#039;\x06&amp;#039;:&lt;br /&gt;
            // Table end&lt;br /&gt;
            if (break_at_pipe &amp;amp;&amp;amp; endings == null) {&lt;br /&gt;
              result = result + s.substring (0, next);&lt;br /&gt;
              get_out = true;&lt;br /&gt;
              break;&lt;br /&gt;
            }&lt;br /&gt;
            // Fall through&lt;br /&gt;
          case &amp;#039;\x02&amp;#039;:&lt;br /&gt;
            // End of a template or table&lt;br /&gt;
            result = result + s.substring (0, next);&lt;br /&gt;
            if (endings == null || endings[endings.length - 1] != ch) {&lt;br /&gt;
              // Spurious template or table end&lt;br /&gt;
              if (ch == &amp;#039;\x02&amp;#039;)&lt;br /&gt;
                result = result + &amp;#039;&amp;amp;#x7D;&amp;amp;#x7D;&amp;#039;;&lt;br /&gt;
              else&lt;br /&gt;
                result = result + &amp;#039;&amp;amp;#x7C;&amp;amp;#x7D;&amp;#039;;&lt;br /&gt;
            } else {            &lt;br /&gt;
              result = result + pop_end ();&lt;br /&gt;
            }&lt;br /&gt;
            s = s.substring (next+1);&lt;br /&gt;
            break;&lt;br /&gt;
          case &amp;#039;\x08&amp;#039;:&lt;br /&gt;
            // End of gallery&lt;br /&gt;
            result = result + s.substring (0, next+1);&lt;br /&gt;
            if (endings != null &amp;amp;&amp;amp; endings[endings.length - 1] == ch) pop_end (); &lt;br /&gt;
            s = s.substring (next+1);&lt;br /&gt;
            break; &lt;br /&gt;
          case &amp;#039;\x03&amp;#039;:&lt;br /&gt;
          case &amp;#039;[&amp;#039;:&lt;br /&gt;
            {&lt;br /&gt;
              if (!with_links &amp;amp;&amp;amp; endings == null) {&lt;br /&gt;
                get_out = true;&lt;br /&gt;
                break;&lt;br /&gt;
              }&lt;br /&gt;
              // Image links must be treated specially, since they may contain nested links&lt;br /&gt;
              // in the caption!&lt;br /&gt;
              var initial = null;  // If set, it&amp;#039;s &amp;#039;image:&amp;#039; or &amp;#039;file:&amp;#039; and we have an image link&lt;br /&gt;
              i = next;&lt;br /&gt;
              while (i &amp;lt; s.length &amp;amp;&amp;amp; s.charAt (i) == ch) i++;&lt;br /&gt;
              if (ch == &amp;#039;\x03&amp;#039; &amp;amp;&amp;amp; i &amp;lt; s.length &amp;amp;&amp;amp; s.charAt (i) == &amp;#039;[&amp;#039;) i++;&lt;br /&gt;
              function get_initial (i, s)&lt;br /&gt;
              {&lt;br /&gt;
                for (var j = 0; j &amp;lt; TextCleaner.imgNamespaceNames.length; j++) {&lt;br /&gt;
                  if (s.length &amp;gt;= i + TextCleaner.imgNamespaceNames[j].length + 1) {&lt;br /&gt;
                    var t = s.substr (i, TextCleaner.imgNamespaceNames[j].length + 1);&lt;br /&gt;
                    if (t.toLowerCase() == (TextCleaner.imgNamespaceNames[j].toLowerCase () + &amp;#039;:&amp;#039;))&lt;br /&gt;
                      return t;&lt;br /&gt;
                  }&lt;br /&gt;
                }&lt;br /&gt;
                return null;&lt;br /&gt;
              }&lt;br /&gt;
              initial = get_initial (i, s);&lt;br /&gt;
&lt;br /&gt;
              // Scan ahead. We&amp;#039;ll break at the next top-level | or ] or ]] or [ or [[ or {| or |}&lt;br /&gt;
              var lk_text = sanitize (s.substring (i),&lt;br /&gt;
                                      false,           // No links at top-level allowed&lt;br /&gt;
                                      caption_level + 1,&lt;br /&gt;
                                      false,           // No thumbs&lt;br /&gt;
                                      true,            // Break at pipe&lt;br /&gt;
                                      false,           // No tables&lt;br /&gt;
                                      false);          // No galleries&lt;br /&gt;
              var lk_text_length = consumed[caption_level];&lt;br /&gt;
              j = i + lk_text_length;&lt;br /&gt;
              if (j &amp;gt;= s.length) {&lt;br /&gt;
                // Used up the whole text: [[Foo or [bar&lt;br /&gt;
                if (initial != null &amp;amp;&amp;amp; allow_only_thumbs)&lt;br /&gt;
                  // Should in any case have started with [[, not [&lt;br /&gt;
                  result = result + s.substring (0, i-1) + &amp;#039;\x03:&amp;#039; + initial&lt;br /&gt;
                         + lk_text.substring (initial.length) + &amp;#039;\x04&amp;#039;;&lt;br /&gt;
                else&lt;br /&gt;
                  result = result + s.substring (0, i) + lk_text&lt;br /&gt;
                         + ((s.charAt (i-1) == &amp;#039;[&amp;#039;) ? &amp;#039;]&amp;#039; : &amp;#039;\x04&amp;#039;);&lt;br /&gt;
                s = &amp;quot;&amp;quot;;&lt;br /&gt;
                break;&lt;br /&gt;
              }&lt;br /&gt;
              if (s.charAt (j) == &amp;#039;|&amp;#039;) k = j; else k = -1;&lt;br /&gt;
              if (k &amp;lt; 0) {&lt;br /&gt;
                // No pipe found: we should be on the closing ]] or ] or [[Foo]] or [bar]&lt;br /&gt;
                if (initial != null &amp;amp;&amp;amp; allow_only_thumbs)&lt;br /&gt;
                  // Should in any case have started with [[, not [&lt;br /&gt;
                  result = result + s.substring (0, i-1) + &amp;#039;\x03:&amp;#039; + initial&lt;br /&gt;
                         + lk_text.substring (initial.length) + &amp;#039;\x04&amp;#039;;&lt;br /&gt;
                else&lt;br /&gt;
                  result = result + s.substring (0, i) + lk_text&lt;br /&gt;
                         + ((s.charAt (i-1) == &amp;#039;[&amp;#039;) ? &amp;#039;]&amp;#039; : &amp;#039;\x04&amp;#039;);&lt;br /&gt;
                if (s.charAt (j) == &amp;#039;]&amp;#039; || s.charAt (j) == &amp;#039;\x04&amp;#039;) {&lt;br /&gt;
                  // Indeed closing the link&lt;br /&gt;
                  s = s.substring (j+1);&lt;br /&gt;
                } else {&lt;br /&gt;
                  s = s.substring (j);&lt;br /&gt;
                }&lt;br /&gt;
                break;&lt;br /&gt;
              } else {&lt;br /&gt;
                var caption = null;&lt;br /&gt;
                var used    = 0;&lt;br /&gt;
                // Pipe found.&lt;br /&gt;
                if (initial == null) {&lt;br /&gt;
                  // Not an image link. Must be something like [[Foo|Bar]].&lt;br /&gt;
                  caption = sanitize&lt;br /&gt;
                              ( s.substring (k+1)&lt;br /&gt;
                               , false             // No links, please&lt;br /&gt;
                               , caption_level + 1&lt;br /&gt;
                               , false             // No thumbs either&lt;br /&gt;
                               , false             // Don&amp;#039;t care about pipes&lt;br /&gt;
                               , true              // Allow tables (yes, parser allows that!)&lt;br /&gt;
                               , true);            // Allow galleries (?)&lt;br /&gt;
                  // Now we&amp;#039;re at [[, [, ]], or ]&lt;br /&gt;
                  used = consumed[caption_level];&lt;br /&gt;
                  result = result + s.substring (0, i) + lk_text + &amp;#039;|&amp;#039; + caption&lt;br /&gt;
                         + ((s.charAt (i-1) == &amp;#039;[&amp;#039;) ? &amp;#039;]&amp;#039; : &amp;#039;\x04&amp;#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                  var q = s.substring (k);&lt;br /&gt;
                  // We assume that there are no templates, nowikis, and other nasty things&lt;br /&gt;
                  // in the parameters. Search forward until the next [, {, ], }&lt;br /&gt;
                  l = q.search(/[\x01\x02\x03[\x04\]\{\}\x05\x06\x07\x08]/);&lt;br /&gt;
                  if (l &amp;lt; 0) l = q.length;&lt;br /&gt;
                  if (l+1 &amp;lt; q.length) q = q.substring (0, l+1);&lt;br /&gt;
                  var is_thumb = q.search (/\|\s*thumb(nail)?\s*[\|\x04]/) &amp;gt;= 0;&lt;br /&gt;
                  var img_width = /\|\s*(\d+)px\s*[\|\x04]/.exec (q);&lt;br /&gt;
                  if (img_width &amp;amp;&amp;amp; img_width.length &amp;gt; 1) {&lt;br /&gt;
                    img_width = parseInt (img_width[1], 10);&lt;br /&gt;
                    if (isNaN (img_width)) img_width = null;&lt;br /&gt;
                  } else&lt;br /&gt;
                    img_width = null;&lt;br /&gt;
                  if (img_width === null) img_width = is_thumb ? 180 : 301;&lt;br /&gt;
                  var is_small = img_width &amp;lt;= 300;&lt;br /&gt;
                  &lt;br /&gt;
                  // Caption starts at the last pipe before l. If that is a parameter,&lt;br /&gt;
                  // it doesn&amp;#039;t hurt.&lt;br /&gt;
                  var m = k + q.lastIndexOf (&amp;#039;|&amp;#039;, l);&lt;br /&gt;
                  caption = sanitize&lt;br /&gt;
                              (  s.substring (m+1)&lt;br /&gt;
                               , is_thumb                  // Allow links only if it&amp;#039;s a thumb&lt;br /&gt;
                               , caption_level + 1&lt;br /&gt;
                               , allow_thumbs &amp;amp;&amp;amp; is_thumb&lt;br /&gt;
                               , false                     // Don&amp;#039;t break at pipe&lt;br /&gt;
                               , is_thumb                  // Tables only if it&amp;#039;s a thumb&lt;br /&gt;
                               , is_thumb);                // Allow galleries for thumbs (?)&lt;br /&gt;
                  used = consumed[caption_level];&lt;br /&gt;
                  // caption used &amp;#039;used&amp;#039; chars from m+1, s.charAt (m+1+used) == &amp;#039;\x04&amp;#039;&lt;br /&gt;
                  is_thumb = allow_thumbs &amp;amp;&amp;amp; is_small;&lt;br /&gt;
                  if (is_thumb || !allow_only_thumbs)&lt;br /&gt;
                    result = result + s.substring (0, i-1) + &amp;#039;\x03&amp;#039; + lk_text ;&lt;br /&gt;
                  else&lt;br /&gt;
                    result = result + s.substring (0, i-1) + &amp;#039;\x03:&amp;#039; + initial&lt;br /&gt;
                           + lk_text.substring (initial.length);&lt;br /&gt;
                  result = result + s.substring (k, m+1) + caption + &amp;#039;\x04&amp;#039;;&lt;br /&gt;
                  k = m;&lt;br /&gt;
                }&lt;br /&gt;
                next = k+1+used;&lt;br /&gt;
                if (next &amp;lt; s.length) {&lt;br /&gt;
                  if (s.charAt (next) != &amp;#039;\x04&amp;#039;)&lt;br /&gt;
                    s = s.substring (next);&lt;br /&gt;
                  else&lt;br /&gt;
                    s = s.substring (next+1);&lt;br /&gt;
                } else&lt;br /&gt;
                  s = &amp;quot;&amp;quot;;&lt;br /&gt;
              }&lt;br /&gt;
              break;&lt;br /&gt;
            }&lt;br /&gt;
          case &amp;#039;\x04&amp;#039;:&lt;br /&gt;
          case &amp;#039;]&amp;#039;:&lt;br /&gt;
            // Extra bracket.&lt;br /&gt;
            result = result + s.substring (0, next);&lt;br /&gt;
            if (caption_level == 0 &amp;amp;&amp;amp; !break_at_pipe) {&lt;br /&gt;
              result = result + (ch == &amp;#039;]&amp;#039; ? &amp;#039;&amp;amp;#x5D;&amp;#039; : &amp;#039;&amp;amp;#x5D;&amp;amp;#x5D;&amp;#039;);&lt;br /&gt;
              s = s.substring (next+1);&lt;br /&gt;
            } else&lt;br /&gt;
              get_out = true;&lt;br /&gt;
            break;&lt;br /&gt;
          case &amp;#039;|&amp;#039;:&lt;br /&gt;
            result = result + s.substring (0, next);&lt;br /&gt;
            if (break_at_pipe &amp;amp;&amp;amp; endings == null) {&lt;br /&gt;
              // Pipe character at top level&lt;br /&gt;
              get_out = true;&lt;br /&gt;
            } else {&lt;br /&gt;
              if (caption_level == 0 &amp;amp;&amp;amp; !break_at_pipe &amp;amp;&amp;amp; endings == null)&lt;br /&gt;
                result = result + &amp;#039;&amp;amp;#x7C;&amp;#039;; // Top-level pipe character&lt;br /&gt;
              else&lt;br /&gt;
                result = result + &amp;#039;|&amp;#039;;&lt;br /&gt;
              s = s.substring (next+1);&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        } // end switch&lt;br /&gt;
      } // end while&lt;br /&gt;
      if (in_nowiki) result = result + &amp;quot;\&amp;lt;\/nowiki&amp;gt;&amp;quot;; // Make sure this nowiki is closed.&lt;br /&gt;
      // Close open templates and tables&lt;br /&gt;
      while (endings != null) {&lt;br /&gt;
        ch = pop_end ();&lt;br /&gt;
        result = result + (ch == &amp;#039;\x06&amp;#039; ? &amp;#039;\n&amp;#039; : &amp;quot;&amp;quot;) + ch;&lt;br /&gt;
      }&lt;br /&gt;
      if (caption_level &amp;gt; 0) {&lt;br /&gt;
        var used_up = initial_length - (get_out ? (s.length - next) : 0);&lt;br /&gt;
        if (consumed.length &amp;lt; caption_level)&lt;br /&gt;
          consumed[consumed.length] = used_up;&lt;br /&gt;
        else&lt;br /&gt;
          consumed[caption_level-1] = used_up;&lt;br /&gt;
      }&lt;br /&gt;
      return result;      &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Replace multi-character tokens by one-character placeholders, simplifying the&lt;br /&gt;
    // subsequent processing.&lt;br /&gt;
    var s = input.replace (/\{\{/g, &amp;#039;\x01&amp;#039;)&lt;br /&gt;
                 .replace (/\n\s*\|\}\}\}/g, &amp;#039;\n\x06\x02&amp;#039;) // Table end + template end&lt;br /&gt;
                 .replace (/\}\}/g, &amp;#039;\x02&amp;#039;)&lt;br /&gt;
                 .replace (/\[\[/g, &amp;#039;\x03&amp;#039;)&lt;br /&gt;
                 .replace (/\]\]/g, &amp;#039;\x04&amp;#039;)&lt;br /&gt;
                 .replace (/\n\s*\{\|/g, &amp;#039;\n\x05&amp;#039;)       // Table start and end must be on own line&lt;br /&gt;
                 .replace (/^\s*\{\|/, &amp;#039;\x05&amp;#039;)           // Table start at the very beginning&lt;br /&gt;
                 .replace (/\n\s*\|\}/g, &amp;#039;\n\x06&amp;#039;)       // (we strip leading whitespace)&lt;br /&gt;
                 .replace (/\&amp;lt;\s*gallery\s*\&amp;gt;/g, &amp;#039;\x07&amp;#039;)&lt;br /&gt;
                 .replace (/\&amp;lt;\/\s*gallery\s*\&amp;gt;/g, &amp;#039;\x08&amp;#039;);&lt;br /&gt;
&lt;br /&gt;
    s = sanitize (s, true, 0, true, false, true, true);&lt;br /&gt;
    // with links, allow thumbs, don&amp;#039;t break at pipe, allow tables, allow galleries&lt;br /&gt;
    return s.replace (/\x01/g, &amp;#039;\{\{&amp;#039;)&lt;br /&gt;
            .replace (/\x02/g, &amp;#039;\}\}&amp;#039;)&lt;br /&gt;
            .replace (/\x03/g, &amp;#039;\[\[&amp;#039;)&lt;br /&gt;
            .replace (/\x04/g, &amp;#039;\]\]&amp;#039;)&lt;br /&gt;
            .replace (/\x05/g, &amp;#039;\{\|&amp;#039;)&lt;br /&gt;
            .replace (/\x06/g, &amp;#039;\|\}&amp;#039;)&lt;br /&gt;
            .replace (/\x07/g, &amp;#039;&amp;lt;gallery&amp;gt;&amp;#039;)&lt;br /&gt;
            .replace (/\x08/g, &amp;#039;&amp;lt;/gallery&amp;gt;&amp;#039;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// &amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Monakhos</name></author>
	</entry>
</feed>