/// 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