User:PerfektesChaos/js/WikiSyntaxTextMod/dE.js

Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/// PerfektesChaos/js/WikiSyntaxTextMod/dE.js
/// 2023-02-28 PerfektesChaos@de.wikipedia
/// Fingerprint: #0#0#
/// License: CC-by-sa/4.0
/// <nowiki>
// WikiSyntaxTextMod:  Wiki syntax specific code, particular elements
/* global mw:true, mediaWiki:false                                     */
/* jshint forin:false,
          bitwise:true, curly:true, eqeqeq:true, latedef:true,
          laxbreak:true,
          nocomma:true, strict:true, undef:true, unused:true           */


if ( typeof mediaWiki  !==  "object" ) {   // disconnected
   mw  =  {  config: false,
             libs:   { WikiSyntaxTextMod:  { }
                    },
            log:    function () {"use strict";}
          };
}
( function ( mw ) {
   "use strict";
   var version  =  -7.65,
       sign     =  "WikiSyntaxTextMod",
       sub      =  "E",
       rls, self, WSTM;
   if ( typeof mw.loader  ===  "object" ) {
      rls   =  { };
      self  =  "user:PerfektesChaos/" + sign + "/" + sub;
      rls[ self ] = "loading";
      mw.loader.state( rls );
   }
   if ( typeof mw.libs[ sign ]  !==  "object" ) {   // isolated
      mw.libs[ sign ]  =  { };
   }
   WSTM  =  mw.libs[ sign ];
   if ( typeof WSTM.w  !==  "object" ) {
      WSTM.w  =  { elem: { }  };
   }
   if ( typeof WSTM.w.elem  !==  "object" ) {
      WSTM.w.elem  =  { };
   }
   WSTM.w.elem.vsn   =  version;
   WSTM.w.elem.self  =  self;
   if ( typeof WSTM.bb  !==  "object" ) {
      WSTM.bb  =  { };
   }
   if ( typeof WSTM.debugging  !==  "object" ) {
      WSTM.debugging  =  { };
   }
} ( mw ) );



/*
Requires: JavaScript 1.3
          (String.charCodeAt String.fromCharCode String.replace)
          JavaScript 1.5  RegExp non-capturing parenthese
 */



//-----------------------------------------------------------------------



mw.libs.WikiSyntaxTextMod.bb.bbE  =  function (WSTM) {
   // Building block and run environment support
   // 2012-05-18 PerfektesChaos@de.wikipedia
   "use strict";
   if ( typeof WSTM.util  !==  "object" ) {
      WSTM.util  =  { };
   }


   if ( typeof WSTM.util.fiatObjects  !==  "function" ) {
      WSTM.util.fiatObjects  =  function (adult, activate, assign) {
         // Ensure existence of at least empty object
         // Precondition:
         //    adult     -- parent object
         //    activate  -- String with name of child object
         //    assign    -- optional object with initial definition
         //                 if containing object components,
         //                 they will be asserted as well
         // Postcondition:
         //    adult has been extended
         // Uses:
         //    .util.fiatObjects()  -- recursive
         // 2012-05-18 PerfektesChaos@de.wikipedia
         var elt,
             obj,
             s;
         if ( typeof adult[ activate ]  !==  "object" ) {
            adult[ activate ]  =  ( assign  ?  assign  :  { } );
         }
         if ( assign ) {
            obj  =  adult[ activate ];
            for ( s in assign ) {
               elt  =  assign[ s ];
               if ( typeof elt  ===  "object" ) {
                  WSTM.util.fiatObjects( obj, s, elt );
               }
            }  // for s in obj
         }
      };   // .util.fiatObjects()
   }


   WSTM.util.fiatObjects(WSTM,  "debugging",  { loud: false });


};   // .bb.bbE()
mw.libs.WikiSyntaxTextMod.bb.bbE(mw.libs.WikiSyntaxTextMod);
delete mw.libs.WikiSyntaxTextMod.bb.bbE;



//-----------------------------------------------------------------------



