MediaWiki:Wikificator.js

Vikilug‘atdan olingan

Eslatma: Saqlaganingizdan soʻng, oʻzgarishlarni koʻrish uchun brauzeringiz keshini tozalashingizga toʻgri kelishi mumkin.

  • Firefox / Safari: Shift tugmasini bosgan holda, Yangilash unsurlar darchasini bosing, yoki Ctrl-F5 yoki Ctrl-R (Macda ⌘-R) ni bosing
  • Google Chrome: Ctrl-Shift-R (Macda ⌘-Shift-R) ni bosing
  • Internet Explorer / Edge: Ctrlni bosgan holda, Yangilashni bosing, yoki Ctrl-F5ni bosing
  • Opera: Ctrl-F5ni bosing.
// [[Vikipediya:Vikifikator]] 

/* <pre> */
var txt;

var wmFullText = 'Vikifikator ushbu sahifadagi BUTUN matnni qayta ishlaydi. Davom etsinmi?';
var wmCantWork = 'Vikifikator brauzeringizda ishlamaydi';
var wmWontWork = 'Vikifikator Netscape 4.x va eskirogʻida ishlamaydi';


var wmCategoryNS = 'Category';
var wmTemplateNS = 'Template';
var wmUserNS = 'User';
var wmImageNS = 'Image';
var wmMediaNS = 'Media';

var wmLocaleNS = new Array(wmCategoryNS, wmTemplateNS, wmUserNS, wmImageNS, wmMediaNS);
var wmEnNS = new Array('category', 'template', 'user', 'image', 'media');

