User:PerfektesChaos/js/WikiSyntaxTextMod/dO.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
This user script seems to have a documentation page at User:PerfektesChaos/js/WikiSyntaxTextMod/dO. |
/// PerfektesChaos/js/WikiSyntaxTextMod/dO.js
// Objects for wiki syntax specific code
/// 2019-08-01 PerfektesChaos@de.wikipedia
/// Fingerprint: #0#0#
/// @license: CC-by-sa/4.0 GPLv3
/// <nowiki>
/* global mw:true, mediaWiki:false */
/* jshint forin:false, nocomma:false,
bitwise:true, curly:true, eqeqeq:true, latedef:true,
laxbreak:true,
strict:true, undef:true, unused:true */
if ( typeof mediaWiki !== "object" ) { // disconnected
mw = { libs: { WikiSyntaxTextMod: { }
},
log: function () {"use strict";}
};
}
( function ( mw ) {
"use strict";
var version = -7.21,
sign = "WikiSyntaxTextMod",
sub = "O",
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.o !== "object" ) {
WSTM.o = { };
}
WSTM.o.vsn = version;
WSTM.o.self = self;
if ( typeof WSTM.bb !== "object" ) {
WSTM.bb = { };
}
if ( typeof WSTM.debugging !== "object" ) {
WSTM.debugging = { };
}
} ( mw ) );
// Provides:
// .o.URL2wiki
// .o.Weblink
// .o.Wikilink
// .o.WikiTom
/*
Requires: JavaScript 1.3
(String.charCodeAt String.fromCharCode String.replace)
*/
//-----------------------------------------------------------------------
mw.libs.WikiSyntaxTextMod.bb.URL2wiki = function (WSTM) {
// Administration of wikilinks
// 2013-03-15 PerfektesChaos@de.wikipedia
// Class:
// Public:
// set()
// Private:
// init()
// .law true: https mandatory
// .index number: position of "://" in .source
// .multiple number: of leading brackets '[' (0, 1, 2)
// .newFrom number: of chars in .source for replacement region start
// .newTo number: of chars in .source for replacement region end
// .scheme URL protocol, may be false or terminated by ':'
// .shift replacement string (total) , beginning at .newFrom
// .show non-empty title string
// .sister wikilink sister project
// .site domain (including port)
// .slashed path etc.
// .source wikitext
// .start wikilink prefix string terminated with ':', or false
// .storage target of wikilink
// .story title of wikilink, or false
// .suite string: URL false: wikilink
// .suffix aftermath, after "]"
"use strict";
var U2W;
WSTM.o.URL2wiki = function () {
// .constructor for new
// Postcondition:
// Returns .o.URL2wiki object
// Uses:
// > .o.URL2wiki::
// .o.Wikilink.init()
// 2013-03-15 PerfektesChaos@de.wikipedia
var p;
this.init();
for (p in WSTM.o.URL2wiki) {
this[ p ] = WSTM.o.URL2wiki[ p ];
} // for p in
return this;
}; // .o.URL2wiki() .constructor
U2W = WSTM.o.URL2wiki;
U2W.prototype.init = function () {
// Initialize existing URL2wiki object
// Postcondition:
// .o.URL2wiki object has been reset
// Uses:
// > .o.URL2wiki::
// > .***
// 2013-03-15 PerfektesChaos@de.wikipedia
this.index = -1;
this.mode = 0;
this.multiple = -1;
this.newFrom = false;
this.newTo = false;
this.scheme = false;
this.shift = false;
this.show = false;
this.sister = false;
this.site = false;
this.slashed = false;
this.source = false;
this.start = false;
this.storage = false;
this.story = false;
this.suite = false;
this.suffix = false;
}; // .o.URL2wiki.init()
U2W.prototype.fetch = function () {
// Retrieve URL segments from wikitext
// Uses:
// > .o.URL2wiki::
// > .source
// > .index
// >< .move
// < .multiple
// < .newFrom
// < .site
// < .slashed
// .w.link.web.fetch()
// 2013-03-15 PerfektesChaos@de.wikipedia
var i, s;
this.multiple = 0;
WSTM.w.link.web.fetch(this, true); // cave!
s = this.source.substr(this.index + this.move);
i = s.indexOf(" ");
if (i > 0) {
s = s.substr(0, i);
this.move = i + 1;
} else {
this.move = s.length;
}
i = s.indexOf("/");
if (i > 0) {
this.site = s.substr(0, i);
if (i < s.length - 1) {
this.slashed = s.substr(i);
}
} else {
this.site = s;
}
}; // .o.URL2wiki.fetch()
U2W.prototype.finish = function () {
// Modify source string if URL improved
// Postcondition:
// .o.URL2wiki object has been reset
// Uses:
// > .o.URL2wiki::
// > .source
// < .shift
// 2013-03-15 PerfektesChaos@de.wikipedia
}; // .o.URL2wiki.finish()
U2W.prototype.fire = function () {
// Perform analysis
// Postcondition:
// .o.URL2wiki object has been evaluated
// Uses:
// > .o.URL2wiki::
// > .scheme
// > .site
// > .slashed
// > .show
// < .mode
// < .sister
// < .storage
// < .story
// .w.link.wiki.url()
// 2013-03-15 PerfektesChaos@de.wikipedia
var i, g, s;
switch (this.scheme) {
case "http:" :
s = "http://";
i = 7;
break;
case "https:" :
s = "https://";
i = 8;
break;
default:
s = "//";
i = 2;
} // switch .scheme
s = s + this.site;
g = WSTM.w.link.wiki.url(i, s, this.slashed, this.show);
switch (typeof(g)) {
case "string" : // reformatted URL (later: object parts)
this.mode = 1;
this.shift = g;
break;
case "object" : // wikilink
this.mode = 2;
if (g[0]) {
this.sister = g[0];
}
this.storage = g[1];
this.story = g[2];
s = (this.sister ? this.sister + this.storage
: this.storage);
if (this.show || this.story) {
this.story = (this.show ? this.show : this.story);
if (! this.sister && this.story === s) {
this.story = false;
}
}
break;
} // switch typeof .url()
}; // .o.URL2wiki.fire()
U2W.prototype.getMode = function () {
// Return state (1: URL refinement; 2: wikilink) false: unchanged
// Uses:
// > .o.URL2wiki::
// > .mode
// 2013-03-15 PerfektesChaos@de.wikipedia
return this.mode;
}; // .o.URL2wiki.getMode()
U2W.prototype.getRemoveFrom = function () {
// Return number of target chars since which to remove, or false
// Uses:
// > .o.URL2wiki::
// > .newFrom
// 2013-03-15 PerfektesChaos@de.wikipedia
return this.newFrom;
}; // .o.URL2wiki.getRemoveFrom()
U2W.prototype.getRemoveTo = function () {
// Return number of target chars to be removed, or false
// Uses:
// > .o.URL2wiki::
// > .newTo
// 2013-03-15 PerfektesChaos@de.wikipedia
return this.newTo;
}; // .o.URL2wiki.getRemoveTo()
U2W.prototype.getSuffix = function () {
// Return suffix to be integrated, or false
// Uses:
// > .o.URL2wiki::
// > .story
// > .suffix
// .w.link.wiki.fore()
// 2013-03-15 PerfektesChaos@de.wikipedia
var r = false;
if (this.mode === 2) { // wikilink
if (this.story && this.suffix) {
r = WSTM.w.link.wiki.fore(this.suffix, 0);
if (r) {
r = this.suffix.substr(0, r);
}
}
}
return r;
}; // .o.URL2wiki.getSuffix()
U2W.prototype.getTarget = function () {
// Returns wikilink target, or URL
// Uses:
// > .o.URL2wiki::
// > .mode
// > .sister
// > .storage
// .getURL()
// 2013-03-15 PerfektesChaos@de.wikipedia
var r;
if (this.mode === 2) { // wikilink
if (this.sister) {
r = this.sister + this.storage;
} else {
r = this.storage;
}
} else { // reformatted URL
r = this.getURL();
}
return r;
}; // .o.URL2wiki.getTarget()
U2W.prototype.getTextReplace = function () {
// Returns replacement string, maybe false if nothing to do
// Uses:
// > .o.URL2wiki::
// > .mode
// > .shift
// > .sister
// > .storage
// > .story
// > .multiple
// .getTarget()
// 2013-03-15 PerfektesChaos@de.wikipedia
var r;
switch (this.mode) {
case 1 : // reformatted URL
r = this.shift;
break;
case 2 : // wikilink
r = this.getTarget();
if (this.story) {
r = r + "|" + this.story;
}
r = "[" + r + "]";
if (! this.multiple) {
r = "[" + r + "]";
}
break;
default :
r = false;
} // switch .mode
return r;
}; // .o.URL2wiki.getTextReplace()
U2W.prototype.getTitle = function () {
// Returns link title, maybe "" if not necessary
// Uses:
// > .o.URL2wiki::
// > .story
// 2013-03-15 PerfektesChaos@de.wikipedia
return (this.story ? this.story : "");
}; // .o.URL2wiki.getTitle()
U2W.prototype.getURL = function () {
// Returns URL, maybe reformatted
// Uses:
// > .o.URL2wiki::
// > .law
// > .scheme
// > .site
// > .slashed
// 2013-03-15 PerfektesChaos@de.wikipedia
var r;
if (this.law) {
r = "https://";
} else {
r = (this.scheme ? this.scheme + "//" : "//");
}
r = r + this.site + "/"
+ (this.slashed ? this.slashed : "");
return r;
}; // .o.URL2wiki.getURL()
U2W.prototype.set = function (assign, access) {
// Initialize existing weblink object
// Precondition:
// assign -- Weblink object, or string with URL
// object: > .scheme
// > .site
// > .slashed
// > .show
// > .suffix
// access -- position of "://" in assign string
// Postcondition:
// .o.URL2wiki object has been evaluated
// Uses:
// > .o.URL2wiki::
// < .index
// < .source
// < .multiple
// < .scheme
// < .site
// < .slashed
// < .show
// < .suffix
// .init()
// .fetch()
// .fire()
// .finish()
// .str.substrEnd()
// 2013-03-15 PerfektesChaos@de.wikipedia
this.init();
switch (typeof(assign)) {
case "string" : // string with URL
this.index = access;
this.source = assign;
this.fetch();
break;
case "object" : // Weblink
this.multiple = assign.multiple;
this.scheme = assign.scheme;
this.site = assign.site;
this.slashed = assign.slashed;
this.show = assign.show;
this.suffix = assign.suffix;
break;
} // switch .scheme
if (this.site) {
if (! this.scheme || this.scheme === "http:"
|| this.scheme === "https:") {
if (WSTM.str.substrEnd(this.site, 4) === ".org") {
this.fire();
if (this.source) {
this.finish();
}
}
}
}
}; // .o.URL2wiki.set()
}; // .bb.URL2wiki()
mw.libs.WikiSyntaxTextMod.bb.URL2wiki(mw.libs.WikiSyntaxTextMod);
delete mw.libs.WikiSyntaxTextMod.bb.URL2wiki;
//-----------------------------------------------------------------------
mw.libs.WikiSyntaxTextMod.bb.Weblink = function (WSTM) {
// Administration of weblinks
// 2015-12-25 PerfektesChaos@de.wikipedia
// Class:
// Public:
// set()
// getIncrement()
// Private:
// fault()
// fenced()
// fiat()
// filled()
// filter()
// fire()
// first()
// fix()
// flat()
// friend()
// fruit()
// further()
// format()
// init()
// .lazy false: any modification happened
// .limited true: enclosed in brackets (leading bracket '[')
// .lackScheme true: relative URL protocol was set to https
// .lowScheme true: URL protocol has been downcased
// .leaf true: template parameter; terminate suffix by '|'
// .index number: position of URL begin in .source
// .join number: start of interesting region in .node
// .keep number: length of URL
// .maxTitle number: limiting length for suspicious titles
// .maxURL number: limiting URL length
// .mode number: WikiTom mode
// .move number: string incrementation
// .met number: end of prolog
// .moving number: node incrementation on global search
// .multiple number: of leading brackets '[' (0, 1, 2)
// .node number: of current within .off
// .off parent WikiTom node
// .points Array of Arrays with found and replacement information
// .scheme URL protocol, may be false or terminated by ':'
// .shift replacement string for link target
// .shower non-empty title string (continued in fuerher node)
// .source wikitext including prolog
// .url2w URL2wiki object
"use strict";
var WebLK;
WSTM.o.Weblink = function (available, allow) {
// .constructor for new
// Precondition:
// available -- limiting URL length, or false
// allow -- limiting length for suspicious titles, or false
// Postcondition:
// Returns .o.Weblink object
// Uses:
// > .o.Weblink::
// > .joinSuffix
// >< .re.schemes
// < .maxURL
// < .maxTitle
// < .points
// > .w.link.protocol.weblinks
// 2013-03-15 PerfektesChaos@de.wikipedia
var p;
for (p in WSTM.o.Weblink) {
this[ p ] = WSTM.o.Weblink[ p ];
} // for p in
if (! WebLK.re.schemes) {
WebLK.re.schemes = WSTM.w.link.protocol.weblinks;
}
if (typeof(available) === "number") {
this.maxURL = available;
}
if (typeof(allow) === "number") {
this.maxTitle = allow;
}
this.points = new Array(WebLK.joinSuffix + 1);
return this;
}; // .o.Weblink() .constructor
WebLK = WSTM.o.Weblink;
// Definition of constants
// 2016-01-01 PerfektesChaos@de.wikipedia
WebLK.joinProlog = 0;
WebLK.joinLBrack = 1;
WebLK.joinScheme = 2;
WebLK.joinSite = 3;
WebLK.joinSlash = 4;
WebLK.joinSelect = 5;
WebLK.joinShow = 6;
WebLK.joinRBrack = 7;
WebLK.joinSuffix = 8;
WebLK.maxTitle = 300;
WebLK.maxURL = 511;
WebLK.re = { schemes: "|ftp|git|http|https|mms|svn|",
split: new RegExp("[\"{}]"),
stop: "({,:.;?!\"\\"
};
/*
WebLK.prototype.fruit = function (about) {
// Debug info
// Precondition:
// about -- informative key, or nothing.
// Debug
// 2013-03-15 PerfektesChaos@de.wikipedia
var e, i,
o = { },
s = "|joinLBrack|joinProlog|joinRBrack|joinScheme|joinSelect|"
+ "joinShow|joinSite|joinSlash|joinSuffix|"
+ "lowScheme|maxTitle|maxURL|off|points|"
+ "re|source|url2w|";
for (e in this) {
if (typeof(this[e]) !== "function") {
if (s.indexOf("|"+e+"|") < 0) {
o[e] = this[e];
}
}
} // for e in this
s = (about ? " " + about : "" ) + " points";
for (i = 0; i <= WebLK.joinSuffix; i++) {
e = this.points[ i ];
s = s + "\n" + e[0] + " >>";
if (typeof(e[1]) === "string") {
s = s + e[1].substr(0,350);
} else {
s = s + e[1];
}
s = s + "<< " + e[2];
} // for i
mw.log(WSTM.debugging,".o.Weblink.fruit()"+s,0,o);
}; // .o.Weblink.fruit()
*/
WebLK.prototype.facet = function (about, adjacent) {
// Retrieve string from range
// Precondition:
// about -- level to begin
// .joinSite
// .joinSlash
// .joinShow
// .joinRBrack
// adjacent -- optional: number of last level to include
// Postcondition:
// Returns string including range
// Uses:
// > .o.Weblink::
// > .points
// > .joinSite
// > .joinSlash
// > .joinShow
// 2013-03-15 PerfektesChaos@de.wikipedia
var e, i,
k = (typeof(adjacent) === "number" ? adjacent : about),
r = "";
for (i = about; i <= k; i++) {
e = this.points[ i ][1];
switch (i) {
case WebLK.joinSite :
if (i > about) {
r = r + "//";
}
break;
case WebLK.joinSlash :
e = "/";
break;
case WebLK.joinShow :
if (i > about) {
e = " " + e;
}
break;
} // switch i
if (e) {
r = r + e;
}
} // // for i
return r;
}; // .o.Weblink.facet()
WebLK.prototype.fair = function () {
// Perform user defined modifications
// Uses:
// > .o.Weblink::
// > .multiple
// > .joinProlog
// > .joinLBrack
// > .joinShow
// > .joinSuffix
// > .joinScheme
// > .joinSelect
// > .joinRBrack
// < .mode
// .facet()
// .feed()
// .fit()
// .fill()
// > .mod.url
// > .o.WikiTom.TextOnly
// < .mod.lazy
// .w.link.replace.flip()
// .str.substrEnd()
// 2013-03-15 PerfektesChaos@de.wikipedia
var i, sB, sE, x;
if (this.multiple) {
sB = this.facet(WebLK.joinProlog, WebLK.joinLBrack);
if (this.showing) {
sE = "]";
} else {
sE = this.facet(WebLK.joinShow, WebLK.joinSuffix);
}
} else {
this.fit(WebLK.joinSuffix, this.feed(), false);
sB = this.facet(WebLK.joinProlog);
sE = this.facet(WebLK.joinSuffix);
}
x = WSTM.w.link.replace.flip(WSTM.mod.url,
this.facet(WebLK.joinScheme,
WebLK.joinSelect),
sB,
sE,
"url");
if (x) {
if (typeof(x) === "object") {
if (typeof(x[0]) === "string") {
sB = x[0];
if (sB) {
if (WSTM.str.substrEnd(sB, 2) === "[[") {
this.mode = WSTM.o.WikiTom.LinkWiki;
}
}
this.fit(WebLK.joinProlog, sB, true);
this.fit(WebLK.joinLBrack, false, true);
}
if (x[1]) {
this.fill(x[1]);
}
if (typeof(x[2]) === "string") {
sE = x[2];
this.fit(WebLK.joinShow, false, true);
this.fit(WebLK.joinRBrack, false, true);
if (sE) {
i = sE.indexOf("]");
if (i >= 0) {
this.fit(WebLK.joinShow, sE.substr(0, i), true);
this.fit(WebLK.joinRBrack, "]", true);
sE = sE.substr(i + 1);
}
}
this.fit(WebLK.joinSuffix, sE, true);
}
} else {
this.fill(x);
}
WSTM.mod.lazy = false;
}
}; // .o.Weblink.fair()
WebLK.prototype.fault = function (adapt, abolish, align, around) {
// Convert URL formatted by titled wikilink syntax
// Precondition:
// adapt -- string segment beginning with "//"
// abolish -- position of Pipe in adapt
// align -- position of "/" in adapt
// around -- position of "]" in adapt
// Uses:
// > .o.Weblink::
// > .joinProlog
// > .joinShow
// > .joinSelect
// < .mod.lazy
// .facet()
// .fit()
// .fetch()
// .fenced()
// .errors.found()
// 2013-03-15 PerfektesChaos@de.wikipedia
var i = abolish,
j = adapt.indexOf(" "),
s = this.facet(WebLK.joinProlog);
this.fit(WebLK.joinProlog,
s.substr(0, s.length - 1),
true);
s = adapt.substr(0, around + 2);
if (j > 0 && j < abolish) {
i = j;
}
this.fetch(s.substr(0, i), false);
s = adapt.substr(i + 1, around - i);
this.fit(WebLK.joinShow, s, false);
if (i === j) {
this.fit(WebLK.joinShow, s.replace(/\|/g, " "), true);
}
this.fenced(this.facet(WebLK.joinSelect), true);
WSTM.mod.lazy = false;
WSTM.errors.found("weblinkWikilink", true, "[[" + s);
}; // .o.Weblink.fault()
WebLK.prototype.feed = function () {
// Retrieve not yet processed source string
// Postcondition:
// Returns string
// Uses:
// > .o.Weblink::
// > .source
// > .move
// 2013-03-15 PerfektesChaos@de.wikipedia
return this.source.substr(this.move);
}; // .o.Weblink.feed()
WebLK.prototype.fenced = function (adjust, already) {
// Escape bracket pairs within URL path and store
// Precondition:
// adjust -- string with potential bracket pairs
// already -- Not initial scan
// Postcondition:
// Returns adjust, or false if escaped and stored
// Uses:
// > .o.Weblink::
// > .joinSelect
// > .joinRBrack
// > .joinScheme
// < .mod.lazy
// .fit()
// .facet()
// .errors.found()
// Requires: JavaScript 1.3 charCodeAt()
// 2013-08-09 PerfektesChaos@de.wikipedia
var i, k, s,
n = 0,
slash = adjust,
r = adjust;
do {
k = slash.indexOf("]");
if (k > 0) {
i = slash.indexOf("[");
if (i < 0) {
break; // while
} else if (i < k - 1) {
if (slash.charCodeAt(k + 1) === 93) {
break; // while
} else {
s = slash.slice(i + 1, k);
if (s.length) {
if (! /^[-a-z.A-Z_0-9]+$/.test(s)) {
break; // while
}
}
if (k > 0) {
slash = slash.substr(0, i)
+ "[" + s + "]"
+ slash.substr(k + 1);
n += 8;
}
}
} else {
break; // while
}
}
} while (k > 0); // do
if (n) {
if (! already) {
this.fit(WebLK.joinSelect,
adjust.substr(0, slash.length - n),
false);
}
this.fit(WebLK.joinSelect, slash, true);
this.fit(WebLK.joinRBrack, "", true);
WSTM.mod.lazy = false;
WSTM.errors.found("weblinkBrackets",
true,
this.facet(WebLK.joinScheme,
WebLK.joinSelect));
r = false;
}
return r;
}; // .o.Weblink.fenced()
WebLK.prototype.fetch = function (apply, already) {
// Split URL string into components
// Precondition:
// apply -- string segment beginning with URL
// already -- Not initial scan
// Postcondition:
// object components are initialized or updated
// Uses:
// > .o.Weblink::
// > .joinScheme
// > .joinSite
// > .joinSelect
// > .joinShow
// > .joinSuffix
// .fit()
// .facet()
// Requires: JavaScript 1.3 charCodeAt()
// 2013-03-15 PerfektesChaos@de.wikipedia
var s = false,
show = false,
site = false,
slash = false,
suffix = false,
i = -1;
if (apply) {
i = apply.indexOf("//");
}
if (i >= 0) {
site = apply.substr(i + 2);
if (i > 3) {
if (apply.charCodeAt(i - 1) === 58) { // ':'
s = apply.substr(0, i);
} else {
site = false;
}
} else if (i) {
site = false;
}
}
this.fit(WebLK.joinScheme, s, already);
if (site) {
i = site.indexOf(" ");
if (i > 0) {
site = site.substr(0, i);
show = site.substr(i + 1);
i = show.indexOf("]");
s = this.facet(WebLK.joinShow);
if (s) {
show = show + s;
}
if (i > 0) {
suffix = this.facet(WebLK.joinSuffix);
suffix = show.substr(i) + (suffix ? suffix : "");
show = show.substr(0, i);
}
}
i = site.indexOf("/");
if (i > 0) {
this.fit(WebLK.joinSlash, "/", already);
slash = site.substr(i + 1);
site = site.substr(0, i);
}
i = site.indexOf("?");
if (i > 0) {
slash = site.substr(i + 1)
+ (slash ? "/" + slash : "");
site = site.substr(0, i);
}
if (site.length < 5) { // ix.de
this.fit(WebLK.joinScheme, false, true);
} else {
if (show) {
this.fit(WebLK.joinShow, show, true);
}
if (suffix) {
this.fit(WebLK.joinSuffix, suffix, true);
}
}
}
this.fit(WebLK.joinSite, site, already);
this.fit(WebLK.joinSelect, slash, already);
}; // .o.Weblink.fetch()
WebLK.prototype.fiat = function () {
// Analyze and adjust URL and embedding within brackets
// Uses:
// > .o.Weblink::
// > .move
// > .multiple
// > .joinSite
// > .joinScheme
// > .joinSelect
// > .leaf
// > .joinSuffix
// >< .source
// .feed()
// .fault()
// .fit()
// .facet()
// .fenced()
// .filled()
// .frozen()
// < .mod.lazy
// .errors.found()
// .str.terminated()
// Requires: JavaScript 1.3 charCodeAt()
// 2013-09-06 PerfektesChaos@de.wikipedia
var i, j, k, less, limit, n, s, slashed, suffix,
m = -2;
s = this.feed();
i = s.indexOf("\n\n");
less = (i > 0);
if (less) {
s = s.substr(0, i);
this.source = this.source.substr(0, this.move + i);
}
i = s.indexOf("</ref>");
limit = (i > 0);
if (limit) {
less = true;
s = s.substr(0, i);
}
i = s.indexOf("/");
k = s.indexOf("]");
n = s.indexOf("\n");
if (this.multiple > 1 && k > 0) {
m = s.indexOf("|");
if (m > 0) {
if (m < k
&& s.charCodeAt(k + 1) === 93
&& (n < 0 || n > k)) { // ']'
this.fault(s, m, i, k);
} else {
m = -3;
}
}
less = true;
}
if (m < 0) {
j = s.indexOf(" ");
if (j < 0) {
m = s.length;
} else {
m = j;
}
if (n >= 0 && n < m) {
m = n;
less = true;
}
if (k >= 0 && k < m) {
m = k;
}
if (i > 0 && i < m) {
this.fit(WebLK.joinSite, s.substr(0, i), false);
this.fit(WebLK.joinSlash, "/", false);
slashed = this.feed();
if (limit) {
i = slashed.indexOf("</ref>");
if (i > 0) {
slashed = slashed.substr(0, i);
}
}
if (j > 0) {
j = slashed.indexOf(" ");
if (j > 0) {
slashed = slashed.substr(0, j);
} else {
slashed = false;
}
}
} else {
i = s.indexOf("?", m);
if (i > 0 && i < m) {
slashed = s.substr(i);
this.fit(WebLK.joinSite, s.substr(0, i), false);
this.fit(WebLK.joinSlash, "/", true);
WSTM.mod.lazy = false;
WSTM.errors.found("weblinkStrange",
true,
this.facet(WebLK.joinScheme,
WebLK.joinSlash)
+ slashed);
} else {
this.fit(WebLK.joinSite, s.substr(0, m), false);
this.fit(WebLK.joinSlash, "/", true);
slashed = false;
}
}
if (slashed) {
if (n > 0) {
n = slashed.indexOf("\n");
if (n > 0) {
slashed = slashed.substr(0, n);
}
}
if (k > 0) {
k = slashed.indexOf("]");
if (k >= 0) {
s = slashed.substr(0, k);
i = s.indexOf("[");
if (i < 0) {
this.fit(WebLK.joinSelect, s, false);
this.fit(WebLK.joinRBrack, "]", false);
slashed = false;
suffix = this.feed();
} else {
slashed = this.fenced(slashed, false);
if (slashed) {
i = slashed.indexOf("]");
if (i < 0) {
suffix = false;
} else {
suffix = slashed.substr(i + 1);
slashed = slashed.substr(0, i);
this.fit(WebLK.joinRBrack, "]", false);
}
}
}
if (suffix) {
if (this.leaf) {
suffix = WSTM.str.terminated(suffix, "|");
}
this.fit(WebLK.joinSuffix, suffix, false);
}
}
} else if (this.limited) {
this.fit(WebLK.joinSelect, slashed, false);
i = s.indexOf(" ");
if (i > 0) {
this.fit(WebLK.joinShow, s.substr(i + 1), false);
}
if (! less) {
if (this.frozen()) {
slashed = false;
}
}
if (slashed) {
this.fit(WebLK.joinRBrack, "]", true);
WSTM.errors.found("weblinkBracketRight",
true,
this.facet(WebLK.joinScheme,
WebLK.joinSelect));
slashed = false;
}
}
if (slashed) {
if (this.multiple === 0) {
slashed = WSTM.str.terminated(slashed, " ");
slashed = WSTM.str.terminated(slashed, "\n");
slashed = WSTM.str.terminated(slashed, "</ref>");
}
this.fit(WebLK.joinSelect, slashed, false);
}
}
if (this.limited) {
if (! this.facet(WebLK.joinRBrack)) {
this.filled();
}
}
}
}; // .o.Weblink.fiat()
WebLK.prototype.fill = function (apply) {
// Process URL replacement
// Precondition:
// apply -- URL, or replaced string
// Uses:
// > .o.Weblink::
// < .shift
// < .lazy
// < .mode
// .fetch()
// .facet()
// > .o.WikiTom.TextOnly
// 2013-03-15 PerfektesChaos@de.wikipedia
this.fetch(apply, true);
if (! this.facet(WebLK.joinSite)) {
this.shift = apply;
this.lazy = false;
this.mode = WSTM.o.WikiTom.TextOnly;
}
}; // .o.Weblink.fill()
WebLK.prototype.filled = function () {
// Analyze and adjust link title and suffix
// Uses:
// > .o.Weblink::
// > .source
// > .maxTitle
// > .joinScheme
// > .joinSelect
// > .joinShow
// > .joinRBrack
// > .leaf
// > .joinSuffix
// > .limited
// .feed()
// .further()
// .fit()
// .facet()
// .flat()
// .str.terminated()
// .str.trimR()
// .errors.found()
// Requires: JavaScript 1.3 charCodeAt()
// 2013-03-15 PerfektesChaos@de.wikipedia
var i, j, k, s, show;
s = this.feed();
k = s.charCodeAt(0);
if (k === 32) { // ' '
s = s.substr(1);
k = s.indexOf("]");
if (k < 0) {
if (s.length < this.maxTitle) {
k = this.further(); // return
}
} else if (k < this.maxTitle) {
i = s.indexOf("[[");
if (i >= 0 && i < k) {
show = s.substr(0, i);
this.fit(WebLK.joinShow, show, false);
this.fit(WebLK.joinRBrack, "]", false);
s = s.substr(i);
if (this.leaf) {
s = WSTM.str.terminated(s, "|");
}
this.fit(WebLK.joinSuffix, s, false);
if (i) {
k = show.length;
show = WSTM.str.trimR(show);
if (show.length < k) {
s = " " + s;
this.fit(WebLK.joinShow, show, true);
this.fit(WebLK.joinSuffix, s, true);
}
}
i = 2;
do {
k = s.indexOf("]]", i);
if (k > 0) {
i = k + 2;
k = s.indexOf("]", i);
j = s.indexOf("[[", i);
if (j > 0 && k > 0 && k < j) {
i = -2;
}
} else {
k = s.indexOf("]", i);
i = -3;
}
if (k > 0 && i < 0) {
s = s.substr(0, k) + s.substr(k + 1);
this.fit(WebLK.joinSuffix, s, true);
break; // while
}
} while (k > 0);
k = 0;
} else {
this.fit(WebLK.joinShow, s.substr(0, k), false);
this.fit(WebLK.joinRBrack, "]", false);
s = s.substr(k + 1);
if (this.leaf) {
s = WSTM.str.terminated(s, "|");
}
this.fit(WebLK.joinSuffix, s, false);
}
this.flat();
} else {
k = -2;
}
} else if (k === 93) { // ']'
this.fit(WebLK.joinRBrack, "]", false);
s = s.substr(1);
if (this.leaf) {
s = WSTM.str.terminated(s, "|");
}
this.fit(WebLK.joinSuffix, s, false);
}
if (this.limited) {
if (k < 0) {
WSTM.errors.found("weblinkBracketRight",
false,
"[" + this.facet(WebLK.joinScheme,
WebLK.joinSelect));
}
}
}; // .o.Weblink.filled()
WebLK.prototype.filter = function () {
// Test URL for user warning request
// Uses:
// > .o.Weblink::
// > .shift
// > .joinScheme
// > .joinSelect
// .facet()
// .warn.filter()
// 2013-03-15 PerfektesChaos@de.wikipedia
var s;
if (this.shift) {
s = this.shift;
} else {
s = this.facet(WebLK.joinScheme, WebLK.joinSelect);
}
WSTM.warn.filter(s, "url");
}; // .o.Weblink.filter()
WebLK.prototype.finalize = function () {
// Terminate analysis
// Uses:
// > .o.Weblink::
// > .mode
// > .joinProlog
// > .joinLBrack
// > .joinScheme
// > .joinSelect
// < .index
// < .keep
// .facet()
// .forward()
// > .o.WikiTom.LinkWeb
// 2013-03-15 PerfektesChaos@de.wikipedia
var s;
if (this.lazy) {
s = this.facet(WebLK.joinProlog, WebLK.joinLBrack);
this.index = s.length;
s = this.facet(WebLK.joinScheme, WebLK.joinSelect);
this.keep = s.length;
} else {
this.forward();
}
}; // .o.Weblink.finalize()
WebLK.prototype.fire = function () {
// Start analysis
// Uses:
// > .o.Weblink::
// > .node
// > .join
// > .off
// > .leaf
// > .limited
// > .index
// > .joinProlog
// > .multiple
// > .met
// > .joinLBrack
// > .mark
// > .joinScheme
// > .scheme
// > .lackScheme
// > .lowScheme
// > .joinSite
// < .source
// .fit()
// .fiat()
// .fix()
// .facet()
// .friend()
// .fair()
// .filter()
// .finalize()
// > .o.WikiTom.LinkWeb
// > .mod.url
// > .warn.url
// .o.WikiTom().fetch()
// .w.link.web.fetch()
// .str.substrEnd()
// 2015-12-25 PerfektesChaos@de.wikipedia
var i, s;
this.source = this.off.fetch(this.node, this.join, false);
if (this.leaf && ! this.limited) {
i = this.source.indexOf("|", this.index);
if (i > 0) {
this.source = this.source.substr(0, i);
}
}
WSTM.w.link.web.fetch(this, this.limited);
if ((this.multiple > 0) === this.limited) {
this.fit(WebLK.joinProlog,
this.source.substr(0, this.met),
false);
if (this.multiple) {
s = this.feed();
this.fit(WebLK.joinLBrack, s.substr(0, this.mark), false);
if (this.mark > 1) {
this.fit(WebLK.joinLBrack, "[", true);
}
}
this.fit(WebLK.joinScheme, this.scheme, false);
if (this.lackScheme || this.lowScheme) {
this.fit(WebLK.joinScheme, this.scheme, true);
}
this.fiat();
this.fix();
s = this.facet(WebLK.joinSite);
if (s) {
if (WSTM.str.substrEnd(s, 4) === ".org") {
this.friend();
}
if (this.mode === WSTM.o.WikiTom.LinkWeb) {
if (WSTM.mod.url) {
this.fair();
}
if (WSTM.warn.url) {
if (this.mode === WSTM.o.WikiTom.LinkWeb) {
this.filter();
}
}
}
}
this.finalize();
}
}; // .o.Weblink.fire()
WebLK.prototype.fit = function (about, apply, alter) {
// Extend modified area
// Precondition:
// about -- level
// apply -- string segment
// alter -- string is modified
// Uses:
// > .o.Weblink::
// > .joinLBrack
// > .joinScheme
// > .joinSite
// > .joinSelect
// > .joinSuffix
// >< .points
// >< .move
// < .lazy
// .w.link.filter()
// 2015-09-12 PerfektesChaos@de.wikipedia
var swap,
e = this.points[ about ],
s = (apply ? apply : "");
if (alter) {
if (s !== (e[1] ? e[1] : "")) {
e[2] = true;
}
} else if (apply) {
e[0] = apply.length;
this.move += e[0];
}
e[1] = s;
switch (about) {
case WebLK.joinScheme:
swap = s.toLowerCase();
if (swap !== s) {
e[1] = swap;
e[2] = true;
}
if (alter) {
e[2] = apply;
} else {
e[0] += 2;
this.move += 2;
}
break;
case WebLK.joinSite:
if (s) {
swap = WSTM.w.link.filter(s, false);
swap = (swap ? swap : s).toLowerCase();
if (swap !== s) {
e[1] = swap;
e[2] = true;
}
}
break;
case WebLK.joinSelect:
if (s) {
swap = WSTM.w.link.filter(s, false);
if (swap && swap !== s) {
e[1] = swap;
e[2] = true;
}
}
break;
case WebLK.joinShow:
if (! alter) {
e[0] += 1;
this.move++;
}
break;
case WebLK.joinSuffix:
if (! alter) {
this.move -= e[0];
}
break;
} // switch about
if (e[2]) {
this.lazy = false;
}
}; // .o.Weblink.fit()
WebLK.prototype.fix = function () {
// Inspect resulting URL for suspicious content
// Uses:
// > .o.Weblink::
// > .re.schemes
// > .joinScheme
// > .joinSite
// > .joinSelect
// > .multiple
// > .re.split
// > .re.stop
// > .maxURL
// .facet()
// .str.substrExcept()
// .util.isURL()
// .str.substrEnd()
// .errors.found()
// 2016-01-28 PerfektesChaos@de.wikipedia
var s = this.facet(WebLK.joinScheme),
site = this.facet(WebLK.joinSite),
scan;
if (s) {
scan = "|" + WSTM.str.substrExcept(s, 1) + "|";
if (WebLK.re.schemes.indexOf(scan) < 0) {
WSTM.errors.found("weblinkScheme",
false,
this.facet(WebLK.joinScheme,
WebLK.joinSelect));
}
s = this.facet(WebLK.joinScheme, WebLK.joinSite);
} else {
s = "//" + site;
}
if (site && WSTM.util.isURL(s)) {
WSTM.errors.found("weblinkDomain", false, site);
}
scan = this.facet(WebLK.joinSelect);
if (scan) {
s = s + "/" + scan;
if (scan.indexOf("''") > 3) {
WSTM.errors.found("weblinkApostrophs", false, s);
}
if (this.multiple === 1) {
if (scan.indexOf("|") >= 0) {
WSTM.errors.found("weblinkPipe", false, s);
}
}
if (WebLK.re.split.test(scan)) {
WSTM.errors.found("weblinkSpecial", false, s);
}
if (WebLK.re.stop.indexOf(WSTM.str.substrEnd(scan, 1))
>= 0) {
WSTM.errors.found("weblinkPunctuation", false, s);
}
// /<\/[a-z]+>/.test(s)
}
if (s.length > this.maxURL) {
WSTM.errors.found("weblinkURLlength", false, s);
}
}; // .o.Weblink.fix()
WebLK.prototype.flat = function () {
// Standardize link title spacing
// Postcondition:
// Returns true if shrinked
// Uses:
// > .o.Weblink::
// >< .re.spaces
// < .mod.lazy
// .facet()
// .str.trim()
// 2013-03-15 PerfektesChaos@de.wikipedia
var s = this.facet(WebLK.joinShow),
n = s.length,
r = false;
if (s.indexOf("\n") >= 0) {
WSTM.mod.lazy = false;
}
s = WSTM.str.trim(s, true);
if (s) {
if (! this.re.spaces) {
this.re.spaces = new RegExp(" +", "g");
}
s = s.replace(this.re.spaces, " ");
r = (s.length < n);
} else {
s = false;
r = true;
}
this.fit(WebLK.joinShow, s, r);
return r;
}; // .o.Weblink.flat()
WebLK.prototype.focus = function (at, advance) {
// Aggregate splitted information
// Precondition:
// at -- code of first element to be collected
// advance -- code of last element to be collected
// Postcondition:
// Returns Array [old length,
// replacement string,
// replace it]
// Uses:
// > .o.Weblink::
// > .mode
// > .lazy
// > .points
// > .joinShow
// .facet()
// > .o.WikiTom.LinkWeb
// 2013-05-26 PerfektesChaos@de.wikipedia
var e, i, s,
l = (this.mode !== WSTM.o.WikiTom.LinkWeb),
m = l,
n = 0;
if (this.lazy) {
for (i = at; i <= advance; i++) {
e = this.points[ i ];
n += e[0];
} // for i
s = false;
} else {
s = this.facet(at, advance);
for (i = at; i <= advance; i++) {
e = this.points[ i ];
n += e[0];
l = (l || e[2]);
} // for i
if (at === WebLK.joinShow && this.points[ at ][1] && ! m) {
s = " " + s;
}
}
return [n, s, l];
}; // .o.Weblink.focus()
WebLK.prototype.format = function (anode, access, around, arg) {
// Initialize existing weblink object with node
// Precondition:
// anode -- parent node WikiTom object
// access -- location object
// .i start of "://" or "[" in .j
// .j start of interesting region in .k
// .k sibling number of location
// around -- number of known leading brackets '[' (0, 1)
// arg -- template parameter on unbracket link
// Postcondition:
// Returns position object to continue search
// .i string position in entire node
// .k node number
// .o.Weblink object was set, has been analyzed and reformatted
// WikiTom nodes in basic text have been updated
// Uses:
// WikiTom().toString()
// > .o.Weblink::
// > .joinSuffix
// > .joinScheme
// >< .move
// < .off
// < .node
// < .index
// < .join
// < .multiple
// < .limited
// < .leaf
// < .mode
// < .keep
// < .lazy
// < .moving
// < .shift
// < .shower
// < .points
// .fire()
// .facet()
// > .o.WikiTom.LinkWeb
// 2013-05-02 PerfektesChaos@de.wikipedia
var i, r;
this.move = 0;
this.off = anode;
this.node = access.k;
this.index = access.i;
this.join = access.j;
this.multiple = around;
this.limited = (around > 0);
this.leaf = arg;
this.mode = WSTM.o.WikiTom.LinkWeb;
this.keep = -1;
this.lazy = true;
this.moving = 0;
this.shift = false;
this.shower = false;
for (i = 0; i <= WebLK.joinSuffix; i++) {
this.points[ i ] = [0, false, false];
} // for i
this.fire();
r = { k: this.node + this.moving };
if (this.moving) {
r.i = 0;
} else {
r.i = this.join + this.index;
this.index = r.i;
if (this.keep > 0) {
r.i += this.keep - 1;
} else if (this.move < 0) {
r.i += this.move;
} else if (this.limited) {
r.i += 9;
} else {
r.i += 2 + this.facet(WebLK.joinScheme).length;
}
}
return r;
}; // .o.Weblink.format()
WebLK.prototype.forward = function () {
// Modify source text
// Uses:
// > .o.Weblink::
// > .joinProlog
// > .joinLBrack
// > .off
// > .node
// > .join
// > .shift
// > .joinScheme
// > .joinSelect
// > .mode
// > .joinShow
// > .joinSuffix
// < .index
// < .keep
// .focus()
// > .o.WikiTom()::
// .flip()
// 2013-05-26 PerfektesChaos@de.wikipedia
var got = this.focus(WebLK.joinProlog, WebLK.joinLBrack);
this.index = got[0];
if (got[2]) {
this.off.flip(this.node, this.join, this.index, got[1]);
this.index = got[1].length;
}
got = this.focus(WebLK.joinScheme, WebLK.joinSelect);
if (typeof(this.shift) === "string") {
got[1] = this.shift;
got[2] = true;
}
if (got[2]) {
this.keep = got[1].length;
this.off.flip(this.node,
this.join + this.index,
got[0],
got[1]);
} else {
this.keep = got[0];
}
got = this.focus(WebLK.joinShow, WebLK.joinSuffix);
if (got[2]) {
this.off.flip(this.node,
this.join + this.index + this.keep,
got[0],
got[1]);
}
if (this.mode !== WSTM.o.WikiTom.LinkWeb) {
this.keep = -1;
}
}; // .o.Weblink.forward()
WebLK.prototype.freeze = function (advanced) {
// Freeze link target as recently formatted
// Uses:
// > .o.Weblink::
// > .keep
// > .node
// > .index
// > .off
// < .mode
// < .lookup
// > .o.WikiTom.folder()
// 2013-03-15 PerfektesChaos@de.wikipedia
var url,
r = advanced;
if (this.keep > 0) {
url = this.off.folder(this.index,
this.node,
this.index + this.keep,
this.node);
if (url) {
url.mode = WSTM.o.WikiTom.LinkWeb;
url.lookup = false;
r = { i: 0,
k: this.node + (this.index ? 2 : 1) };
}
}
return r;
}; // .o.Weblink.freeze()
WebLK.prototype.frozen = function () {
// Skip nowiki/comment WTOM within link title
// Postcondition:
// Returns true if closing bracket found after WTOM
// Uses:
// > .o.Weblink::
// > .moving
// > .node
// > .off
// > .maxTitle
// > .o.WikiTom.TextOnly
// .o.WikiTom().focus()
// .o.WikiTom().fetch()
// 2013-09-12 PerfektesChaos@de.wikipedia
var i, other, s,
r = false;
if (! this.moving) {
other = this.off.focus(this.node + 1);
if (other) {
if (other.mode > WSTM.o.WikiTom.TextOnly) {
other = this.off.focus(this.node + 2);
if (other) {
if (other.mode <= WSTM.o.WikiTom.TextOnly) {
s = this.off.fetch(this.node + 2, 0, false);
i = s.indexOf("\n");
if (i >= 0) {
s = s.substr(0, i);
}
i = s.indexOf("]");
if (i >= 0) {
if (i < WebLK.maxTitle) {
s = s.substr(0, i);
r = (s.indexOf("[") < 0);
}
}
}
}
}
}
}
return r;
}; // .o.Weblink.frozen()
WebLK.prototype.friend = function () {
// Check whether detected URL can be converted into wikilink
// Uses:
// > .o.Weblink::
// > .joinScheme
// > .joinSite
// > .joinSelect
// > .joinShow
// > .joinSuffix
// > .limited
// > .index
// >< .url2w
// >< .move
// < .mode
// < .shift
// .facet()
// .fetch()
// .fit()
// >< .o.URL2wiki()
// .set()
// .getMode()
// .getRemoveTo()
// .getTextReplace()
// .getTarget()
// .getTitle()
// .getURL()
// > .mod.wikilink
// > .o.WikiTom.LinkWiki
// .errors.found()
// 2013-12-14 PerfektesChaos@de.wikipedia
var t, u2w, x;
if (! this.url2w) {
this.url2w = new WSTM.o.URL2wiki();
}
u2w = this.url2w;
this.url2w.set({ multiple: this.multiple,
scheme: this.facet(WebLK.joinScheme),
site: this.facet(WebLK.joinSite),
slashed: this.facet(WebLK.joinSelect),
show: this.facet(WebLK.joinShow),
suffix: this.facet(WebLK.joinSuffix)
},
false);
switch (this.url2w.getMode()) {
case 1 :
this.fetch(this.url2w.getTextReplace(), true);
break;
case 2 :
if (this.limited) {
this.mode = WSTM.o.WikiTom.LinkWiki;
this.fetch(false, true);
x = this.url2w.getTarget();
this.fit(WebLK.joinSelect, x, true);
t = u2w.getTitle();
if (t && t !== x) {
this.fit(WebLK.joinShow, t + "]", true);
x = this.url2w.getSuffix();
if (x) {
this.fit(WebLK.joinSuffix, x, true);
}
this.shift = "|";
} else if (t === "") {
this.shift = true;
} else {
this.shift = "]";
}
if (this.shift === true) {
this.shift = "[" + x + "]";
this.fit(WebLK.joinShow, "", true);
this.move = (this.index ? -1 : 0);
} else {
this.shift = "[" + this.facet(WebLK.joinSelect)
+ this.shift;
this.move = (this.index ? -2 : 0);
}
} else {
WSTM.errors.found("wikilinkURL",
false,
u2w.getURL()
+ String.fromCharCode(10, 8658, 10)
+ "[[" + u2w.getTarget() + "]]");
}
break;
} // switch .url2w.get()
}; // .o.Weblink.friend()
WebLK.prototype.further = function () {
// Skip over node
// Postcondition:
// Returns number < 0 iff ']' not found
// Uses:
// > .o.Weblink::
// > .node
// > .off
// > .maxTitle
// < .moving
// < .shower
// .facet()
// > .o.WikiTom.TextOnly
// .o.WikiTom().focus()
// .o.WikiTom().fetch()
// .errors.found()
// 2013-03-15 PerfektesChaos@de.wikipedia
var got, m, s,
past = this.off.focus(this.node + 1),
r = -2;
if (past) {
m = past.mode;
if (m > WSTM.o.WikiTom.TextOnly) {
past = this.off.focus(this.node + 2);
this.moving = 2;
if (past) {
m = past.mode;
if (m > WSTM.o.WikiTom.TextOnly) {
this.moving = 3;
}
}
if (m < WSTM.o.WikiTom.TextOnly) {
s = this.off.fetch(this.node + this.moving, 0, false);
r = s.indexOf("]");
if (r >= 0 && r < this.maxTitle) {
if (r) {
this.shower = s.substr(0, r);
s = "\f" + this.shower + "\f";
got = /\f([^<\n]*)\f/.exec(s);
if (got) {
if (this.shower.indexOf("[") >= 0) {
this.shower = false;
}
} else {
this.shower = false;
}
} else {
this.shower = "";
}
}
}
}
}
if (this.shower === false) {
WSTM.errors.found("weblinkBracketRight",
false,
"["
+ this.facet(this.joinScheme,
this.joinSelect));
}
return r;
}; // .o.Weblink.further()
}; // .bb.Weblink()
mw.libs.WikiSyntaxTextMod.bb.Weblink(mw.libs.WikiSyntaxTextMod);
delete mw.libs.WikiSyntaxTextMod.bb.Weblink;
//-----------------------------------------------------------------------
mw.libs.WikiSyntaxTextMod.bb.Wikilink = function (WSTM) {
// Administration of wikilinks
// 2012-10-01 PerfektesChaos@de.wikipedia
// Class:
// Public:
// getChange()
// getError()
// getIncrement()
// getRemoveFrom()
// getRemoveTo()
// getSortkey()
// getTargetLength()
// getTextReplace()
// getType()
// getUserModified()
// set()
// setTarget()
// Private:
// adjust()
// analyze()
// capitalize()
// category()
// closingBracket()
// extend()
// file()
// language()
// lineFeedAhead()
// magic()
// magic_ISBN()
// namespace()
// newline()
// old2New()
// pipeSymbols()
// project()
// specials() // -> special()
// target()
// title()
// unlink()
// url()
// init()
// .label true: pipe trick completion
// .lapsus true: syntax error detected
// .last true: pipe at end of parameter list
// .lead true: target starts with ":"
// .leader true: first item in category or interlanguage sequence
// .leap true: leading whitespace
// .learn true: link modified by user replacement
// .lfAhead true: line feed present before link
// .lift true: left brackets shifted
// .limited true: enclosed in brackets (single bracket termination)
// .lack true: single "[" heading
// .lock true: freeze wikilink targets
// .index number: position of "[[" in .source
// .inPipe number: of chars in analyze until pipe symbol, or false
// .inTerm number: of chars in analyze until terminating bracket
// .join number: relative position of "[["
// .justify number: default lang for project link
// .keySort number: of chars to be unconditionally locked as sort key
// .mode number: interwiki, category, media (file) etc.
// .move number: incrementation on global search
// .newFrom number: of chars in .source for replacement region start
// .newTo number: of chars in .source for replacement region end
// .next number: of chars in .suffix to be added, or all
// .node number: of .onto within .off
// .nucleus number: of target chars to be locked
// .off WikiTom with <includeonly> spans, or false
// .onto current WikiTom node
// .score wikilink target
// .sequence media parameters
// .sister 'project:', if any
// .shift replacement string (total)
// .show non-empty title string
// .slang 'language:', if any
// .source wikitext including "[[" at .index
// .special category or interwiki content // -> schedule
// .start replacement string (preceeding)
// .subcase downcased wgTitle
// .suffix aftermath
"use strict";
var WikiLK;
WSTM.o.Wikilink = function () {
// .constructor for new
// Postcondition:
// Returns .o.Wikilink object
// Uses:
// > .g.wTitle
// < .o.Wikilink.subcase
// .o.Wikilink.init()
// .hooks.fire()
// .str.deCapitalize()
// 2016-08-17 PerfektesChaos@de.wikipedia
var p;
this.init();
this.index = false;
this.lock = false;
this.move = false;
this.newFrom = false;
this.node = false;
this.off = false;
this.onto = false;
this.source = false;
// this.lfAhead = false;
if (WSTM.hooks.fire("capitalize1")) {
this.subcase = WSTM.str.deCapitalize(WSTM.g.wTitle);
} else {
this.subcase = WSTM.g.wTitle;
}
for (p in WSTM.o.Wikilink) {
this[ p ] = WSTM.o.Wikilink[ p ];
} // for p in
return this;
}; // .o.Wikilink() .constructor
WikiLK = WSTM.o.Wikilink;
// Definition of constants
// 2012-10-24 PerfektesChaos@de.wikipedia
WikiLK.ModeNull = -9;
WikiLK.ModeWeb = -7;
WikiLK.ModeWiki = 91;
WikiLK.ModeIw = 93;
WikiLK.ModeFile = 6;
WikiLK.ModeCat = 14;
WikiLK.ModeMap = -5; // special weblink ([[DOI:...]] etc.)
// 6 special interwikilink ([[bugzilla:...]] etc.)
// 7 page
WikiLK.prototype.init = function () {
// Initialize existing wikilink object
// Postcondition:
// .o.Wikilink object has been reset
// Uses:
// > .o.Wikilink::
// > .***
// 2015-12-20 PerfektesChaos@de.wikipedia
this.label = false;
this.lapsus = false;
this.last = false;
this.lead = false;
this.leader = false;
this.leap = false;
this.learn = false;
this.lift = false;
this.limited = false;
this.lock = false;
this.inPipe = false;
this.inTerm = false;
this.join = false;
this.justify = false;
this.keySort = false;
this.mode = false;
this.move = false;
this.newFrom = false;
this.newTo = false;
this.next = false;
this.node = false;
this.nucleus = false;
this.off = false;
this.onto = false;
this.score = false;
this.sequence = false;
this.shift = false;
this.show = false;
this.sister = false;
this.slang = false;
this.special = false;
this.start = false;
this.suffix = false;
}; // .o.Wikilink.init()
WikiLK.prototype.adjust = function (analyze) {
// Analyze entire link syntax, divide into major parts
// Precondition:
// analyze -- string with link content beginning with '[['
// Uses:
// > .w.link.namespace.nsFile
// > .o.Wikilink::
// > .ModeFile
// > .ModeMap
// > .show
// < .lack
// < .mode
// < .limited
// < .join
// < .inTerm
// < .inPipe
// < .lapsus
// < .move
// < .leap
// < .suffix
// < .score
// < .lift
// .file()
// .extend()
// .newline()
// .url()
// .closingBracket()
// .pipeSymbols()
// .analyze()
// < .mod.lazy
// .w.link.namespace.furnish()
// .w.link.wiki.iwMap()
// .str.trim()
// .errors.found()
// .str.isBlank()
// Requires: JavaScript 1.3 charCodeAt()
// 2016-02-05 PerfektesChaos@de.wikipedia
var s = analyze.substr(2),
inside = 2,
join = s.indexOf("\n\n"),
lack = (analyze.substr(0, 2) !== "[["),
later = false,
c,
e,
newl,
mid,
shift,
start,
swap;
if (join > 0) {
s = s.substr(0, join);
} // paragraph found
join = s.indexOf(":");
if (join > 1) {
if (WSTM.w.link.namespace.furnish(s.substr(0, join),
false,
false) ===
WSTM.w.link.namespace.nsFile) {
this.mode = this.ModeFile; // (not Media:)
if (this.file(analyze.substr(2), join + 1)) {
s = "";
}
join = s.indexOf("\n");
if (join > 0) {
s = s.substr(0, join);
} // EOL -- image description might contain strange things
} else {
start = s.substr(0, join);
if ( start.indexOf("[[") < 0 ) {
swap = WSTM.w.link.wiki.iwMap(start);
if (swap) {
this.mode = this.ModeMap;
later = (swap !== start);
if (later) {
start = swap;
s = start + s.substr(join);
} // adjust
swap = s.substr(join + 1);
mid = swap.indexOf("]]");
if (mid > 0) {
swap = swap.substr(0, mid);
shift = WSTM.str.trim(swap, true);
if (swap !== shift) {
later = swap.length - shift.length;
s = start + ":" + shift
+ s.substr(start.length + 1 + mid);
}
if (typeof(WSTM.util[ start ]) === "object") {
e = WSTM.util[ start ];
if (typeof(e.failure) === "function") {
swap = s.substr(start.length + 1);
swap = swap.substr(0, swap.indexOf("]]"));
e = e.failure(swap);
switch (typeof e) {
case "string" : // simple correction
mid = start.length + 1 + swap.length;
s = WSTM.str.makeString(32,
swap.length - e.length)
+ start + ":" + e
+ s.substr(mid);
break;
case "object" : // severe
WSTM.errors.found("badURI", true, e[1]);
break;
} // switch typeof e
}
}
if (typeof(later) === "number") {
s = WSTM.str.makeString(32, later) + s;
}
}
} // interwiki mapping
} // interwiki mapping
}
} // may be prefixed
join = s.indexOf("]") + 2;
this.limited = (join > 1);
if (this.limited) { // first terminating bracket found
inside = s.indexOf("[") + 2;
if (inside > 1) {
if (inside < join) {
if (this.mode !== this.ModeFile &&
inside === 2) { // triple bracket, or even more
c = s.charCodeAt(0);
this.join = 0;
this.newTo = join;
this.extend(32);
while (WSTM.str.isBlank(c, false)
|| c === 91) { // [
s = s.substr(1);
c = s.charCodeAt(0);
this.join++;
join--;
} // while
WSTM.mod.lazy = false;
WSTM.errors.found("tooManyLeftBrackets",
true,
analyze.substr(0, 100));
} else { // got opening bracket inside, could be File:
join = inside;
s = s.substr(0, join - 2);
this.limited = false;
}
}
}
this.inTerm = join;
}
if (s) {
newl = s.indexOf("\n") + 2;
mid = s.indexOf("|") + 2;
if (! this.limited) {
if (this.mode === this.ModeFile) {
join = s.length; // "]]"
} else {
this.extend(-1);
if (newl > 1) {
s = s.substr(0, newl - 1);
}
if (mid > 1) {
s = s.substr(0, mid);
}
if (s.length && mid < 1) { // not folded
WSTM.errors.found("wikilinkBracketsAhead",
false,
mid +
"[[" + s.substr(0, 100));
}
s = false;
}
}
}
if (s) {
if (mid > 1) {
if (mid < join) {
this.inPipe = mid;
}
}
if (newl > 1) {
if (this.limited) {
if (newl < this.inTerm) {
s = this.newline(s, newl);
newl = false;
} // newline within bracket pair
}
if (newl) {
s = s.substr(0, newl - 2);
if (mid > newl) {
this.inPipe = false;
}
}
}
}
if (s) {
while (WSTM.str.isBlank(s.charCodeAt(0), false)) {
s = s.substr(1);
join--;
if (this.inPipe) {
mid--;
}
this.extend(1);
this.leap = true;
} // while ltrim
if (join === 2) { // "[[\n"
WSTM.errors.found("linkTargetMissing",
true,
analyze.substr(0, 100));
this.extend(-1);
s = false;
} else if (s.charCodeAt(0) === 93) { // ']' // [[]
this.extend(-1);
s = false;
} else if (this.limited) { // at least single brackets
if (s.length >= join) {
this.suffix = s.substr(join - 1);
s = s.substr(0, join - 2);
}
if (this.url(s)) {
s = false;
}
} // not empty
}
if (s) { // neither URL nor empty
if (later) {
this.extend(1);
}
this.closingBracket(s);
if (this.score) {
if (this.inPipe) {
this.pipeSymbols(mid - 2);
if (lack || this.lack) {
s = analyze.substr(0, 1);
if (this.start) {
this.start = this.start + s;
} else {
this.start = s;
}
this.extend(32, 0);
this.join++;
this.lift = true;
}
}
if (this.score || this.show) {
this.analyze();
} else if (this.score) { // ??? impossible ! this.score
this.extend(-1);
}
} // local
}
}; // .o.Wikilink.adjust()
WikiLK.prototype.analyze = function () {
// Analyze bracket content fractions and aftermath
// Precondition:
// Fractions .score, .show, .suffix are defined.
// Uses:
// > .o.Wikilink::
// > .ModeMap
// > .mode
// > .lead
// > .inPipe
// > .newFrom
// > .newTo
// > .start
// > .index
// > .ModeWiki
// > .lack
// > .next
// >< .score
// >< .show
// >< .suffix
// >< .nucleus
// >< .leap
// < .label
// < .lock
// < .shift
// < .move
// .target()
// .title()
// .unlink()
// .context()
// .magic()
// .extend()
// .lineFeedAhead()
// .str.substrEnd()
// .w.link.wiki.fore()
// .str.isLetter()
// Requires: JavaScript 1.3 charCodeAt()
// 2013-03-06 PerfektesChaos@de.wikipedia
var c,
linking,
n,
s;
if (this.score) {
if (this.mode !== this.ModeMap) { // not Interwiki mapping
this.target();
}
if (! this.mode) { // not Category:
if (! this.lead) {
this.unlink();
}
this.label = (this.inPipe && ! this.show);
if (this.label) {
this.show = this.context();
this.extend(2);
} // context style [[title (Abc)|]]
}
}
if (! this.mode) { // magic?
this.magic();
if (this.show) {
this.title();
}
}
if (this.lock) {
if (this.newFrom === 2 && ! this.nucleus) {
n = this.score.length;
if (n > 0) {
this.nucleus = n;
}
}
}
if (this.leap) {
if (this.start) {
c = WSTM.str.substrEnd(this.start, 1);
} else if (this.index > 0) {
c = this.source.substr(this.index - 1, 1);
} else {
c = false;
n = 10;
}
if (c) {
n = c.charCodeAt(0);
}
if (n === 10 || n === 32) {
this.leap = false;
} else {
this.extend(32);
this.move++;
}
}
if (! this.mode) {
if (this.show) { // titled
if (WSTM.str.isLetter(WSTM.str.substrEnd(this.show, 1))) {
// c'td?
n = WSTM.w.link.wiki.fore(this.suffix, 0);
if (n) {
this.show = this.show + this.suffix.substr(0, n);
this.extend(16, n);
if (n < this.suffix.length) {
// TODO 2013-03-06 (n > this.suffix.length) IMPOSSIBLE. Bug!
this.suffix = this.suffix.substr(n);
} else {
this.suffix = false;
}
}
} // isLetter
if (typeof(this.newTo) === "number") {
if (this.newTo >= this.inTerm) {
if (typeof(this.score) === "string") {
this.score = this.score + "|" + this.show;
this.show = false;
}
}
}
} // titled
if (this.newFrom === 2) {
this.mode = this.ModeWiki;
}
}
this.lineFeedAhead();
if (typeof(this.newTo) === "number") {
this.join = (typeof(this.join) === "number" ? this.join
: 0);
if (this.newTo > this.join) {
if (typeof(this.shift) === "boolean") {
this.shift = (this.score ? this.score : "");
}
}
if (this.newFrom <= 0) {
linking = (typeof(this.score) === "string")
&& this.newTo > this.join;
if (linking) {
if (typeof(this.start) === "string") {
if (WSTM.str.substrEnd(this.start, 2) === "[[") {
linking = this.leap;
}
}
}
this.shift = (this.leap ? " " : "")
+ (linking ? "[[" : "")
+ (this.shift ? this.shift : "");
}
if (this.start && this.newFrom <= 0) {
this.shift = this.start + (this.shift ? this.shift : "");
}
n = this.join + this.inTerm + (this.lack ? 1 : 2);
if (this.newTo >= n) {
if (this.score && this.mode !== this.ModeFile) {
this.shift = (this.shift ? this.shift : "") + "]]";
}
if (this.suffix && this.next) {
s = this.suffix;
if (typeof(this.next) === "number") {
s = s.substr(0, this.next);
}
this.shift = (this.shift ? this.shift : "") + s;
} // suffix
} // newTo
}
if (this.score) {
n = this.score.length;
if (n > this.move) {
this.move = n;
}
}
}; // .o.Wikilink.analyze()
WikiLK.prototype.capitalize = function () {
// Capitalize wikilink if appropriate
// Precondition:
// address -- string with link target
// Uses:
// > .o.Wikilink::
// > .sister
// > .show
// >< .score
// .extend()
// .hooks.fire()
// 2012-09-27 PerfektesChaos@de.wikipedia
var low2up,
s,
start = this.score.substr(0, 1),
swap = start.toUpperCase();
if (start !== swap) { // 1st letter downcased
low2up = true;
if (this.sister) {
s = this.sister.substr(0, 5) + ":";
low2up = (s.substr(0, 5) !== "wikt:");
} // no upcasing in Wiktionary
if (low2up) {
low2up = WSTM.hooks.fire("wikilink_lower1",
[ this.score, this.show ]);
} // upcasing appropriate
if (low2up) {
this.score = swap + this.score.substr(1);
this.extend(1);
} // upcase
} // 1st letter downcased
}; // .o.Wikilink.capitalize()
WikiLK.prototype.category = function () {
// Handle category of page
// Uses:
// > .w.encountered.DEFAULTSORT
// > .g.wTitle
// > .g.wNsNumber
// > .o.WikiTom.LinkCategory
// > .o.Wikilink::
// > .sister
// > .label
// > .ModeCat
// >< .score
// >< .show
// >< .inPipe
// < .lock
// < .keySort
// < .mode
// < .special // -> schedule
// < .leader
// .extend()
// .w.elem.sortkey()
// .hooks()
// .w.link.wiki.further()
// 2016-01-23 PerfektesChaos@de.wikipedia
var s = this.score.substr(0, 1),
leave;
if (s.toUpperCase() !== s) {
this.score = s.toUpperCase() + this.score.substr(1);
this.extend(1);
}
if (! this.sister) { // [[Category: ]]
if (this.inPipe) { // [[Category: | ]]
if (this.show) {
s = WSTM.w.elem.sortkey(this.show);
if (typeof(s) === "string") {
if (! s.length) {
this.show = false;
} else {
this.show = s;
}
this.extend(2);
}
if (this.label) {
this.show = false;
} else {
if (WSTM.w.encountered.DEFAULTSORT) {
if (WSTM.hooks.fire("sortkey_ignorecase")) {
leave = (this.show.toUpperCase() ===
WSTM.w.encountered.DEFAULTSORT
.toUpperCase());
} else {
leave = (this.show ===
WSTM.w.encountered.DEFAULTSORT);
}
} else if (WSTM.g.wNsNumber === 0) {
if (WSTM.hooks.fire("sortkey_ignorecase")) {
leave = (this.show.toUpperCase() ===
WSTM.g.wTitle.toUpperCase());
} else {
leave = (this.show === WSTM.g.wTitle);
}
}
if (leave) {
this.show = false;
this.extend(2);
}
} // not possibly erroneous "|]]"
} // non-empty sortkey
if (this.show) { // non-empty sortkey
if (WSTM.str.substrEnd(this.show, 1) === "|") {
this.show = this.show.substr(0,
this.show.length - 1);
}
if (this.lock) {
this.keySort = this.show.length;
}
this.score = this.score + "|" + this.show;
this.show = false;
this.extend(2);
this.inPipe = false;
} else { // empty/emptied sortkey
this.extend(1);
} // sortkey
} // pipe symbol
this.mode = this.ModeCat;
this.special = this.score;
this.leader = WSTM.w.link.wiki.further(
{ mode: WSTM.o.WikiTom.LinkCategory,
source: this.score } );
if ( ! this.lead
&& typeof WSTM.lang.write === "object" ) {
this.lead = WSTM.lang.write.lead;
}
} // ! sister
}; // .o.Wikilink.category()
WikiLK.prototype.closingBracket = function (adjust) {
// Check or complete link content for second closing bracket
// Precondition:
// adjust -- string with link inner content
// Neither URL nor empty
// Postcondition:
// this.score defined if appropriate
// Uses:
// > .o.Wikilink::
// > .ModeFile
// >< .suffix
// >< .mode
// >< .lapsus
// < .score
// .extend()
// .errors.found()
// Requires: JavaScript 1.3 charCodeAt()
// 2013-01-22 PerfektesChaos@de.wikipedia
var less = true,
n;
if (this.suffix) {
if (this.suffix.charCodeAt(0) === 93) { // ']'
this.score = adjust;
if (this.suffix.length < 2) {
this.suffix = false;
} else {
this.suffix = this.suffix.substr(1);
if (this.suffix.charCodeAt(0) === 93
&&false) { // ']' ////////////////////////////////
n = this.suffix.length;
this.lapsus = true;
this.suffix = this.suffix.substr(1);
this.extend(16, 3);
if (this.suffix.charCodeAt(0) === 93) { // ']'
this.suffix = this.suffix.substr(1);
this.extend(16, 4);
}
WSTM.errors.found("tooManyRightBrackets",
true,
"[[" + this.score + "]]]");
}
}
less = false;
}
}
if (less) {
if (this.mode === this.ModeFile) {
this.score = adjust;
} else {
WSTM.errors.found("secondClosingBracket", true, adjust);
if (this.lapsus) {
this.extend(-1);
} else { // append ']'
this.score = adjust + "]";
this.extend(9);
this.lapsus = true;
}
}
}
}; // .o.Wikilink.closingBracket()
WikiLK.prototype.context = function () {
// Retrieve context title for [[fool:bar (Abc)|]]
// Postcondition:
// Returns link title
// RegExp was used.
// Uses:
// > .o.Wikilink::
// > .score
// > .sister
// >< .rePipeTrick
// >< .reSpace
// > .g.wNsIds
// .g.fetch()
// .str.trimL()
// Requires: JavaScript 1.3 fromCharCode()
// Info: "Pipe trick"
// * Strip off and use as title
// ** anything looking like a namespace -- [[CSI: Miami|]]
// ** bracketed suffix.
// ** comma ',' does not matter.
// 2013-03-08 PerfektesChaos@de.wikipedia
var got,
r,
sB = "(" + String.fromCharCode(65288),
sE = ")" + String.fromCharCode(65289),
// FF08 FF09 FULLWIDTH PARENTHESIS
re = sB + sE;
re = "([^" + re + "]*[^ " + re + "]) *"
+ "[" + sB + "].+[" + sE + "]";
re = new RegExp(re, "");
if (! this.rePipeTrick) {
sB = "(" + String.fromCharCode(65288);
sE = ")" + String.fromCharCode(65289);
// FF08 FF09 FULLWIDTH PARENTHESIS
this.rePipeTrick = sB + sE;
this.rePipeTrick = "([^" + this.rePipeTrick + "]*"
+ "[^ " + this.rePipeTrick + "]) *"
+ "([" + sB + "].+[" + sE + "])$";
this.rePipeTrick = new RegExp(this.rePipeTrick, "");
}
got = this.rePipeTrick.exec(this.score);
r = (got ? got[1] : this.score);
got = r.indexOf(":", 1);
if (got > 0) {
if (this.sister) {
r = r.substr(this.sister.length);
got = r.indexOf(":");
}
}
if (got) {
if (WSTM.g.fetch(WSTM.g.wNsIds, "wgNamespaceIds")) {
if (! this.reSpace) {
this.reSpace = new RegExp(" +", "g");
}
sB = r.substr(0, got).toLowerCase();
sB = sB.replace(this.reSpace, "_");
if (! WSTM.g.wNsIds[ sB ]) {
got = 0;
}
}
if (got) {
r = WSTM.str.trimL(r.substr(got + 1), true, false);
}
}
return r;
}; // .o.Wikilink.context()
WikiLK.prototype.extend = function (assign, around) {
// Extend replacement region
// Precondition:
// assign -- kind of extension
// -1 -- no extension
// 1 -- target region (beginning at 2)
// 2 -- title region
// 3 -- end of both target and title
// 4 -- begin at 0, not at 2
// 8 -- end after first terminating bracket
// 9 -- second terminating bracket appended
// 16 -- append afterward characters
// 32 -- begin and terminate at least at 0
// around -- position extending outside brackets
// assign=16 after second bracket
// assign=32 before first bracket
// Uses:
// > .o.Wikilink::
// > .inPipe
// > .inTerm
// >< .newFrom
// >< .newTo
// 2013-01-22 PerfektesChaos@de.wikipedia
var n;
switch (assign) {
case -1 :
this.newFrom = 2;
this.newTo = false;
break;
case 1 :
case 2 :
case 3 :
case 8 :
case 9 :
case 16 :
switch (assign) {
case 1 :
n = (this.inPipe ? this.inPipe : this.inTerm);
break;
case 2 :
case 3 :
n = this.inTerm;
break;
case 8 :
n = this.inTerm + 1;
break;
case 9 :
n = this.inTerm;
break;
case 16 :
n = this.inTerm + 2;
if (around) {
n += around;
}
break;
} // switch assign
if (typeof(this.newTo) === "number") {
if (n > this.newTo) {
this.newTo = n;
}
} else {
this.newTo = n;
}
break;
case 4 :
if (this.newFrom > 0) {
this.newFrom = 0;
}
break;
case 32 :
if (this.newFrom > 0) {
this.newFrom = 0;
}
if (around) {
this.newFrom -= around;
}
if (typeof(this.newTo) !== "number") {
this.newTo = 0;
}
break;
} // switch assign
}; // .o.Wikilink.extend()
WikiLK.prototype.file = function (analyze, ahead) {
// Analyze Media embedding in File: namespace
// Precondition:
// analyze -- string with link content beginning after '[['
// ahead -- position after ':' of namespace
// Postcondition:
// Returns found object, or false
// Uses:
// > .o.Wikilink::
// > .off
// > .index
// > .node
// > .ModeFile
// < .mode
// .o.WikiTom().find()
// 2015-11-02 PerfektesChaos@de.wikipedia
var r = this.off.find("]]",
this.index + 2,
this.node,
true,
false,
false);
if (r) {
if (r.k === this.node) {
this.filer(analyze, ahead, r.i, true);
} else {
this.filer(analyze,
ahead,
analyze.length + 1,
false);
}
}
return r;
}; // .o.Wikilink.file()
WikiLK.prototype.filer = function (analyze, ahead, after, all) {
// Analyze leading section of Media embedding in File: namespace
// Precondition:
// analyze -- string with embedding start beginning after '[['
// truncated if links, templates, comments inside
// ahead -- position after ':' of namespace
// after -- position of termination in analyze (before ']]')
// all -- full caption seems to be present
// Uses:
// > .o.Wikilink::
// > .index
// > .node
// > .ModeFile
// >< .newTo
// < .limited
// < .mode
// < .inTerm
// < .inPipe
// < .score
// < .last
// < .sequence
// .filing()
// .str.trim()
// .target()
// .extend()
// > .w.link.namespace.nsFile
// .str.trim()
// .w.link.namespace.fetch()
// .mod.wikilink()
// .w.img.format()
// .str.substrEnd()
// 2017-09-13 PerfektesChaos@de.wikipedia
var inside = false,
leap = false,
loose = false,
s = analyze.substr(ahead),
slice = false,
join = s.indexOf("|"),
n;
this.limited = true;
this.mode = this.ModeFile; // (not Media: nor :File:)
this.inTerm = (all ? after - this.index - 2 : after);
if (join > 2) {
if (s.substr(0,join).indexOf("]]") < 0) {
if ((/\|\s*$/.test(s)) && s.indexOf("|") < 0) {
this.last = true;
}
this.inPipe = join;
} else {
join = -2;
this.inPipe = false;
n = s.indexOf("\n{|");
if (n >= 0) {
s = s.substr(0, n);
}
}
}
if (join > 2) {
if (join + ahead < after) {
this.inPipe = join + ahead;
this.score = s.substr(0, join);
slice = s.substr(join + 1);
n = slice.indexOf("\n{|"); // /\n:*{|/
if (n >= 0) {
slice = slice.substr(0, n);
}
inside = slice.indexOf("[[");
loose = (slice.indexOf("]]") < 0 && /\s$/.test(slice));
slice = slice.substr(0, this.inTerm - this.inPipe - 1);
if (inside < 0 && n >= 0) {
inside = n;
}
if (inside >= 0 &&
ahead + join + inside <= this.inTerm) {
slice = this.filing(ahead + join + 3);
if (slice) {
this.inTerm = this.inPipe + slice.length + 2;
if (/\s$/.test(slice)) {
loose = true;
}
leap = true;
} else {
this.inPipe = false;
}
} else if (all) {
this.last = true;
}
}
}
if ( ! this.inPipe) {
this.score = s.substr(0, this.inTerm - ahead);
}
this.target();// TODO Ensure capitalization CamelCase Media title
n = this.score.length;
this.score = WSTM.str.trim(this.score);
if (n !== this.score.length) {
n = this.score.length - n;
if ( this.inPipe) {
this.inPipe += n;
}
this.inTerm += n;
}
this.score = WSTM.w.link.namespace.fetch(
WSTM.w.link.namespace.nsFile,
false,
false)
+ ":" + this.score;
if (WSTM.mod.wikilink) {// TODO
// WSTM.w.link.replace.flip(WSTM.mod.wikilink,
// this.score,
// false,
// false,
// "File:");
}
n = this.score.length;
if (this.score !== analyze.substr(0, n)) {
this.shift = this.score;
}
if (this.inPipe) {
this.sequence = slice;
slice = WSTM.w.img.format(this);
if (typeof(slice) === "string") {
if ( ! this.shift) {
this.shift = this.score;
}
if (slice.length) {
this.shift = this.shift + "|" + slice
+ (leap ? "|" : "");
this.newTo += ahead - (leap ? 0 : 1);
} else if (this.last) {
this.shift = this.shift + "|";
}
if (loose) {
n = s.length + this.inTerm - this.inPipe + 1;
if (n > this.newTo) {
this.newTo = n;
}
this.shift = this.shift
+ s.substr(this.inTerm - ahead)
+ " ";
}
this.inPipe = false;
}
} else {
if (this.shift) {
this.newTo = this.inTerm + 2;
loose = true;
}
this.inTerm = n;
this.move = n;
}
if (this.shift) {
if (loose) {
this.extend(3);
} else {
this.extend(1);
this.newTo += 2;
}
}
}; // .o.Wikilink.filer()
WikiLK.prototype.filing = function (after) {
// Shift Media title with links inside to the end of transclusion
// Precondition:
// after -- position of pipe in transclusion
// Postcondition:
// Returns string with parameters, or false if nothing to do
// Uses:
// > .o.Wikilink::
// > .source
// > .off
// > .index
// > .node
// < .inPipe
// < .o.WikiTom().learnt
// .o.WikiTom().find()
// .o.WikiTom().flip()
// 2015-10-12 PerfektesChaos@de.wikipedia
var gotE = false,
i = this.index + after,
j = i,
k = this.node,
n = 0,
loop = true,
r = false,
tom = this.off,
// table = tom.find([/\n:*{|/, 0],
// i, k, true, false, false);
table = tom.find("\n{|", i, k, true, false, false),
gotB,
m,
s;
//if (table) {
//mw.log(WSTM.debugging,".o.Wikilink.filing() table",0,table);
//}
do {
gotB = tom.find("[[", j, k, true, false, false);
gotE = tom.find("]]", j, k, true, false, false);
if (table) {
if (table.k < gotE.k ||
(table.k === gotE.k && table.i < gotE.i)) {
gotB = false;
}
}
loop = (gotB && gotE);
if (loop) {
//mw.log(WSTM.debugging,".o.Wikilink.filing() gotB && gotE",0);
if (! n) {
s = tom.fetch(this.node);
if (gotB.k === this.node) {
s = s.substr(0, gotB.i);
}
n = s.lastIndexOf("|");
}
if (gotB.k === gotE.k) {
loop = (gotB.i < gotE.i);
} else {
loop = (gotB.k < gotE.k);
}
if (loop) {
j = gotE.i + 2;
k = gotE.k;
} else {
r = s.substr(i, n - i);
gotE = false;
}
}
} while (loop); // do
//mw.log(WSTM.debugging,".o.Wikilink.filing() +loop",0);
if (gotE) {
//mw.log(WSTM.debugging,".o.Wikilink.filing() gotE",0);
s = tom.fetch(gotE.k);
s = s.substr(0, gotE.i);
m = s.lastIndexOf("|");
if (s.substr(m + 1, 1) === "}") {
m = -1;
}
if (m >= j) {
s = s.substr(m);
j = s.indexOf("[[");
if (j > 0 && gotE.k === this.node) {
n = j;
} else {
tom.flip(gotE.k, m, s.length, "");
tom.flip(this.node, i - 1, 0, s);
n += s.length;
}
}
r = tom.fetch(this.node).substr(i, n - i);
}
return r;
}; // .o.Wikilink.filing()
WikiLK.prototype.language = function (ahead) {
// Analyze wikilink beginning whether it starts with language
// Check language identification, remove wgContentLanguage
// Precondition:
// ahead -- position of ':' in this.score (>0)
// .justify -- behaviour if no explicit "lang" identified
// 1 adjust with wgContentLanguage
// 2 adjust with "en"
// false (else)
// do nothing than trimming and downcasing
// Postcondition:
// Returns true iff language stripped off from this.score
// RegExp was used.
// Uses:
// > .g.projLang
// > .g.projLone
// > .lang.write.linklang
// > .lang.write.lead
// > .o.Wikilink::
// > .mode
// > .ModeFile
// >< .justify
// >< .score
// < .lead
// < .slang
// .extend()
// .str.trimL()
// .lang.flop()
// .str.trimR()
// 2014-10-10 PerfektesChaos@de.wikipedia
var learnt = false,
left = false,
r = false,
s = this.score.substr(0, ahead),
slang = false, // language specification
story; // heading part of article title
s = WSTM.str.trimL(s, false);
if (s.length < ahead) {
learnt = true;
} // trimmed
story = WSTM.lang.flop(s);
if (! story) {
slang = WSTM.str.trimR(s, false).toLowerCase();
if (slang !== s) {
learnt = true;
}
} // matching lang?
if (! slang) {
if (this.justify) {
switch (this.justify) {
case 1 :
slang = false;
learnt = story;
break;
case 2 :
slang = "en";
learnt = true;
break;
} // switch this.justify
left = true;
} else if ( typeof WSTM.lang.write === "object" ) {
if (this.mode !== this.ModeFile) {
slang = WSTM.lang.write.linklang;
this.lead = WSTM.lang.write.lead;
learnt = true;
}
}
}
if (slang === WSTM.g.projLang) {
if (! WSTM.g.projLone) {
slang = false;
learnt = true;
}
}
if (learnt || slang || story) { // language or similar identified
this.score = this.score.substr(ahead + 1);
if (story) {
this.score = story + ":" + this.score;
slang = false;
} else {
this.score = WSTM.str.trimL(this.score, false);
if (left) {
this.score = s + ":" + this.score;
}
}
if (slang) {
this.slang = slang + ":";
r = true;
}
this.extend(1);
this.justify = false;
} else {
if (this.justify) {
if (this.lead) {
this.lead = false;
this.extend(1);
}
}
}
return r;
}; // .o.Wikilink.language()
WikiLK.prototype.lineFeedAhead = function () {
// Ensure that a category or interlanguage starts on a new line
// Uses:
// > .o.Wikilink::
// > .mode
// > .ModeIw
// > .ModeWiki
// > .ModeCat
// > .slang
// > .show
// > .source
// > .index
// >< .start
// >< .move
// .extend()
// .util.isO_639_1() .lang.flop()
// .errors.found()
// .str.isBlank()
// Requires: JavaScript 1.3 charCodeAt()
// 2017-01-30 PerfektesChaos@de.wikipedia
var c, k, s, m;
if (this.mode === this.ModeIw) {
if (this.slang.length === 3) { // like "bd:"
if (WSTM.lang.flop(this.slang.substr(0, 2))) {
this.mode = this.ModeWiki; // downgrade "bd"/"wd"
} // not a language code
} // A2 language code
if (this.mode === this.ModeIw) { // still interlanguage
if (this.show) {
WSTM.errors.found("interlanguageTitled",
false,
this.score + "|" + this.show);
this.show = false;
} // titled
}
} // interlanguage supposed
if (this.mode === this.ModeCat || this.mode === this.ModeIw) {
if (this.start) {
if (this.start >= 3) {
s = this.start;
k = s.length - 3;
c = s.charCodeAt(k);
}
} else {
if (this.index > 0) {
s = this.source;
k = this.index - 1;
c = s.charCodeAt(k);
} else {
c = false;
}
}
if (c && c !== 10) {
m = 0;
while (WSTM.str.isBlank(c, true)) {
m++;
if (! k) {
break; // while
}
k--;
c = s.charCodeAt(k);
}
if (c === 10) {
if (this.start) {
this.start = s.substr(0, k - 2);
} else {
this.start = "";
}
this.extend(32, m);
this.move -= m + 2;
} else {
// TODO 2016-06
if (this.start) {
k = this.start.length - 2;
this.start = this.start.substr(0, k) + "\n";
} else {
this.start = "\n";
}
this.extend(32); // 2017-01-30 (32,1) -> (32)
this.move++;
}
} // no break
} // category or interlanguage
}; // .o.Wikilink.lineFeedAhead()
WikiLK.prototype.magic = function () {
// Analyze wikilink whether it is actually a magic word
// Precondition:
// Neither File nor Category
// Uses:
// > .o.Wikilink::
// > .show
// > .score
// .magic_ISBN()
// 2010-10-01 PerfektesChaos@de.wikipedia
var s = (this.show ? this.score + "|" + this.show
: this.score);
if (s.indexOf("ISBN") >= 0) {
this.magic_ISBN();
}
/*
PMID Nummer min.6
Richtig: PMID 4957203
Falsch: PMID:4957203
Falsch: PubMed 4957203
RFC ISSN DOI gleichrangig Linkziele schützen
*/
}; // .o.Wikilink.magic()
WikiLK.prototype.magic_ISBN = function () {
// Analyze wikilink and context whether it is actually magic ISBN
// Precondition:
// Wikilink contains magic word "ISBN" in some way
// Uses:
// > .g.re.ISBN
// > .o.Wikilink::
// > .suffix
// > .ModeNull
// >< .show
// >< .score
// < .inPipe
// < .mode
// < .shift
// .extend()
// .w.elem.isbn.format()
// .str.substrEnd()
// Requires: JavaScript 1.3 charCodeAt()
// 2015-07-29 PerfektesChaos@de.wikipedia
var found = false,
k,
later,
n,
narrow,
swap;
if (this.show) {
narrow = this.show.length;
swap = ">" + this.show;
if (narrow > 7) {
if (narrow >= 14) {
swap = swap + this.suffix;
} else {
swap = false;
}
}
if (swap) {
swap = swap + "\t";
found = WSTM.g.re.ISBN.exec(swap);
}
if (swap && found && found.index) {
found = false;
}
if (found) {
k = 0;
n = swap.length;
swap = WSTM.w.elem.isbn.format(found);
if (! swap) {
swap = found[0];
} // unchanged
if (WSTM.str.substrEnd(swap, 1) === "\t") {
swap = swap.substr(0, n - 1);
if (narrow <= 7) {
k--;
}
} // end of source
this.shift = swap.substr(1);
if (narrow <= 7) {
k += found[0].length - 5;
} else {
k += 2;
}
this.extend(16, k);
} // |ISBN]] + number
}
if (! (found || this.show)) {
later = (this.score === "ISBN");
if (later) {
swap = "ISBN " + this.suffix;
} else {
swap = this.score;
}
swap = ">" + swap + "\t";
found = WSTM.g.re.ISBN.exec(swap);
if (found && found.index) {
found = false;
}
if (found) {
k = (later ? found[0].length - 6 : 0);
swap = WSTM.w.elem.isbn.format(found);
if (! swap) {
swap = found[0];
} // unchanged
n = swap.length - 1;
if (swap.charCodeAt(n) === 9) { // \t
swap = swap.substr(0, n);
if (later) {
k--;
}
}
this.extend(16, k);
this.shift = swap.substr(1);
} // [[ISBN + number
}
if (found) {
this.extend(4);
this.show = false;
this.score = false;
this.inPipe = false;
this.mode = this.ModeNull;
}
}; // .o.Wikilink.magic_ISBN()
WikiLK.prototype.namespace = function (ahead) {
// Analyze wikilink beginning whether it starts with namespace
// Precondition:
// ahead -- position of ':' in this.score (>0)
// Uses:
// > .o.Wikilink::
// > .sister
// > .slang
// > .lead
// > .inPipe
// >< .score
// >< .show
// < .nucleus
// < .lock
// .extend()
// .category()
// .specials()
// .capitalize()
// > .w.link.namespace.nsCategory
// > .w.link.namespace.nsSpecial
// > .w.link.namespace.nsPage
// .w.link.namespace.furnish()
// .w.link.namespace.fetch()
// .w.link.wiki.decode()
// 2012-10-01 PerfektesChaos@de.wikipedia
var space = this.score.substr(0, ahead),
key = WSTM.w.link.namespace.furnish(space,
this.slang,
this.sister),
s,
swap;
if (key) { // relevant namespace?
s = (this.sister || this.slang ? "en" : false);
this.score = this.score.substr(ahead + 1);
swap = WSTM.w.link.namespace.fetch(key, s, this.score);
if (swap) {
if (space !== swap) {
this.extend(1);
}
space = swap;
}
if (this.lead && ! this.sister) { // :File: or :Category:
this.sister = ":";
this.extend(1);
}
s = WSTM.w.link.wiki.decode(this.score,
true, false, true, true);
if (s) {
this.score = s;
this.extend(1);
}
if (this.lock && ! this.sister && this.show) {
this.nucleus = space.length + 1 + this.score.length;
if (this.nucleus + 2 !== this.inPipe) {
this.extend(1);
}
}
switch (key) {
case WSTM.w.link.namespace.nsCategory :
this.category();
break;
case WSTM.w.link.namespace.nsSpecial :
this.specials();
break;
} // switch key
if (this.score) {
this.capitalize();
this.score = space + ":" + this.score;
}
} // key
}; // .o.Wikilink.namespace()
WikiLK.prototype.newline = function (analyze, address) {
// Repair line break within wikilink, if appropriate
// Precondition:
// analyze -- string with link inner content
// address -- position of '\n' in environment (>1)
// Postcondition:
// Returns repaired analyzed string, or false
// Uses:
// > .o.Wikilink::
// > .inTerm
// > .inPipe
// > .join
// >< .score
// < .lapsus
// .extend()
// < .mod.lazy
// .str.setChar()
// 2012-05-09 PerfektesChaos@de.wikipedia
var maxd = 50,
newl,
r = analyze,
leak = (address < maxd
|| this.inTerm - address < maxd);
if (leak) {
this.extend(3);
} else if (this.inPipe) {
if (address < maxd) { // left of pipe
leak = (this.inPipe - address < maxd);
this.extend(1);
} else { // right of pipe
leak = (address - this.inPipe < maxd);
this.extend(2);
}
}
// TODO maybe [[File:
if (leak) { // error detected and repairing
r = WSTM.str.setChar(analyze, 32, address - 2); // ' '
newl = r.indexOf("\n") + 2;
if (newl > 1 && newl < this.join) { // newline(s) left
this.extend(-1);
r = false;
}
this.lapsus = true;
WSTM.mod.lazy = false;
} else {
this.extend(-1);
r = false;
}
return r;
}; // .o.Wikilink.newline()
WikiLK.prototype.old2New = function () {
// Perform user defined replacements
// Precondition:
// .mod.wikilink is defined.
// Uses:
// > .o.Wikilink::
// > .source
// > .index
// > .ModeNull
// >< .show
// >< .suffix
// >< .score
// >< .learn
// >< .start
// >< .mode
// < .next
// .extend()
// > .mod.wikilink
// .w.link.replace.flip()
// .str.trimR()
// .str.substrEnd()
// Requires: JavaScript 1.3 charCodeAt()
// 2013-12-11 PerfektesChaos@de.wikipedia
var i,
j,
n,
s,
sB = this.source.substr(0, this.index + 2),
sE = (this.show ? "|" + this.show : "") + "]]" +
(this.suffix ? this.suffix : ""),
sO,
x = WSTM.w.link.replace.flip(WSTM.mod.wikilink,
this.score,
sB, sE, "[[");
if (x) {
this.learn = true;
this.extend(1);
if (typeof(x) === "string") {
this.score = x;
} else {
if (x[0]) {
if (x[0] !== sB) {
for (j = 0; j < sB.length; j++) {
if (x[0].charCodeAt(j) !== sB.charCodeAt(j)) {
break; // for j
}
} // for j
}
}
if (x[1]) {
j = x[1].indexOf("]]");
if (j >= 0) {
mw.log(WSTM.debugging,
".o.Wikilink.old2New() TODO ]] in replaced",
2);
}
j = x[1].indexOf("|");
if (j >= 0) {
mw.log(WSTM.debugging,
".o.Wikilink.old2New() TODO pipe in replaced",
2);
}
if (this.score !== x[1]) {
this.score = x[1];
this.extend(3);
}
}
if (x[0]) {
sO = x[0];
n = sB.length;
for (j = 0; j < n; j++) {
if (sO.charCodeAt(j) !== sB.charCodeAt(j)) {
break; // for j
}
} // for j
if (j >= 0) {
this.start = sO.substr(j);
}
j = n - j - 2;
sB = WSTM.str.substrEnd(this.start, 2);
if (sB === "[[") {
n = this.start.length - 2;
this.start = this.start.substr(0, n);
} else { // unlink
this.extend(4);
this.shift = this.start + this.score;
this.mode = this.ModeNull;
}
if (j > 0) {
this.extend(32, j);
}
}
if (x[2] === sE) {
x[2] = false;
}
if (x[2]) {
sO = x[2];
if ( ! this.mode) {
this.mode = 0;
}
if (x[3]) {
this.shift = this.start + this.score + sO;
this.mode = this.ModeNull;
this.show = false;
this.suffix = "";
this.extend(4);
this.extend(16, sO.length); // 2013-12-11
// -1 -- no extension
// 1 -- target region (beginning at 2)
// 2 -- title region
// 3 -- end of both target and title
// 4 -- begin at 0, not at 2
// 8 -- end after first terminating bracket
// 9 -- second terminating bracket appended
// 16 -- append afterward characters
// 32 -- begin and terminate at least at 0
mw.log(WSTM.debugging,"WikiLK.old2New() sO="+sO,0); //2013-12-01
} else {
j = sO.indexOf("]]");
if (this.mode <= 0 || ! j) {
if (j >= 0) {
n = this.suffix.length;
for (i = sO.length; i && n; i--, n--) {
if (this.suffix.charCodeAt(n)
!== sO.charCodeAt(i)) {
break; // for i
}
} // for i
if (i || n) {
this.extend(16, n);
this.next = i;
}
if (sO.charCodeAt(0) === 124) { // '|'
sO = sO.substr(1);
j--;
}
this.show = (j ? sO.substr(0, j)
: false);
this.suffix = sO.substr(j + 2);
}
j = -1;
if (x[0]) {
this.extend(3);
}
} else {
this.show = false;
}
}
if (j > 0) {
s = sO.substr(0, j);
if (s.indexOf("[") < 0) {
this.show = WSTM.str.trimR(s, true);
j += 2;
} else {
j = -2;
}
} else if (j === 0) {
j = 2;
}
if (this.show) {
i = this.show.indexOf("|");
if (i > 0) {
this.score = this.score
+ this.show.substr(0, i);
this.show = this.show.substr(i + 1);
}
}
if (this.suffix) {
n = this.suffix.length;
} else {
n = 0;
}
this.extend(2);
}
if (this.mode < 0) {
this.start = false;
this.show = false;
this.score = false;
this.inPipe = false;
}
} // modified
} // user defined replacements
}; // .o.Wikilink.old2New()
WikiLK.prototype.pipeSymbols = function (align) {
// Analyze pipe symbol(s) within wikilink
// Precondition:
// align -- position of '|' in this.score (>=0)
// Uses:
// > .o.Wikilink::
// > .ModeFile
// >< .score
// >< .mode
// < .lapsus
// < .show
// .extend()
// .str.trimL()
// .errors.found()
// 2012-10-18 PerfektesChaos@de.wikipedia
var lead,
less,
mid,
n,
s,
shine = this.score.substr(align + 1);
if (align > 0) {
this.score = this.score.substr(0, align);
} else {
this.score = false;
}
s = WSTM.str.trimL(shine, false);
n = s.length;
if (n < shine.length) {
this.extend(2);
} // ltrim
if (n === 0) {
if (! this.score) { // [[|]]
WSTM.errors.found("meaninglessLinkTarget", true, "");
this.extend(-1);
shine = false;
}
}
if (shine) {
mid = s.indexOf("|");
if (mid < 0) {
this.show = shine;
} else { // second pipe
if (mid === 0) { // directly following
s = s.substr(1);
mid = s.indexOf("|");
this.extend(2);
this.lapsus = true;
if (mid < 0) {
s = WSTM.str.trimL(s, false);
if (! s.length) {
s = false;
}
}
} else {
less = true;
if (this.score) {
lead = false;
less = (this.mode !== this.ModeFile);
} else { // empty target, something like [[|a|b]]
lead = true;
this.score = WSTM.str.trimR(s.substr(0, mid),
false);
s = WSTM.str.trimL(s.substr(mid + 1),
false);
mid = s.length;
this.extend(2);
}
if (less && s) {
if (s.substr(0, mid).indexOf("{{") < 0) {
WSTM.errors.found("multiplePipeSymbols",
lead,
"[[" + (lead ? "|" : "")
+ this.score + "|"
+ s.substr(0, 50));
// this.source.substr(
if (this.lapsus) {
this.extend(-1);
s = false;
} else {
this.lapsus = true;
}
}
} // less
}
this.show = s;
} // second pipe
}
}; // .o.Wikilink.pipeSymbols()
WikiLK.prototype.project = function (ahead) {
// Analyze wikilink beginning whether it starts with project
// Precondition:
// ahead -- position of ':' in this.score (>0)
// Postcondition:
// Returns true iff project stripped off from this.score
// RegExp was used.
// Uses:
// > .o.Wikilink::
// >< .score
// < .lead
// < .sister
// < .justify
// .extend()
// .str.trimL()
// .str.camelCasing()
// .w.link.projects.friend()
// 2012-12-06 PerfektesChaos@de.wikipedia
var join,
kind,
sole = "|commons|mediawiki|meta|",
swap,
r = false,
s = this.score.substr(0, ahead);
if (ahead === 1) {
if (s === s.toUpperCase()) {
s = false;
// ":sv:S:t Eriksplan (tunnelbanestation)"
}
}
if (s) {
r = WSTM.w.link.projects.friend(s, true);
}
if (r) { // project identified
kind = r[0];
swap = r[1];
this.score = WSTM.str.trimL(this.score.substr(ahead + 1),
false);
if (this.score.length < ahead + 1) {
this.extend(1);
} // trimmed
if (kind === 3) {
if (sole.indexOf("|" + swap + "|") > 0) {
this.sister = swap + ":";
if (this.score.charCodeAt(4) === 58) { // ':'
join = 4;
} else if (this.score.charCodeAt(5) === 58) { // ':'
join = 5;
} else {
join = 0;
}
if (join) {
s = this.score.substr(0, join).toLowerCase();
if (s === "file" || s === "image") {
swap = this.score;
join++;
this.score = this.score.substr(join);
this.score = WSTM.str.trimL(this.score, false);
this.score = WSTM.str.camelCasing(this.score);
this.lead = true;
this.sister = this.sister + "File:";
if (swap !== this.sister + this.score) {
this.extend(1);
}
kind = false;
swap = false;
}
}
}
}
if (kind) {
if (this.lead) { // superfluous heading ':'
this.extend(1);
}
this.lead = true;
if (swap) {
this.sister = swap + ":";
this.justify = kind;
if (swap !== s) {
this.extend(1);
}
} else { // itself
this.justify = 2;
this.extend(1);
}
} else if (swap) { // project major namespace
this.score = swap + ":" + this.score;
this.extend(1);
} // mode
} // affiliated project
return r;
}; // .o.Wikilink.project()
WikiLK.prototype.specials = function () {
// Handle link into special namespace
// Precondition:
// .score is defined, special namespace already stripped off.
// Uses:
// > .o.Wikilink::
// > .ModeNull
// >< .RE_ISBN
// >< .score
// < .inPipe
// < .show
// < .shift
// < .mode
// .extend()
// .hooks.fire()
// .util.code.isbn()
// 2017-01-01 PerfektesChaos@de.wikipedia
var got,
s = this.score.substr(0, 1);
if (! WikiLK.RE_ISBN) {
WikiLK.RE_ISBN = "^([^/]+)"
+ "/(ISBN *)?"
+ "([-0-9]{9,}[0-9X]|[-0-9]{13,})$";
WikiLK.RE_ISBN = new RegExp(WikiLK.RE_ISBN, "i");
}
if (s.toUpperCase() !== s) {
this.score = s.toUpperCase() + this.score.substr(1);
this.extend(1);
}
got = WikiLK.RE_ISBN.exec(this.score);
if (got) {
if (WSTM.hooks.fire("booksources", got[1])) {
s = got[3];
got = WSTM.util.code.isbn(s);
if (got[0]) {
if (got[1]) {
s = got[1];
}
}
this.extend(4);
this.shift = "ISBN " + s;
this.extend(16, 0);
this.inPipe = false;
this.show = false;
this.score = false;
this.mode = this.ModeNull;
}
}
}; // .o.Wikilink.specials()
WikiLK.prototype.target = function () {
// Analyze wikilink target
// Precondition:
// .score is defined.
// Uses:
// > .o.Wikilink::
// > .ModeFile
// > .justify
// > .ModeIw
// >< .score
// >< .show
// >< .lead
// >< .slang
// >< .sister
// < .mode
// < .leap
// < .special
// < .leader
// .extend()
// .project()
// .language()
// .namespace()
// .capitalize()
// .old2New()
// > .lang.chr.zwsp
// > .lang.chr.zwnj
// > .lang.chr.zwj
// > .o.WikiTom.LinkInterWiki
// > .mod.wikilink
// .w.link.filter()
// .str.isBlank()
// .str.trimL()
// .w.link.wiki.target()
// .w.link.wiki.further()
// Requires: JavaScript 1.3 charCodeAt() fromCharCode()
// 2012-11-06 PerfektesChaos@de.wikipedia
var s = WSTM.w.link.filter(this.score,
this.show
|| (this.mode === this.ModeFile)),
join,
label,
lang,
re;
if (s) {
this.score = s;
this.extend(1);
} // undesired character removed
if (WSTM.str.isBlank(this.score.charCodeAt(0), false)) {
this.score = WSTM.str.trimL(this.score.substr(1), true);
if (! this.show) {
this.leap = true;
}
}
while (this.score.charCodeAt(0) === 58) { // ':'
this.lead = true;
this.score = WSTM.str.trimL(this.score.substr(1), true);
} // while leading ':'
join = this.score.indexOf(":");
if (join > 0) {
label = this.project(join);
lang = false;
if (! label) {
lang = this.language(join);
}
if (label || (lang && this.lead)) { // one already in effect
join = this.score.indexOf(":");
if (join > 0) {
if (label) { // (:)project:lang:Lemma ??
this.language(join);
} else if (this.lead) { // :lang:project:Lemma ??
this.project(join);
}
} // ':' ':'
}
if (! this.slang
&& this.justify === 2) { // no lang, but needed
this.slang = "en:";
this.extend(1);
this.lead = true;
}
if (this.slang) { // lang detected
// 200A 8203 ZERO WIDTH SPACE
// 200B 8204 ZERO WIDTH NON-JOINER
// 200C 8205 ZERO WIDTH JOINER
if (WSTM.lang.chr.zwsp.indexOf(":" + this.slang) >= 0) {
if (this.score.indexOf(" ") >= 0) {
re = new RegExp(" ", "g");
s = String.fromCharCode(8203);
if (re.test(this.score)) {
this.score = this.score.replace(re, s);
}
}
}
if (this.score.indexOf("&zw") >= 0) {
if (WSTM.lang.chr.zwnj.indexOf(":" + this.slang) >= 0) {
re = new RegExp("‌", "g");
if (re.test(this.score)) {
s = String.fromCharCode(8204);
this.score = this.score.replace(re, s);
}
}
if (WSTM.lang.chr.zwj.indexOf(":" + this.slang) >= 0) {
re = new RegExp("‍", "g");
if (re.test(this.score)) {
s = String.fromCharCode(8205);
this.score = this.score.replace(re, s);
}
}
}
if (this.sister) {
this.sister = this.sister + this.slang;
this.lead = true;
} else if (this.lead) {
this.sister = ":" + this.slang;
} else { // (! this.lead) -- interlanguage
this.mode = this.ModeIw; // .interlanguage()
this.special = this.slang + this.score;
this.sister = this.slang;
s = this.slang.substr(0,
this.slang.length - 1);
this.leader = WSTM.w.link.wiki.further(
{ mode: WSTM.o.WikiTom.LinkInterWiki,
source: s } );
}
}
join = this.score.indexOf(":");
} // ':'
s = WSTM.w.link.wiki.target(this.score, ! this.show);
if (s) {
this.score = s;
this.extend(1);
if (join > 0) { // adjust
join = this.score.indexOf(":");
}
}
if (join > 0) { // namespace?
this.namespace(join);
} // namespace?
if (this.show) {
if (WSTM.str.isBlank(this.show.charCodeAt(0), false)) {
this.show = WSTM.str.trimL(this.show.substr(1), true);
this.leap = true;
}
this.capitalize();
} // titled?
if (this.sister) {
this.score = this.sister + this.score;
}
if (this.lead && ! this.sister) {
if (this.score.charCodeAt(0) !== 47) { // '/'
this.lead = false;
}
}
if (WSTM.mod.wikilink && this.score) {
this.old2New();
} // user defined replacements
}; // .o.Wikilink.target()
WikiLK.prototype.title = function () {
// Analyze wikilink title and representation
// Precondition:
// this.show not a Category
// Uses:
// > .o.Wikilink::
// >< .show
// >< .suffix
// >< .next
// < .leap
// .extend()
// .str.trimR()
// .str.isBlank()
// .str.trimL()
// Requires: JavaScript 1.3 charCodeAt()
// 2012-12-27 PerfektesChaos@de.wikipedia
var k,
leap,
m = this.show.length,
n;
this.show = WSTM.str.trimR(this.show, false);
n = this.show.length;
if (n < m) {
leap = false;
if (this.suffix) {
k = this.suffix.charCodeAt(0);
if (k === 10) {
leap = true;
} else {
leap = WSTM.str.isBlank(k, true);
}
}
if (leap) { // whitespace follows
this.extend(2);
} else {
this.suffix = " " + (this.suffix ? this.suffix : "");
this.extend(16, 0);
this.next = (this.next ? this.next++ : 1);
}
} // rtrim
if (WSTM.str.isBlank(this.show.charCodeAt(0), false)) {
this.show = WSTM.str.trimL(this.show.substr(1), false);
this.extend(32);
this.leap = true;
} // ltrim
}; // .o.Wikilink.title()
WikiLK.prototype.unlink = function () {
// Analyze link whether it can be unlinked or merged with title
// Precondition:
// Wikilink without leading colon ':'
// Uses:
// > .g.wTitle
// > .g.wNsNumber
// > .o.Wikilink::
// > .sister
// > .subcase
// > .off
// > .onto
// > .ModeNull
// > .lapsus
// >< .score
// >< .show
// >< .suffix
// >< .next
// < .inPipe
// < .shift
// < .mode
// .extend()
// .hooks.fire()
// .str.deCapitalize()
// .errors.found()
// .w.link.wiki.fore()
// .str.isLetter()
// 2016-08-17 PerfektesChaos@de.wikipedia
var lower = WSTM.hooks.fire("capitalize1"),
sw = (lower ? WSTM.str.deCapitalize(this.score)
: this.score),
io,
j,
n,
sh;
if (! this.sister && WSTM.g.wNsNumber === 0) {
io = 0;
if (sw === this.subcase) { // unlink
io = 1;
WSTM.errors.found("wikilinkSelf", false, false);
} else if (sw.indexOf(this.subcase + "#") === 0) { // intern
io = 2;
}
if (io > 0) {
if (this.off && this.onto) {
if (this.off.isNodeInSpan(this.onto)) {
io = -1;
}
}
}
if (io === 1) { // unlink
this.inPipe = false;
if (this.show) {
this.shift = this.show;
this.show = false;
} else {
this.shift = this.score;
}
this.score = false;
this.extend(4);
this.extend(16, 0);
this.mode = this.ModeNull;
} else if (io === 2) { // internal
this.score = this.score.substr(WSTM.g.wTitle.length);
this.extend(1);
}
} // same project
if (this.show) {
sh = (lower ? WSTM.str.deCapitalize(this.show)
: this.show);
if (sw === sh && ! this.sister) {
this.score = this.show;
this.show = false;
this.extend(3);
this.inPipe = false;
} else if (n && ! this.lapsus) {
n = sw.length;
if (sw === sh.substr(0, n)
&& WSTM.str.isLetter(sh.substr(n - 1, 1))
// [[Ferrari F2001|Ferrari F2001B]]
// !== [[Ferrari F2001]]B
&& WSTM.str.isLetter(sh.substr(n, 1))) {
j = WSTM.w.link.wiki.fore(sh, n);
if (j) {
if (j + n === sh.length) {
this.score = this.show.substr(0, n);
this.show = this.show.substr(n);
j = this.show.length;
if (j > 0) {
if (this.suffix) {
this.suffix = this.show + this.suffix;
if (! this.next) {
this.next = j;
}
} else {
this.suffix = this.show;
if (! this.next) {
this.next = true;
}
}
}
this.show = false;
this.extend(16, 0);
this.inPipe = false;
} // link range unchanged
} // do not merge sophisticated link titles
} else if (this.suffix) {
if (sh === sw.substr(0, sh.length)) {
j = WSTM.w.link.wiki.fore(this.suffix, 0);
if (j) {
if (sw === sh + this.suffix.substr(0, j)) {
this.suffix = this.suffix.substr(j);
this.show = false;
this.extend(16, j);
this.inPipe = false;
}
}
}
}
} // title === target, or part
} // titled
}; // .o.Wikilink.unlink()
WikiLK.prototype.url = function (adjust) {
// Analyze bracket content whether it starts with an URL
// Precondition:
// adjust -- string with possible link target, left trimmed
// Postcondition:
// Returns true iff adjust starts with an URL
// Uses:
// > .o.Wikilink::
// > .suffix
// > .ModeWeb
// < .lapsus
// < .mode
// < .move
// < .shift
// .extend()
// .util.isURL()
// Requires: JavaScript 1.3 charCodeAt()
// 2016-01-20 PerfektesChaos@de.wikipedia
var r = false,
s;
switch (adjust.charCodeAt(1)) {
case 47 : // '/'
r = (adjust.charCodeAt(0) === 47);
break;
case 116 : // 't'
s = adjust.substr(0, 4);
r = (s === "http" || s === "ftp:");
break;
} // switch charCodeAt(1)
if (r && WSTM.util.isURL(adjust, true, true)) {
r = true;
this.extend(3);
this.extend(4);
if (this.suffix) {
if (this.suffix.charCodeAt(0) === 93) { // ']'
this.extend(8); // post first bracket
} // terminating double brackets
} // follow
this.lapsus = true;
this.mode = this.ModeWeb;
this.move = adjust.length + 2;
this.shift = "[" + adjust;
}
return r;
}; // .o.Wikilink.url()
WikiLK.prototype.getBracketShift = function () {
// Returns true if leading bracket has been shifted to the right
// Uses:
// > .o.Wikilink::
// > .leap
// > .lift
// 2012-10-10 PerfektesChaos@de.wikipedia
return (this.leap || this.lift);
}; // .o.Wikilink.getBracketShift()
WikiLK.prototype.getChange = function () {
// Returns true if any need for changes
// Uses:
// > .o.Wikilink::
// > .shift
// > .newTo
// > .newFrom
// > .source
// > .index
// 2012-09-19 PerfektesChaos@de.wikipedia
var r = (typeof(this.shift) === "string");
if (r) {
r = (typeof(this.newTo) === "number");
if (r) {
if (this.newFrom === 2) {
r = (this.source.substr(this.index + 2, this.newTo - 2)
!== this.shift);
} else {
r = (typeof(this.newFrom) === "number");
}
}
}
return r;
}; // .o.Wikilink.getChange()
WikiLK.prototype.getError = function () {
// Return true if severe syntax error detected (repaired if change)
// Uses:
// > .o.Wikilink::
// > .lapsus
// 2010-10-01 PerfektesChaos@de.wikipedia
return this.lapsus;
}; // .o.Wikilink.getError()
WikiLK.prototype.getIncrement = function () {
// Returns number of chars to advance in basic text
// Uses:
// > .o.Wikilink::
// > .move
// 2010-10-01 PerfektesChaos@de.wikipedia
return this.move;
}; // .o.Wikilink.getIncrement()
WikiLK.prototype.getLeader = function () {
// Returns true if category/interlanguage has been first occurrence
// Uses:
// > .o.Wikilink::
// > .leader
// 2012-04-26 PerfektesChaos@de.wikipedia
return this.leader;
}; // .o.Wikilink.getLeader()
WikiLK.prototype.getRemoveFrom = function () {
// Returns number of target chars since which to remove, or false
// Uses:
// > .o.Wikilink::
// > .newFrom
// > .newTo
// 2011-05-03 PerfektesChaos@de.wikipedia
var k = this.newFrom;
if (k) {
if (typeof(this.newTo) !== "number") {
k = false;
}
}
return k;
}; // .o.Wikilink.getRemoveFrom()
WikiLK.prototype.getRemoveTo = function () {
// Returns number of target chars to be removed, or false
// Uses:
// > .o.Wikilink::
// > .newTo
// 2010-10-01 PerfektesChaos@de.wikipedia
return this.newTo;
}; // .o.Wikilink.getRemoveTo()
WikiLK.prototype.getSortkey = function () {
// Returns number of chars to be unconditionally locked, or false
// Uses:
// > .o.Wikilink::
// > .keySort
// 2010-10-01 PerfektesChaos@de.wikipedia
return this.keySort;
}; // .o.Wikilink.getSortkey()
WikiLK.prototype.getSpecial = function () {
// Returns category or interlanguage content
// Uses:
// > .o.Wikilink::
// > .special // -> schedule
// 2010-10-01 PerfektesChaos@de.wikipedia
return this.special;
}; // .o.Wikilink.getSpecial()
WikiLK.prototype.getTargetLength = function () {
// Returns number of target chars to lock, or false if not adhere
// Uses:
// > .o.Wikilink::
// > .lock
// > .score
// > .nucleus
// 2010-10-01 PerfektesChaos@de.wikipedia
// [1]
var r = false;
if (this.lock && this.score) {
r = (this.nucleus ? this.nucleus : this.score.length);
}
return r;
}; // .o.Wikilink.getTargetLength()
WikiLK.prototype.getTextReplace = function () {
// Returns replacement string, maybe false if nothing to do
// Uses:
// > .o.Wikilink::
// > .shift
// 2010-10-01 PerfektesChaos@de.wikipedia
return this.shift;
}; // .o.Wikilink.getTextReplace()
WikiLK.prototype.getTitle = function () {
// Returns title string, maybe false
// Uses:
// > .o.Wikilink::
// > .show
// 2018-11-19 PerfektesChaos@de.wikipedia
return this.show;
}; // .o.Wikilink.getTitle()
WikiLK.prototype.getType = function () {
// Returns special link type, or false if not a link
// .ModeNull unlinked (magic, self-reference, or replaced)
// .ModeWeb weblink
// .ModeWiki normal wikilink
// .ModeFile file (not Media:)
// .ModeCat category
// .ModeIw interlanguage
// special interwikilink ([[bugzilla:...]] etc.)
// page
// .ModeMap special weblink ([[DOI:...]] etc.)
// Uses:
// > .o.Wikilink::
// > .mode
// 2010-10-22 PerfektesChaos@de.wikipedia
return this.mode;
}; // .o.Wikilink.getType()
WikiLK.prototype.getUserModified = function () {
// Returns true if user defined modification performed
// Uses:
// > .o.Wikilink::
// > .learn
// 2010-10-01 PerfektesChaos@de.wikipedia
return this.learn;
}; // .o.Wikilink.getUserModified()
WikiLK.prototype.set = function (anode, access, adhere) {
// Initialize existing wikilink object with node
// Precondition:
// anode -- parent node object
// access -- anode position {i,k} where '[[' starts
// adhere -- true: freeze link targets
// Postcondition:
// .o.Wikilink object was set and has been analyzed
// RegExp was used.
// Uses:
// WikiTom().toString()
// > .o.Wikilink::
// < .onto
// < .node
// < .index
// < .lack
// < .lock
// < .off
// < .move
// < .newFrom
// < .source
// .init()
// .adjust()
// 2013-02-15 PerfektesChaos@de.wikipedia
this.init();
this.off = anode;
this.node = access.k;
this.onto = anode.focus(this.node);
this.index = access.i;
this.lack = access.lack;
this.lock = adhere;
this.move = 2;
this.newFrom = 2;
this.source = this.onto.toString();
this.adjust(this.source.substr(this.index));
}; // .o.Wikilink.set()
/*
WikiLK.prototype.setTarget = function (adjust) {
// Initialize existing wikilink object with target string
// Precondition:
// adjust -- target string
// Postcondition:
// .o.Wikilink object was set and has been analyzed
// RegExp was used.
// Uses:
// WikiTom().toString()
// > .o.Wikilink::
// < .source
// .init()
// .adjust()
// 2010-11-06 PerfektesChaos@de.wikipedia
this.init();
this.source = adjust;
this.adjust(this.source);
}; // .o.Wikilink.setTarget()
*/
}; // .bb.Wikilink()
mw.libs.WikiSyntaxTextMod.bb.Wikilink(mw.libs.WikiSyntaxTextMod);
delete mw.libs.WikiSyntaxTextMod.bb.Wikilink;
//-----------------------------------------------------------------------
mw.libs.WikiSyntaxTextMod.bb.WikiTom = function (WSTM) {
// Text and wikisyntax node
// 2012-07-07 PerfektesChaos@de.wikipedia
"use strict";
var WTOM;
WSTM.o.WikiTom = function (assign, above) {
// .constructor for new
// Precondition:
// assign -- string
// above -- parent Node root: null
// Postcondition:
// Returns new WikiTom
// 2012-03-12 PerfektesChaos@de.wikipedia
this.parent = above; // Object
this.source = assign; // String basic or no change in children
this.learnt = false; // boolean any (minor) modification
this.lookup = true; // boolean may be searched
this.limited = false; // boolean end of block
this.mode = 0; // Number kind of node
// this.children // Array of WikiTom nodes
// this.scope // String group description
return this;
}; // .o.WikiTom() .constructor
WTOM = WSTM.o.WikiTom;
// Definition of constants
// 2016-01-12 PerfektesChaos@de.wikipedia
WTOM.type = "WikiTom";
WTOM.WSTMinternal = -9;
WTOM.TextOnly = 1;
WTOM.Nowiki = 10;
WTOM.Inline = 11;
WTOM.CodedBlock = 13;
WTOM.CodedInline = 14;
WTOM.CodeBlock = 15;
WTOM.Code = 16;
WTOM.Comment = 18;
WTOM.CommentOld = 19;
WTOM.Tag = 20;
WTOM.TagUnary = 21;
WTOM.TagBegin = 22;
WTOM.TagEnd = 23;
WTOM.TagBinary = 29;
WTOM.LinkWiki = 31;
WTOM.LinkFile = 32; // link to File: even without NS
WTOM.LinkTemplate = 33; // link to Template: even in {{
WTOM.LinkCategory = 34;
WTOM.LinkExtWiki = 35;
WTOM.LinkInterWiki = 36;
WTOM.LinkWikiTotal = 38; // link to entire Link including [[]]
WTOM.LinkWikiPipe = 38;
WTOM.LinkWeb = 39;
WTOM.MagicWord = 41;
WTOM.ParserFun = 42;
WTOM.Template = 43;
WTOM.TmplBrackets = 44;
WTOM.TmplParName = 45;
WTOM.TmplParAssign = 46;
WTOM.TmplParValue = 47;
WTOM.TmplParAccess = 48;
WTOM.FileParam = 48;
WTOM.Sortkey = 50;
WTOM.Table = 60;
WTOM.TableRow = 61;
WTOM.TableAttr = 62;
WTOM.prototype.fade = function () {
// Deconstruct WikiTom node
// Postcondition:
// Allocated members are destroyed.
// Uses:
// >- this.children
// >- this.source
// this.children.fade()
// 2012-03-07 PerfektesChaos@de.wikipedia
var i;
if (this.source) {
delete this.source;
}
if (this.children) {
for (i = 0; i < this.children.length; i++) {
this.children[i].fade();
} // for i
delete this.children;
}
}; // .o.WikiTom().fade()
WTOM.prototype.fetch = function (assigned, ahead, alone) {
// Access string in WikiTom
// Precondition:
// assigned -- sibling number to be accessed
// ahead -- string position to start within assigned
// ahead < 0 count from end
// alone -- retrieve charCodeAt only
// Postcondition:
// Returns string, or false if assigned not found
// Uses:
// > this.children
// > this.source
// this.children.toString()
// mw.log()
// 2012-07-17 PerfektesChaos@de.wikipedia
var j,
r = false;
if (this.children) {
if (assigned < this.children.length) {
r = this.children[assigned].toString();
} else {
mw.log(WSTM.debugging,
".WikiTom().fetch() node beyond length " + assigned,
3,
this);
r = "";
}
} else { // plain string
if (assigned) {
mw.log(WSTM.debugging,
".WikiTom().fetch() bad node for string " + assigned,
3,
this);
} else if (this.source) {
r = this.source;
} else { // empty page
r = "";
}
}
if (r && ahead) {
if (ahead < 0) {
j = r.length + ahead;
if (j > 0) {
r = r.substr(j);
}
} else {
r = r.substr(ahead);
}
}
if (r && alone) {
r = r.charCodeAt(0);
}
return r;
}; // .o.WikiTom().fetch()
WTOM.prototype.find = function (achieve, already, assigned, allow, alone, attached) {
// Find term in WikiTom
// Precondition:
// achieve -- string or regexp info to be searched
// regexp info:
// [0] RegExp object
// [1] bracket number
// already -- string position to start
// assigned -- sibling number containing already
// allow -- permit inspection of children
// alone -- skip after element limitation since assigned
// attached -- achieve is deeper than application request
// Postcondition:
// Returns false, if achieve not found, or found info object
// .i string position of beginning
// .k sibling number
// .m regexp match for bracket number, if regexp
// .r regexp result array, if regexp
// .child object if allow and attached
// .i string position of beginning in child
// .k child number
// .o WikiTom child itself
// RegExp was used.
// Uses:
// > this.lookup
// > this.source
// > this.children
// > this.limited
// this.children.find() -- recursive
// 2012-06-16 PerfektesChaos@de.wikipedia
var join,
node,
e,
i,
j,
n,
s,
r = false;
if (this.lookup) {
join = (typeof(already) === "number" ? already : 0);
node = (typeof(assigned) === "number" ? assigned : 0);
if (typeof(this.children) === "object") {
if (allow) {
n = this.children.length;
j = join;
for (i = node; i < n; i++) {
e = this.children[i];
r = e.find(achieve, j, 0, attached, false, attached);
if (r) {
if (attached) {
r.child = { i: r.i,
k: r.k,
o: this };
}
r.k = i;
break; // for i
}
if (alone && e.limited) {
break; // for i
}
j = 0;
} // for i
}
} else if (! node) { // plain string
s = this.source;
n = s.length;
if (n) {
if (join) {
if (n > join) {
s = s.substr(join);
} else {
n = 0;
}
}
if (n) {
if (typeof(achieve) === "string") {
j = s.indexOf(achieve);
if (j >= 0) {
r = { i: join + j,
k: 0 };
}
} else {
j = s.search(achieve[0]);
if (j >= 0) {
r = s.match(achieve[0]);
r = { i: join + j,
k: 0,
m: r[ achieve[1] ],
r: r };
}
}
}
}
}
}
return r;
}; // .o.WikiTom().find()
WTOM.prototype.fixTab = function (adjust) {
// Remove tab chars from WikiTom, if any
// Precondition:
// adjust -- WikiTom to be changed, if necessary
// > .mode
// > .children
// >< .source
// Postcondition:
// adjust is updated
// Uses:
// > this.CodedBlock
// this.fixTab() -- recursive
// .w.chr.fixTab()
// this.fresh()
// 2012-03-23 PerfektesChaos@de.wikipedia
var j,
s;
if (adjust.mode !== WTOM.CodedBlock) {
if (adjust.children) {
for (j = 0; j < adjust.children.length; j++) {
this.fixTab(adjust.children[j]);
} // for j
} else if (adjust.source) {
s = WSTM.w.chr.fixTab(adjust.source);
if (s) {
adjust.fresh(s);
}
}
}
}; // .o.WikiTom().fixTab()
WTOM.prototype.flip = function (assigned, ahead, amount, apply) {
// Exchange string in WikiTom
// Precondition:
// assigned -- sibling number containing ahead
// ahead -- string position to start exchange within assigned
// amount -- number of characters to remove within assigned
// apply -- string to be inserted
// Postcondition:
// Returns entire node string, or false
// Uses:
// > this.children
// > this.limited
// > this.lookup
// > this.mode
// >< this.source
// this.children.toString()
// this.fade()
// this.fresh()
// .str.setString()
// mw.log()
// 2012-04-30 PerfektesChaos@de.wikipedia
var s = false,
r = false,
p;
if (this.children) {
if (assigned < this.children.length) {
r = this.children[assigned].toString();
} else {
s = "node beyond length";
}
} else { // plain string
if (assigned) {
s = "bad node for string";
} else {
r = this.source;
}
}
if (s) {
mw.log(WSTM.debugging,
".WikiTom().flip() " + s + " " + assigned,
3,
this);
} else {
r = WSTM.str.setString(r, ahead, amount, apply);
if (this.children) {
s = new WSTM.o.WikiTom(r, this);
p = this.children[assigned];
s.limited = p.limited;
s.lookup = p.lookup;
s.mode = p.mode;
this.children[assigned] = s;
p.fade();
s.fresh(false);
} else {
this.fresh(r);
}
}
return r;
}; // .o.WikiTom().flip()
WTOM.prototype.flush = function (avoid) {
// Remove one child
// Precondition:
// avoid -- child number
// Postcondition:
// this has been updated
// Uses:
// > this.children
// mw.log()
// 2012-04-23 PerfektesChaos@de.wikipedia
var q = this.children;
if (q) {
if (avoid < q.length) {
q.splice(avoid, 1);
} else {
mw.log(WSTM.debugging,
".WikiTom().flush() bad node for discard; r=" + avoid
+ " / " + q.length,
3,
this);
}
} else {
mw.log(WSTM.debugging,
".WikiTom().flush() no child to discard; r=" + avoid,
3,
this);
}
}; // .o.WikiTom().flush()
WTOM.prototype.focus = function (assign) {
// Access particular child
// Precondition:
// assign -- child number
// Postcondition:
// Returns WikiTom; or false if failed
// Uses:
// > this.children
// 2012-03-25 PerfektesChaos@de.wikipedia
var r = false;
if (this.children) {
if (assign < this.children.length) {
r = this.children[assign];
}
} else if (assign) {
mw.log(WSTM.debugging,
".WikiTom().focus() has no children",
3,
this);
} else {
r = this;
}
return r;
}; // .o.WikiTom().focus()
WTOM.prototype.fold = function (assign, align, append, allow) {
// Split child with searchable string content
// Precondition:
// assign -- child number
// align -- position where to split
// append -- true: insert after; false: insert before
// allow -- true: permit initial string separation
// Postcondition:
// Returns inserted WikiTom, even if string is empty;
// or false if failed
// Uses:
// > this.source
// > this.children
// mw.log()
// 2012-07-07 PerfektesChaos@de.wikipedia
var r = false,
s;
if (this.children) {
if (assign < this.children.length) {
if (align) {
r = this.children[assign];
if (r.children) {
r = false;
mw.log(WSTM.debugging,
".WikiTom().fold() no string node: " + assign,
3,
this);
} else {
s = r.source;
if (align <= s.length) {
if (append) {
r.source = s.substr(0, align);
s = s.substr(align);
} else {
this.children[assign].source = s.substr(align);
s = s.substr(0, align);
}
} else {
r = false;
mw.log(WSTM.debugging,
".WikiTom().fold() > string end: " + align,
3,
this);
}
}
} else {
s = "";
}
if (r) {
r = new WSTM.o.WikiTom(s, this);
this.children.splice((append ? assign+1 : assign), 0, r);
r.learnt = this.learnt;
}
} else {
mw.log(WSTM.debugging,
".WikiTom().fold() invalid child number: " + assign,
3,
this);
}
} else if (allow) {
this.children = [ new WSTM.o.WikiTom(this.source, this) ];
} else {
mw.log(WSTM.debugging,
".WikiTom().fold() has no children",
3,
this);
}
return r;
}; // .o.WikiTom().fold()
WTOM.prototype.folder = function (ahead, assign, after, adjacent) {
// Subdivide separated section, even over multiple children
// Precondition:
// ahead -- begin position within assign
// assign -- child number of begin
// after -- end position within adjacent
// adjacent -- child number of end
// Postcondition:
// Returns inserted WikiTom
// Uses:
// > this.source
// > this.children
// this.fold()
// mw.log()
// 2012-03-18 PerfektesChaos@de.wikipedia
var beg,
end,
r = false,
i,
later,
n,
s;
if (this.children) {
if (adjacent < assign || adjacent > this.children.length) {
mw.log(WSTM.debugging,
".WikiTom().folder() bad nodes for string; b="
+ assign + " e=" + adjacent
+ " / " + this.children.length,
3,
this);
} else {
r = true;
for (i = assign; i <= adjacent; i++) {
if (this.children[i].children) {
mw.log(WSTM.debugging,
".WikiTom().folder() no string: b=" + assign,
3,
this);
r = false;
break; // for i
}
} // for i
if (r) {
beg = false;
end = false;
n = adjacent;
if (after) {
r = this.fold(adjacent, after, false);
if (r) {
end = r;
n++;
}
}
}
if (r) {
i = assign;
if (ahead) {
r = this.fold(assign, ahead, true);
if (r) {
beg = r;
end = false;
i++;
n++;
}
}
}
if (r) {
s = "";
if (end) {
s = end.source;
}
if (i < n) {
for (n = n-1; n > i; n--) {
s = this.children[i].toString() + s;
} // for i
this.children.splice(i, n - i - 1);
}
if (beg) {
s = beg.source + s;
}
this.children[i].source = s;
r = this.children[i];
}
}
} else {
if (assign || adjacent) {
mw.log(WSTM.debugging,
".WikiTom().folder() bad nodes for string b="
+ assign + " e=" + adjacent,
3,
this);
} else {
later = (after < this.source.length);
n = (ahead ? 2 : 1) + (later ? 1 : 0);
this.children = new Array(n);
i = 0;
if (ahead) {
s = this.source.substr(0, ahead);
this.children[0] = new WSTM.o.WikiTom(s, this);
i = 1;
}
s = this.source.substr(ahead, after - ahead);
this.children[i] = new WSTM.o.WikiTom(s, this);
r = this.children[i];
if (later) {
i++;
s = this.source.substr(after);
this.children[i] = new WSTM.o.WikiTom(s, this);
}
if (this.learnt) {
for (i = 0; i < n; i++) {
this.children[i].learnt = true;
} // for i
}
}
}
return r;
}; // .o.WikiTom().folder()
WTOM.prototype.fork = function (at, advance, ancestor, assign, attach) {
// Introduce deeper level
// Precondition:
// at -- child number of begin
// advance -- child number of end; advance >= at
// ancestor -- name of family (tag etc.)
// assign -- family mode
// attach -- true: 'include' tag
// Postcondition:
// Nodes from at until advance (including) created at parent at.
// Returns parent, if succeeded, else false
// Uses:
// >< this.children
// >< this.parent
// < this.mode
// < this.scope
// < this.source
// mw.log()
// 2012-04-14 PerfektesChaos@de.wikipedia
var i,
r = false;
if (this.children) {
r = new WSTM.o.WikiTom(false, this);
r.children = this.children.slice(at, advance + 1);
r.mode = assign;
r.scope = ancestor;
for (i = 0; i < r.children.length; i++) {
r.children[i].parent = r;
if (attach) {
r.children[i].include = true;
} else {
r.children[i][ancestor] = true;
}
} // for i
this.children[at] = r;
if (advance > at) {
this.children.splice(at + 1, advance - at);
}
if (at) {
delete r.source;
}
r.parent = this;
} else {
mw.log(WSTM.debugging, ".WikiTom().fork() no children", 3, this);
}
return r;
}; // .o.WikiTom().fork()
WTOM.prototype.free = function () {
// Replace parents of children by this parent
// Uses:
// > this.children
// > this.parent
// 2012-04-22 PerfektesChaos@de.wikipedia
var e,
i,
n;
if (this.children) {
n = this.children.length;
for (i = 0; i < n; i++) {
e = this.children[i];
e.free();
e.parent = this;
} // for i
}
}; // .o.WikiTom().free()
WTOM.prototype.fresh = function (apply) {
// Mark this and above nodes as modified
// Precondition:
// apply -- optional string to be stored
// Postcondition:
// nodes are marked.
// Uses:
// > this.children
// > this.parent
// < this.source
// < this.learnt
// this.fresh() -- recursive
// 2012-03-23 PerfektesChaos@de.wikipedia
this.learnt = true;
if (this.children) {
this.source = false;
} else if (apply) {
this.source = apply;
} else if (typeof(apply) === "string") {
this.source = "";
}
if (this.parent) {
this.parent.fresh(false);
}
}; // .o.WikiTom().fresh()
WTOM.prototype.getCount = function () {
// How many nodes?
// Postcondition:
// Return current node count.
// Uses:
// > this.children
// 2012-03-19 PerfektesChaos@de.wikipedia
var r = 0;
if (this.children) {
r = this.children.length;
}
return r;
}; // .o.WikiTom().getCount()
WTOM.prototype.isNodeInSpan = function () {
// Is this node within <include>...</include> span?
// Postcondition:
// Returns true, if anode within span, else false
// Uses:
// > .w.encountered.include
// 2012-04-06 PerfektesChaos@de.wikipedia
var r = false;
if (WSTM.w.encountered.include) {
r = (this.include ? true : false);
}
return r;
}; // .o.WikiTom().isNodeInSpan()
WTOM.prototype.replace = function (apply, assign) {
// Precondition:
// apply -- RegExp object, or Array of replacement pairs
// assign -- single replacement, or false if replacement pairs
// Postcondition:
// Nodes are modified
// Uses:
// > this.children
// > this.lookup
// > this.mode
// > .o.WikiTom.TextOnly
// >< this.source
// this.replace() -- recursive
// .util.translate.flip()
// this.fresh()
// 2019-08-01 PerfektesChaos@de.wikipedia
var i,
n,
s;
if (this.lookup) {
if (this.children) {
n = this.children.length;
for (i = 0; i < n; i++) {
this.children[i].replace(apply, assign);
} // for i
} else {
if (this.mode <= WTOM.TextOnly) {
s = this.source;
if (s) {
if (typeof(assign) === "string") {
n = s.replace(apply, assign);
} else {
n = WSTM.util.translate.flip(s, apply);
}
if (n !== s) {
this.fresh(n);
}
}
}
}
}
}; // .o.WikiTom().replace()
WTOM.prototype.toString = function () {
// Postcondition:
// Returns string
// Uses:
// > this.source
// > this.children
// > this.learnt
// this.toString()
// 2012-05-16 PerfektesChaos@de.wikipedia
var i,
n,
p,
r = this.source;
if (this.children) {
if (this.learnt || ! r) {
n = this.children.length;
r = "";
for (i = 0; i < this.children.length; i++) {
p = this.children[i];
if (p) {
// if (p.hasOwnProperty("toString")) { /// failed
if (p.toString) {
r = r + p.toString();
}
}
} // for i
}
} else if (! r) {
r = "";
}
return r;
}; // .o.WikiTom().toString()
WTOM.prototype.trimL = function (any) {
// Trim leftmost node from heading spacing charcodes of any kind
// Precondition:
// any -- true: remove also zero width and direction marks
// Postcondition:
// Returns true, if whitespace removed
// leftmost node modified, if whitespace
// Uses:
// > this.source
// > this.children
// > .o.WikiTom().lookup
// > .o.WikiTom().mode
// > .o.WikiTom.TextOnly
// .str.trimL()
// this.fresh()
// 2013-04-29 PerfektesChaos@de.wikipedia
var n,
r = false,
s = false;
if (this.children) {
n = this.children[0];
if (n.lookup) {
if (n.mode <= WTOM.TextOnly) {
if (n.source) {
s = n.source;
}
}
}
} else if (this.source) {
s = this.source;
}
if (s) {
n = s.length;
s = WSTM.str.trimL(s, any);
r = (s.length < n);
if (r) {
if (this.children) {
this.children[0].fresh(s);
} else {
this.fresh(s);
}
}
}
return r;
}; // .o.WikiTom().trimL()
WTOM.prototype.trimR = function (any, also) {
// Trim rightmost node from trailing spacing charcodes of any kind
// Precondition:
// any -- true: include zero width and direction marks
// also -- true: remove also line break
// Postcondition:
// Returns true, if whitespace removed
// rightmost node modified, if whitespace
// Uses:
// > this.source
// > this.children
// > .o.WikiTom().lookup
// > .o.WikiTom().mode
// > .o.WikiTom.TextOnly
// .str.trimR()
// .str.substrEnd()
// this.fresh()
// 2012-05-28 PerfektesChaos@de.wikipedia
var n,
p,
r = false,
s = false;
if (this.children) {
p = this.children[this.children.length - 1];
if (p.lookup) {
if (p.mode <= WTOM.TextOnly) {
if (p.source) {
s = p.source;
}
}
}
} else if (this.source) {
s = this.source;
}
if (s) {
n = s.length;
s = WSTM.str.trimR(s, any, also);
r = (s.length < n);
if (r) {
if (this.children) {
p.fresh(s);
} else {
this.fresh(s);
}
}
}
return r;
}; // .o.WikiTom().trimR()
WTOM.prototype.DEBUGparent = function () {
// Replace parent objects by brief string for debugging report
// Uses:
// > this.parent
// > this.children
// this.toString()
// 2012-04-22 PerfektesChaos@de.wikipedia
var e,
i,
n;
if (this.parent) {
this.parent = this.parent.toString().substr(0, 100);
}
if (this.children) {
n = this.children.length;
for (i = 0; i < n; i++) {
e = this.children[i].DEBUGparent();
} // for i
}
}; // .o.WikiTom().DEBUGparent()
}; // .bb.WikiTom()
mw.libs.WikiSyntaxTextMod.bb.WikiTom(mw.libs.WikiSyntaxTextMod);
delete mw.libs.WikiSyntaxTextMod.bb.WikiTom;
//-----------------------------------------------------------------------
( function ( WSTM ) {
"use strict";
var sub = "O",
self = WSTM.o.self,
version = WSTM.o.vsn,
rls;
if ( typeof WSTM.main === "object"
&& WSTM.main &&
typeof WSTM.main.wait === "function" ) {
// Start on import: callback to waiting ...
WSTM.main.wait( sub, version );
} else 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: utf-8-dos
// fill-column: 80
// End:
/// EOF </nowiki> WikiSyntaxTextMod/dO.js