MediaWiki:Wikifier.js
Перейти к навигации
Перейти к поиску
Замечание: Чтобы после сохранения вступили в силу изменения стилей, перезагрузите файл //traditio.wiki/w/load.php?debug=false&lang=ru&modules=site&only=styles&skin=vector&*, если используете скин Vector, или //traditio.wiki/w/load.php?debug=false&lang=ru&modules=site&only=styles&skin=common&*, если используете скин Common.
Чтобы вступили в силу изменения скриптов, перезагрузите файл //traditio.wiki/w/load.php?debug=false&lang=ru&modules=site&only=scripts&skin=vector&*, если используете скин Vector, или //traditio.wiki/w/load.php?debug=false&lang=ru&modules=site&only=scripts&skin=common&*, если используете скин Common.
Гаджеты и импортируемые скрипты загружаются отдельными файлами.
/*
* Внимание! Этот скрипт не загружается. См. MediaWiki:Gadget-wikifier.js.
*
* Викификатор
*/
// '''ВНИМАНИЕ! Внося изменения в код, не забывайте обновлять справку на странице [[Традиция:Викификатор]]'''
var wmVersion = '2011-11-23'
var wmCantWork = 'Викификатор не может работать в Вашем браузере\n\nWikificator cannot work in your browser'
var wmTalkPage = 'Викификатор не обрабатывает страницы обсуждения целиком.\n\nВыделите Ваше сообщение — обработано будет только оно'
// Функция викифицирует переданный текст и возвращает викифицированный:
function wikifyText (s) {
var txt='', hidden = [];
var u = '\u00A0'; // -- unbreakable space.
if (wgNamespaceNumber % 2 == 1 || wgNamespaceNumber == 4) { // -- это обсуждение.
u = ' ';
// Несколько дат, вероятно, чужие подписи::
var sigs = s.match (/\d\d:\d\d, \d\d? \S{3,8} 20\d\d \(UTC\)/g);
if (sigs && sigs.length > 1) {
alert(wmTalkPage);
return s;
}
}
s = hideTag (s, 'nowiki');
s = hideTag (s, 'pre');
s = hideTag (s, 'source');
s = hideTag (s, 'code');
s = hideTag (s, 'tt');
s = hideTag (s, 'math');
s = hideTag (s, 'gallery');
s = hide (s, /{\{[\s\S]+?}}/g); // -- templates
s = hide (s, /^ .*/mg);
s = hide (s, /(https?|ftp|news|nntp|telnet|irc|gopher):\/\/[^\s\[\]<>"]+ ?/gi);
s = hide (s, /^#(redirect|перенапр(авление)?)/i);
s = s.replace (/ +(\n|\r)/g, '$1'); // -- пробелы в конце строки.
s = '\n' + s + '\n';
var replacements1 = [
// Русификация пространств имён:
[/(\[\[:?)(category|категория):( *)/ig, '$1Категория:']
, [/(\[\[:?)(image|изображение|file):( *)/ig, '$1Файл:']
// Оформление дат:
, [/(\(|\s)(\[\[[12]?\d{3}\]\])[\u00A0 ]?(-{1,3}|–|—) ?(\[\[[12]?\d{3}\]\])(\W)/g, '$1$2—$4$5']
, [/(\[\[[12]?\d{3}\]\]) ?(гг?\.)/g, '$1' + u + '$2']
, [/(\(|\s)(\[\[[IVX]{1,5}\]\])[\u00A0 ]?(-{1,3}|–|—) ?(\[\[[IVX]{1,5}\]\])(\W)/g, '$1$2—$4$5']
, [/(\[\[[IVX]{1,5}\]\]) ?(вв?\.)/g, '$1' + u + '$2']
, [/\[\[(\d+)\]\][\u00A0 ]год/g, '[[$1' + u + 'год]]']
, [/\[\[((\d+)(?: (?:год )?в [\wa-яёА-ЯЁ ]+\|\2)?)\]\][\u00A0 ](год[а-яё]*)/g, '[[$1' + u + '$3]]']
, [/\[\[([XVI]+)\]\][\u00A0 ]век/g, '[[$1' + u + 'век]]']
, [/\[\[(([XVI]+) век\|\2)\]\][\u00A0 ]век/g, '[[$2' + u + 'век]]']
// Удаление недопустимых символов из викиссылок:
, [/(\[\[[^|\[\]]*)[\u00AD\u200E\u200F]+([^\[\]]*\]\])/g, '$1$2'] // -- Soft Hyphen & DirMark.
, [/\[\[ *([a-zA-Zа-яёА-ЯЁ\u00A0-\u00FF %!\"$&'()*,\-.\/0-9:;=?\\@\^_`’~]+) *\| *(\1)([a-zа-яё]*) *\]\]/g, '[[$2]]$3'] // -- ".
, [/\[\[ *([a-zA-Zа-яёА-ЯЁ\u00A0-\u00FF %!\"$&'()*,\-.\/0-9:;=?\\@\^_`’~]+) *\| *([^|[\]]+) *\]\]([a-zа-яё]+)/g, '[[$1|$2$3]]'] // -- ".
];
s = runReplacements (s, replacements1);
s = hide (s, /\[\[[^\]|]+/g); // -- скрытие викиссылок.
var replacements2 = [
// HTML -> викитекст:
[/<<(\S.+\S)>>/g, '"$1"'] // -- угловые кавычки в обычные. Или лучше в «»?
, [/(sup>|sub>|\s)-(\d)/g, '$1−$2'] // -- minus в индексах.
, [/(<sup>2<\/sup>|²)/gi, '²'] // -- символы квадрата
, [/(<sup>3<\/sup>|³)/gi, '³'] // и куба.
, [/<(b|strong)>(.*)<\/(b|strong)>/gi,"'''$2'''"] // -- вики-полужирный.
, [/<(i|em)>(.*)<\/(i|em)>/gi,"''$2''"] // -- вики-курсив.
, [/^<hr ?\/?>/gim, '----'] // -- вики-гор. разделитель.
, [/<\/?(hr|br)( [^\/>]+?)? ?\/?>/gi, '<$1$2 />'] // -- ?
, [/(\n== *Примечания *==\n)<references *\/>/,'$1{\{примечания}}']
];
s = runReplacements (s, replacements2);
s = hide(s, /<[a-z][^>]*?>/gi);
s = hide(s, /^({\||\|-).*/mg); // // -- таблицы и ряды.
s = hide(s, /(^\||^!|!!|\|\|) *[a-z]+=[^|]+\|(?!\|)/mgi); // -- стили ячеек.
s = hide(s, /\| +/g) // -- форматированные ячейки.
s = s.replace (/[ \t]+/g, ' '); // -- двойные пробелы.
var replacements3 = [
// Заголовки:
[/^(=+)[ \t\f\v]*(.*?)[ \t\f\v]*=+$/gm, '$1 $2 $1'] // -- окружить пробелами.
, [/([^\r\n])(\r?\n==.*==\r?\n)/g, '$1\n$2'] // -- пустую строку впереди.
, [/^== см(\.?|отрите) ?также ==$/gmi, '== См. также =='] // -- «См. также».
, [/^== сноски ==$/gmi, '== Примечания ==']
, [/^== (.+)[.:] ==$/gm, '== $1 =='] // -- точка или двоеточие в конце.
, [/«|»|“|”|„/g, '"'] // -- временное скрытие нормальных кавычек. Нужно ли?
// Тире и дефисы:
, [/–/g, '-'] // -- – -> hyphen
, [/&(#151|[nm]dash);/g, '—'] // -- -> —
, [/( |\s)-{1,3} /g, ' — '] // -- hyphen -> —
, [/(\d)--(\d)/g, '$1—$2'] // -- -> —
, [/(\D)--(\D)/g, '$1' + u + '— $2'] // -- -> —
// Точки и запятые до и после сносок:
, [/,((<ref[^<\/>]*?(>[^<]+?<\/ref|\/)>)+)/gi , '{{,}}$1'] // -> запятая до;
, [/\.((<ref[^<\/>]*?(>[^<]+?<\/ref|\/)>)+)/gi, '{{тчк}}$1'] // -> точка до;
, [/((<ref[^<\/>]*?(>[^<]+?<\/ref|\/)>)+),/gi , '{{,}}$1'] // -> запятая после;
, [/((<ref[^<\/>]*?(>[^<]+?<\/ref|\/)>)+)\./gi, '{{тчк}}$1'] // -> точка после;
// Мнемоники HTML -> символы:
, [/&#x([0-9a-f]{1,4});/gi, function(n,a){return String.fromCharCode(eval('0x'+a.substr(-4)))}] //́
, [/©/gi,'©']
, [/®/gi,'®']
, [/§/gi,'§']
, [/€/gi,'€']
, [/¥/gi,'¥']
, [/£/gi,'£']
, [/°/g,'°']
, [/\(tm\)|\(тм\)|™/gi,'™']
, [/\.\.\.|…/g,'…']
, [/\+-|±/g,'±']
, [/~=/g,'≈']
, [/\^2(\D)/g,'²$1']
, [/\^3(\D)/g,'³$1']
, [/&((la|ra|bd|ld)quo|quot);/g,'"']
, [/([\wа-яА-ЯёЁ])'([\wа-яА-ЯёЁ])/g,'$1’$2'] //'
, [/№№/g,'№']
// Годы и века
, [/(\(|\s)([12]?\d{3})[\u00A0 ]?(-{1,3}|—) ?([12]?\d{3})(?![\w-°])/g, '$1$2—$4']
, [/([12]?\d{3}) ?(гг?\.)/g, '$1' + u + '$2']
, [/(\(|\s)([IVX]{1,5})[\u00A0 ]?(-{1,3}|—) ?([IVX]{1,5})(?![\w-°])/g, '$1$2—$4']
, [/([IVX]{1,5}) ?(вв?\.)/g, '$1' + u + '$2']
// Сокращения:
, [/(Т|т)\.\s?е\./g, '$1о есть']
, [/(Т|т)\.\s?к\./g, '$1ак как']
, [/(В|в)\sт\. ?ч\./g, '$1 том числе']
, [/и\sт\.\s?д\./g, 'и' + u + 'т\.' + u + 'д\.']
, [/и\sт\.\s?п\./g, 'и' + u + 'т\.' + u + 'п\.']
, [/(Т|т)\.\s?н\./g, '$1\.' + u + 'н\.']
, [/н\.\s?э\./g, 'н\.' + u + 'э\.']
, [/(Д|д)(о|\.)\sн\.\s?э\./g, '$1о' + u + 'н\.' + u + 'э\.']
, [/(\d)[\u00A0 ]?(млн|млрд|трлн|(?:м|с|д|к)?м|[км]г)\.?(?=[,;.]| "?[а-яё-])/g, '$1' + u + '$2']
, [/(\d)[\u00A0 ](тыс)([^\.А-Яа-яЁё])/g, '$1' + u + '$2.$3']
, [/ISBN:\s?(?=[\d\-]{8,17})/, 'ISBN ']
// Пробелы:
, [/^([#*:]+)[ \t\f\v]*([^ \t\f\v*#:;])/gm, '$1 $2'] // -- в списках.
, [/(\S) (-{1,3}|—) (\S)/g, '$1' + u + '— $3']
, [/([А-Я]\.) ?([А-Я]\.) ?([А-Я][а-я])/g, '$1' + u + '$2' + u + '$3']
, [/([А-Я]\.)([А-Я]\.)/g, '$1 $2']
, [/([а-я]\.)([А-ЯA-Z])/g, '$1 $2'] // -- после точки.
, [/([)"а-яa-z\]])\s*,([\[("а-яa-z])/g, '$1, $2'] // -- после точки.
, [/([)"а-яa-z\]])\s([,;])\s([\[("а-яa-z])/g, '$1$2 $3']
, [/([^%\/\w]\d+?(?:[.,]\d+?)?) ?([%‰])(?!-[А-Яа-яЁё])/g, '$1' + u + '$2'] // -- проценты.
, [/(\d) ([%‰])(?=-[А-Яа-яЁё])/g, '$1$2'] // -- 5%-й
, [/([№§])(\s*)(\d)/g, '$1'+u+'$3']
, [/\( +/g, '(']
, [/ +\)/g, ')'] // -- убрать пробелы у внутренних сторон скобок.
// Температура:
, [/([\s\d=≈≠≤≥<>("'|])([+±−-]?\d+?(?:[.,]\d+?)?)(([ °^*]| [°^*])[CС])(?=[\s"').,;!?|])/gm, '$1$2' + u + '°C']
, [/([\s\d=≈≠≤≥<>("'|])([+±−-]?\d+?(?:[.,]\d+?)?)(([ °^*]| [°^*])F)(?=[\s"').,;|!?])/gm, '$1$2' + u + '°F']
// Десятичная точка → запятая:
, [/(\s\d+)\.(\d+[\u00A0 ]*[%‰°])/gi, '$1,$2']
];
s = runReplacements (s, replacements3);
// Восстановление кавычек: "" → «»:
for (var i=1; i<=2; i++) {
s = s.replace (/([\s\u00A0·\x02!|#'"\/(;+-])"([^"]*)([^\s"(|])"([^a-zа-яё])/ig, '$1«$2$3»$4'); //"
}
while (/«[^»]*«/.test(txt)) {
s = s.replace (/«([^»]*)«([^»]*)»/g, '«$1„$2“');
}
s = s.substr (1, s.length - 2); // -- удаление начального и конечного пробелов.
if ('0'.replace('0', '$$') == '$') { // -- $ в регэксах, как всегда IE особенный.
for (var i = 0; i < hidden.length; i++) {
hidden [i] = hidden [i].replace (/\$/g, '$$$$');
}
}
// Раскрытие скрытого в hide ():
while (hidden.length > 0) {
s = s.replace ('\x01' + hidden.length + '\x02', hidden.pop ());
}
return s;
// Вспомогательные функции:
// Выполнение массива замен:
function runReplacements (s, pairs) {
jQuery.each (pairs, function () { s = s.replace (this [0], this [1]);});
return s;
}
// Скрытие фрагментов путём окружения \x01 и \x02:
function hide (txt, re) {
return txt.replace (re, function (s) {return '\x01' + hidden.push (s) + '\x02'});
}
function hideTag (txt, tag) {
return hide (txt, RegExp ('<' + tag + '( [^>]+)?>[\\s\\S]+?<\\/' + tag + '>', 'gi'));
}
}
pound;/gi,'£']
, [/