mw.libs.WikiSyntaxTextMod.bb.elem  =  function (WSTM) {
   // Particular syntax elements
   // Uses:
   //    .util.fiatObjects()
   // 2012-10-10 PerfektesChaos@de.wikipedia
   "use strict";
   WSTM.util.fiatObjects( WSTM,  "w",
                          { elem:  { isbn:   { },
                                     tables: { }
                                   }
                          } );



   WSTM.w.elem.wordlist  =  [ "DEFAULTSORT",
                              "DISPLAYTITLE",
                              "REDIRECT" ];
   // ////////////////////////////////////////////////////////////// MORE



   WSTM.w.elem.defaultsort  =  function (adjust, assign) {
      // Check "{{DEFAULTSORT:" code and localize keyword
      // Precondition:
      //    adjust  -- entire expression like "DEFAULTSORT:sortkey}}"
      //    assign  -- keyword like "DEFAULTSORT" or localized
      // Postcondition:
      //    Returns (updated) expression
      // Uses:
      //    >  .w.template.sort
      //    >  .g.wTitle
      //    >< .w.encountered.DEFAULTSORT
      //    .errors.found()
      //    .hooks.fire()
      //    .w.elem.sortkey()
      // 2016-01-23 PerfektesChaos@de.wikipedia
      var k       =  adjust.indexOf(":"),
          lapsus  =  true,
          sorter  =  adjust.substr(k + 1),
          leave,
          shift,
          symbol;
      if ( typeof WSTM.w.encountered.DEFAULTSORT  ===  "string" ) {
         WSTM.errors.found( "defaultsortRepeated",
                            false,
                            "{{" + adjust );
      } else {
         if ( WSTM.hooks.fire( "defaultsort_strict" ) ) {
            symbol  =  WSTM.w.template.sort;
            symbol  =  symbol.substr(1,  symbol.substr(1).indexOf("|"));
         } else {
            symbol  =  assign.toUpperCase();
         }
         sorter  =  sorter.slice( 0, -2 );
         if ( sorter.length ) {
            if ( sorter.indexOf("\n") < 0 ) {
               shift  =  this.sortkey( sorter );
               if (shift) {
                  sorter  =  shift;
               }
               if (WSTM.hooks.fire( "sortkey_ignorecase" )) {
                  leave  =  ( sorter.toUpperCase() ===
                              WSTM.g.wTitle.toUpperCase() );
               } else {
                  leave  =  ( sorter === WSTM.g.wTitle );
               }
               if (leave) {
                  WSTM.errors.found( "defaultsortSuperfluous",
                                     false,
                                     "{{" + adjust );
               } else {
                  lapsus  =  false;
               }
            } else {
               WSTM.errors.found( "defaultsortLineBreak",
                                  false,
                                  "{{" + adjust );
            }
         } else {
            WSTM.errors.found("defaultsortEmpty",
                              false,
                              "{{" + adjust);
         }
         WSTM.w.encountered.DEFAULTSORT  =  sorter;
      }
      return  (lapsus  ?  adjust  :  symbol + ":" + sorter + "}}");
   };   // .w.elem.defaultsort()



   WSTM.w.elem.displaytitle  =  function (adjust, assign) {
      // Check "{{DISPLAYTITLE:" code, delete if entirely redundant
      // Precondition:
      //    adjust  -- entire expression like "DISPLAYTITLE:title}}"
      //    assign  -- keyword like "DISPLAYTITLE" or localized
      //    attach  -- detected keyword
      // Postcondition:
      //    Returns false, if to be discarded,
      //            or string with possibly formatted adjust string
      // Uses:
      //    >  .w.template.show
      //    >  .g.wNsNumber
      //    >  .g.wTitle
      //    >< .w.encountered.DISPLAYTITLE
      //     < .mod.lazy
      //    .str.trimL()
      //    .errors.found()
      //    .hooks.fire()
      //    .str.substrEnd()
      //    .str.trimR()
      // Requires: JavaScript 1.3   charCodeAt()
      // 2012-09-24 PerfektesChaos@de.wikipedia
      var k       =  adjust.indexOf(":"),
          r       =  adjust,
          show    =  WSTM.str.trimL(adjust.substr(k + 1),  false),
          symbol;
      if ( typeof WSTM.w.encountered.DISPLAYTITLE  ===  "string" ) {
         WSTM.errors.found("displaytitleRepeated",
                           false,
                           "{{" + adjust);
      } else {
         if (WSTM.hooks.fire("displaytitle_localize")) {
            symbol  =  WSTM.w.template.sort;
            symbol  =  symbol.substr(1,  symbol.substr(1).indexOf("|"));
         } else {
            symbol  =  assign.toUpperCase();
         }
         if (WSTM.str.substrEnd(show, 2)  ===  "}}") {
   //    if (show.slice(-2) === "}}") {
            show  =  WSTM.str.trimR(show.slice(0, -2),  false,  false);
            if (show.indexOf("\n") < 0) {
               if (show === WSTM.g.wTitle  &&  ! WSTM.g.wNsNumber) {
                  r              =  false;
                  WSTM.mod.lazy  =  false;
               }
               /*
               k  =  show.charCodeAt(0);
               if ((k >= 48  &&  k <= 57)   ||
                   (k >= 65  &&  k <= 90)) {
               }   // digit or capital latin
               */
               WSTM.w.encountered.DISPLAYTITLE  =  show;
            } else {
               WSTM.errors.found("displaytitleDubios",
                                 false,
                                 "{{" + adjust);
            }
            show  =  show + "}}";
         } else {
            WSTM.errors.found("displaytitleDubios",
                              false,
                              "{{" + adjust);
         }
         if (r) {
            r  =  symbol + ":" + show;
         }
      }
      return  r;
   };   // .w.elem.displaytitle()



   WSTM.w.elem.exportsingle  =  function (ahead) {
      // Process a '#WikiSyntaxTextMod EXPORT' page begin
      // Precondition:
      //    ahead  -- first block / entire wikitext
      //    Page starts with '#WikiSyntaxTextMod EXPORT'
      // Postcondition:
      //    Line has been removed, import languages added.
      // Uses:
      //    >  .lang.translate.read
      //    >  .g.wNsNumber
      //    >  .g.wDBname
      //    >  .o.WikiTom.WSTMinternal
      //    >< .text
      //     < .lang.write
      //    .g.fetchDB()
      //    .lang.translate.further()
      //    .lang.translate.flush()
      //    .lang.translate.finish()
      //    .o.WikiTom().focus()
      //    .o.WikiTom().fresh()
      // 2014-10-10 PerfektesChaos@de.wikipedia
      var re     =  new RegExp("^#WikiSyntaxTextMod +EXPORT +"
                               + "([a-z]+(_[a-z]+)?)\n+"
                               + "(<h1.+</h1>\n+)?",
                               "i"),
          scope  =  false,
          got,
          slang,
          stuff;
      WSTM.lang.write  =  false;
      got              =  re.exec(ahead);
      if (got) {
         stuff  =  ahead.substr(got[0].length);
         //  WSTM.g.wNsNumber > 0        TRANSLATE
         if (WSTM.g.wNsNumber === 2  ||
             WSTM.g.wNsNumber === 4  ||
             WSTM.g.wNsNumber >= 100) {
            scope  =  got[1].toLowerCase();
            if (scope !== WSTM.g.wDBname) {
               got  =  WSTM.g.fetchDB(scope);
               if (got) {
                  slang            =  got[0];
                  WSTM.lang.write  =  { db:       scope,
                                        lang:     slang,
                                        lead:     true,
                                        linkproj: got[1],
                                        linklang: slang };
                  WSTM.lang.translate.further(scope,
                                              WSTM.lang.translate.read,
                                              true);
                  WSTM.lang.translate.further(slang,
                                              WSTM.lang.translate.read,
                                              true);
                  WSTM.lang.translate.flush(slang, scope);
                  WSTM.lang.translate.finish(0);
                  scope  =  "#WikiSyntaxTextMod EXPORT " + scope
                            + "\n\n\n"
                            + "<h1>EXPORT " + scope + "</h1>\n\n\n";
                  stuff  =  scope + stuff;
               }
            }
         }
         got  =  WSTM.text.focus(0);
         got.fresh(stuff);
         if (scope) {
            got  =  WSTM.text.fold(0, scope.length, false, true);
            if (got) {
               got.mode    =  WSTM.o.WikiTom.WSTMinternal;
               got.lookup  =  false;
            }
         }
      }
   };   // .w.elem.exportsingle()



   WSTM.w.elem.fair  =  function (all) {
      // Isolate paragraph and headline ranges
      // Precondition:
      //    all  -- WikiTom to be analyzed and subdivided (root)
      // Postcondition:
      //    all  has been subdivided, where appropriate
      // Uses:
      //    .hooks.fire()
      //    .o.WikiTom().find()
      //    .o.WikiTom().flip()
      //    .o.WikiTom().folder()
      //    .o.WikiTom().focus()
      //    .errors.found()
      //    .str.trim()
      //    .w.elem.fragment()
      // Requires: JavaScript 1.3   charCodeAt()
      // 2014-08-25 PerfektesChaos@de.wikipedia
      var m    =  WSTM.hooks.fire("headline_spacing"),
          re   =  [ /\r?\n(\r?\n+)([^\n]+\r?\n)?/, 1 ],
          got  =  all.find(re, 0, 0, true, false, false),
          d,
          h,
          j,
          k,
          n,
          p,
          s;
      while (got) {
         j  =  got.i;
         k  =  got.k;
         n  =  got.m.length;
         if (n > 1) {
            d  =  (WSTM.hooks.fire("linegap", got.r[2])  ?  1  :  2);
            if (n > d) {
               all.flip(k,  j,  n - d,  "");
               n  -=  d;
            }
         }
         if (j) {
            all.folder(0,  k,  j + 1,  k);
            p  =  all.focus(k);
            if (p) {
               p.limited  =  true;
            }
            k++;
            j  =  1;
         } else {
            j  +=  n + 1;
         }
         got  =  all.find(re, j, k, false, false, false);
      }   // while got
      re   =  [ /([^=])?(=+)([^=\n].*[^=\n]|[^=\n])(=+)([^=\r?\n]+)?\r?\n?/,
                0 ];
      got  =  all.find(re, 0, 0, true, false, false);
      while (got) {
         d  =  got.child;
         if (d) {
            j  =  0;
            k  =  got.k + 1;
            this.fair(d.o);
         } else {
            j    =  got.i;
            k    =  got.k;
            n    =  got.m.length;
            got  =  got.r;
            if (got[1]) {
               if (got[1].charCodeAt(0) === 10) {
                  j++;
               } else {
                  got  =  false;
                  if (! j) {
                     j++;
                     n  -=  2;
                  }
               }
            } else if (j || k) {
               got  =  false;
               if (k  &&  ! j) {
                  p  =  all.focus(got.k - 1);
                  got  =  p.lookup;
                  if (! got) {
                     j  =  1;
                     n--;
                  }
               }
            }
            if (got) {
               s  =  got[5];
               if (s) {
                  s  =  WSTM.str.trim(s);
                  if (s.length) {
                     WSTM.errors.found("headlineEnd",
                                       false,
                                       got[2] + got[3] + got[4]);
                     got  =  false;
                  }
               }
               if (got) {
                  s  =  got[2];
                  h  =  s.length;
                  if (h === got[4].length) {
                     if (h === 1) {
                        if (WSTM.hooks.fire("headline_1")) {
                           WSTM.errors.found("headline1",
                                             false,
                                             "= " + got[3] + " =");
                        }
                     }
                     n  =  h + got[3].length + h;
                     if (j) {
                        h  =  all.folder(0, k, j, k);
                        if (h) {
                           p  =  all.focus(k);
                           if (p) {
                              p.limited  =  true;
                           }
                        }
                        k++;
                        j  =  0;
                     }
                     if (all.folder(0, k, n, k)) {
                        h  =  all.focus(k);
                        if (h) {
                           p  =  WSTM.str.trim(got[3]);
                           // .w.polish.strong()   still ???
                           this.fragment(p, false);
                           h.limited  =  true;
                           h.scope    =  "headline";
                           if (m) {
                              if (m > 0) {
                                 s  =  s + " " + p + " " + s;
                              } else {
                                 s  =  s + p + s;
                              }
                              if (s !== h.toString()) {
                                 // no links nor templates defined yet
                                 all.flip(k, 0, n, s);
                              }
                           }
                        }
                        k++;
                        j  =  0;
                     }
                  } else {
                     WSTM.errors.found("headlineUnequal",
                                       false,
                                       got[2] + got[3] + got[4]);
                     j  +=  got[2].length +
                            got[3].length +
                            got[4].length;
                  }
               }
            }
            if (j) {
               j  +=  n - 2;
            } else if (! k) {
               j  =  3;
            }
         }
         got  =  all.find(re, j, k, true, false, false);
      }   // while got
   };   // .w.elem.fair()



   WSTM.w.elem.finishing  =  function () {
      // Perform general syntax polish
      // Postcondition:
      //    RegExp was used.
      // Uses:
      //    >  .w.chr.detected.exchange
      //    >  .w.chr.detected.ampersand
      //    >  .w.chr.detected.nbHyphen
      //    >  .w.chr.detected.ordMasc
      //    >  .w.encountered.table
      //    >< .text
      //    .w.chr.flushEntities()
      //    .w.chr.flushChars()
      //    .hooks.fire()
      //    .util.translate.factory()
      //    .o.WikiTom().replace()
      //    .w.elem.tables.features()
      //    .w.elem.tables.fire()
      //    .w.elem.isbn.fire()
      // 2023-02-28 PerfektesChaos@de.wikipedia
      var tms  =  [ ["([0-9])&(nbsp|#(160|x0*[aA]0));%",
                     "$1 %"],
                    ["&#x202[89];",
                     "\n"],
                    ["\n\\| *(border|class|(col|row)span)"
                            + " *= *(1?[0-9]) *\\|",
                     "\n|$1=\"$3\"|"],
                    ["\\b(?:PMID|RFC)"
                     + "(?::&nbsp;| *: *)"
                     + "([0-9]{1,7}(?:[ /.,;<)\n]|\\]))",
                     "PMID $1"],
                    ["\\[\\[((?:PMID|RFC) [0-9]{1,7})\\]\\]",
                     "$1"]
                   ],
          c1, c2, c3, t;
      if (WSTM.w.chr.detected.nbHyphen) {
         c1   =  String.fromCharCode(8209);   // 2011 NON-BREAKING HYPHEN
         t    =  [   [c1 + "( |\n|<(br|div)\\b)",
                      "-$1"],
                     ["( |\n|/>)" + c1,
                      "$1-"]   ];
         tms  =  tms.concat(t);
      }
      if (WSTM.w.chr.detected.ordMasc) {
         c1   =  String.fromCharCode(186);    // \xBA &ordm;
         c2   =  String.fromCharCode(176);    // degree
         c3   =  String.fromCharCode(8722);   // minus
         t    =  [  ["([0-9][.,][0-9]+)" + c1,
                     "$1" + c2],
                    ["(" + c3 + "[0-9]+[.,]?[0-9]*)" + c1,
                     "$1" + c2],
                    ["( |&nbsp;)" + c1
                     + "([CFR])\\b",
                     "$1" + c2 + "$2"]    ];
         tms  =  tms.concat(t);
      }
      if (WSTM.w.chr.detected.ampersand) {
         //    new RegExp("&[#A-Za-z]")
         WSTM.w.chr.flushEntities(WSTM.text);
      }
      if (WSTM.w.chr.detected.exchange) {
         WSTM.w.chr.flushChars(WSTM.text);
      }
      t  =  WSTM.hooks.fire("finishing");
      if (t) {
         tms  =  tms.concat(t);
      }
      tms  =  WSTM.util.translate.factory(tms, ".finishing");
      WSTM.text.replace(tms);
      if (WSTM.w.encountered.table) {
         this.tables.features();
      } else {
      }
      this.tables.fire();
      this.isbn.fire(WSTM.text, false);
   };   // .w.elem.finishing()



   WSTM.w.elem.fire  =  function () {
      // Start element analysis
      // Uses:
      //    .w.elem.fair()
      //    .w.elem.tags()
      //    .w.tags.future()
      //    .w.elem.references()
      //    .w.elem.galleries()
      //    .w.elem.imagemaps()
      // 2012-12-07 PerfektesChaos@de.wikipedia
      this.fair(WSTM.text);
      this.tags();    // -> plain !!!
      if (WSTM.w.tags.future("references", false)) {
         this.references();
      }
      if (WSTM.w.tags.future("gallery", false)) {
         this.galleries();
      }
      if (WSTM.w.tags.future("imagemap", false)) {
         this.imagemaps();
      }
   };   // .w.elem.fire()



   WSTM.w.elem.fixed  =  function (analyze, ahead) {
      // Isolate any indented paragraph
      // Precondition:
      //    analyze  -- WikiTom to be analyzed in detail
      //    ahead    -- true: top level of entire text
      // Postcondition:
      //    analyze  has been subdivided and locked, where appropriate
      // Uses:
      //    >  WSTM.o.WikiTom.TextOnly
      //    .w.elem.fixing()
      // 2012-04-28 PerfektesChaos@de.wikipedia
      var e,
          i;
      if (WSTM.text.children) {
         for (i = 0;  i < analyze.children.length;  i++) {
            e  =  analyze.children[i];
            if (e.mode <= WSTM.o.WikiTom.TextOnly) {
               i  =  this.fixing(analyze, i);
/*
            } else if (e.mode <= WSTM.o.WikiTom.Tag) {
               //  this.fixed(e, false); // /////////////////////////////
*/
            }
         }   // for i
      } else {
         this.fixing(analyze, 0);
      }
   };   // .w.elem.fixed()



   WSTM.w.elem.fixing  =  function (analyze, assign) {
      // Isolate any indented paragraph in string
      // Precondition:
      //    analyze  -- WikiTom to be analyzed partially
      //    assign   -- number of string WikiTom to be analyzed
      // Postcondition:
      //    Returns node number
      //    all  has been subdivided and locked, where appropriate
      //    RegExp was used.
      // Uses:
      //    >  WSTM.o.WikiTom.TextOnly
      //    >  WSTM.o.WikiTom.CodeBlock
      //    .o.WikiTom().find()
      //    .o.WikiTom().focus()
      //    .o.WikiTom().fold()
      //    .o.WikiTom().fork()
      //    .o.WikiTom().folder()
      // Requires: JavaScript 1.3   charCodeAt()
      // 2012-05-03 PerfektesChaos@de.wikipedia
      var beg  =  false,
          end  =  false,
          got  =  0,
          r    =  assign,
          c;
      if (! assign) {
         if (analyze.fetch(0, 0, true)  ===  32) {
            beg    =  { i: 0,  k: 0 };
         }
      }
      if (! beg) {
         got  =  analyze.find("\n ", 2, r, false, true, false);
         if (got) {
            if (analyze.focus(got.k).mode <= WSTM.o.WikiTom.TextOnly) {
               beg  =  { i: got.i,  k: got.k };
            }
         }
      }
      if (beg) {
         end  =  { i: beg.i + 1,  k: beg.k };
         do {
            got  =  analyze.find("\n",  end.i + 1,  end.k,
                                 false,  true,  false);
            if (got) {
               c    =  analyze.fetch(got.k,  got.i + 1,  true);
               if (c === 32  ||  c === 10) {
                  if (got.k === beg.k) {
                     end  =  { i: got.i,  k: got.k };
                  } else {
                     got  =  false;
                  }
               } else {
                  got  =  false;
               }
               //  if   end.k > beg.k  ->   WSTM.o.WikiTom.TextOnly
            } else {
               end.i  =  analyze.fetch(end.k, 0, false).length;
               got    =  false;
            }
         } while (got);   // do
         if (end.k > beg.k) {
            if (end.i) {
               analyze.fold(end.k, end.i, false);
               end.i  =  0;
            }
            if (beg.i) {
               if (analyze.fold(beg.k, beg.i, true)) {
                  beg.k++;
                  beg.i  =  0;
               }
            }
            got  =  analyze.fork(beg.k, end.k, "code", false, false);
         } else if (end.i - beg.i  >  3) {
            got  =  analyze.folder(beg.i, beg.k, end.i, beg.k);
         }
         if (got) {
            got.mode    =  WSTM.o.WikiTom.CodeBlock;
            got.lookup  =  false;
         }
      }
      return  r;
   };   // .w.elem.fixed()



   WSTM.w.elem.fragment  =  function (anchor, alone) {
      // Precondition:
      //    anchor  -- fragment id to be added
      //    alone   -- true:  do not permit existing anchor id
      // Uses:
      //    >< .w.anchors
      //    .errors.found()
      // 2011-03-26 PerfektesChaos@de.wikipedia
      var l  =  false,
          n  =  WSTM.w.anchors,
          s  =  anchor.replace( new RegExp("(  +|_)", "g"),  " " ),
          i;
      if (! alone) {
         s  =  s.replace( /<[^>]+>/, "" ).replace( /{{.+}}/, "" );
      }
      if (WSTM.w.anchors) {
         for (i = 0;  i < n;  i++) {
            l  =  (WSTM.w.anchors[i] === s);
            if (l) {
               if (alone) {
                  WSTM.errors.found("anchorRepeated", false, anchor);
               }
               break;
            }
         }   // for i
         if (! l) {
            WSTM.w.anchors.push(s);
         }
      } else {
         WSTM.w.anchors  =  [ s ];
      }
   };   // .w.elem.fragment()



   WSTM.w.elem.furnish  =  function () {
      // Uses:
      //    >  .config.format.*
      //     < .elem.*
      // 2015-03-03 PerfektesChaos@de.wikipedia
      var cnf, p;
      if ( typeof WSTM.config  ===  "object"   &&   WSTM.config ) {
         cnf  =  WSTM.config;
         if ( typeof cnf.format  ===  "object"   &&   cnf.format ) {
            cnf  =  cnf.format;
      	   for ( p in cnf ) {
      	      this[ p ]  =  cnf[ p ];
      	   }   // for p in WSTM.config.format.*
         }
      }
   };   // .w.elem.furnish()



   WSTM.w.elem.galleries  =  function () {
      // Adapt all <gallery>...</gallery> blocks
      // Precondition:
      //    At least one gallery block has been detected before.
      // Postcondition:
      //    Nodes are modified where suitable.
      //    RegExp was used.
      // Uses:
      //    >  .w.link.namespace.nsFile
      //    >  .mod.plain.stm
      //    >  .text
      //          >  .children
      //          >  .mode
      //          >  .scope
      //    >  .WikiTom.TagBinary
      //    >< .w.link.namespace.sFile
      //    .w.link.namespace.fetch()
      //    .o.WikiTom().getCount()
      //    .w.elem.gallery()
      // 2015-03-10 PerfektesChaos@de.wikipedia
      var n  =  0,
          x  =  false,
          i,
          p;
      if ( typeof this.galleryIndent  ===  "number"
           &&  this.galleryIndent >= 1) {
         n  =  Math.floor(this.galleryIndent);
      }
      if ( WSTM.w.link.namespace.sFile !== "string" ) {
         WSTM.w.link.namespace.sFile  =
                WSTM.w.link.namespace.fetch(WSTM.w.link.namespace.nsFile,
                                            false);
      }
      if (WSTM.mod.plain) {
         x = WSTM.mod.plain.stm;
      }
      for (i = WSTM.text.getCount() - 1;  i >= 0;  i--) {
         p  =  WSTM.text.children[i];
         if (p.mode === WSTM.o.WikiTom.TagBinary) {
            if (p.scope) {
               if (p.scope === "gallery") {
                  this.gallery(p, WSTM.w.link.namespace.sFile, x, n);
               }
            }
         }
      }   // for i
   };   // .w.elem.galleries()



   WSTM.w.elem.gallery  =  function (adjust, area, apply, align) {
      // Adapt one <gallery>...</gallery> block
      // Precondition:
      //    adjust  -- WikiTom to be analyzed (gallery parent)
      //               >  .children
      //               >< .mode
      //               >< .source
      //    area    -- namespace keyword, before ':'
      //    apply   -- .mod.plain.stm
      //    align   -- number of minimum indentation
      // Postcondition:
      //    Nodes are modified where suitable.
      //    RegExp was used.
      // Uses:
      //    >  .mod.wikilink
      //    >  .mod.luxury
      //    >  .o.WikiTom.LinkFile
      //     < .mod.lazy
      //    .o.WikiTom().fresh()
      //    .str.isBlank()
      //    .str.makeString()
      //    .str.trimL()
      //    .str.trimR()
      //    .o.WikiTom()
      //    .o.WikiTom().toString()
      //    .util.translate.flip()
      //    .w.link.namespace.furnish()
      //    .w.link.wiki.decode()
      //    .w.link.replace.flipper()
      //    .str.setString()
      //    .o.WikiTom().folder()
      // Requires: JavaScript 1.3   charCodeAt()
      // 2015-11-05 PerfektesChaos@de.wikipedia
      var indent  =  align,
          q       =  adjust.children,
          shift   =  "",
          i,
          j,
          k,
          knots,
          last,
          m,
          next,
          s,
          seek,
          single,
          show,
          swift,
          t,
          tom;
      for (k = 0;  k < q.length;  k++) {   // first run
         t  =  q[k];
         if (! t.mode  &&  t.source) {
            s  =  t.source;
            j  =  (s.indexOf("\n\n") >= 0);
            if (j) {
               s  =  s.replace(/\r?\n(\r?\n)+/g, "\n");
               t.fresh( s );
            }
            s  =  "\n" + t.source + "|";
            j  =  0;
            while (j >= 0) {
               j  =  s.indexOf("\n", j);
               if (j >= 0) {
                  i  =  0;
                  j++;
                  for (  true;  true;  j++) {
                     if (WSTM.str.isBlank(s.charCodeAt(j), false)) {
                        i++;
                        if (i > indent) {
                           indent  =  i;
                        }
                     } else {
                        break;   // for j
                     }
                  }   // for j
               }   // fetch single line
            }   // while  \n
         }
      }   // for k
      if (indent) {
         if (indent > 8) {
            indent  =  8;
         }
         shift  =  WSTM.str.makeString(32, indent);
      }
      knots  =  q.length - 1;
      for ( k = knots;  k >= 0;  k-- ) {   // second run
         t  =  q[k];
         if ( ! t.mode ) {
            if ( typeof t.source  ===  "string" ) {
               next  =  t.source.length;
            } else {
               next      =  0;
               t.source  =  "";
            }
            j     =  next;
            last  =  true;
            while ( j >= 0 ) {
               j  =  t.source.lastIndexOf("\n", j);
               if ( j < 0 ) {
                  single  =  t.source.substring(0,  next);
               } else {
                  single  =  t.source.substring(j + 1,  next);
               }
               if (single) {
                  i  =  single.indexOf("|");
                  /* 2013-07:
                     Mydoc.pdf|page=5|comment
                     MyTiff.tif|lossy|description
                     .svg|lang
                  */
                  if (i > 0) {
                     swift  =  WSTM.str.trimR(single.substr(0, i),
                                              false,  false);
                     show   =  WSTM.str.trimL(single.substr(i + 1),
                                              true);
                     if (show.length) {
                        if (show.indexOf("[") >= 0) {
                           tom  =  new WSTM.o.WikiTom(show, null);
                           WSTM.w.link.fire(tom, true, false, false);
                           show  =  tom.toString();
                        }
                        if (apply) {
                           show  =  WSTM.util.translate.flip(show,
                                                             apply);
                        }
                        show  =  "|" + show;
                     } else if (last  &&  k < knots) {
                        show  =  "|";
                     } else {
                        show  =  "";
                     }
                  } else {
                     show   =  "";
                     swift  =  single;
                  }
                  if ( ! k  ||  j >= 0) {
                     swift  =  WSTM.str.trimL(swift, true);
                     i      =  swift.indexOf(":");
                     if (i) {
                        if (i > 0) {
                           s  =  WSTM.str.trimR( swift.substr(0, i) );
                           if (WSTM.w.link.namespace.furnish(s) === 6) {
                              swift  =  WSTM.str.trimL(swift.substr(i+1),
                                                       true);
                           }
                        }
                     } else {
                        swift  =  WSTM.str.trimL(swift.substr(1), true);
                     }
                     s  =  WSTM.w.link.wiki.decode(swift, true, false,
                                                   false, true);
                     if (s) {
                        swift  =  s;
                     }
                     if (WSTM.mod.wikilink) {
                        seek  =  area + ":" + swift;
                        s     =  WSTM.w.link.replace.flipper(seek,
                                                             false,
                                                             false,
                                                             false);
                        if (s) {
                           swift  =  s.substr(area.length + 1);
                        }
                     }
                     // show might contain a wikilink; refine
                     show  =  shift + swift + show;
                     if (show !== single) {
                        t.fresh( WSTM.str.setString(t.source,
                                                    j + 1,
                                                    next - j - 1,
                                                    show) );
                        WSTM.mod.lazy  =  false;
                     }
                     if (WSTM.mod.luxury) {
                        i  =  j + 1 + indent;
                        m  =  adjust.folder(i,
                                            k,  i + swift.length,
                                            k);
                        if (m) {
                           m.mode    =  WSTM.o.WikiTom.LinkFile;
                           m.lookup  =  false;
                           t         =  q[k];
                        }
                     }
                  }
               }
               last  =  false;
               next  =  j;
               j--;
            }   // while  \n
         }
      }   // for k--
   };   // .w.elem.gallery()



   WSTM.w.elem.hashmagic  =  function () {
      // Pages beginning with #, like #REDIRECT statement
      // Postcondition:
      //    Modifies text, if appropriate
      //    RegExp was used.
      // Uses:
      //    >  .text
      //    .o.WikiTom().fetch()
      //    .w.elem.exportsingle()
      //    .w.elem.importsingle()
      //    .w.elem.redirect()
      // Requires: JavaScript 1.3   charCodeAt()
      // 2012-09-07 PerfektesChaos@de.wikipedia
      var start  =  WSTM.text.fetch(0, 0, false),
          got,
          re,
          s;
// TODO   leading whitespace
      if (start.charCodeAt(0) === 35) {   // '#'
         s  =  start.substr(1);
         if (s.substr(0, 17)  ===  "WikiSyntaxTextMod") {
             re   =  new RegExp("^#WikiSyntaxTextMod +([a-z]+) ", "i");
             got  =  re.exec(start);
             if (got) {
                switch (got[1].toUpperCase()) {
                   case "EXPORT" :
                      this.exportsingle(start);
                      break;
                   case "IMPORT" :
                      this.importsingle(start);
                      break;
                   case "TRANSLATE" :
                      // one-liner, write project
                      break;
                }   // switch got[1]
             }   // got
         } else {
            this.redirect(s);
         }
      }   // '#'
   };   // .w.elem.hashmagic()



   WSTM.w.elem.imagemaps  =  function () {
      // Adapt all <imagemap>...</imagemap> blocks
      // Precondition:
      //    At least one imagemap block has been detected before.
      // Postcondition:
      //    Nodes are modified where suitable.
      //    RegExp was used.
      // Uses:
      //    >  .text
      //          >  .children
      //          >  .mode
      //          >  .scope
      //    >  .WikiTom.TagBinary
      //    .o.WikiTom().getCount()
      //    .w.elem.imagemap()
      // 2012-06-20 PerfektesChaos@de.wikipedia
   };   // .w.elem.imagemaps()



   WSTM.w.elem.importsingle  =  function (ahead) {
      // Process a '#WikiSyntaxTextMod IMPORT' page begin
      // Precondition:
      //    ahead  -- first block / entire wikitext
      //    Page starts with '#WikiSyntaxTextMod IMPORT'
      // Postcondition:
      //    Line has been removed, import languages added.
      // Uses:
      //    >< .text
      //    .lang.translate.fair()
      //    .o.WikiTom().focus()
      //    .o.WikiTom().fresh()
      // 2014-10-10 PerfektesChaos@de.wikipedia
      var re   =  new RegExp("^#WikiSyntaxTextMod +"
                             + "IMPORT +([a-z][a-z][-a-z]*)\n+",
                             "i"),
          got  =  re.exec(ahead);
      if (got) {
         WSTM.lang.translate.fair( got[1], false );
         WSTM.text.focus(0).fresh(ahead.substr(got[0].length));
      }
   };   // .w.elem.importsingle()



   WSTM.w.elem.isbn.fire  =  function (analyze, access) {
      // Find ISBN magic codes, exchange against improvements
      // Precondition:
      //    analyze  -- WikiTom to be analyzed
      //    access   -- object  { i, k }  with start position, or false
      // Postcondition:
      //    Nodes are modified where suitable.
      //    RegExp was used.
      // Uses:
      //    >  .g.re.ISBN
      //    .o.WikiTom().find()
      //    .w.elem.isbn.fire()  -- recursive
      //    .w.elem.isbn.format()
      //    .o.WikiTom().flip()
      // 2017-04-04 PerfektesChaos@de.wikipedia
      var target   =  [ WSTM.g.re.ISBN, 0 ],
          deep,
          details,
          got,
          suggest;
      if (access) {
         got  =  access;
      } else {
         got  =  { i: 0,  k: 0 };
      }
      do {
         got  =  analyze.find(target, got.i, got.k, true, false, false);
         if (got) {
            deep  =  got.child;
            if (deep) {
               this.fire(deep.o, deep);
               got.i  =  0;
               got.k++;
            } else {
               details  =  got.r;
               if (details[6] === "f") {
                  details[6]  =  "\n";
               }
               suggest  =  this.format(details);
               if (suggest) {
                  analyze.flip(got.k, got.i, details[0].length, suggest);
                  got.i  +=  suggest.length - 2;
               } else {
                  got.i  +=  6;
               }
            }
         }
      } while (got);   // do
   };   // .w.elem.isbn.fire()



   WSTM.w.elem.isbn.format  =  function (adjust) {
      // Check and reformat ISBN magic code
      // Precondition:
      //    adjust  -- regexp result array
      //                [0]  entire context
      //                [1]  prolog
      //                     preceding non-whitespace  ('|': template)
      //                [2]  "ISBN"
      //        6 10 14 [3]  10 | 13
      //              4 [4]  '=' assignment, if any
      //             15 [5]  I-S-B-N
      //             17 [6]  epilog
      // Postcondition:
      //    Returns  string  reformatted changed sequence (adjust[0])
      //                     (without last digit and epilog **+????***)
      //                     insert hyphens etc., spaces replaced by '-'
      //                     x->X
      //                     '-' inserted before language, checknumber
      //                         at ISBN-13 bookland
      //             false   adjust is invalid or unchanged
      // Uses:
      //    .util.isbn.format()
      // Requires: JavaScript 1.3   charCodeAt()
      // 2012-05-23 PerfektesChaos@de.wikipedia
      var lapsus   =  false,
          liaison  =  ( typeof adjust[ 4 ]  ===  "string" ),
          need     =  adjust[ 3 ],
          score    =  adjust[ 5 ],
          r,
          stuff;
      if ( ! liaison ) {
         lapsus  =  true;
      }
      if ( need ) {
         need  =  Number(need);
      }
      r  =  WSTM.util.isbn.format( score, need );
      if ( r[ 0 ] ) {
         if ( r[ 1 ] ) {
            lapsus  =  true;
            score   =  r[1];
         } else if ( typeof adjust[ 11 ]  ===  "string" ) {
            if ( adjust[ 11 ] !== " " ) {
               lapsus  =  true;
            }
         } else {
            lapsus  =  true;
         }
      } else {
         lapsus  =  false;
      }
      if (lapsus) {
         stuff   =  adjust[1];
         if (stuff.charCodeAt(0) === 124  &&  liaison) {  // '|' template
            stuff  =  stuff + adjust[2] + adjust[4];
         } else {
            stuff  =  stuff + "ISBN ";
         }   // template ?
         stuff  =  stuff + score + adjust[6];
         if (adjust[0] === stuff) {
            r  =  false;
         } else {
            r  =  stuff;
         }
      } else {
         r  =  false;
      }   // validity
      return  r;
   };   // .w.elem.isbn.format()



   WSTM.w.elem.redirect  =  function (ahead) {
      // Standardize #REDIRECT statement
      // Precondition:
      //    ahead  -- first block / entire wikitext after '#'
      // Postcondition:
      //   // '#'
      //    Modifies text, if appropriate
      //    RegExp was used.
      // Uses:
      //    >  .lang.translate.read
      //    >  .text
      //    .lang.translate.feed()
      //    .lang.translate.fetch()
      //    .hooks.fire()
      //    .str.capitalize()
      //    .o.WikiTom().flip()
      //    .o.WikiTom().fresh()
      // Requires: JavaScript 1.3   charCodeAt()
      // 2016-01-08 PerfektesChaos@de.wikipedia
      var re  =  WSTM.lang.translate.feed("|",
                                          "REDIRECT",
                                          "REDIRECT",
                                          WSTM.lang.translate.read,
                                          true),
          colon,
          got,
          launch,
          second,
          shift,
          sign;
      re   =  "(" + re + ")"
              + "(:?)"
              + "( *)"
              + "\\[\\[ *";
      re   =  new RegExp(re, "i");
      got  =  re.exec(ahead);
      if (got) {
         if (! got.index) {
            colon  =  WSTM.hooks.fire("redirect.colon");
            if (colon) {
               colon  =  (colon > 0  ?  ":"  :  got[2]);
            } else {
               colon  =  "";
            }
            shift  =  WSTM.hooks.fire("redirect.mode");
            if (! shift) {
               shift  =  WSTM.lang.translate.fetch("REDIRECT");
            } else if ( typeof shift  !==  "string" ) {
               shift  =  got[1];
            }
            launch  =  (got[2].length !== colon.length  ||
                        got[3].length !== 1);
            if (! launch) {
               sign    =  got[1];
               launch  =  (sign.length !== shift.length);
               if (! launch) {
                  launch  =  (sign !== shift);
                  if (launch) {
                     second  =  WSTM.hooks.fire("redirect.variant");
                     if (second) {
                        if (second.indexOf("C") >= 0) {
                           launch  =
                                   (sign !== WSTM.str.capitalize(shift));
                        }
                     }
                  }
               }
            }
            if (launch) {
               shift  =  shift + colon + " [[";
               WSTM.text.flip(0, 1, got[0].length, shift);
               WSTM.text.fresh();
//console.log(".w.elem.redirect()",WSTM.text.toString())
            }   // non-standard
         }   // heading
// TODO   single line
      }   // got
   };   // .w.elem.redirect()



   WSTM.w.elem.references  =  function () {
      // Adapt all <references>...</references> blocks
      // Precondition:
      //    At least one references block has been detected before.
      // Postcondition:
      //    Nodes are modified where suitable.
      //    RegExp was used.
      // Uses:
      //    >  .text
      //          >  .children
      //          >  .mode
      //          >  .scope
      //          >< .source
      //    >  .WikiTom.TagBinary
      //     < .mod.lazy
      //    .o.WikiTom().getCount()
      //    .str.trimL()
      //    .o.WikiTom().fresh()
      //    .hooks.fire()
      // Requires: JavaScript 1.3   charCodeAt()
      // 2015-12-25 PerfektesChaos@de.wikipedia
      var refBeg   =  new RegExp("([^ \n>]) *(</?ref?[ \n>])", "g"),
          refEnd   =  new RegExp("(</?ref[^>\n]*>) *([^ \n>])", "g"),
          refMid   =  new RegExp("</ref>\n\n+", "g"),
          refPre   =  new RegExp("<ref[^>\n]*> *\f"),
          i,
          k,
          lead,
          m,
          p,
          q,
          s,
          t;
      for (i = WSTM.text.getCount() - 1;  i >= 0;  i--) {
         p  =  WSTM.text.children[i];
         if (p.mode === WSTM.o.WikiTom.TagBinary) {
            if ( typeof p.scope  ===  "string"
                 &&     p.scope  ===  "references" ) {
               m  =  1;
               q  =  p.children;
               t  =  q[1];
               if (! t.mode) {
                  s  =  "\n"  +  WSTM.str.trimL(t.source, true, true);
                  if (s !== t.source) {
                     t.fresh(s);
                     WSTM.mod.lazy  =  false;
                  }
               }
               lead  =  true;
               for (k = 1;  k < q.length;  k++) {
                  t  =  q[k];
                  if ( typeof t.mode  ===  "number"   && // TODO  Resolve
                       ! t.mode ) {
                     s  =  t.source;
                     if (lead) {
                        if (s.charCodeAt(0) !== 10) {
                           s  =  "\n" + s;
                        }
                     }
                     m  =  k;
                     s  =  s.replace(refBeg, "$1\n$2")
                            .replace(refEnd, "$1\n$2")
                            .replace(refMid, "</ref>\n");
                     if (refPre.test(s + "\f")) {
                        s  =  s + "\n";
                     }
                     if (s !== t.source) {
                        t.fresh(s);
                        WSTM.mod.lazy  =  false;
                     }
                     lead  =  false;
                  }
               }   // for k
               t  =  q[m];
               s  =  t.source;
               if (s.charCodeAt(s.length - 1)  !==  10) {
                  t.fresh(s + "\n");
                  WSTM.mod.lazy  =  false;
               }
               WSTM.hooks.fire("references", p);
            }
         }
      }   // for i
   };   // .w.elem.references()



   WSTM.w.elem.refgroups  =  function (arglist) {
      // Bookkeeping of <references group=>
      // Precondition:
      //    arglist  -- tags object
      //                >  .props
      // Postcondition:
      //    Returns refgroup ID, or "><" for global
      // Uses:
      //    >< .w.encountered.refgroups
      //    .w.tags.furnished()
      //    .str.trim()
      //    .errors.found()
      // 2012-08-23 PerfektesChaos@de.wikipedia
      var r  =  "><",
          s;
      if (arglist.props) {
         s  =  WSTM.w.tags.furnished(arglist.props, "group");
         if (s) {
            s  =  WSTM.str.trim(s);
            if (s.length) {
               r  =  s;
            }
         }
      }
      if (WSTM.w.encountered.refgroups) {
         if (WSTM.w.encountered.refgroups[r]) {
            if (r === "><") {
               s  =  "";
            } else {
               s  =  "'" + r + "'";
            }
            WSTM.errors.found("referencesRepeated", false, s);
         } else {
            WSTM.w.encountered.refgroups[r]  =  true;
         }
      } else {
         WSTM.w.encountered.refgroups     =  { };
         WSTM.w.encountered.refgroups[r]  =  true;
      }
      return  r;
   };   // .w.elem.refgroups()



   WSTM.w.elem.sortkey =  function (adjust) {
      // Retrieve key for sorting (currently dewiki only)
      // Precondition:
      //    adjust  -- string to be checked or modified
      // Postcondition:
      //    Returns information about sortable string
      //            false   if nothing to do, adjust is fine
      //            string  changes against adjust
      //    RegExp is not modified
      // Uses:
      //    >  .g.wTitle
      //    .str.sortString()
      // 2012-05-03 PerfektesChaos@de.wikipedia
      var s      =  adjust.substr( 0, 1 ),
          learn  =  ( s === WSTM.g.wTitle ),
          shift  =  adjust,
          sup    =  s.toUpperCase(),
          sort;
      if (s !== sup) {
         shift  =  sup + shift.substr(1);
         learn  =  true;
      }   // capitalize
      sort  =  WSTM.str.sortString( shift );
      if ( sort ) {
         shift  =  sort;
         s      =  shift.substr(0, 1);
         sup    =  s.toUpperCase();
         if ( s !== sup ) {
            shift  =  sup + shift.substr(1);
         }   // capitalize
         learn  =  true;
      }   // char changed
      return  ( learn ? shift : false );
   };   // .w.elem.sortkey()



   WSTM.w.elem.tables.fire  =  function () {
      // Format table syntax attributes
      // Postcondition:
      //    Nodes are modified where suitable.
      // Uses:
      //    .w.tables.format()
      // 2013-06-22 PerfektesChaos@de.wikipedia
      this.format("(\n)?(:*\\{\\|)(.+)\n",           true,   "{|");
      this.format("(\n\\|-+)([^-\n].+)\n",           false,  "|-");
      this.format("(\n!)([- a-zA-Z]+=[^!|\n]+)\\|",  false,  "!");
   };   // .w.elem.tables.fire()



   WSTM.w.elem.tables.format  =  function ( access, ahead, about ) {
      // Format particular table syntax attributes
      // Precondition:
      //    access  -- regexp string of table syntax
      //    ahead   -- true: separated bracket for leading line break
      //    about   -- activity information
      // Postcondition:
      //    Nodes are modified where suitable.
      //    RegExp was used.
      // Uses:
      //    >  .text
      //    .w.tags.features()
      //    .w.tags.flush()
      //    .str.trimR()
      //    .o.WikiTom().flip()
      //    .hooks.fire()
      // 2023-01-01 PerfektesChaos@de.wikipedia
      var got      =  { i: 0,  k: 0 },
          j        =  ( ahead ? 2 : 1 ),
          k        =  j + 1,
          target   =  [ access, 0 ],
          located,
          m,
          n,
          props,
          set,
          shift;
      do {
         got  =  WSTM.text.find( target,
                                 got.i,
                                 got.k,
                                 true,
                                 false,
                                 false );
         if ( got ) {
            if ( ahead ) {
               located  =  ( ! got.i  ||
                             got.r[ 1 ] );   // &&  ! got.k ????
            } else {
               located  =  true;
            }
            if ( located ) {
               set    =  got.r[ k ];   // r[3]
               props  =  WSTM.w.tags.features( set, about );
               if ( props ) {
                  if ( about === "{|" ) {
                     // class prettytable
                     WSTM.hooks.fire( "tablehead", props );
                  }
                  shift  =  WSTM.w.tags.flush( props, false );
                  if ( shift ) {
                     shift  =  WSTM.str.trimR( shift );
                     if ( about === "{|"  &&
                          shift === " border=\"0\"" ) {
                        shift  =  "";
                     }
                  } else {
                     shift  =  "";
                  }
               } else {
                  shift  =  set;
               }
               if ( shift !== set ) {
                  m  =  set.length;
                  n  =  got.i  +  got.r[ 0 ].length  -  m  -  1;
                  WSTM.text.flip( got.k, n, m, shift );
                  set  =  shift;
               }
            } else {
               set  =  "";
            }
            got.i  +=  got.r[ j ].length + set.length;   // r[2]
         }
      } while ( got );   // do
   };   // .w.elem.tables.format()



   WSTM.w.elem.tables.furnish  =  function () {
      // Initialize
      // Postcondition:
      //    Nodes are modified where suitable.
      // Uses:
      //    >  .mod.table
      //    >  .text
      //     < .w.encountered.table
      //     < .mod.luxury
      // 2016-01-30 PerfektesChaos@de.wikipedia
      var got;
      if (WSTM.mod.table) {
         got  =  WSTM.text.find( [ "(\n)?(:*\\{\\|)(.+)\n", 0 ],
                                 0,
                                 0,
                                 true,
                                 false,
                                 false );
         if (got   &&   (! got.i  ||  got.r[1])) {
            WSTM.w.encountered.table  =  true;
            WSTM.mod.luxury           =  true;
         }
      }
   };   // .w.elem.tables.furnish()



   WSTM.w.elem.tags  =  function () {
      // Adapt separated textual <tags>...</tags> blocks
      // Precondition:
      //    At least one binary block has been detected before.
      // Postcondition:
      //    Nodes are modified where suitable.
      //    RegExp was used.
      // Uses:
      //    >  .text
      //          >  .children
      //          >  .mode
      //          >  .scope
      //    >  .WikiTom.TagBinary
      //    >  .mod.lock
      //    >  .mod.plain
      //    .o.WikiTom().getCount()
      //    .w.template.fire()
      //    .w.link.fire()
      //    .o.WikiTom().replace()
      //    .w.elem.isbn.fire()
      // Requires: JavaScript 1.3   charCodeAt()
      // 2013-05-12 PerfektesChaos@de.wikipedia
      var i,
          p,
          s;
      for (i = WSTM.text.getCount() - 1;  i >= 0;  i--) {
         p  =  WSTM.text.children[i];
         if (p.mode === WSTM.o.WikiTom.TagBinary) {
            s  =  "|" + p.scope + "|";
            WSTM.w.template.fire(p, true);
            if ("|gallery|".indexOf(s) < 0) {
               WSTM.w.link.fire(p, false, WSTM.mod.lock, false);
            }
            if (WSTM.mod.plain) {
               if (WSTM.mod.plain.stm  &&
                   "|gallery|imagemap|".indexOf(s) < 0) {
                  p.replace(WSTM.mod.plain.stm, false);
               }
            }
            this.isbn.fire(p, false);
            /*
            if ("|references|".indexOf(s)  <  0) {
            }
            */
         }
      }   // for i
   };   // .w.elem.tags()



};   // .bb.elem()
mw.libs.WikiSyntaxTextMod.bb.elem(mw.libs.WikiSyntaxTextMod);
delete mw.libs.WikiSyntaxTextMod.bb.elem;



//-----------------------------------------------------------------------



( function ( WSTM ) {
   "use strict";
   var sub      =  "E",
       self     =  WSTM.w.elem.self,
       version  =  WSTM.w.elem.vsn,
       rls;
   if ( typeof WSTM.main  !==  "object" ) {
      WSTM.main  =  { };
   }
   if ( ! WSTM.main.bb ) {
      WSTM.main.bb  =  { };
   }
   WSTM.main.bb[ sub ]  =  { load: true,
                             vsn:  version };
   if ( typeof WSTM.main.wait  ===  "function" ) {
      // Start on import: callback to waiting ...
      WSTM.main.wait( sub, version );
   }
   if ( typeof mw.loader  ===  "object"   &&
        typeof mw.hook  !==  "undefined" ) {
      rls = { };
      rls[ self ] = "ready";
      mw.loader.state( rls );
      mw.hook( "WikiSyntaxTextMod/" + sub + ".ready" )
        .fire( [ sub, version ] );
   }
} ( mw.libs.WikiSyntaxTextMod ) );



// Emacs
// Local Variables:
// coding: iso-8859-1-dos
// fill-column: 80
// End:

/// EOF </nowiki>   WikiSyntaxTextMod/dE.js