document.editform.wpTextbox1.onkeyup = function(event){
  if(event.keyCode == 32){
  	var txtarea = document.editform.wpTextbox1;
  	var startPos = txtarea.selectionStart;
    var endPos = txtarea.selectionEnd;
    var scrollTop = txtarea.scrollTop;
    var letter_pattern = /[0-9a-z`'ʻʼ‘’]/i;
    var letter = "";
    var letter_pos = 0;
    var pointfound = false;
    var spacefound = false;
    txt = ". " + (txtarea.value);
  	for(i = startPos - 1; i >= 0; i--){
  		k = txt.substring(i, i + 1);
  		//confirm("" + k + " " + i);
  		if(letter_pattern.test(k) === true && spacefound === false){
  			letter = k;
  			letter_pos = i - 2;
  		}
  		else{
  			if(k == " " || k == "\n"){
  				spacefound = true;
  			}
  			else if((k == "." || k == "!" || k == "?") && spacefound === true){
  				pointfound = true;
  				break;
  			}
  			else{
  				break;
  			}
  		}
  	}
  	if(pointfound === true){
  		if(letter != letter.toUpperCase()){
  			txtarea.value = txtarea.value.substring(0, letter_pos) + letter.toUpperCase() + txtarea.value.substring(letter_pos + 1, txtarea.value.length);
            //txtarea.focus();
            txtarea.selectionStart = startPos;
		    txtarea.selectionEnd = endPos;
		    txtarea.scrollTop = scrollTop;
  		}
  	}
  }
}


if (window.event) {
    document.onkeypress = pressed;
}

function pressed() //On Ctrl+Enter (MSIE)
{ key = window.event.keyCode; if (key == 10) { Wikify(); } }

//======================================
function Wikify() {
    check_regexp(); // Check whether regular expressions are supported
    document.editform.wpTextbox1.focus();
    var txtarea = document.editform.wpTextbox1;
    if (document.selection && !is_gecko)/* IE */{
        txt = " " + document.selection.createRange().text;
        if (txt == " ") { all_text(); } // If nothing was selected;
        else {
            Process();
            txt = txt.substr(1, txt.length - 1);
            document.selection.createRange().text = txt;
        }
    }
    else if ((txtarea.selectionStart || txtarea.selectionStart == '0') && (navigator.productSub > 20031000)) /*Gecko-browsers older then 10.2003*/{
        var startPos = txtarea.selectionStart;
        var endPos = txtarea.selectionEnd;
        var scrollTop = txtarea.scrollTop;
        txt = " " + (txtarea.value).substring(startPos, endPos);
        if (txt == " ") { all_text(); } // If nothing was selected;
        else {
            Process();
            txt = txt.substr(1, txt.length - 1);
            txtarea.value = txtarea.value.substring(0, startPos) + txt + txtarea.value.substring(endPos, txtarea.value.length);
            txtarea.focus();
        }
    }
    else { if (confirm(wmFullText)) { all_text(); } } // Other browsers
}
//======================================
function all_text()// Process all text
{
    txt = " " + document.editform.wpTextbox1.value;
    Process();
    txt = txt.substr(1, txt.length - 1);
    document.editform.wpTextbox1.value = txt;
}
//======================================
function check_regexp()// Check whether regular expressions are supported
{
    var reg1 = "code";
    reg1 = reg1.replace(/d/g, "r");
    if (reg1 != "core") { alert(wmCantWork); exit; }
    b_ver = navigator.appVersion.substr(0, 1);
    if (navigator.appName == "Netscape" && b_ver < 5) { alert(wmWontWork); exit; }
    return;
}
function Process()
// We have 3 more pairs of safe chars in \x1A — \x1F !
{

    //var nowiki = ReplaceElements( '\<math\>(.|\r|\n)+?\<\/math\>, "\x03", "\x04" );
    //That variant will make ReplaceTags() function unnecessary, but it's so ugly...

    var nowiki = ReplaceTags('nowiki', "\x03", "\x04");
    var pre = ReplaceTags('pre', "\x12", "\x13");
    var math = ReplaceTags('math', "\x05", "\x06");
    var gallery = ReplaceTags('gallery', "\x14", "\x15");


    // Exclude lines starting with space
    f_space = txt.substr(0, 1);
    txt = txt.substr(1, txt.length - 1);

    var sp_lines = ReplaceElements("^( )(.+)$", "\x16", "\x17");

    txt = f_space + txt;

    ProcessNS(wmEnNS, wmLocaleNS);
    CorrectRanges();

    // Exclude templates and internal links
    var templates = ReplaceElements("\\{\\{(.|\\r|\\n)+?\\}\\}", "\x18", "\x19");
    var links = ReplaceElements("(\\[\\[)(.*?)(\\||\\]\\])", "\x10", "\x11");

    HTML2Wiki();

    // Exclude tags and tag attributes (all text in quotes after "=" sign)
    var attrs = ReplaceElements('(=)(\\s?)(\\' + '")(.*?)(\\")', "\x0E", "\x0F");
    var tags = ReplaceElements("<([^>]*?)>", "\x01", "\x02");

    ProcessTypography();

    //alert(txt);

    RestoreElements(tags, "\x01", "\x02");
    RestoreElements(attrs, "\x0E", "\x0F");
    RestoreElements(links, "\x10", "\x11");
    RestoreElements(templates, "\x18", "\x19");
    RestoreElements(sp_lines, "\x16", "\x17");
    RestoreElements(gallery, "\x14", "\x15");
    RestoreElements(math, "\x05", "\x06");
    RestoreElements(pre, "\x12", "\x13");
    RestoreElements(nowiki, "\x03", "\x04");

}

function HTML2Wiki() {
    // UZBEK02
    //============================TEMPO=====
    txt = txt.replace(/(A|a|E|e|N|n|O|o|G|g|T|t)\'''/g, "$1 20072006NGPP132604")
    txt = txt.replace(/(A|a|E|e|N|n|O|o|G|g|T|t)\''/g, "$1 20072006NGPP132604_onlytwo")
    txt = txt.replace(/(A|a|E|e|N|n|T|t)\'/g, "$1ʻ")
    txt = txt.replace(/(O|o|G|g)\'/g, "$1ʻ")
    txt = txt.replace(/(A|a|E|e|N|n|O|o|G|g|T|t)\ ?20072006NGPP132604_onlytwo/g, "$1''")
    txt = txt.replace(/(A|a|E|e|N|n|O|o|G|g|T|t)\ ?20072006NGPP132604/g, "$1'''")

    // Replace <b>, <strong> tags with ''' and <i>, <em> with ''
    txt = txt.replace(/\<\/?(b|strong)\>/gim, "\'\'\'")
    txt = txt.replace(/\<\/?(i|em)\>/gim, "\'\'")

    // Replace <hr> tag with ----, improve <hr> and <br> tags
    txt = txt.replace(/\<hr ?\/?\>/gi, "----")
    txt = txt.replace(/\<hr ([^\>\/]+?) ?\/?\>/gi, "<hr $1 />")
    txt = txt.replace(/\<br\/?\>/gi, "<br />")
    txt = txt.replace(/\<br ([^\>\/]+?) ?\/?\>/gi, "<br $1 />")

}

// Process default namespaces

function ProcessNS(En_NS_List, Loc_NS_List) {

    for (i = 0; i < En_NS_List.length; i++) {
        //alert("(\\[\\[)(:?)(" + En_NS_List[i] + "|" +
        //Loc_NS_List[i] + ")(:)( *)");

        txt = txt.replace(new RegExp("(\\[\\[:?)(" + En_NS_List[i] + "|" +
  Loc_NS_List[i] + "):( *)", "gi"), "$1" + Loc_NS_List[i] + ":");

    }
}

//======================================
// Replace '<replaced_tag> ... </replaced_tag>' (<nowiki> <br/> </nowiki>)
// with 'opepening_char + tag's counter + closing_char' ('\x03'+1'+'\x04')
//======================================

function ReplaceTags(replaced_tag, op_char, cl_char)

// @replaced_tag - tag to be replaced
// @op_char, @cl_char (opening & closing chars) - "Safe" pair of 
// unicode unprintable characters, that will be used in replacement
{

    var counter = 0; //tags counter

    // RegExp pattern
    var pattern = "\\<" + replaced_tag + "\\>(.|\r|\n)+?\<\\/" + replaced_tag + "\\>";

    // RegExp template to be replaced (multiline text between 
    // <replaced_tag> and </replaced_tag> case sensitive tags)
    var replaced_regexp = new RegExp(pattern, "im")

    // Buffer for replaced matches storage. It's array of matching substrings -
    // multiline text between <replaced_tag> and </replaced_tag> case sensitive tags ()
    matches_buffer = txt.match(new RegExp(pattern, "gim"));

    // while some substring of txt matches replaced_regexp...
    while (replaced_regexp.test(txt)) {
        txt = txt.replace(replaced_regexp, op_char + ++counter + cl_char);
    }
    return matches_buffer;
}

//======================================
// Replace '<replaced_tag> ... </replaced_tag>' (<nowiki> <br/> </nowiki>)
// with 'opepening_char + tag's counter + closing_char' ('\x03'+1'+'\x04')
//======================================

function ReplaceElements(req_exp, op_char, cl_char)

// @req_exp - reqular expression to be replaced
// @op_char, @cl_char (opening & closing chars) - "Safe" pair of 
// unicode unprintable characters, that will be used in replacement
{

    var counter = 0; //tags counter

    // RegExp template to be replaced (multiline, case sensitive)
    var replaced_regexp = new RegExp(req_exp, "m")

    // Buffer for replaced matches storage. It's array of matching substrings.
    // (multiline, case sensitive, global)
    matches_buffer = txt.match(new RegExp(req_exp, "gm"));

    // while some substring of txt matches replaced_regexp...
    while (replaced_regexp.test(txt)) {
        //alert(txt.match(replaced_regexp));
        txt = txt.replace(replaced_regexp, op_char + ++counter + cl_char);
    }
    return matches_buffer;
}

//======================================
// Restore text, that was damaged by replacing 3 chars with substring from array
//======================================

function RestoreElements(replaced_buffer, op_char, cl_char)

// @replaced_buffer - array of replaced substrings.
// @op_char, @cl_char (opening & closing chars) - "Safe" pair 
// to be replaced with <replaced_tag> and </replaced_tag> accordingly
{

    var counter = 0; //tags counter

    // RegExp template to be replaced (3 chars: tag's counter 
    // surrunded by "Safe" pair)
    var replaced_regexp = new RegExp("\\" + op_char + "([0-9]*)\\" + cl_char);

    //replaced_regexp = /\x03([0-9]*)\x04/

    // while some substring of txt matches replaced_regexp...
    while (replaced_regexp.test(txt)) {
        txt = txt.replace(replaced_regexp, replaced_buffer[counter++]);
    }
    return txt;
}

// Corrects year and century ranges in text
function CorrectRanges() {
    // Correct year ranges
    //txt = txt.replace(/(\(|\s)(\[?\[?[12]?\d{3}\]?\]?)[\u00A0 ]?(-|--|–|—) ?(\[?\[?[12]?\d{3}\]?\]?)(\W)/g, "$1$2—$4$5")
    //txt = txt.replace(/(\[?\[?[12]?\d{3}\]?\]?) ?(г\.|гг\.)/g, "$1\u00A0$2")
    // Correct century ranges
    //txt = txt.replace(/(\(|\s)(\[?\[?[IVX]{1,5}\]?\]?)[\u00A0 ]?(-|--|–|—) ?(\[?\[?[IVX]{1,5}\]?\]?)(\W)/g, "$1$2—$4$5")
    //txt = txt.replace(/(\[?\[?[IVX]{1,5}\]?\]?) ?(в\.|вв\.)/g, "$1\u00A0$2")
}

/***************************************************
Typographical considerations
***************************************************/
function ProcessTypography() {

    // Insert spaces in titles
    txt = txt.replace(/^(=+)([ \t\f\v]*)(.*?)([ \t\f\v]*)(=+)$/gm, "$1 $3 $1")
    //======================================
    // Use 1 character to display squaring and cubing
    txt = txt.replace(/(<sup>2<\/sup>|&sup2;)/g, "²");
    txt = txt.replace(/(<sup>3<\/sup>|&sup3;)/g, "³");
    txt = txt.replace(/(\^2)(\D)/g, "²$2");
    txt = txt.replace(/(\^3)(\D)/g, "³$2");
    //======================================
    // Replace right HTML symbols with wrong ones in order to process everything
    txt = txt.replace(/–/g, "-")
    txt = txt.replace(/(«|»|“|”|„|\&((la|ra|bd|ld)quo|#132|#147|#148|quot);)/g, "\"")
    //======================================
    // Replace double hyphen with a dash
    txt = txt.replace(/(--)(\[\[Участник|\~\~\~)/g, "—$2")
    //======================================
    // Replace set of 'less then' or 'greater then' symbols (<< or >>) with usual double quotes
    txt = txt.replace(/(<<)(\S.+\S)(>>)/g, "\"$2\"")
    //======================================
    // Process degree sign "°", "+-" and "~="
    txt = txt.replace(/(\+[--])|(&plusmn;)/g, "±")
    txt = txt.replace(/(~=)/g, "≈")
    txt = txt.replace(/\&deg;/g, "°")
    txt = txt.replace(/([ =≈≠≤≥<>("'|]|^)([+±−\-]?\d+?(?:[.,]\d+?)?)(([ °^*]| [°^*])[CС])(?=[ "').,;!?|]|$)/gm, "$1$2\u00A0°C")
    txt = txt.replace(/([ =≈≠≤≥<>("'|]|^)([+±−\-]?\d+?(?:[.,]\d+?)?)(([ °^*]| [°^*])F)(?=[ "').,;|!?]|$)/gm, "$1$2\u00A0°F")
    //======================================
    // Replace "...", "&hellip;" and "&#133;" with ellipsis
    txt = txt.replace(/(\.{3}|\&(hellip|#133);)/g, '…')
    // Apostrophe handler
    txt = txt.replace(/([\wа-яА-ЯёЁ])'([\wа-яА-ЯёЁ])/g, "$1’$2")
    // Minus handler
    txt = txt.replace(/(sup\>|sub\>|\s)-(\d)/g, "$1−$2")
    //======================================
    // Replace hyphens and en dashes with normal dashes
    txt = txt.replace(/\&(#151|[nm]dash);/g, "—")
    txt = txt.replace(/(&nbsp;|[\f\n\r\t\v\u00A0\u2028\u2029])(-|--|–) /g, "$1— ")
    txt = txt.replace(/(\d)--(\d)/g, "$1—$2")
    // Insert non-braiking space before dashes
    txt = txt.replace(/(\S) (-|--|–|—) (\S)/g, "$1\u00A0— $3")
    //======================================
    // Special characters: ©, ®, ™, §, €, ¥ и £.
    txt = txt.replace(/\&copy;/gi, "©")
    txt = txt.replace(/(\(r\)|\&reg;)/gi, "®")
    txt = txt.replace(/(\((tm|тм)\)|\&trade;)/gi, "™")
    txt = txt.replace(/(\(p\)|\&sect;)/gi, "§")
    txt = txt.replace(/\&euro;/gi, "€")
    txt = txt.replace(/\&yen;/gi, "¥")
    txt = txt.replace(/\&pound;/gi, "£")
    //======================================
    // UZBEK01
    txt = txt.replace(/(O|o|G|g)\`/g, "$1ʻ")
    txt = txt.replace(/(A|a|E|e|N|n|T|t)\`/g, "$1ʼ")
    txt = txt.replace(/(O|o|G|g)\ʼ/g, "$1ʻ")
    txt = txt.replace(/(A|a|E|e|N|n|T|t)\ʻ/g, "$1ʼ")
    txt = txt.replace(/(O|o|G|g)\’/g, "$1ʻ")
    txt = txt.replace(/(A|a|E|e|N|n|T|t)\’/g, "$1ʼ")
    //======================================
    //// Cyr - Lat ala Uzbek
    //txt = txt.replace(/(б|в|г|д|ж|з|к|л|м|н|п|р|с|т|ф|х|ц|ч|ш|щ|,|:)\е/g, "$1e")
    //txt = txt.replace(/(а|е|ё|и|о|у|э|ю|я|,|:)\ц/g, "$1ts")
    //txt = txt.replace(/(ц)/g, "s")
    //txt = txt.replace(/(е)/g, "e")
    //txt = txt.replace(/(ъ)/g, "ʼ")
    //txt = txt.replace(/(Ты)/g, "Ti")
    //txt = txt.replace(/(ты)/g, "ti")
    //txt = txt.replace(/(Ё)/g, "Yo")
    //txt = txt.replace(/(ё)/g, "yo")
    //txt = txt.replace(/(Сентябрь)/g, "sentabr")
    //txt = txt.replace(/(Октябрь)/g, "oktabr")
    //txt = txt.replace(/(сентябрь)/g, "sentabr")
    //txt = txt.replace(/(октябрь)/g, "oktabr")
    //txt = txt.replace(/(Сентябр)/g, "sentabr")
    //txt = txt.replace(/(Октябр)/g, "oktabr")
    //txt = txt.replace(/(сентябр)/g, "sentabr")
    //txt = txt.replace(/(октябр)/g, "oktabr")
    //txt = txt.replace(/(Ж)/g, "J")
    //txt = txt.replace(/(ж)/g, "j")
    //txt = txt.replace(/(а)/g, "a")
    //txt = txt.replace(/(А)/g, "A")
    //txt = txt.replace(/(б)/g, "b")
    //txt = txt.replace(/(Б)/g, "B")
    //txt = txt.replace(/(в)/g, "v")
    //txt = txt.replace(/(В)/g, "V")
    //txt = txt.replace(/(г)/g, "g")
    //txt = txt.replace(/(Г)/g, "G")
    //txt = txt.replace(/(ғ)/g, "gʻ")
    //txt = txt.replace(/(Ғ)/g, "Gʻ")
    //txt = txt.replace(/(д)/g, "d")
    //txt = txt.replace(/(Д)/g, "D")
    //txt = txt.replace(/(е)/g, "e")
    //txt = txt.replace(/(Е)/g, "Ye")
    //txt = txt.replace(/(з)/g, "z")
    //txt = txt.replace(/(З)/g, "Z")
    //txt = txt.replace(/(и)/g, "i")
    //txt = txt.replace(/(И)/g, "I")
    //txt = txt.replace(/(й)/g, "y")
    //txt = txt.replace(/(Й)/g, "Y")
    //txt = txt.replace(/(к)/g, "k")
    //txt = txt.replace(/(К)/g, "K")
    //txt = txt.replace(/(қ)/g, "q")
    //txt = txt.replace(/(Қ)/g, "Q")
    //txt = txt.replace(/(л)/g, "l")
    //txt = txt.replace(/(Л)/g, "L")
    //txt = txt.replace(/(м)/g, "m")
    //txt = txt.replace(/(М)/g, "M")
    //txt = txt.replace(/(н)/g, "n")
    //txt = txt.replace(/(Н)/g, "N")
    //txt = txt.replace(/(о)/g, "o")
    //txt = txt.replace(/(О)/g, "O")
    //txt = txt.replace(/(п)/g, "p")
    //txt = txt.replace(/(П)/g, "P")
    //txt = txt.replace(/(р)/g, "r")
    //txt = txt.replace(/(Р)/g, "R")
    //txt = txt.replace(/(с)/g, "s")
    //txt = txt.replace(/(С)/g, "S")
    //txt = txt.replace(/(т)/g, "t")
    //txt = txt.replace(/(Т)/g, "T")
    //txt = txt.replace(/(у)/g, "u")
    //txt = txt.replace(/(У)/g, "U")
    //txt = txt.replace(/(ў)/g, "oʻ")
    //txt = txt.replace(/(Ў)/g, "Oʻ")
    //txt = txt.replace(/(ф)/g, "f")
    //txt = txt.replace(/(Ф)/g, "F")
    //txt = txt.replace(/(х)/g, "x")
    //txt = txt.replace(/(Х)/g, "X")
    //txt = txt.replace(/(ҳ)/g, "h")
    //txt = txt.replace(/(Ҳ)/g, "H")
    //txt = txt.replace(/(ц)/g, "s")
    //txt = txt.replace(/(Ц)/g, "Ts")
    //txt = txt.replace(/(Ч)/g, "Ch")
    //txt = txt.replace(/(ч)/g, "ch")
    //txt = txt.replace(/(Ш)/g, "Sh")
    //txt = txt.replace(/(ш)/g, "sh")
    //txt = txt.replace(/(ы)/g, "i")
    //txt = txt.replace(/(Ы)/g, "I")
    //txt = txt.replace(/(Ь)/g, "")
    //txt = txt.replace(/(ь)/g, "")
    //txt = txt.replace(/(Э)/g, "E")
    //txt = txt.replace(/(э)/g, "e")
    //txt = txt.replace(/(Ю)/g, "Yu")
    //txt = txt.replace(/(ю)/g, "yu")
    //txt = txt.replace(/(Я)/g, "Ya")
    //txt = txt.replace(/(я)/g, "ya")

    //======================================
    // Correct the reductions
    txt = txt.replace(/(Т|т)\. ?е\./g, "$1о есть")
    txt = txt.replace(/(Т|т)\. ?к\./g, "$1ак как")
    txt = txt.replace(/(В|в) т\. ?ч\./g, "$1 том числе")
    txt = txt.replace(/и т\. ?д\./g, "и\u00A0т\.\u00A0д\.")
    txt = txt.replace(/и т\. ?п\./g, "и\u00A0т\.\u00A0п\.")
    txt = txt.replace(/(Т|т)\. ?н\./g, "$1\.\u00A0н\.")
    txt = txt.replace(/н\. ?э\./g, "н\.\u00A0э\.")
    txt = txt.replace(/(Д|д)(о|\.) н\. ?э\./g, "$1о\u00A0н\.\u00A0э\.")
    txt = txt.replace(/(\d) (тыс)([^\.А-Яа-яЁё])/g, "$1\u00A0$2.$3")
    txt = txt.replace(/(\d) (млн|млрд|трлн)([^А-Яа-яЁё])/g, "$1\u00A0$2$3")
    // Insert missing and delete unnecessary spaces
    txt = txt.replace(/([А-Я]\.) ?([А-Я]\.) ?([А-Я][а-я])/g, "$1\u00A0$2\u00A0$3")
    txt = txt.replace(/([А-Я]\.)([А-Я]\.)/g, "$1 $2")
    txt = txt.replace(/^([#\*:]+)([ \t\f\v]*)([^ \t\f\v\*#:])/gm, "$1 $3")
    txt = txt.replace(/([а-я])(\.)([А-ЯA-Z])/g, "$1$2 $3")
    txt = txt.replace(/([а-яa-z\)\»\“\"\]])(\s*)(\,)([а-яa-z\(\«\„\"\[])/g, "$1$3 $4")
    txt = txt.replace(/([а-яa-z\)\»\“\"\]])(\s)([\,\;])(\s)([а-яa-z\(\«\„\"\[])/g, "$1$3 $5")
    txt = txt.replace(/([^%\/\w]\d+?(?:[.,]\d+?)?) ?([%‰])(?!-[А-Яа-яЁё])/g, "$1\u00A0$2")
    txt = txt.replace(/(\d) ([%‰])(?=-[А-Яа-яЁё])/g, "$1$2")
    txt = txt.replace(/([№§])(\s*)(\d)/g, "$1\u00A0$3")
    txt = txt.replace(/(^|[^ \t])([ \t]+)($|\n)/gm, "$1$3")
    txt = txt.replace(/(\()( +)/g, "$1");
    txt = txt.replace(/( +)(\))/g, "$2");
    //======================================
    // Avoid double spaces
    txt = txt.substr(1, txt.length - 1);
    txt = txt.replace(/(\S)([ \t]{2,})([\S\r])/g, "$1 $3")
    txt = " " + txt
    //======================================
    // Replace double quotes ("")  with double angle quotes («»)
    //txt = txt.replace(/([\x01-(\s\|\"]|\/|\+)(\")([^\"]{0,})([^\s\"(])(\")/g, "$1«\$3\$4»")
    // Quotations in quotes
    if (/"/.test(txt)) {
        txt = txt.replace(/([\x01(\s\"])(\")([^\"]{0,})([^\s\"(])(\")/g, "\$1„\$3\$4“")
        while (/(«)([^»]*)(«)/.test(txt))
            txt = txt.replace(/(«)([^»]*)(«)([^»]*)(»)/g, "\$1\$2„\$4“")
    }

}


function addWkikifPanel() {
    var wf = '<a href="javascript:Wikify();" title="Vikifikatsiya qil!" style="text-decoration: none;color:#000; font-weight:bold; font-size:16px; border:solid 1px #4444FF; background: #aabbff !important; padding: 1px 4px !important;" accesskey="w">Vikifikator</a></span> [<a href="/wiki/Vikipediya:Vikifikator" target="_blank" title="Vikifikator haqida yordam beti">?</a>]';

    /*var d = document;
    if (d.getElementById('wpSummaryLabel')) {
        var wps = d.getElementById('wpSummaryLabel').getElementsByTagName('span')[0];
        if (wps) {
            wps.innerHTML = wf + wps.innerHTML;
        }
    }*/
    //$('.editOptions').before(wf);
    var $editTools = $('.mw-editTools');
    $('.editOptions').before($editTools);
    $('#wikificatorPlaceHolder').append(wf);

    oldSel = document.getElementById('specialchars');
    if (oldSel) oldSel.innerHTML = '';
}

// Вставляет стаб, выбранный из списка
function insertStub(obj) {
    var id = obj.options[obj.selectedIndex].value;
    if (id != '0') insertTags(t[id][0], t[id][2], t[id][1]);
    obj.selectedIndex = 0;
}

$(document).ready(addWkikifPanel);

/* </pre> */