تفاوت میان نسخه‌های «مدیاویکی:Gadget-Extra-Editbuttons-persianwikitools.js»

از مشروطه
پرش به ناوبری پرش به جستجو
(صفحه‌ای تازه حاوی «// <nowiki> // DO NOT REMOVE THIS LINE EVER /** * Wikipedia specific Persian text style improvement tools * Tests: [[مدیاویکی:Gad...» ایجاد کرد)
 
 
خط ۷: خط ۷:
 
/*global persianTools, persianToolsDictionary, autoEd*/
 
/*global persianTools, persianToolsDictionary, autoEd*/
 
var persianWikiTools = (function () {
 
var persianWikiTools = (function () {
    'use strict';
+
'use strict';
    var patterns = {
+
var patterns = {
        arabicDigitsEnglishContext: /[a-z]([\|a-z %"'\._:\;,\-\\\/\(\)\#\^\+\d><–\[\]&?{}](?!\|\|))*\d|(\d|[a-z])[a-z %"'\._:\;\|,\-\\\/\(\)\#\^\+\d><–\[\]&?{}]*[a-z]\d*/gi,
+
arabicDigitsEnglishContext: /[a-z]([\|a-z %"'\._:\;,\-\\\/\(\)\#\^\+\d><–\[\]&?{}](?!\|\|))*\d|(\d|[a-z])[a-z %"'\._:\;\|,\-\\\/\(\)\#\^\+\d><–\[\]&?{}]*[a-z]\d*/gi,
        arabicTagEnclosed: /\{\{(?:عربی|شروع عربی|آغاز عربی)\}\}([\s\S]*?)\{\{(?:پایان عربی)\}\}/g,
+
arabicTagEnclosed: /\{\{(?:عربی|شروع عربی|آغاز عربی)\}\}([\s\S]*?)\{\{(?:پایان عربی)\}\}/g,
        LtRTagEnclosed: /\{\{(?:چپ چین|چپ‌چین)\}\}([\s\S]*?)\{\{(?:پایان چپ‌چین|پایان چپ چین|پایان)\}\}/g,
+
LtRTagEnclosed: /\{\{(?:چپ چین|چپ‌چین)\}\}([\s\S]*?)\{\{(?:پایان چپ‌چین|پایان چپ چین|پایان)\}\}/g,
        argumentsBlacklist: /(?:accessdate|namespace|image|تصویر|doi|style|شابک|عرض|bibcode|isbn|issn|pmid|arxiv|upright|upleft|padding|spacing|border|filename|نام پرونده)\s*\=\s*[^\|\}\]]*/gi,
+
argumentsBlacklist: /(?:accessdate|namespace|image|تصویر|doi|style|شابک|عرض|bibcode|isbn|issn|pmid|arxiv|upright|upleft|padding|spacing|border|filename|نام پرونده)\s*\=\s*[^\|\}\]]*/gi,
        color: /#(?:[abcdef0-9]{8}|[abcdef0-9]{6}|[abcdef0-9]{3})/gi,
+
color: /#(?:[abcdef0-9]{8}|[abcdef0-9]{6}|[abcdef0-9]{3})/gi,
        //colorAsParameter: /\=\s*(?:[abcdef0-9]{8}|[abcdef0-9]{6}|[abcdef0-9]{3})(?:[\s\|\}]|$)/gi,
+
//colorAsParameter: /\=\s*(?:[abcdef0-9]{8}|[abcdef0-9]{6}|[abcdef0-9]{3})(?:[\s\|\}]|$)/gi,
        // space, ", \t, \n, {, |, }, ... they will interfere with wiki markup
+
// space, ", \t, \n, {, |, }, ... they will interfere with wiki markup
        decodeUriBlacklist: /(?:%20|%27|%5C|%5E|%60|%23|%25|%3C|%3E|%5B|%5D|%22|%09|%0A|%7B|%7C|%7D)/gi,
+
decodeUriBlacklist: /(?:%20|%27|%5C|%5E|%60|%23|%25|%3C|%3E|%5B|%5D|%22|%09|%0A|%7B|%7C|%7D)/gi,
        diffLink: /\[\[(?:ویژه|Special):(?:تفاوت|Diff)\/[^\|\]]*/gi,
+
diffLink: /\[\[(?:ویژه|Special):(?:تفاوت|Diff)\/[^\|\]]*/gi,
        englishDate: /\d{1,2},? [a-z]{3,} \d{2,4}/gi, // 3, May 2013
+
englishDate: /\d{1,2},? [a-z]{3,} \d{2,4}/gi, // 3, May 2013
        fileNames: /(?:پرونده|File|تصویر|Image)\:.*?(?=\||\]|\n|$)/gi, // don't capture | after
+
fileNames: /(?:پرونده|File|تصویر|Image)\:.*?(?=\||\]|\n|$)/gi, // don't capture | after
        fileParameter: /\|\s*(image|تصویر)\s*\=\s*.*/g,
+
fileParameter: /\|\s*(image|تصویر)\s*\=\s*.*/g,
        ipSign: /\[\[ویژه:مشارکت\u200cها.*?\]\]/g,
+
ipSign: /\[\[ویژه:مشارکت\u200cها.*?\]\]/g,
        isbn: /(?:ISBN|ISSN|PMID) [\d\-]*/gi,
+
isbn: /(?:ISBN|ISSN|PMID) [\d\-]*/gi,
        galleryTag: /<gallery.*?>[\s\S]*?<\/gallery>/g,
+
galleryTag: /<gallery.*?>[\s\S]*?<\/gallery>/g,
        htmlAttributes: /(?:style|perrow|colspan|color|rowspan|cellpadding|cellspacing|height|width|size|border|thumbtime|name|perrow|upright|upleft)\s*[\=\:]\s*(?:['\"].*?['\"]|[\da-z]+)/gi,
+
htmlAttributes: /(?:style|perrow|colspan|color|rowspan|cellpadding|cellspacing|height|width|size|border|thumbtime|name|perrow|upright|upleft)\s*[\=\:]\s*(?:['\"].*?['\"]|[\da-z]+)/gi,
        htmlEntity: /&#\d+;/,
+
htmlEntity: /&#\d+;/,
        imagePixelSize: /[\|=] *[x\d]+?(px|پیکسل)[\]\|\s]/g, // means it will capture |10px| and |10x10px|
+
imagePixelSize: /[\|=] *[x\d]+?(px|پیکسل)[\]\|\s]/g, // means it will capture |10px| and |10x10px|
        insideQuote: /[^ا]".*?"/g,
+
insideQuote: /[^ا]".*?"/g,
        wikilinkTargets: /\[[^\[|\]]+/g,
+
wikilinkTargets: /\[[^\[|\]]+/g,
        nowikiTag:/<nowiki>.+?<\/nowiki>/g,
+
nowikiTag:/<nowiki>.+?<\/nowiki>/g,
        preTag:/<pre.*?>.*?<\/pre>/g,
+
preTag:/<pre.*?>.*?<\/pre>/g,
        insideHtmlComment: /<\!\-\-[\s\S]*?\-\->/g,
+
insideHtmlComment: /<\!\-\-[\s\S]*?\-\->/g,
        linksOnEnglishContext: /[a-z][\:\,\. ]*\[\[[\da-z\-\, ]*/gi,
+
linksOnEnglishContext: /[a-z][\:\,\. ]*\[\[[\da-z\-\, ]*/gi,
        mathTag: /<math.*?>[\s\S]*?<\/math>/g,
+
mathTag: /<math.*?>[\s\S]*?<\/math>/g,
        otherLanguagesInline: /\{\{(?:به .+?|به انگلیسی|انگلیسی|عربی|حدیث|به عربی|به اردو|اردو|lang\-[au]r)[\s\S]*?\}\}/g,
+
otherLanguagesInline: /\{\{(?:به .+?|به انگلیسی|انگلیسی|عربی|متن عربی|عبارت عربی|حدیث|به عربی|به اردو|اردو|lang\-[au]r|پینگ|ping)[\s\S]*?\}\}/g,
        parameter: /\{\{\{\d+/gi,
+
parameter: /\{\{\{\d+/gi,
        parenthesesAfterDigits: /\w\s?\([\w\s\.\-]*?\)/g,
+
parenthesesAfterDigits: /\w\s?\([\w\s\.\-]*?\)/g,
        parenthesesHa: /\)ها/g,
+
parenthesesHa: /\)ها/g,
        ref: /(?:<ref[^\/]*?>[\s\S]*?<\/ref>|<ref[^\/]*?\/>)/g, // inside <ref></ref> and <ref/>
+
ref: /(?:<ref[^\/]*?>[\s\S]*?<\/ref>|<ref[^\/]*?\/>)/g, // inside <ref></ref> and <ref/>
        refname: /\<ref name\=.*?\>/g,
+
refname: /\<ref name\=.*?\>/g,
        citation:/\{\{\s*(?:[Cc]it|یادکرد).*?[_\s]*(?:\{\{.*?\}\}|[^\}])*\}\}/g,
+
citation:/\{\{\s*(?:[Cc]it|یادکرد).*?[_\s]*(?:\{\{.*?\}\}|[^\}])*\}\}/g,
        signatures: /\[\[(?:کاربر|User|بحث[ _]کاربر|User[_ ]talk)\:.*?\]\]/gi,
+
signatures: /\[\[(?:کاربر|User|بحث[ _]کاربر|User[_ ]talk)\:.*?\]\]/gi,
        sourceTag: /(<source.*?>[\s\S]*?<\/source>|<syntaxhighlight.*?>[\s\S]*?<\/syntaxhighlight>|<code.*?>[\s\S]*?<\/code>|<timeline.*?>[\s\S]*?<\/timeline>)/g,
+
sourceTag: /(<source.*?>[\s\S]*?<\/source>|<syntaxhighlight.*?>[\s\S]*?<\/syntaxhighlight>|<code.*?>[\s\S]*?<\/code>|<timeline.*?>[\s\S]*?<\/timeline>)/g,
        tagNames: /<\/?[a-zA-Z\d]*/g,
+
tagNames: /<\/?[a-zA-Z\d]*/g,
        templateEnglishName: /(الگو|Template):[a-z][a-z\d\-\+_]+/gi,
+
templateEnglishName: /(الگو|Template):[a-z][a-z\d\-\+_]+/gi,
        templateWithEnglishName: /\{\{[ \_]*(?:(?:الگو|Template):)?(?:start\-date)[ \_]*\|.*?\}\}/gi,
+
templateWithEnglishName: /\{\{[ \_]*(?:(?:الگو|Template):)?(?:start\-date)[ \_]*\|.*?\}\}/gi,
        templateParameterName: /\|\s*(?=[a-z_]*\d)[a-z_\d]*\s*\=/gi,
+
templateParameterName: /\|\s*(?=[a-z_]*\d)[a-z_\d]*\s*\=/gi,
        globalExceptionTag: /(<nowiki>.+?<\/nowiki>|<!--[\s]*ابر[\s]*-->.+?<!--[\s]*\/[\s]*ابر[\s]*-->)/gi,
+
globalExceptionTag: /(<nowiki>.+?<\/nowiki>|<!--[\s]*ابر[\s]*-->.+?<!--[\s]*\/[\s]*ابر[\s]*-->)/gi,
        translatedUrl: /.(کام|نت|آی‌آر)/g,
+
translatedUrl: /.(کام|نت|آی‌آر)/g,
        url: /\/\/.*?(?=[\s\n\|\}\]<]|$)/gi     // بدون https?: هم ممکن است
+
boxVar: /([a-zA-Z][۱۲۳۴۵۶۷۸۹۰]+) *\=/g,
    };
+
url: /\/\/.*?(?=[\s\n\|\}\]<]|$)/gi, // بدون https?: هم ممکن است
 +
articleTitleParts: new RegExp('\\s' + mw.config.get('wgTitle').split(' ').join('\\s|\\s') + '\\s', 'g')
 +
};
  
    function escapeRE( s ) {
+
function escapeRE( s ) {
        return s.replace( /([$()*+\-.?[\\\]^{|}])/g, '\\$1' );
+
return s.replace( /([$()*+\-.?[\\\]^{|}])/g, '\\$1' );
    }
+
}
  
    function descendingFromComparetor(x, y) {
+
function descendingFromComparetor(x, y) {
        return x.from - y.from;
+
return x.from - y.from;
    }
+
}
  
    function replaceExcept(text, callback, excepts) {
+
function replaceExcept(text, callback, excepts) {
        var match, result = [], i, ranges, minRange, to, min, max;
+
var match, result = [], i, ranges, minRange, to, min, max;
        while (text !== '') {
+
while (text !== '') {
            ranges = [];
+
ranges = [];
  
            for (i in excepts) {
+
for (i in excepts) {
                if (excepts.hasOwnProperty(i)) {
+
if (excepts.hasOwnProperty(i)) {
                    // a global regex should be reset before calls
+
// a global regex should be reset before calls
                    excepts[i].lastIndex = 0;
+
excepts[i].lastIndex = 0;
                    match = excepts[i].exec(text);
+
match = excepts[i].exec(text);
                    if (match !== null) {
+
if (match !== null) {
                        ranges.push({
+
ranges.push({
                            from: match.index,
+
from: match.index,
                            to: match.index + match[0].length
+
to: match.index + match[0].length
                        });
+
});
                    }
+
}
                }
+
}
            }
+
}
  
            // so nothing is matched
+
// so nothing is matched
            if (ranges.length === 0) {
+
if (ranges.length === 0) {
                result.push(callback(text));
+
result.push(callback(text));
                break;
+
break;
            }
+
}
  
            minRange = ranges.sort(descendingFromComparetor)[0];
+
minRange = ranges.sort(descendingFromComparetor)[0];
            min = minRange.from;
+
min = minRange.from;
  
            to = [];
+
to = [];
            for (i in ranges) {
+
for (i in ranges) {
                if (ranges.hasOwnProperty(i)) {
+
if (ranges.hasOwnProperty(i)) {
                    if (ranges[i].from <= minRange.to) {
+
if (ranges[i].from <= minRange.to) {
                        to.push(ranges[i].to);
+
to.push(ranges[i].to);
                    }
+
}
                }
+
}
            }
+
}
            max = Math.max.apply(null, to);
+
max = Math.max.apply(null, to);
  
            result.push(callback(text.substr(0, min)));
+
result.push(callback(text.substr(0, min)));
            result.push(text.substr(min, max - min));
+
result.push(text.substr(min, max - min));
            // console.log('Excepted: "' + text.substr(min, max - min) + '"');
+
// console.log('Excepted: "' + text.substr(min, max - min) + '"');
            text = text.substr(max);
+
text = text.substr(max);
        }
+
}
        return result.join('');
+
return result.join('');
    }
+
}
  
    function wikiConvertToPersianCharacters(text) {
+
function wikiConvertToPersianCharacters(text) {
        return replaceExcept(
+
return replaceExcept(
            text,
+
text,
            persianTools.toStandardPersianCharacters,
+
persianTools.toStandardPersianCharacters,
            [patterns.globalExceptionTag, patterns.otherLanguagesInline, patterns.arabicTagEnclosed, patterns.fileNames, patterns.signatures, patterns.url]
+
[patterns.globalExceptionTag, patterns.otherLanguagesInline, patterns.arabicTagEnclosed, patterns.fileNames, patterns.signatures, patterns.url]
        );
+
);
    }
+
}
  
    if (!String.prototype.trim) { // if is not available currently
+
if (!String.prototype.trim) { // if is not available currently
        String.prototype.trim = function () {
+
String.prototype.trim = function () {
            return this.replace(/^\s+|\s+$/g, '');
+
return this.replace(/^\s+|\s+$/g, '');
        };
+
};
    }
+
}
  
    function autoFormatCleanReferences ( str ) {
+
function autoFormatCleanReferences ( str ) {
        // تمیزکاری autoFormater.js > cleanReferences
+
// تمیزکاری autoFormater.js > cleanReferences
        str = str.replace(
+
str = str.replace(
            /<\s*references\s*(\s\b[^<>]*?)?\s*(?:\/|>\s*<\s*\/\s*references)\s*>/gi,
+
/<\s*references\s*(\s\b[^<>]*?)?\s*(?:\/|>\s*<\s*\/\s*references)\s*>/gi,
            '<references$1 />'
+
'<references$1 />'
        );
+
);
        str = str.replace( /<\s*references\s*(\s\b[^<\/>]*?)?\s*>/gi, '<references$1>' );
+
str = str.replace( /<\s*references\s*(\s\b[^<\/>]*?)?\s*>/gi, '<references$1>' );
        str = str.replace( /<\s*\/\s*references\s*>/gi, '<\/references>' );
+
str = str.replace( /<\s*\/\s*references\s*>/gi, '<\/references>' );
        var re = /(<references[^<\/>]*)>/g, m;
+
var re = /(<references[^<\/>]*)>/g, m;
        while ( m = re.exec( str ) ) {
+
while ( m = re.exec( str ) ) {
            if ( str.indexOf( '<\/references>', m.index ) < 0 ) {
+
if ( str.indexOf( '<\/references>', m.index ) < 0 ) {
                str = str.slice( 0, m.index ) + m[1] + ' />' + str.slice( m.index + m[0].length );
+
str = str.slice( 0, m.index ) + m[1] + ' />' + str.slice( m.index + m[0].length );
            }
+
}
        }
+
}
        str = str.replace( /< *ref\s*(\s\b[^<>]*?)\s*(?:\/+|>\s*<\s*\/+\s*ref) *>/gi, '<ref$1 />' );
+
str = str.replace( /< *ref\s*(\s\b[^<>]*?)\s*(?:\/+|>\s*<\s*\/+\s*ref) *>/gi, '<ref$1 />' );
  
        /* remove line breaks with assays only the top of the article */
+
/* remove line breaks with assays only the top of the article */
        var i = str.indexOf( '<references' ),
+
var i = str.indexOf( '<references' ),
            slice;
+
slice;
        if ( i > 0 ) {
+
if ( i > 0 ) {
            slice = str.slice( i );
+
slice = str.slice( i );
            slice = slice.replace( /< *ref\s*(\s\b[^<\/>]*?)?\s*>[\t ]*/gi, '<ref$1>' );
+
slice = slice.replace( /< *ref\s*(\s\b[^<\/>]*?)?\s*>[\t ]*/gi, '<ref$1>' );
            slice = slice.replace( /(?:(\n[\t ]*)|[\t ]*)<\s*\/+\s*ref\s*>/gi, '$1<\/ref>' );
+
slice = slice.replace( /(?:(\n[\t ]*)|[\t ]*)<\s*\/+\s*ref\s*>/gi, '$1<\/ref>' );
            str = str.slice( 0, i );
+
str = str.slice( 0, i );
        }
+
}
        str = str.replace( /< *ref\s*(\s\b[^<\/>]*?)?\s*>\s*/gi, '<ref$1>' );
+
str = str.replace( /< *ref\s*(\s\b[^<\/>]*?)?\s*>\s*/gi, '<ref$1>' );
        str = str.replace( /\s*<\s*\/+\s*ref\s*>/gi, '<\/ref>' );
+
str = str.replace( /\s*<\s*\/+\s*ref\s*>/gi, '<\/ref>' );
        if ( slice ) {
+
if ( slice ) {
            str += slice;
+
str += slice;
        }
+
}
  
        /* Space between the end of block and remove <ref> or two <ref> */
+
/* Space between the end of block and remove <ref> or two <ref> */
        str = str.replace( /([!,.;?]|<ref\b[^<>]*(?:\/|>[^<>]*<\/ref)>) +(?=<ref[ >])/gi, '$1' );
+
str = str.replace( /([!,.;?]|<ref\b[^<>]*(?:\/|>[^<>]*<\/ref)>) +(?=<ref[ >])/gi, '$1' );
        /* Two identical punctuation before and cut after a <ref> on one */
+
/* Two identical punctuation before and cut after a <ref> on one */
        return str.replace( /([!,.:;?])(<ref\b[^<>]*(?:\/|>[^<>]*<\/ref)>)\1/gi, '$1$2' );
+
return str.replace( /([!,.:;?])(<ref\b[^<>]*(?:\/|>[^<>]*<\/ref)>)\1/gi, '$1$2' );
    }
+
}
  
    function autoFormatCleanTags(str) {
+
function autoFormatCleanTags(str) {
        str = str.replace( /(<\/?s)trike\b/gi, '$1' );
+
str = str.replace( /(<\/?s)trike\b/gi, '$1' );
        str = str.replace(
+
str = str.replace(
            /<sub\s*(>[^<>]*<)\s*(?:su[bp]\s*[.\/\\]+|[.\/\\]+\s*su[bp])\s*>/gi,
+
/<sub\s*(>[^<>]*<)\s*(?:su[bp]\s*[.\/\\]+|[.\/\\]+\s*su[bp])\s*>/gi,
            '<sub$1/sub>'
+
'<sub$1/sub>'
        );
+
);
        str = str.replace(
+
str = str.replace(
            /<sup\s*(>[^<>]*<)\s*(?:su[bp]\s*[.\/\\]+|[.\/\\]+\s*su[bp])\s*>/gi,
+
/<sup\s*(>[^<>]*<)\s*(?:su[bp]\s*[.\/\\]+|[.\/\\]+\s*su[bp])\s*>/gi,
            '<sup$1/sup>'
+
'<sup$1/sup>'
        );
+
);
  
        /* Drop default font attributes */
+
/* Drop default font attributes */
        str = str.replace(
+
str = str.replace(
            /(<font\b[^<>]*?)\s+fa\w+(?:[\s"',=]*(?:Arial|Helvetica(?:\W?N\w*)?|sans\W?serif)\b)+[\s"';]*(?=\s\w+\s*=|>)/gi,
+
/(<font\b[^<>]*?)\s+fa\w+(?:[\s"',=]*(?:Arial|Helvetica(?:\W?N\w*)?|sans\W?serif)\b)+[\s"';]*(?=\s\w+\s*=|>)/gi,
            '$1'
+
'$1'
        );
+
);
        str = str.replace(
+
str = str.replace(
            /(<font\b[^<>]*?)\s+size[\s"',=]*(?:-1\b|2\b|100\b[ ,.]*\d*%|1(?:\.0*)?em\b)["';]*/gi,
+
/(<font\b[^<>]*?)\s+size[\s"',=]*(?:-1\b|2\b|100\b[ ,.]*\d*%|1(?:\.0*)?em\b)["';]*/gi,
            '$1'
+
'$1'
        );
+
);
        /* Remove inline elements with no attributes */
+
/* Remove inline elements with no attributes */
        while ( /<(font|span)\s*>\s*(?:<(?!\1)|[^<])*?\s*<\/\1[^<>]*>/i.test( str ) ) {
+
while ( /<(font|span)\s*>\s*(?:<(?!\1)|[^<])*?\s*<\/\1[^<>]*>/i.test( str ) ) {
            str = str.replace( /<(font|span)\s*>\s*((?:<(?!\1)|[^<])*?)\s*<\/\1[^<>]*>/gi, '$2' );
+
str = str.replace( /<(font|span)\s*>\s*((?:<(?!\1)|[^<])*?)\s*<\/\1[^<>]*>/gi, '$2' );
        }
+
}
        str = str.replace(
+
str = str.replace(
            /<font\s+color[\s"',=]*(#[\dA-F]{3,6}|[a-z]{3,20})[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
+
/<font\s+color[\s"',=]*(#[\dA-F]{3,6}|[a-z]{3,20})[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
            '<span style="color:$1;">$2<\/span>'
+
'<span style="color:$1;">$2<\/span>'
        );
+
);
        str = str.replace(
+
str = str.replace(
            /<font\s+size[\s"',=]*(?:-[2-9]|[01])[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
+
/<font\s+size[\s"',=]*(?:-[2-9]|[01])[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
            '<small>$1<\/small>'
+
'<small>$1<\/small>'
        );
+
);
        str = str.replace(
+
str = str.replace(
            /<font\s+size[\s"',=]*(?:[+-]0|3)[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
+
/<font\s+size[\s"',=]*(?:[+-]0|3)[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
            '<span style="font-size:larger;">$1<\/span>'
+
'<span style="font-size:larger;">$1<\/span>'
        );
+
);
        /* Merge nested inline tags */
+
/* Merge nested inline tags */
        str = str.replace(
+
str = str.replace(
            /<(abbr|cite|mark|q|s|small|u)\s*><(font|span)\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*>([^<>]*)<\/\2\s*>\s*(?=<\/\1\s*>)/gi,
+
/<(abbr|cite|mark|q|s|small|u)\s*><(font|span)\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*>([^<>]*)<\/\2\s*>\s*(?=<\/\1\s*>)/gi,
            '<$1 style="$3;">$4'
+
'<$1 style="$3;">$4'
        );
+
);
        str = str.replace(
+
str = str.replace(
            /(<span\b[^<>]*?)\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*><span\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*>([^<>]*)<\/span\s*>\s*(?=<\/span\s*>)/gi,
+
/(<span\b[^<>]*?)\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*><span\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*>([^<>]*)<\/span\s*>\s*(?=<\/span\s*>)/gi,
            '$1 style="$2; $3;">$4'
+
'$1 style="$2; $3;">$4'
        );
+
);
  
        /* Verschiedenste Formen von HTML-Zeilenumbrüchen durch einheitliche ersetzen */
+
/* Verschiedenste Formen von HTML-Zeilenumbrüchen durch einheitliche ersetzen */
        str = str.replace( /<(?:[\s\/\\]*br\b)+\s*(\s\w[^<>]*?)?[\s.\/\\]*>/gi, '<br$1 />' );
+
str = str.replace( /<(?:[\s\/\\]*br\b)+\s*(\s\w[^<>]*?)?[\s.\/\\]*>/gi, '<br$1 />' );
        /* Unnötige HTML-Zeilenumbrüche entfernen, wenn sowieso ein Absatz folgt */
+
/* Unnötige HTML-Zeilenumbrüche entfernen, wenn sowieso ein Absatz folgt */
        str = str.replace( / *<br \/>(?=\n[\n#*:;])/gi, '' );
+
str = str.replace( / *(?:{{سخ}}|<br \/>)(?=[\r\n][\n#*:;\|}\]])/gi, '' );
        str = str.replace(
+
str = str.replace(
            /<(ref|small|su[bp])\b\s*(\s\w[^<>]*?)?\s*><small\s*>([^<>]*)<\/small\s*><\/\1\s*>/gi,
+
/<(ref|small|su[bp])\b\s*(\s\w[^<>]*?)?\s*><small\s*>([^<>]*)<\/small\s*><\/\1\s*>/gi,
            '<$1$2>$3<\/$1>'
+
'<$1$2>$3<\/$1>'
        );
+
);
        str = str.replace(
+
str = str.replace(
            /<small\s*><(ref|small|su[bp])\b\s*(\s\w[^<>]*?)?\s*?( ?\/|>[^<>]*<\/\1)\s*><\/small\s*>/gi,
+
/<small\s*><(ref|small|su[bp])\b\s*(\s\w[^<>]*?)?\s*?( ?\/|>[^<>]*<\/\1)\s*><\/small\s*>/gi,
            '<$1$2$3>'
+
'<$1$2$3>'
        );
+
);
        /* Drop old navigation bar wrapper, see [[Template:NaviBlock]] */
+
/* Drop old navigation bar wrapper, see [[Template:NaviBlock]] */
        return str.replace(
+
return str.replace(
            /<div\s+class[^<>\w]*BoxenVerschmelzen[^<>\w]*>\s*(\{\{[^#:<>{}]*\}\})\s*<\/div>/gi,
+
/<div\s+class[^<>\w]*BoxenVerschmelzen[^<>\w]*>\s*(\{\{[^#:<>{}]*\}\})\s*<\/div>/gi,
            '$1'
+
'$1'
        );
+
);
    }
+
}
  
    function autoFormatCleanDuplicateLinks(str){
+
function autoFormatCleanDuplicateLinks(str) {
 +
/* Exclude files and infoboxes from the start of the article */
 +
var m = /^(?:\s*\[\[\w+:(?:\[\[[^\n\]]*\]\]|[^\n\]])*\]\])*(?:\s*\{\{(?:\{\{[^}]*\}\}|[^}])*\}\})+/.exec( str ),
 +
start = m ? m[0].length : 0,
 +
found = [],
 +
a = [];
 +
/* Unlink years that are linked more than one time */
 +
var re = /\[\[ *([۱۲][۱۲۳۴۵۶۷۸۹۰]{3}|[۱۲][۱۲۳۴۵۶۷۸۹۰]{3} \((میلادی|قمری)\)) *\]\]/g;
 +
/* In each case the first discovery of a year noted entlinken thereafter */
 +
while ( m = re.exec( str ) ) {
 +
if ( m.index >= start ) {
 +
found[m[1]] ? a.push( m ) : found[m[1]] = true;
 +
}
 +
}
 +
var r = '',
 +
p = 0;
 +
for ( var i = 0; i < a.length; i++ ) {
 +
r += str.slice( p, a[i].index ) + a[i][1];
 +
p = a[i].index + a[i][0].length;
 +
}
 +
return p ? r + str.slice( p ) : str;
 +
}
  
        /* Exclude files and infoboxes from the start of the article */
+
function autoFormatCleanDates(str){
        var m = /^(?:\s*\[\[\w+:(?:\[\[[^\n\]]*\]\]|[^\n\]])*\]\])*(?:\s*\{\{(?:\{\{[^}]*\}\}|[^}])*\}\})+/.exec( str ),
+
var months = ["ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر", 'فروردین', 'اردیبهشت', 'خرداد', 'تیر',
            start = m ? m[0].length : 0,
+
'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند',"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
            found = [],
 
            a = [];
 
        /* Unlink years that are linked more than one time */
 
        var re = /\[\[ *([۱۲][۱۲۳۴۵۶۷۸۹۰]{3}|[۱۲][۱۲۳۴۵۶۷۸۹۰]{3} \((میلادی|قمری)\)) *\]\]/g;
 
        /* In each case the first discovery of a year noted entlinken thereafter */
 
        while ( m = re.exec( str ) ) {
 
            if ( m.index >= start ) {
 
                found[m[1]] ? a.push( m ) : found[m[1]] = true;
 
            }
 
        }
 
        var r = '',
 
            p = 0;
 
        for ( var i = 0; i < a.length; i++ ) {
 
            r += str.slice( p, a[i].index ) + a[i][1];
 
            p = a[i].index + a[i][0].length;
 
        }
 
        return p ? r + str.slice( p ) : str;
 
    }
 
  
    function autoFormatCleanDates(str){
+
/* Add missing space between day and month */
        var months = ["ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر", 'فروردین', 'اردیبهشت', 'خرداد', 'تیر',
+
str = str.replace( new RegExp( '([\\s!\'(>|„](?:3[01]|[12]\\d|0?[1-9])\\.?)(?=(?:' +
            'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند',"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
+
months.join( '|' ) + ')\\b)', 'g' ), '$1 ' );
 +
/* No non-breaking space between month and year */
 +
str = str.replace( new RegExp( '(\\b(?:3[01]|[12]\\d|0?[1-9])\\.?(?:[\\s\\xA0]|&nbsp;)+(?:' +
 +
months.join( '|' ) + '))(?:\xA0|&nbsp;)(?=[12]\\d{3}\\b)', 'g' ), '$1 ' );
 +
/* Missverständliches deutsches Datumsformat durch Langform ersetzen */
 +
var separator= ' ';
 +
str = str.replace(
 +
/([\s'(>„])(3[01]|[12]\d|0?[1-9])\. *(1[012]|0?[1-9])\. *(?=[12]\d{3}[!,.:;?]?[\s')<\]“])/g,
 +
function( $0, $1, $2, $3 ) {
 +
return $1 + ( $2 | 0 ) + separator + months[$3 | 0] + ' ';
 +
}
 +
);
 +
// عدد فارسی
 +
str = str.replace( new RegExp( '([\\s!\'(>|„](?:۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\\.?)(?=(?:' +
 +
months.join( '|' ) + ')[\\s\')<\\]»}|])', 'g' ), '$1 ' );
 +
/* No non-breaking space between month and year */
 +
str = str.replace( new RegExp( '([\\s\'(>«](?:۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\\.?(?:[\\s\\xA0]|&nbsp;)+(?:' +
 +
months.join( '|' ) + '))(?:\xA0|&nbsp;)(?=[۱۲][۱۲۳۴۵۶۷۸۹]{3}[\\s\')<\\]»}|])', 'g' ), '$1 ' );
 +
/* Missverständliches deutsches Datumsformat durch Langform ersetzen */
 +
var separator= ' ';
 +
str = str.replace(
 +
/([\s'(>«])(۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\. *(۱[۰۱۲]|۰?[۱۲۳۴۵۶۷۸۹])\. *(?=[۱۲][۱۲۳۴۵۶۷۸۹]{3}[!,.:;?]?[\s')<\]»}|])/g,
 +
function( $0, $1, $2, $3 ) {
 +
return $1 + ( $2 | 0 ) + separator + months[$3 | 0] + ' ';
 +
}
 +
);
 +
return str
 +
}
  
        /* Add missing space between day and month */
+
function quotation(text) {
        str = str.replace( new RegExp( '([\\s!\'(>|„](?:3[01]|[12]\\d|0?[1-9])\\.?)(?=(?:' +
+
// این تابع زمانی گیومه را به فارسی تیدیل می‌کند که در پاراگراف مورد نظر تعداد گیومهٔ لاتین زوج باشد.
            months.join( '|' ) + ')\\b)', 'g' ), '$1 ' );
+
var lines = text.split(/\n\n/);
        /* No non-breaking space between month and year */
+
var result = [];
        str = str.replace( new RegExp( '(\\b(?:3[01]|[12]\\d|0?[1-9])\\.?(?:[\\s\\xA0]|&nbsp;)+(?:' +
+
for (var i = 0; i < lines.length; ++i) {
            months.join( '|' ) + '))(?:\xA0|&nbsp;)(?=[12]\\d{3}\\b)', 'g' ), '$1 ' );
+
var line = lines[i];
        /* Missverständliches deutsches Datumsformat durch Langform ersetzen */
+
if ((line.match(/"/g) || []).length % 2 === 0) { // count of quote marks
        var separator= ' ';
+
// تبدیل گیومهٔ لاتین به فارسی
        str = str.replace(
+
// این دستور در ابتدا باشد تا فاصله‌های قبل و بعد گیومه هم اصلاح شود
            /([\s'(>„])(3[01]|[12]\d|0?[1-9])\. *(1[012]|0?[1-9])\. *(?=[12]\d{3}[!,.:;?]?[\s')<\]“])/g,
+
line = line.replace(
            function( $0, $1, $2, $3 ) {
+
new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.\\)]+)"((?:\\[\\[|).*?[' + persianTools.persianCharacters + '؛\\]+?(?:\\]\\]|\\.|\\<|\\:|))"([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{\\(]|$)', 'g'),
                return $1 + ( $2 | 0 ) + separator + months[$3 | 0] + ' ';
+
'$1«$2»$3'
            }
+
);
        );
+
// if some of quote marks are remained from conversion, something might wrong, revert
        //عدد فارسی
+
var testline=line.replace(/(?:<ref[^\/]*?>[\s\S]*?<\/ref>|<ref[^\/]*?\/>)/g,'')
        str = str.replace( new RegExp( '([\\s!\'(>|„](?:۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\\.?)(?=(?:' +
 
            months.join( '|' ) + ')[\\s\')<\\]»}|])', 'g' ), '$1 ' );
 
        /* No non-breaking space between month and year */
 
        str = str.replace( new RegExp( '([\\s\'(>«](?:۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\\.?(?:[\\s\\xA0]|&nbsp;)+(?:' +
 
            months.join( '|' ) + '))(?:\xA0|&nbsp;)(?=[۱۲][۱۲۳۴۵۶۷۸۹]{3}[\\s\')<\\]»}|])', 'g' ), '$1 ' );
 
        /* Missverständliches deutsches Datumsformat durch Langform ersetzen */
 
        var separator= ' ';
 
        str = str.replace(
 
            /([\s'(>«])(۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\. *(۱[۰۱۲]|۰?[۱۲۳۴۵۶۷۸۹])\. *(?=[۱۲][۱۲۳۴۵۶۷۸۹]{3}[!,.:;?]?[\s')<\]»}|])/g,
 
            function( $0, $1, $2, $3 ) {
 
                return $1 + ( $2 | 0 ) + separator + months[$3 | 0] + ' ';
 
            }
 
        );
 
        return str
 
    }
 
  
    function quotation(text) {
+
if (testline.match(/"/g)) {
        // این تابع زمانی گیومه را به فارسی تیدیل می‌کند که در پاراگراف مورد نظر تعداد گیومهٔ لاتین زوج باشد.
+
line = lines[i];
        var lines = text.split(/\n\n/);
+
}
        var result = [];
+
}
        for (var i = 0; i < lines.length; ++i) {
+
// رفع مشکل استفاده از ـً به جای گیومه لاتین در متن فارسی
            var line = lines[i];
+
line=line.replace(new RegExp('ا\\"([ ]*[' +persianTools.persianCharacters + '])', 'g'), 'اً$1')
            if ((line.match(/"/g) || []).length % 2 === 0) { // count of quote marks
+
// ”“ تبدیل
                // تبدیل گیومهٔ لاتین به فارسی
+
line = line.replace(
                // این دستور در ابتدا باشد تا فاصله‌های قبل و بعد گیومه هم اصلاح شود
+
new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)“((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))”([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
                line = line.replace(
+
'$1«$2»$3'
                    new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.\\)]+)"((?:\\[\\[|).*?[' + persianTools.persianCharacters + '؛\\]+?(?:\\]\\]|\\.|\\<|\\:|))"([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{\\(]|$)', 'g'),
+
);
                    '$1«$2»$3'
+
//وارونه ”“ تبدیل
                );
+
line = line.replace(
                // if some of quote marks are remained from conversion, something might wrong, revert
+
new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)”((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))“([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
                var testline=line.replace(/(?:<ref[^\/]*?>[\s\S]*?<\/ref>|<ref[^\/]*?\/>)/g,'')
+
'$1«$2»$3'
 +
);
 +
// ‘’ تبدیل
 +
line = line.replace(
 +
new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)‘((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))’([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
 +
'$1«$2»$3'
 +
);
 +
//وارونه ‘’ تبدیل
 +
line = line.replace(
 +
new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)’((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))‘([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
 +
'$1«$2»$3'
 +
);
 +
// ‚’ تبدیل  
 +
line = line.replace(
 +
new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)‚((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|))’([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
 +
'$1«$2»$3'
 +
);
 +
// „” تبدیل
 +
line = line.replace(
 +
new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)„((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))”([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
 +
'$1«$2»$3'
 +
);
 +
// << >> تبدیل
 +
line = line.replace(
 +
new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)\\<\\<((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))\\>\\>([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
 +
'$1«$2»$3'
 +
);
 +
// (()) تبدیل
 +
line = line.replace(
 +
new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)\\(\\(((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))\\)\\)([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
 +
'$1«$2»$3'
 +
);
 +
result.push(line);
 +
}
 +
return result.join('\n\n');
 +
}
 +
/**
 +
* افزودن ستون به الگوی پانویس
 +
* @param {string} text محتوا
 +
*/
 +
function addColumnToRefTemplate(text) {
 +
if ((text.match(/<ref>/gi) || []).length >= 6) {
 +
var refTemplate = /\{{2}پانویس([^\}\{]+)?\}{2}/i.exec(text), needChange = false;
 +
if (refTemplate) {
 +
if (refTemplate[1] !== undefined) {
 +
var refParams = refTemplate[1].split('|');
 +
for (var i = refParams.length - 1; i >= 0; i--) {
 +
// اگر از پیش ستون یا پارامتر عرض تعریف شده‌باشد تغییری ایجاد نمی‌شود.
 +
if (refParams[i].length == 1 || refParams[i].indexOf('عرض') > -1) {
 +
needChange = true;
 +
break;
 +
}
 +
}
 +
}
 +
if (refTemplate[1] === undefined || !needChange) {
 +
return text.replace(refTemplate[0], refTemplate[0].replace('}}', '|۲}}'));
 +
}
 +
}
 +
}
 +
 +
return text;
 +
}
 +
 +
/**
 +
* اصلاح پیوندها
 +
* @param  {string} text محتوا
 +
* @return {string}
 +
*/
 +
function fixBadLinks(text) {
 +
// حذف متن جایگزین پیوند اگر با نشانی پیوند برابر باشد؛ مانند [[سلام|سلام]]
 +
text = text.replace(/\[{2}([^\|]+)\|\1\]{2}/gi, '[[$1]]');
  
                if (testline.match(/"/g)) {
+
// حذف پیوند سال و روز ماه
                    line = lines[i];
+
text = text.replace(/\[{2}([۰-۹]+|[۰-۹]+ [\u0621-\u0655\u067E\u0686\u0698\u06AF\u06A9\u0643\u06AA\uFED9\uFEDA\u06CC\uFEF1\uFEF2]+)(?:\|(.+))?\]{2}/g, function (match, p1, p2) {
                }
+
// اگر فقط سال پیوند شده‌باشد یا به شکل [[سال|همان سال]] باشد فقط سال را می‌گرداند.
            }
+
if (p2 === undefined || p1 === p2) {
            // رفع مشکل استفاده از ـً به جای گیومه لاتین در متن فارسی
+
// اگر پیوند به روز و ماه بود، برای جلوگیری از اشتباه و تداخل، بررسی می‌شوند که حتما یکی از ماه‌ها داخل رشته باشد.
            line=line.replace(new RegExp('ا\\"([ ]*[' +persianTools.persianCharacters + '])', 'g'), 'اً$1')
+
if (p1.indexOf(" ") > -1) {
            // ”“ تبدیل
+
var
            line = line.replace(
+
months = ["فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند",
                new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)“((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))”([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
+
"ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر",
                '$1«$2»$3'
+
"محرم", "صفر", "ربیع‌الاول", "ربیع‌الثانی", "جمادی‌الاول", "جمادی‌الثانی", "رجب", "شعبان", "رمضان", "شوال", "ذیقعده", "ذیحجه"],
            );
+
i;
            //وارونه ”“ تبدیل
+
for (i = months.length - 1; i >= 0; i--) {
            line = line.replace(
+
if (p1.indexOf(months[i]) > -1) {
                new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)”((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))“([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
+
return p1;
                '$1«$2»$3'
+
}
            );
+
}
            // ‘’ تبدیل
+
return "[[" + p1 + "]]";
            line = line.replace(
+
}
                new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)‘((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))’([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
+
return p1;
                '$1«$2»$3'
+
}
            );
+
// اگر متن جایگزین پیوند مخالف پیوند سال بود، متن جایگزین را برمی‌گرداند.
            //وارونه ‘’ تبدیل
+
return p2;
            line = line.replace(
+
});
                new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)’((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))‘([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
 
                '$1«$2»$3'
 
            );
 
            // ‚’ تبدیل
 
            line = line.replace(
 
                new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)‚((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|))’([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
 
                '$1«$2»$3'
 
            );
 
            // „” تبدیل
 
            line = line.replace(
 
                new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)„((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))”([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
 
                '$1«$2»$3'
 
            );
 
            // << >> تبدیل
 
            line = line.replace(
 
                new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)\\<\\<((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))\\>\\>([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
 
                '$1«$2»$3'
 
            );
 
            // (()) تبدیل
 
            line = line.replace(
 
                new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)\\(\\(((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))\\)\\)([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
 
                '$1«$2»$3'
 
            );
 
            result.push(line);
 
        }
 
        return result.join('\n\n');
 
    }
 
    /**
 
    * افزودن ستون به الگوی پانویس
 
    * @param {string} text محتوا
 
    */
 
    function addColumnToRefTemplate(text) {
 
        if ((text.match(/<ref>/gi) || []).length >= 6) {
 
            var refTemplate = /\{{2}پانویس([^\}\{]+)?\}{2}/i.exec(text), needChange = false;
 
            if (refTemplate) {
 
                if (refTemplate[1] !== undefined) {
 
                    var refParams = refTemplate[1].split('|');
 
                    for (var i = refParams.length - 1; i >= 0; i--) {
 
                        // اگر از پیش ستون یا پارامتر عرض تعریف شده‌باشد تغییری ایجاد نمی‌شود.
 
                        if (refParams[i].length == 1 || refParams[i].indexOf('عرض') > -1) {
 
                            needChange = true;
 
                            break;
 
                        }
 
                    }
 
                }
 
                if (refTemplate[1] === undefined || !needChange) {
 
                    return text.replace(refTemplate[0], refTemplate[0].replace('}}', '|۲}}'));
 
                }
 
            }
 
        }
 
       
 
        return text;
 
    }
 
   
 
    /**
 
    * اصلاح پیوندها
 
    * @param  {string} text محتوا
 
    * @return {string}
 
    */
 
    function fixBadLinks(text) {
 
        // حذف متن جایگزین پیوند اگر با نشانی پیوند برابر باشد؛ مانند [[سلام|سلام]]
 
        text = text.replace(/\[{2}([^\|]+)\|\1\]{2}/gi, '[[$1]]');
 
  
        // حذف پیوند سال و روز ماه
+
return text;
        text = text.replace(/\[{2}([۰-۹]+|[۰-۹]+ [\u0621-\u0655\u067E\u0686\u0698\u06AF\u06A9\u0643\u06AA\uFED9\uFEDA\u06CC\uFEF1\uFEF2]+)(?:\|(.+))?\]{2}/g, function (match, p1, p2) {
+
}
        // اگر فقط سال پیوند شده‌باشد یا به شکل [[سال|همان سال]] باشد فقط سال را می‌گرداند.
 
        if (p2 === undefined || p1 === p2) {
 
            // اگر پیوند به روز و ماه بود، برای جلوگیری از اشتباه و تداخل، بررسی می‌شوند که حتما یکی از ماه‌ها داخل رشته باشد.
 
            if (p1.indexOf(" ") > -1) {
 
                var
 
                    months = ["فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند",
 
    "ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر",
 
    "محرم", "صفر", "ربیع‌الاول", "ربیع‌الثانی", "جمادی‌الاول", "جمادی‌الثانی", "رجب", "شعبان", "رمضان", "شوال", "ذیقعده", "ذیحجه"],
 
                    i;
 
                for (i = months.length - 1; i >= 0; i--) {
 
                    if (p1.indexOf(months[i]) > -1) {
 
                        return p1;
 
                    }
 
                }
 
                return "[[" + p1 + "]]";
 
            }
 
            return p1;
 
        }
 
        // اگر متن جایگزین پیوند مخالف پیوند سال بود، متن جایگزین را برمی‌گرداند.
 
        return p2;
 
    });
 
  
    return text;
+
function wikiPunctuation(text) {
}
+
text = autoFormatCleanReferences (text)
 +
text = autoFormatCleanTags(text)
 +
text = autoFormatCleanDuplicateLinks(text)
 +
text = replaceExcept(
 +
text,
 +
function (text) {
 +
return quotation(text);
 +
},
 +
[patterns.ref]
 +
);
 +
if (mw.config.get('wgNamespaceNumber') === 0){
 +
var old_text=text.replace(/\=\=/g, '')
 +
if (old_text==text){//در صورتی که در مقاله بخش‌بندی وجود نداشته باشد
 +
text=text.replace(/(\n\{\{سخ\}\}|\n\n)(\s|_|)\'\'\'(.*?)\'\'\'(\s|_|)(\{\{سخ\}\}|\n)([\n\#\*])/g, '\n\n== $3 ==\n$6')
 +
}
 +
}
 +
text = replaceExcept(
 +
text,
 +
function (text) {
 +
text = text.replace(
 +
new RegExp('([' + persianTools.persianCharactersNoVowels + '])ـ+([' + persianTools.persianCharactersNoVowels + '])', 'g'),
 +
'$1$2'
 +
);
 +
return text.replace(new RegExp('([' + persianTools.persianCharacters + '])(\\]\\]|), (\\[\\[|)?(?=[' + persianTools.persianCharacters + "])", 'g'), '$1$2، $3');
 +
},
 +
[patterns.globalExceptionTag, patterns.fileNames, patterns.url, patterns.galleryTag, patterns.sourceTag, patterns.translatedUrl, patterns.parenthesesHa]
 +
);
 +
text = replaceExcept(
 +
text,
 +
function (text) {
 +
return text.replace(/(<\/ref>)\s+(<ref)/g, '$1$2').replace(/([^=])\s+<ref(?!erences)/g, '$1<ref');
 +
},
 +
[/\{\{(پانویس|پانویس‌ها|پی‌نوشت)\s*\|[\s\S]*/]
 +
);
 +
return replaceExcept(
 +
text,
 +
function (text) {
 +
return persianTools.punctuation(text)
 +
.replace(/^([*#]+)([^*#\:\s])/mg, '$1 $2') // Adds a space after the # or * for lists
 +
.replace(/^([*#]+) {2,}([^*#\:\s])/mg, '$1 $2'); // Trim more that one space after the # or * for lists
 +
},
 +
[patterns.globalExceptionTag, patterns.fileNames, patterns.url, patterns.wikilinkTargets, patterns.galleryTag, patterns.sourceTag, patterns.translatedUrl, patterns.parenthesesHa]
 +
)
 +
.replace(/\u00A0/g, ' ') // convert implicit nbsp to space, probably is being added by some bug on ContentTranslation
 +
.replace(/٬ /g, '، ')
 +
.replace(new RegExp('([' + persianTools.persianCharacters + '\]])٬', 'g'), '$1،')
 +
.replace(new RegExp('([' + persianTools.persianCharacters + '])(\]\]|»|)[ ]*[,]', 'g'), '$1$2، ')
 +
.replace(new RegExp('\\[\\[(' + escapeRE(mw.config.get('wgPageName')) + ')\\]\\]', 'g'), '$1') // پیوندزدایی از خود صفحه
 +
//برگرفته از https://tools.wmflabs.org/checkwiki/cgi-bin/checkwiki.cgi?project=fawiki&view=project
 +
.replace(/\[\[([^\|\]]+)\|\1([\u200c ]*(های?))\]\]/g, '[[$1]]$2')//[[Special:Diff/17515365/17865938]]
 +
.replace(/([\S]*)[\s\u200c]*-[\s\u200c]*(تاکنون)(?![ ]+)/g, '$1-اکنون')//[[Special:Diff/17515365/17865938]]
 +
//مشکل در نشانی اینترنتی
 +
.replace(/(\<ref.*?\>) *(\[|)\www(3|)\./gi, '$1$2http://www$3.')
 +
.replace(/\[\[ *(https?\:\/\/.*?) *\]\]/g, '[$1]')
 +
.replace(/\[\[ *(\/\/.*?) *\]\]/g, '[$1]')
 +
.replace(/(https?:\/?\/?){2,}/g, '$1')
 +
// تمیزکاری autoFormatter.js > cleanExternalLinks
 +
.replace(/\b(?:http(s?)(?::+\/*|\/\/+:*)\b)+/gi, 'http$1://')
 +
// repair links with vertical stroke
 +
.replace(/(\[https?:\/\/[^\s[\]|]*?) *\| *(?=[^\s=[\]|]+\])/gi, '$1 ')
 +
// supplement slashes at the end easier Domains
 +
.replace(/(\[https?:\/\/\w[\w.-]*\w\.\w+) +/gi, '$1/ ')
 +
// Domains lowercase, whether labeled or not
 +
.replace(/\bhttps?:\/\/\b[0-9a-z.-]*[A-Z][\w.-]*/g, function ($0) {
 +
return $0.toLowerCase();
 +
})
 +
// پیوند به بیرون‌هایی که در میان پیوند نویسهٔ رفتن به خط بعد، وجود داشته باشد
 +
.replace(/\[(?:https?\:|)\/\/[^\]\[]+\]/g, function (x) {
 +
x = x.replace(/[\n\r]/g,'');
 +
return x
 +
})
 +
// فاصله اول زیربخش
 +
.replace(/^ +(\=+[^\=]+\=+)/mg, '$1')
 +
.replace(/\[\[\|/g, '[[')
 +
.replace(/(\< *\/ *br *\>|\< *br *\\ *\>|\< *br *\. *\>)/g, '<br/>')
 +
.replace(/(\<br *\/\>|\{\{سخ\}\})([\r\n])(\*|\#|\=\=)/g, '$2$3')
 +
.replace(/(\<br *\/\>|\{\{سخ\}\}) *\]\]/g, ']]')
 +
.replace(/\[\[ *(\<br *\/\>|\{\{سخ\}\})/g, '[[')
 +
.replace(/\[\[([^\]]+)\{\{\!\}\}([^\]]+)\]\]/g, '[[$1|$2]]')//وجود {{!}} درون پیوند
 +
.replace(/\[{2}([^\|]+)\|\1\]{2}/gi, '[[$1]]')//زمانی که بخش هدف و نمایه پیوند یکی باشند
 +
.replace(/\[\[(.+)\|('+)(.+\b)('+)\]\]/gi, '$2[[$1|$3]]$4')// انتقال ''' به بیرون پیوند
 +
// تمیزکاری autoFormatter.js > CleanGalleries
 +
.replace(/<gallery\b([^<>]*)>([^<>]+)<\/gallery\b[^<>]*>/gi,
 +
function( $0, $1, $2 ) {
 +
return '<gallery' + $1 + '>' + $2
 +
.replace( /^(\s*)\[+([^[\]]*)\]\]?\s*$/gm, '$1$2' )
 +
.replace( /^(\s*)\[+/gm, '$1' ) + '<\/gallery>';
 +
}
 +
)
 +
// تمیزکاری الگو autoFormater.js > cleanTemplates
 +
.replace( /\{\{\s*:?\s*(?:الگو|Template)\s*:\s*/gi, '{\{' )
 +
// حذف خط زیر از عنوان الگو
 +
.replace(/(?:^|[^{])\{\{[ 0-9a-z\xC0-\u024F-]*_[ \w\xC0-\u024F-]*/gi,
 +
function( $0 ) {
 +
return $0.replace( /_+$/, '' ).replace( /[ _]+/g, ' ' ).replace( /\{ +/, '{' );
 +
}
 +
)
 +
//سایر موارد
 +
.replace(/\[\[(رده|الگو|ویکی\u200cپدیا)\: +/g, '[[$1:')
 +
.replace(/[\n\s]*\{\{[•·ن](w?)\}\}\s*/g, '{{•$1}} ')
 +
.replace(/\=\{\{[•·ن](w?)\}\}\s*/g, '=\n{{•$1}} ')//رفع باگ [[Special:Diff/14799178/16387261]] در خط بالا
 +
.replace(/ *(<\/? ?br ?\/?>|\{\{بر\}\}) */g, '{{سخ}}')
 +
.replace(/\{\{سخ\}\}\n\n/g, '\n\n')
 +
.replace(/\n\n\{\{سخ\}\}/g, '\n\n')
 +
.replace(/\n\n(\*|\#)/g,'\n$1')
 +
.replace(/\n(\#|\*)( |)\n/g,'\n$1')
 +
.replace(/\n(\*|\#)( |)(\={2,})/g,'\n$3')
 +
.replace(/(\n?)\s+?<\/ref>/g, '$1</ref>')
 +
.replace( /^=.*&nbsp;.*=$/gim, function( $0 ) {
 +
return $0.replace( /(?:&nbsp;|\s)+/gi, ' ' );
 +
})
 +
.replace(/([^=])\n+(\=.*?\=\n+)/g, '$1\n\n$2')
 +
.replace(/^(=+([^=].*?)=+)[\t\s]{1,}\n/g, '$1\n')
 +
.replace(/^(\={2,}) +[\:,;>&\^#@•→←↔↑↓—–…~٫،؛ٔ]/mg, '$1') // Cleanup headers
 +
.replace(/[\:,;<&\^#@•→←↔↑↓—–…~٫،؛ٔ] +(\={2,})$/mg, '$1')
 +
.replace(/^(\={2,}\s*)(«)([^\n«»]*?)(»)(\s*\={2,})/mg, '$1 $3 $5')
 +
.replace(/^(\={2,}) *'+(.*?)'+ *(\={2,})/mg, '$1 $2 $3')
 +
.replace(/^[•●⚫⬤]/mg, '*') // Wikify bullets in start of lines
 +
.replace(/^#\s*(REDIRECT|تغییر[ _]?مسیر)/gi, '#تغییرمسیر')
 +
.replace(/^#تغییرمسیر(?=\S)/g, '#تغییرمسیر ') // Adds a space after #REDIRECT
 +
.replace(/(\={2,}) *([^\n\r]*?) *(\={2,})/g, '$1 $2 $3') // Format headings level 2 and above
 +
// فاصله‌های اضافی را از داخل پیوند به بیرون منتقل کند تا اگر اضافه بودند در کدهای دیگر حذف شوند
 +
.replace(/\[\[(\s*)(.*?)(\s*)\]\]/g, '$1[[$2]]$3')
 +
//حذف فاصلهٔ اضافی درون {{}}
 +
.replace(/\{\{(\s*)(.*?)(\s*)\}\}/g, '{{$2}}')
 +
// تبدیل به نویسه / یکی کردن فاصله های مجازی پشت سرهم
 +
.replace(/(\{\{فم\}\}|\&zwnj\;|\u200c+)/g, '\u200c')
 +
// Full stop and comma should be before citation. See en:WP:REFPUNC
 +
.replace(/ *((?:<ref[^\/]*?>.*?<\/ref>)+)([\.،,:])?/g, '$2$1')
 +
.replace(/([^.])([\.،,:]){2}((?:<ref[^\/]*?>.*?<\/ref>)+)/g, '$1$2$3')
 +
.replace(/ *((?:<ref[^\/]*?\/>)+)([\.،,:])/g, '$2$1')
 +
.replace(/([^.])([\.،,:]){2}(((?:<ref[^\/]*?\/>)+)+)/g, '$1$2$3')
 +
/* هر رده در یک خط */
 +
.replace( /([^\s>-]) *(\[\[رده:[^\n[\]]*\]\])/gi, '$1\n$2' )
 +
.replace( /(\[\[رده:[^\n[\]]*\]\]) *(?![\s<-]|$)/gi, '$1\n' )
 +
.replace( /(\[\[رده:[^\n[\]]*\]\]\n) *(?!\[\[رده:|[\s<-]|$)/gi,'$1\n')
 +
//ترتیب‌پیش‌فرض
 +
.replace(/\{\{(?:DEFAULTSORT|[Dd]efaultsort|ترتیب|ترتیب[‌ ]پیش[‌ ]?فرض) *[|:] *(?=.*?}})/g, '{{ترتیب‌پیش‌فرض:')
 +
.replace(/\{\{(ترتیب‌پیش‌فرض|DEFAULTSORT)\:[-\w,\s\(\)]+\}\}\n?/g, '')
 +
.replace(/(\{\{(?:ترتیب‌پیش‌فرض|DEFAULT\w*SORT\w*):[^\n{}]*\}\})\s*(?=\[\[رده:)/gi,'$1\n')
 +
.replace(/(\{\{ترتیب‌پیش‌فرض\:)\s/g, '$1')
 +
.replace( /(==\n)\n+(?=<references[^\n<>]*\/>\n\n)/gi, '$1' )
 +
//نچسبیدن و+فاصله به براکت که محصول اشتباه در تایپ کردن است
 +
.replace(/\]\]و /g, ']] و ')
 +
.replace(/(\s|^)\'\'\'(\s|)(.*?)(\s|)\'\'\'(\s)/g, "$1'''$3'''$5") // حذف فاصلهٔ اضافی درون ویکی کد
 +
.replace(/'''\{\{به /g, "''' {{به ")
 +
.replace(/\*(\s+|\n)?\{\{پانویس/g, "{{پانویس")
 +
.replace(/((?:^|\n\s)\=+\s+\=+(?:\s+|)\n)/g, "\n\n")
 +
.replace(/\n{3,}/g, '\n\n')
  
    function wikiPunctuation(text) {
+
.trim();
        text=autoFormatCleanReferences (text)
+
}
        text=autoFormatCleanTags(text)
 
        text=autoFormatCleanDuplicateLinks(text)
 
        text = replaceExcept(
 
            text,
 
            function (text) {
 
                return quotation(text);
 
            },
 
            [patterns.ref]
 
        );
 
        if (mw.config.get('wgNamespaceNumber') === 0){
 
            var old_text=text.replace(/\=\=/g, '')
 
            if (old_text==text){//در صورتی که در مقاله بخش‌بندی وجود نداشته باشد
 
                text=text.replace(/(\n\{\{سخ\}\}|\n\n)(\s|_|)\'\'\'(.*?)\'\'\'(\s|_|)(\{\{سخ\}\}|\n)([\n\#\*])/g, '\n\n== $3 ==\n$6')
 
            }
 
        }
 
        text = replaceExcept(
 
            text,
 
            function (text) {
 
                text = text.replace(
 
                    new RegExp('([' + persianTools.persianCharactersNoVowels + '])ـ+([' + persianTools.persianCharactersNoVowels + '])', 'g'),
 
                    '$1$2'
 
                );
 
                return text.replace(new RegExp('([' + persianTools.persianCharacters + '])(\\]\\]|), (\\[\\[|)?(?=[' + persianTools.persianCharacters + "])", 'g'), '$1$2، $3');
 
            },
 
            [patterns.globalExceptionTag, patterns.fileNames, patterns.url, patterns.galleryTag, patterns.sourceTag, patterns.translatedUrl, patterns.parenthesesHa]
 
        );
 
        text = replaceExcept(
 
            text,
 
            function (text) {
 
                return text.replace(/(<\/ref>)\s+(<ref)/g, '$1$2').replace(/([^=])\s+<ref(?!erences)/g, '$1<ref');
 
            },
 
            [/\{\{(پانویس|پانویس‌ها|پی‌نوشت)\s*\|[\s\S]*/]
 
        );
 
        return replaceExcept(
 
            text,
 
            function (text) {
 
                return persianTools.punctuation(text)
 
                    .replace(/^([*#]+)([^*#\:\s])/mg, '$1 $2') // Adds a space after the # or * for lists
 
                    .replace(/^([*#]+) {2,}([^*#\:\s])/mg, '$1 $2'); // Trim more that one space after the # or * for lists
 
            },
 
            [patterns.globalExceptionTag, patterns.fileNames, patterns.url, patterns.wikilinkTargets, patterns.galleryTag, patterns.sourceTag, patterns.translatedUrl, patterns.parenthesesHa]
 
        )
 
            .replace(/\u00A0/g, ' ') // convert implicit nbsp to space, probably is being added by some bug on ContentTranslation
 
            .replace(/٬ /g, '، ')
 
            .replace(new RegExp('([' + persianTools.persianCharacters + '\]])٬', 'g'), '$1،')
 
            .replace(new RegExp('([' + persianTools.persianCharacters + '])(\]\]|»|)[ ]*[,]', 'g'), '$1$2، ')
 
            .replace(new RegExp('\\[\\[(' + escapeRE(mw.config.get('wgPageName')) + ')\\]\\]', 'g'), '$1')// پیوندزدایی از خود صفحه
 
            //برگرفته از https://tools.wmflabs.org/checkwiki/cgi-bin/checkwiki.cgi?project=fawiki&view=project
 
            //مشکل در نشانی اینترنتی
 
            .replace(/(\<ref.*?\>) *(\[|)\www(3|)\./gi, '$1$2http://www$3.')
 
            .replace(/\[\[ *(https?\:\/\/.*?) *\]\]/g, '[$1]')
 
            .replace(/\[\[ *(\/\/.*?) *\]\]/g, '[$1]')
 
            .replace(/(https?:\/?\/?){2,}/g, '$1')
 
            //تمیزکاری autoFormatter.js > cleanExternalLinks
 
            .replace( /\b(?:http(s?)(?::+\/*|\/\/+:*)\b)+/gi, 'http$1://' )
 
            /* repair links with vertical stroke */
 
            .replace( /(\[https?:\/\/[^\s[\]|]*?) *\| *(?=[^\s=[\]|]+\])/gi, '$1 ' )
 
            /* supplement slashes at the end easier Domains */
 
            .replace( /(\[https?:\/\/\w[\w.-]*\w\.\w+) +/gi, '$1/ ' )
 
            /* Domains lowercase, whether labeled or not */
 
            .replace( /\bhttps?:\/\/\b[0-9a-z.-]*[A-Z][\w.-]*/g, function( $0 ) {
 
                return $0.toLowerCase();
 
            } )
 
            //پیوند به بیرون‌هایی که در میان پیوند نویسهٔ رفتن به خط بعد، وجود داشته باشد
 
            .replace(/\[(?:https?\:|)\/\/[^\]\[]+\]/g, function (x) {
 
                x=x.replace(/[\n\r]/g,'')
 
                return x
 
            })
 
            //فاصله اول زیربخش
 
            .replace(/^ +(\=+.*?\=+)/g, '$1')
 
            .replace(/\[\[\|/g, '[[')
 
            .replace(/(\< *\/ *br *\>|\< *br *\\ *\>|\< *br *\. *\>)/g, '<br/>')
 
            .replace(/(\<br *\/\>|\{\{سخ\}\})([\r\n])(\*|\#|\=\=)/g, '$2$3')
 
            .replace(/\[\[(.*?)\{\{\!\}\}(.*?)\]\]/g, '[[$1|$2]]')//وجود {{!}} درون پیوند
 
            .replace(/\[{2}([^\|]+)\|\1\]{2}/gi, '[[$1]]')//زمانی که بخش هدف و نمایه پیوند یکی باشند
 
            .replace(/\[\[(.+)\|('+)(.+\b)('+)\]\]/gi, '$2[[$1|$3]]$4')// انتقال ''' به بیرون پیوند
 
            //تمیزکاری autoFormatter.js > CleanGalleries
 
            .replace(/<gallery\b([^<>]*)>([^<>]+)<\/gallery\b[^<>]*>/gi,
 
                function( $0, $1, $2 ) {
 
                    return '<gallery' + $1 + '>' + $2
 
                        .replace( /^(\s*)\[+([^[\]]*)\]\]?\s*$/gm, '$1$2' )
 
                        .replace( /^(\s*)\[+/gm, '$1' ) + '<\/gallery>';
 
                }
 
            )
 
            //تمیزکاری الگو autoFormater.js > cleanTemplates
 
            .replace( /\{\{\s*:?\s*(?:الگو|Template)\s*:\s*/gi, '{\{' )
 
            /* حذف خط زیر از عنوان الگو */
 
            .replace(/(?:^|[^{])\{\{[ 0-9a-z\xC0-\u024F-]*_[ \w\xC0-\u024F-]*/gi,
 
                function( $0 ) {
 
                    return $0.replace( /_+$/, '' ).replace( /[ _]+/g, ' ' ).replace( /\{ +/, '{' );
 
                }
 
            )
 
            //سایر موارد
 
            .replace(/\[\[(رده|الگو|ویکی\u200cپدیا)\: +/g, '[[$1:')
 
            .replace(/[\n\s]*\{\{[•·ن](w?)\}\}\s*/g, '{{•$1}} ')
 
            .replace(/\=\{\{[•·ن](w?)\}\}\s*/g, '=\n{{•$1}} ')//رفع باگ [[Special:Diff/14799178/16387261]] در خط بالا
 
            .replace(/ *(<\/? ?br ?\/?>|\{\{بر\}\}) */g, '{{سخ}}')
 
            .replace(/\{\{سخ\}\}\n\n/g, '\n\n')
 
            .replace(/\n\n\{\{سخ\}\}/g, '\n\n')
 
            .replace(/\n\n(\*|\#)/g,'\n$1')
 
            .replace(/\n(\#|\*)( |)\n/g,'\n$1')
 
            .replace(/\n(\*|\#)( |)(\={2,})/g,'\n$3')
 
            .replace(/(\n?)\s+?<\/ref>/g, '$1</ref>')
 
            .replace( /^=.*&nbsp;.*=$/gim, function( $0 ) {
 
                        return $0.replace( /(?:&nbsp;|\s)+/gi, ' ' );
 
            })
 
            .replace(/([^=])\n+(\=.*?\=\n+)/g, '$1\n\n$2')
 
            .replace(/^(=+([^=].*?)=+)[\t\s]{1,}\n/g, '$1\n')
 
            .replace(/^(\={2,}) +[\:,;>&\^#@•→←↔↑↓—–…~٫،؛ٔ]/mg, '$1') // Cleanup headers
 
            .replace(/[\:,;<&\^#@•→←↔↑↓—–…~٫،؛ٔ] +(\={2,})$/mg, '$1')
 
            .replace(/^(\={2,}\s*)(«)([^\n«»]*?)(»)(\s*\={2,})/mg, '$1 $3 $5')
 
            .replace(/^(\={2,}) *'+(.*?)'+ *(\={2,})/mg, '$1 $2 $3')
 
            .replace(/^[•●⚫⬤]/mg, '*') // Wikify bullets in start of lines
 
            .replace(/^#\s*(REDIRECT|تغییر[ _]?مسیر)/gi, '#تغییرمسیر')
 
            .replace(/^#تغییرمسیر(?=\S)/g, '#تغییرمسیر ') // Adds a space after #REDIRECT
 
            .replace(/(\={2,}) *([^\n\r]*?) *(\={2,})/g, '$1 $2 $3') // Format headings level 2 and above
 
            // فاصله‌های اضافی را از داخل پیوند به بیرون منتقل کند تا اگر اضافه بودند در کدهای دیگر حذف شوند
 
            .replace(/\[\[(\s*)(.*?)(\s*)\]\]/g, '$1[[$2]]$3')
 
//حذف فاصلهٔ اضافی درون {{}}
 
            .replace(/\{\{(\s*)(.*?)(\s*)\}\}/g, '{{$2}}')
 
            // تبدیل به نویسه / یکی کردن فاصله های مجازی پشت سرهم
 
            .replace(/(\{\{فم\}\}|\&zwnj\;|\u200c+)/g, '\u200c')
 
            // Full stop and comma should be before citation. See en:WP:REFPUNC
 
            .replace(/ *((?:<ref[^\/]*?>.*?<\/ref>)+)([\.،,:])?/g, '$2$1')
 
            .replace(/([^.])([\.،,:]){2}((?:<ref[^\/]*?>.*?<\/ref>)+)/g, '$1$2$3')
 
            .replace(/ *((?:<ref[^\/]*?\/>)+)([\.،,:])/g, '$2$1')
 
            .replace(/([^.])([\.،,:]){2}(((?:<ref[^\/]*?\/>)+)+)/g, '$1$2$3')
 
            /* هر رده در یک خط */
 
            .replace( /([^\s>-]) *(\[\[رده:[^\n[\]]*\]\])/gi, '$1\n$2' )
 
            .replace( /(\[\[رده:[^\n[\]]*\]\]) *(?![\s<-]|$)/gi, '$1\n' )
 
            .replace( /(\[\[رده:[^\n[\]]*\]\]\n) *(?!\[\[رده:|[\s<-]|$)/gi,'$1\n')
 
            //ترتیب‌پیش‌فرض
 
            .replace(/\{\{(?:DEFAULTSORT|[Dd]efaultsort|ترتیب|ترتیب[‌ ]پیش[‌ ]?فرض) *[|:] *(?=.*?}})/g, '{{ترتیب‌پیش‌فرض:')
 
            .replace(/\{\{(ترتیب‌پیش‌فرض|DEFAULTSORT)\:[-\w,\s\(\)]+\}\}\n?/g, '')
 
            .replace(/(\{\{(?:ترتیب‌پیش‌فرض|DEFAULT\w*SORT\w*):[^\n{}]*\}\})\s*(?=\[\[رده:)/gi,'$1\n')
 
            .replace(/(\{\{ترتیب‌پیش‌فرض\:)\s/g, '$1')
 
            .replace( /(==\n)\n+(?=<references[^\n<>]*\/>\n\n)/gi, '$1' )
 
            //نچسبیدن و+فاصله به براکت که محصول اشتباه در تایپ کردن است
 
            .replace(/\]\]و /g, ']] و ')
 
            .replace(/(\s|^)\'\'\'(\s|)(.*?)(\s|)\'\'\'(\s)/g, "$1'''$3'''$5") // حذف فاصلهٔ اضافی درون ویکی کد
 
            .replace(/'''\{\{به /g, "''' {{به ")
 
            .replace(/\*(\s+|\n)?\{\{پانویس/g, "{{پانویس")
 
            .replace(/((?:^|\n\s)\=+\s+\=+(?:\s+|)\n)/g, "\n\n")
 
            .replace(/\n{3,}/g, '\n\n')
 
  
            .trim();
+
function wikiSubsection(text) {
    }
+
return text.replace(/\<(?:\s*)references?(?:\s*\/|\s*\/\s*)\>/g, '{{پانویس}}')
 +
  .replace(/\{\{(?:[Rr]eflist|[Rr]eferences?|پانویس[‌ ]?ها)(?=\||\})/g, '{{پانویس')
 +
  .replace(/\{\{راست(| |‌)چین\}\}\s*\{\{پانویس(.*?)\}\}\s*\{\{(پایان راست(| |‌)چین|پایان)\}\}/g, '{{پانویس$2}}')
 +
  .replace(/\{\{چپ(| |‌)چین\}\}\s*\{\{پانویس(.*?)\}\}\s*\{\{(پایان چپ(| |‌)چین|پایان)\}\}/g, '{{پانویس$2|چپ‌چین=بله}}')
 +
  .replace(/\<small\>\s*\{\{پانویس(.*?)\}\}\s*\<\/small\>/g, '{{پانویس$1|اندازه=کوچک}}')
 +
  .replace(/(({\{پانویس.*?\}\})(\n|)){1,}/g, '$1')
 +
  .replace(/\=\s*لیست\s*\=/g, '= فهرست =')
 +
  .replace(/\=\s*(?:[gG]allery|نگارستان|گالری (تصویر|عکس|))\s*\=/g, '= نگارخانه =')
 +
  .replace(/\=\s*(?:بیوگرافی|زندگینامه)\s*\=/g, '= زندگی‌نامه =')
 +
  .replace(/\=\s*(?:[eE]xternal links|لینک‌?های بیرونی|پیوندهای خارجی|لینک‌?های خارجی|پیوندهای بیرونی)\s*\=/g, '= پیوند به بیرون =')
 +
  .replace(/\=\s*(?:[nN]otes|[fF]ootnotes?|پاورقی|پاورقی‌ها|پانوشت|پانویس‌ها)\s*\=/g, '= پانویس =')
 +
  .replace(/\=\s*(?:[Ss]ee [Aa]lso|همچنین ببینی[مد]|بیشتر ببینی[مد]|بیشتر بخوانی[مد]|همچنین نگاه کنید|بیشتر بدانی[مد]|مراجعات مرتبط|جستار وابسته|مطلب مرتبط|مطالب مرتبط|مطالعه بیشتر|جستارهای مشابه)\s*\=/g, '= جستارهای وابسته =')
 +
  .replace(/\=\s*(?:منبع|منبع[‌ ]?ها|رفرنس|رفرنس[‌ ]?ها|ارجاع[‌ ]?ها|ارجاع|مرجع[‌ ]?ها|رفرنس|برگرفته از|مراجع|منابع و یادداشت[‌ ]?ها|منبع|مرجع|م[آا]خذ|منابع و م[آا]خذ|منابع و پانویس‌ها|فهرست مراجع|لیست مراجع|فهرست ارجاع[‌ ]?ها|فهرست ارجاع|[rR]eferences)\s*\=/g, '= منابع =')
 +
  .replace(/^\={3,}\s*(جستارهای وابسته|پانویس|منابع)\s*\={3,}$/g, '== $1 ==');
 +
}
 +
function wikiUrlMinifier(text) {
 +
return text
 +
.replace(patterns.url, function (x) {
 +
return replaceExcept(
 +
x,
 +
function (x) {
 +
try {
 +
x = decodeURI(x);
 +
} catch (e) {
 +
try {
 +
x = decodeURIComponent(unescape(x));
 +
} catch (e) {mw.notify(e); }
 +
}
 +
return x;
 +
},
 +
[patterns.globalExceptionTag, patterns.decodeUriBlacklist]
 +
);
 +
})
  
    function wikiSubsection(text) {
+
// Strip the http(s) prefix
        return text.replace(/\<(?:\s*)references?(?:\s*\/|\s*\/\s*)\>/g, '{{پانویس}}')
+
.replace(/\[(https?\:)(?=\/\/(?:[\w\-]+)\.(wiki(pedia|media|data|source|news|oyage|quote)|wiktionary)\.org\/[^\s\]]*)/g, '[')
              .replace(/\{\{(?:[Rr]eflist|[Rr]eferences?|پانویس[‌ ]?ها)(?=\||\})/g, '{{پانویس')
+
.replace(/\[(?:https?\:|)\/\/[\w\-]{2,}\.wikipedia\.org\/wiki\/([^\n?]*?)\]/g, function (x) {
              .replace(/\{\{راست(| |‌)چین\}\}\s*\{\{پانویس(.*?)\}\}\s*\{\{(پایان راست(| |‌)چین|پایان)\}\}/g, '{{پانویس$2}}')
+
x = x.replace(/\[(?:https?\:|)\/\/([\w\-]{2,})\.wikipedia\.org\/wiki\/(.*?) (.*?)\]/g,'[[:$1:$2|$3]]')
              .replace(/\{\{چپ(| |)چین\}\}\s*\{\{پانویس(.*?)\}\}\s*\{\{(پایان چپ(| |‌)چین|پایان)\}\}/g, '{{پانویس$2|چپ‌چین=بله}}')
+
x = x.replace(/\[(?:https?\:|)\/\/([\w\-]{2,})\.wikipedia\.org\/wiki\/(.*?)\]/g,'[[:$1:$2]]')
              .replace(/\<small\>\s*\{\{پانویس(.*?)\}\}\s*\<\/small\>/g, '{{پانویس$1|اندازه=کوچک}}')
+
x = x.replace(/\_/g,' ').replace(/\[\[\:fa\:/g,'[[')
              .replace(/(({\{پانویس.*?\}\})(\n|)){1,}/g, '$1')
+
return x
              .replace(/\=\s*لیست\s*\=/g, '= فهرست =')
+
});
              .replace(/\=\s*(?:[gG]allery|نگارستان|گالری (تصویر|عکس|))\s*\=/g, '= نگارخانه =')
+
}
              .replace(/\=\s*(?:بیوگرافی|زندگینامه)\s*\=/g, '= زندگی‌نامه =')
 
              .replace(/\=\s*(?:[eE]xternal links|لینک‌?های بیرونی|پیوندهای خارجی|لینک‌?های خارجی|پیوندهای بیرونی)\s*\=/g, '= پیوند به بیرون =')
 
              .replace(/\=\s*(?:[nN]otes|[fF]ootnotes?|پاورقی|پاورقی‌ها|پانوشت|پانویس‌ها)\s*\=/g, '= پانویس =')
 
              .replace(/\=\s*(?:[Ss]ee [Aa]lso|همچنین ببینی[مد]|بیشتر ببینی[مد]|بیشتر بخوانی[مد]|همچنین نگاه کنید|بیشتر بدانی[مد]|مراجعات مرتبط|جستار وابسته|مطلب مرتبط|مطالب مرتبط|مطالعه بیشتر|جستارهای مشابه)\s*\=/g, '= جستارهای وابسته =')
 
              .replace(/\=\s*(?:منبع|منبع[‌ ]?ها|رفرنس|رفرنس[‌ ]?ها|ارجاع[‌ ]?ها|ارجاع|مرجع[‌ ]?ها|رفرنس|برگرفته از|مراجع|منابع و یادداشت[‌ ]?ها|منبع|مرجع|م[آا]خذ|منابع و م[آا]خذ|منابع و پانویس‌ها|فهرست مراجع|لیست مراجع|فهرست ارجاع[‌ ]?ها|فهرست ارجاع|[rR]eferences)\s*\=/g, '= منابع =')
 
              .replace(/^\={3,}\s*(جستارهای وابسته|پانویس|منابع)\s*\={3,}$/g, '== $1 ==');
 
    }
 
    function wikiUrlMinifier(text) {
 
        return text
 
            .replace(patterns.url, function (x) {
 
                return replaceExcept(
 
                    x,
 
                    function (x) {
 
                        try {
 
                            x = decodeURI(x);
 
                        } catch (e) {
 
                            try {
 
                                x = decodeURIComponent(unescape(x));
 
                            } catch (e) {mw.notify(e); }
 
                        }
 
                        return x;
 
                    },
 
                    [patterns.globalExceptionTag, patterns.decodeUriBlacklist]
 
                );
 
            })
 
  
            // Strip the http(s) prefix
+
function wikiTextDigitsToPersian(text) {
            .replace(/\[(https?\:)(?=\/\/(?:[\w\-]+)\.(wiki(pedia|media|data|source|news|oyage|quote)|wiktionary)\.org\/[^\s\]]*)/g, '[')
+
text = replaceExcept(
            .replace(/\[(?:https?\:|)\/\/[\w\-]{2,}\.wikipedia\.org\/wiki\/(.*?)\]/g, function (x) {
+
text,
                x=x.replace(/\[(?:https?\:|)\/\/([\w\-]{2,})\.wikipedia\.org\/wiki\/(.*?) (.*?)\]/g,'[[:$1:$2|$3]]')
+
toEnglishDigits,
                x=x.replace(/\[(?:https?\:|)\/\/([\w\-]{2,})\.wikipedia\.org\/wiki\/(.*?)\]/g,'[[:$1:$2]]')
+
[patterns.argumentsBlacklist,patterns.fileNames,patterns.fileParameter]);
                x=x.replace(/\_/g,' ').replace(/\[\[\:fa\:/g,'[[')
+
text = replaceExcept(
                return x
+
text,
            })
+
persianTools.toPersianDigits,
            .replace(/\/\/.*?(?=[\s\n\|\}\]<]|$)/gi, function (x) {
+
[patterns.globalExceptionTag, patterns.url, patterns.argumentsBlacklist, patterns.mathTag, patterns.imagePixelSize, patterns.fileNames, patterns.ref,
                return x.replace(/\{/g, '%7B')
+
patterns.sourceTag, patterns.arabicDigitsEnglishContext, patterns.signatures, patterns.htmlEntity, patterns.diffLink,
                    .replace(/\|/g, '%7C')
+
patterns.htmlAttributes, patterns.fileParameter, patterns.templateParameterName, patterns.ipSign,
                    .replace(/\}/g, '%7D')
+
patterns.parenthesesAfterDigits, patterns.otherLanguagesInline, patterns.isbn, patterns.englishDate,
                    .replace(/\[/g, '%5B')
+
patterns.parameter, patterns.color, patterns.templateEnglishName, patterns.linksOnEnglishContext, patterns.citation, patterns.refname,
                    .replace(/\]/g, '%5D')
+
patterns.LtRTagEnclosed, patterns.boxVar]
                    .replace(/\^/g, '%5E')
+
);
                    .replace(/\"/g, '%22')
+
return text
                    .replace(/\</g, '%3C')
+
// Decimal point, and thousands' separator
                    .replace(/\>/g, '%3E')
+
.replace(/([۱۲۳۴۵۶۷۸۹۰])\.([۱۲۳۴۵۶۷۸۹۰])/g, '$1٫$2')
                    .replace(/\`/g, '%60')
+
.replace(/([۱۲۳۴۵۶۷۸۹۰]),([۱۲۳۴۵۶۷۸۹۰])/g, '$1٬$2')
                    .replace(/\#/g, '%23')
+
.replace(/([۱۲۳۴۵۶۷۸۹۰])( |)\u0652/g, '$1°')//تبدیل نویسه سکون+عدد فارسی به نویسه درجه و عدد فارسی
                    .replace(/\'/g, '%27')
+
.replace(/\u0652( |)([۱۲۳۴۵۶۷۸۹۰])/g, '°$2')
            })
+
//فاصله بین نویسه درجه و حروف الفبای فارسی به جز عدد فارسی
    }
+
.replace(/([\u0621-\u064A\u0653-\u0655\u067E\u0686\u0698\u06AF\u06A9\u0643\u06AA\uFED9\uFEDA\u06CC\uFEF1\uFEF2])°/g, '$1 °');
 +
}
  
    function wikiTextDigitsToPersian(text) {
+
function dictationReplace(x, y, extensions, text) {
        text = replaceExcept(
+
return text.replace(
            text,
+
new RegExp(
            persianTools.toEnglishDigits,
+
'(^|[^' + persianTools.persianCharacters + '])(\\s|\u200c|_|)(' + x + ')(\\s|_)(' + y + ')(\\s|\u200c|_|)(' +
            [patterns.argumentsBlacklist,patterns.fileNames,patterns.fileParameter]);
+
extensions + ')($|[^' + persianTools.persianCharacters + '])',
        text = replaceExcept(
+
'g'
            text,
+
),
            persianTools.toPersianDigits,
+
'$1$2$3\u200c$5$6$7$8'
            [patterns.globalExceptionTag, patterns.url, patterns.argumentsBlacklist, patterns.mathTag, patterns.imagePixelSize, patterns.fileNames, patterns.ref,
+
);
                patterns.sourceTag, patterns.arabicDigitsEnglishContext, patterns.signatures, patterns.htmlEntity, patterns.diffLink,
+
}
                patterns.htmlAttributes, patterns.fileParameter, patterns.templateParameterName, patterns.ipSign,
 
                patterns.parenthesesAfterDigits, patterns.otherLanguagesInline, patterns.isbn, patterns.englishDate,
 
                patterns.parameter, patterns.color, patterns.templateEnglishName, patterns.linksOnEnglishContext, patterns.citation, patterns.refname,
 
                patterns.LtRTagEnclosed]
 
        );
 
        return text
 
            // Decimal point, and thousands' separator
 
            .replace(/([۱۲۳۴۵۶۷۸۹۰])\.([۱۲۳۴۵۶۷۸۹۰])/g, '$1٫$2')
 
            .replace(/([۱۲۳۴۵۶۷۸۹۰]),([۱۲۳۴۵۶۷۸۹۰])/g, '$1٬$2')
 
            .replace(/([۱۲۳۴۵۶۷۸۹۰])( |)\u0652/g, '$1°')//تبدیل نویسه سکون+عدد فارسی به نویسه درجه و عدد فارسی
 
            .replace(/\u0652( |)([۱۲۳۴۵۶۷۸۹۰])/g, '°$2')
 
            //فاصله بین نویسه درجه و حروف الفبای فارسی به جز عدد فارسی
 
            .replace(/([\u0621-\u064A\u0653-\u0655\u067E\u0686\u0698\u06AF\u06A9\u0643\u06AA\uFED9\uFEDA\u06CC\uFEF1\uFEF2])°/g, '$1 °');
 
    }
 
  
    function dictationReplace(x, y, extensions, text) {
+
// it has dependency to MediaWiki:Gadget-Extra-Editbuttons-Dictionary.js
        return text.replace(
+
function dictation(text) {
            new RegExp(
+
var i,
                '(^|[^' + persianTools.persianCharacters + '])(\\s|\u200c|_|)(' + x + ')(\\s|_)(' + y + ')(\\s|\u200c|_|)(' +
+
dictionary = persianToolsDictionary,
                    extensions + ')($|[^' + persianTools.persianCharacters + '])',
+
NASB = '\u064b', // ًـ
                'g'
+
ZAMM = '\u064c'; // ُـ
            ),
+
for (i in dictionary.complexes) {
            '$1$2$3\u200c$5$6$7$8'
+
if (dictionary.complexes.hasOwnProperty(i)) {
        );
+
text = dictationReplace(
    }
+
i,
 +
dictionary.complexes[i],
 +
'ی|یی|ها|های|هایی|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
 +
text
 +
);
 +
}
 +
}
 +
// for last name
 +
text = dictationReplace(
 +
dictionary.personNames,
 +
'ی|یی|زاده|نیا|گان|فر|نژاد|یان|ی\u200cها|یها',
 +
'ی|',
 +
text
 +
);
 +
// for 'آباد's
 +
text = dictationReplace(
 +
dictionary.personNames + '|' + dictionary.addToAbad,
 +
'آباد',
 +
'زاده|نیا|پور|گان|فر|نژاد|ی|یان|ها|های|یی|هایی|ی\u200cها|یها|',
 +
text
 +
);
 +
// for first names
 +
for (i in dictionary.firstNameComplex) {
 +
if (dictionary.firstNameComplex.hasOwnProperty(i)) {
 +
text = text.replace(
 +
new RegExp(
 +
'(^|[^' + persianTools.persianCharacters + ']|\\s|_)(' + i + ')(\\s|_)(' +
 +
dictionary.firstNameComplex[i] + ')(\\s|_)($|[^' + persianTools.persianCharacters + ']|[^' +
 +
persianTools.persianCharacters + '])',
 +
'g'
 +
),
 +
'$1$2\u200c$4$5$6'
 +
);
 +
}
 +
}
 +
// for colors
 +
text = dictationReplace(
 +
dictionary.colorsNames,
 +
'فام|گون',
 +
'زاده|نیا|پور|گان|فر|نژاد|ی|یی|ها|های|هایی|ی\u200cها|یها|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
 +
text
 +
);
 +
// for numbers
 +
text = dictationReplace(
 +
dictionary.persianNumbers,
 +
'گانه|ماهه',
 +
'زاده|نیا|پور|گان|فر|نژاد|ی|یی|ها|های|هایی|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
 +
text
 +
);
 +
// wrong dictation
 +
for (i in dictionary.forReplace) {
 +
if (dictionary.forReplace.hasOwnProperty(i)) {
 +
text = text.replace(
 +
new RegExp(
 +
'(^|[^' + persianTools.persianCharacters + '])(\\s|\u200c|_|)(' + i + ')(\\s|\u200c|_|)($|[^' +
 +
persianTools.persianCharacters + '])',
 +
'g'
 +
),
 +
'$1$2' + dictionary.forReplace[i] + '$4$5'
 +
);
 +
}
 +
}
  
    // it has dependency to MediaWiki:Gadget-Extra-Editbuttons-Dictionary.js
+
// کلماتی که آ دارند
    function dictation(text) {
+
text = text.replace(
        var i,
+
new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.wordsWithA + ")(ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\]|\\s|\\:|\\)|\\<|\\>|؟|\\'|\\!|$)", 'g'),
            dictionary = persianToolsDictionary,
+
function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
            NASB = '\u064b', // ًـ
+
);
            ZAMM = '\u064c'; // ُـ
+
// بن مضارع که آ دارند
        for (i in dictionary.complexes) {
+
text = text.replace(
            if (dictionary.complexes.hasOwnProperty(i)) {
+
new RegExp("(^|\u200c|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.PresentVerbsWithA + ")(م|ی|د|یم|ید|ند)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
                text = dictationReplace(
+
function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
                    i,
+
);
                    dictionary.complexes[i],
 
                    'ی|یی|ها|های|هایی|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
 
                    text
 
                );
 
            }
 
        }
 
        // for last name
 
        text = dictationReplace(
 
            dictionary.personNames,
 
            'ی|یی|زاده|نیا|گان|فر|نژاد|یان|ی\u200cها|یها',
 
            'ی|',
 
            text
 
        );
 
        // for 'آباد's
 
        text = dictationReplace(
 
            dictionary.personNames + '|' + dictionary.addToAbad,
 
            'آباد',
 
            'زاده|نیا|پور|گان|فر|نژاد|ی|یان|ها|های|یی|هایی|ی\u200cها|یها|',
 
            text
 
        );
 
        // for first names
 
        for (i in dictionary.firstNameComplex) {
 
            if (dictionary.firstNameComplex.hasOwnProperty(i)) {
 
                text = text.replace(
 
                    new RegExp(
 
                        '(^|[^' + persianTools.persianCharacters + ']|\\s|_)(' + i + ')(\\s|_)(' +
 
                            dictionary.firstNameComplex[i] + ')(\\s|_)($|[^' + persianTools.persianCharacters + ']|[^' +
 
                            persianTools.persianCharacters + '])',
 
                        'g'
 
                    ),
 
                    '$1$2\u200c$4$5$6'
 
                );
 
            }
 
        }
 
        // for colors
 
        text = dictationReplace(
 
            dictionary.colorsNames,
 
            'فام|گون',
 
            'زاده|نیا|پور|گان|فر|نژاد|ی|یی|ها|های|هایی\u200cها|یها|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
 
            text
 
        );
 
        // for numbers
 
        text = dictationReplace(
 
            dictionary.persianNumbers,
 
            'گانه|ماهه',
 
            'زاده|نیا|پور|گان|فر|نژاد|ی|یی|ها|های|هایی|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
 
            text
 
        );
 
        // wrong dictation
 
        for (i in dictionary.forReplace) {
 
            if (dictionary.forReplace.hasOwnProperty(i)) {
 
                text = text.replace(
 
                    new RegExp(
 
                        '(^|[^' + persianTools.persianCharacters + '])(\\s|\u200c|_|)(' + i + ')(\\s|\u200c|_|)($|[^' +
 
                            persianTools.persianCharacters + '])',
 
                        'g'
 
                    ),
 
                    '$1$2' + dictionary.forReplace[i] + '$4$5'
 
                );
 
            }
 
        }
 
  
        // کلماتی که آ دارند
+
// بن ماضی که آ دارند
        text = text.replace(
+
text = text.replace(
            new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.wordsWithA + ")(ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\]|\\s|\\:|\\)|\\<|\\>|؟|\\'|\\!|$)", 'g'),
+
new RegExp("(^|\u200c|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.PastVerbsWithA + ")(م|ی|یم|ید|ند|ه|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
            function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
+
function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
        );
+
);
        // بن مضارع که آ دارند
 
        text = text.replace(
 
            new RegExp("(^|\u200c|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.PresentVerbsWithA + ")(م|ی|یم|ید|ند)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
 
            function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
 
        );
 
  
        // بن ماضی که آ دارند
+
// همزه ضم
        text = text.replace(
+
text = text.replace(
            new RegExp("(^|\u200c|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.PastVerbsWithA + ")(م|ی|یم|ید|ند|ه|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
+
new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehZam + ")(‌ها|ها|ین|ان|ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
            function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
+
function (x) { return x.replace(/وء/, 'ؤ').replace(/و/i, 'ؤ'); } // 'i' is just to trick bidi algorithm on code view
        );
+
);
 +
//همزه نصب
 +
text = text.replace(
 +
new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehNasb + ")(ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
 +
function (x) { return x.replace(/ا/i, 'أ'); } // 'i' is just to trick bidi algorithm on code view
 +
);
  
        // همزه ضم
+
//همزه وسط کلمه
        text = text.replace(
+
for (i in dictionary.HamzehAtInside) {
            new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehZam + ")(‌ها|ها|ین|ان|ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
+
text = text.replace(new RegExp(
            function (x) { return x.replace(/وء/, 'ؤ').replace(/و/i, 'ؤ'); } // 'i' is just to trick bidi algorithm on code view
+
"(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + i + ')(| )(' + dictionary.HamzehAtInside[i] + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)",
        );
+
'g'
        //همزه نصب
+
), '$1$2ء$4');
        text = text.replace(
+
}
            new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehNasb + ")(ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
 
            function (x) { return x.replace(/ا/i, 'أ'); } // 'i' is just to trick bidi algorithm on code view
 
        );
 
  
        //همزه وسط کلمه
+
// در مورد افزودن یا حذف همزهٔ پایانی اجماعی وجود ندارد.
        for (i in dictionary.HamzehAtInside) {
+
/* text = text.replace(new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehAtEnd + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$2ء'); */
            text = text.replace(new RegExp(
 
                "(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + i + ')(| )(' + dictionary.HamzehAtInside[i] + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)",
 
                'g'
 
            ), '$1$2ء$4');
 
        }
 
  
 +
//الف مقصوره
 +
text = text.replace(
 +
new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.AlefMaghsooreh + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
 +
function (x) { return x.replace(/ا/i, 'ی'); } // 'i' is just to trick bidi algorithm on code view
 +
);
  
        // در مورد افزودن یا حذف همزهٔ پایانی اجماعی وجود ندارد.
+
// صفت+تر
        /* text = text.replace(new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehAtEnd + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$'); */
+
text = text.replace(new RegExp("(^|\\s|_|«|»|\\]|\\[|\\(|\\<|\\>|\\')(" + dictionary.adjective + ")( |_)تر(?= |«|»|\\.|\\[|\\]|،|_|\\s|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$2\u200cتر');
 +
 +
// اسامی رنگ‌ها (به‌عنوان صفت)+تر
 +
text = text.replace(new RegExp("(^|\\s|_|«|»|\\]|\\[|\\(|\\<|\\>|\\')(" + dictionary.colorsNames + ")( |_)تر(?= |«|»|\\.|\\[|\\]|،|_|\\s|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$2\u200cتر');
 +
 +
text = text.replace(/به دست\u200cآورد/g, 'به دست آورد'); // Solving a bug!
 +
text = persianTools.normalizeZwnj(text);
 +
return text.replace(new RegExp("(^|[؛\\s\\n\\.،«»\'\\<\\>؟])(" + dictionary.needsNasb + ')[' + NASB + ZAMM + ']?([؛؟\\s\\n\\.،«»\'"\\<\\>]|$)', 'g'), function (match) {
 +
return match
 +
.replace(new RegExp('ا([\\s\\n\\.،«»؟؛"\'\\>\\<' + ZAMM + '])', 'i'), 'ا' + NASB + '$1')
 +
.replace(new RegExp(NASB + '["' + NASB + ZAMM + ']'), NASB);
 +
});
 +
}
  
        //الف مقصوره
+
function wikiDictation(text) {
        text = text.replace(
+
return replaceExcept(
            new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.AlefMaghsooreh + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
+
text,
            function (x) { return x.replace(/ا/i, 'ی'); } // 'i' is just to trick bidi algorithm on code view
+
dictation,
        );
+
[patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag, patterns.insideQuote, patterns.argumentsBlacklist, patterns.articleTitleParts]
 +
);
 +
}
 +
function wikiApplyOrthography(text) {
 +
text=text //en:Wikipedia:HTML5
 +
//big
 +
.replace(/((?:\<big\>){5})([^<]+)((?:\<\/big\>){5})/g,'<span style="font-size: 56px;">$2</span>')
 +
.replace(/((?:\<big\>){4})([^<]+)((?:\<\/big\>){4})/g,'<span style="font-size: 38px;">$2</span>')
 +
.replace(/((?:\<big\>){3})([^<]+)((?:\<\/big\>){3})/g,'{{خیلی بزرگ|$2}}')
 +
.replace(/((?:\<big\>){2})([^<]+)((?:\<\/big\>){2})/g,'{{بزرگ|$2}}')
 +
.replace(/((?:\<big\>){1})([^<]+|[\s\S]+)((?:\<\/big\>){1})/g,'{{درشت|$2}}')
 +
//center
 +
.replace(/<center><gallery>([\S\s]+?)\<\/gallery><\/center>/g,'<gallery class="center">$1</gallery>')
 +
//.replace(/<center>([\S\s]+?)<\/center>/g,'{{وسط|$1}}')
 +
//empty tag
 +
.replace(/<span style="font-size: [^>]+"><\/span>/g,'')
 +
.replace(/{{(?:درشت|خیلی بزرگ|بزرگ|وسط)\|}}/g,'')
  
        // صفت+تر
+
//حذف برچسب‌های خالی نرم‌افزار مدیاویکی
        text = text.replace(new RegExp("(^|\\s|_|«|»|\\]|\\[|\\(|\\<|\\>|\\')(" + dictionary.adjective + ")( |_)تر(?= |«|»|\\.|\\[|\\]|،|_|\\s|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$2\u200cتر');
+
var tags = ['math', 'code', 'nowiki', 'pre', 'syntaxhighlight' ,'source', 's', 'su[bp]', 'noinclude', 'includeonly', 'big', 'small','gallery'];
       
+
text = replaceExcept(
        // اسامی رنگ‌ها (به‌عنوان صفت)+تر
+
  text,
        text = text.replace(new RegExp("(^|\\s|_|«|»|\\]|\\[|\\(|\\<|\\>|\\')(" + dictionary.colorsNames + ")( |_)تر(?= |«|»|\\.|\\[|\\]|،|_|\\s|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$2\u200cتر');
+
  function (text) {
       
+
for (var i = 0; i < tags.length; ++i) {
        text = text.replace(/به دست\u200cآورد/g, 'به دست آورد'); // Solving a bug!
+
  text = text.replace(new RegExp('\<' + tags[i] + '[^\>]*\>(\\n|\\s|\u200c)*?\<\\/' + tags[i] + '\>', 'g'), '');
        text = persianTools.normalizeZwnj(text);
+
  // remove the tags if they occurred multiple times consequently
        return text.replace(new RegExp("(^|[؛\\s\\n\\.،«»\'\\<\\>؟])(" + dictionary.needsNasb + ')[' + NASB + ZAMM + ']?([؛؟\\s\\n\\.،«»\'"\\<\\>]|$)', 'g'), function (match) {
+
  if (mw.config.get('wgNamespaceNumber') === 0 || mw.config.get('wgNamespaceNumber') === 4) {
            return match
+
text = text.replace(new RegExp('(\<' + tags[i] + '\>){2,}', 'g'), '$1')
                .replace(new RegExp('ا([\\s\\n\\.،«»؟؛"\'\\>\\<' + ZAMM + '])', 'i'), 'ا' + NASB + '$1')
+
  .replace(new RegExp('(\<\\/' + tags[i] + '\>){2,}', 'g'), '$1');
                .replace(new RegExp(NASB + '["' + NASB + ZAMM + ']'), NASB);
+
  }
        });
+
}
    }
+
if (mw.config.get('wgNamespaceNumber') === 0) {
 +
text=text.replace(/\<ref\>[\s\n]*\<\/ref\>/g,'');
 +
};
 +
return text
 +
  },
 +
  [patterns.insideHtmlComment]
 +
);
 +
return replaceExcept(
 +
text,
 +
persianTools.applyOrthography,
 +
[patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag, patterns.wikilinkTargets]
 +
).replace(patterns.galleryTag, function (gallery) {
 +
// apply `applyOrthography` on gallery descriptions separately
 +
return gallery.replace(/^([^\|]*?\|)(.*)$/mg, function (x, y, z) {
 +
return y + persianTools.applyOrthography(z);
 +
});
 +
});
 +
}
 +
 +
// probably should be exactly same above but for applyZwnj
 +
function wikiApplyZwnj(text) {
 +
return replaceExcept(
 +
text,
 +
persianTools.applyZwnj,
 +
[patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag]
 +
).replace(patterns.galleryTag, function (gallery) {
 +
// apply `applyOrthography` on gallery descriptions separatly
 +
return gallery.replace(/^([^\|]*?\|)(.*)$/mg, function (x, y, z) {
 +
return y + persianTools.applyZwnj(z);
 +
});
 +
});
 +
}
  
    function wikiDictation(text) {
+
function replaceEnMonth(text) {
        return replaceExcept(
+
var enMonth = {
            text,
+
'آگست':'اوت',
            dictation,
+
'آگوست':'اوت',
            [patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag, patterns.insideQuote, patterns.argumentsBlacklist]
+
'جولای':'ژوئیه',
        );
+
'مارچ':'مارس',
    }
+
'آپریل':'آوریل',
    function wikiApplyOrthography(text) {
+
'فوریوری':'فوریه',
        //حذف برچسب‌های خالی نرم‌افزار مدیاویکی
+
'january': 'ژانویه',
        var tags = ['math', 'code', 'nowiki', 'pre', 'syntaxhighlight' ,'source', 's', 'su[bp]', 'noinclude', 'includeonly', 'big', 'small','gallery'];
+
'jan': 'ژانویه',
        text = replaceExcept(
+
'february': 'فوریه',
          text,
+
'feb': 'فوریه',
          function (text) {
+
'march': 'مارس',
            for (var i = 0; i < tags.length; ++i) {
+
'mar': 'مارس',
              text = text.replace(new RegExp('\<' + tags[i] + '[^\>]*\>(\\n|\\s|\u200c)*?\<\\/' + tags[i] + '\>', 'g'), '');
+
'april': 'آوریل',
              // remove the tags if they occurred multiple times consequently
+
'apr': 'آوریل',
              if (mw.config.get('wgNamespaceNumber') === 0 || mw.config.get('wgNamespaceNumber') === 4) {
+
'may': 'مه',
                text = text.replace(new RegExp('(\<' + tags[i] + '\>){2,}', 'g'), '$1')
+
'june': 'ژوئن',
                  .replace(new RegExp('(\<\\/' + tags[i] + '\>){2,}', 'g'), '$1');
+
'jun': 'ژوئن',
              }
+
'july': 'ژوئیه',
            }
+
'august': 'اوت',
            if (mw.config.get('wgNamespaceNumber') === 0) {
+
'aug': 'اوت',
                text=text.replace(/\<ref\>[\s\n]*\<\/ref\>/g,'');
+
'september': 'سپتامبر',
            };
+
'sept': 'سپتامبر',
            return text;
+
'sep': 'سپتامبر',
          },
+
'october': 'اکتبر',
          [patterns.insideHtmlComment]
+
'oct': 'اکتبر',
        );
+
'november': 'نوامبر',
        return replaceExcept(
+
'nov': 'نوامبر',
            text,
+
'december': 'دسامبر',
            persianTools.applyOrthography,
+
'dec': 'دسامبر'
            [patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag, patterns.wikilinkTargets]
+
};
        ).replace(patterns.galleryTag, function (gallery) {
+
for (var i in enMonth) {
            // apply `applyOrthography` on gallery descriptions separately
+
var text_new = text.replace(new RegExp(i, 'ig'), enMonth[i])
            return gallery.replace(/^([^\|]*?\|)(.*)$/mg, function (x, y, z) {
+
if (text_new != text) {
                return y + persianTools.applyOrthography(z);
+
return text_new
            });
+
}
        });
+
}
    }
+
return text
   
+
};
    // probably should be exactly same above but for applyZwnj
 
    function wikiApplyZwnj(text) {
 
        return replaceExcept(
 
            text,
 
            persianTools.applyZwnj,
 
            [patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag]
 
        ).replace(patterns.galleryTag, function (gallery) {
 
            // apply `applyOrthography` on gallery descriptions separatly
 
            return gallery.replace(/^([^\|]*?\|)(.*)$/mg, function (x, y, z) {
 
                return y + persianTools.applyZwnj(z);
 
            });
 
        });
 
    }
 
  
    function replaceEnMonth(text) {
+
function wikitranslateEnMonth(text) {
        var enMonth = {
+
text=autoFormatCleanDates(text)
            'آگست':'اوت',
+
return replaceExcept(
            'آگوست':'اوت',
+
text,
            'جولای':'ژوئیه',
+
function translateEnMonth(text) {
            'مارچ':'مارس',
+
var enMonthRegex = '(آگست|آگوست|جولای|مارچ|آپریل|january|jan|february|feb|march|mar|april|apr|may|jun|june|july|august|aug|sep|sept|september|oct|october|nov|november|december|dec)';
            'آپریل':'آوریل',
+
return text.replace(new RegExp('([^a-zA-Z])(\^|\\||\\s|\\=|\\n|\\(|«|\\:)' + enMonthRegex + ' (\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2})\\, (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|\$|\\)|\\}|»)([\^a\-zA\-Z])', 'ig'),
            'فوریوری':'فوریه',
+
function (x) {
            'january': 'ژانویه',
+
x=x.replace(new RegExp('([\^a\-zA\-Z])(\^|\\||\\s|\\=|\\n|\\(|«|\\:)' + enMonthRegex + ' (\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2})\\, (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|\$|\\)|\\}||»)([^a-zA-Z])', 'ig'),
            'jan': 'ژانویه',
+
'$1$2$4 $3 $5$6$7')
            'february': 'فوریه',
+
x = persianTools.toPersianDigits(x);
            'feb': 'فوریه',
+
x = replaceEnMonth(x);
            'march': 'مارس',
+
return x;
            'mar': 'مارس',
+
})
            'april': 'آوریل',
+
.replace(new RegExp('([\^a\-zA\-Z])(\^|\\||\\s|\\=|\\n|\\(|«)((\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2}) |)' + enMonthRegex + ' (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|$|\\)|\\}|»|\\:)([\^a\-zA\-Z])', 'ig'),
            'apr': 'آوریل',
+
function(x) {
            'may': 'مه',
+
x = persianTools.toPersianDigits(x);
            'june': 'ژوئن',
+
x = replaceEnMonth(x);
            'jun': 'ژوئن',
+
return x;
            'july': 'ژوئیه',
+
}
            'august': 'اوت',
+
);
            'aug': 'اوت',
+
}, [patterns.globalExceptionTag, patterns.fileNames, patterns.ref, patterns.fileParameter, patterns.galleryTag, patterns.mathTag, patterns.sourceTag, patterns.templateWithEnglishName, patterns.citation]
            'september': 'سپتامبر',
+
)
            'sept': 'سپتامبر',
+
}
            'sep': 'سپتامبر',
+
            'october': 'اکتبر',
+
var arabicDigits = '0123456789', persianDigits = '۰۱۲۳۴۵۶۷۸۹';
            'oct': 'اکتبر',
+
function robustToEnglishDigits(text) {
            'november': 'نوامبر',
+
var i = 0;
            'nov': 'نوامبر',
+
for (i = 0; i <= 9; i = i + 1) {
            'december': 'دسامبر',
+
text = text.replace(new RegExp('[' + persianDigits[i] + ']', 'g'), arabicDigits[i]);
            'dec': 'دسامبر'
+
}
        };
+
return text;
        for (var i in enMonth) {
+
}
            var text_new = text.replace(new RegExp(i, 'ig'), enMonth[i])
+
            if (text_new != text) {
+
function toEnglishDigits(text) {
                return text_new
+
text = text.replace(/[a-zA-Z]([\_\s\:\.\,\;\]\[\"\'\)\(\}\{\/\\]+|)([۱۲۳۴۵۶۷۸۹۰٪\.٫\-\—\–°÷×\+\,\s\_\:]+)([\_\s\:\.\,\;\]\[\"\'\)\(\}\{\/\\\<\>]+|)([a-zA-Z\>]|$)/g, function (x) {
            }
+
var i = 0;
        }
+
for (i = 0; i <= 9; i = i + 1) {
        return text
+
x = x.replace(new RegExp('[' + persianDigits[i] + ']', 'g'), arabicDigits[i]);
    };
+
}
 +
return x;
 +
});
 +
// bug [[Special:Diff/17760890/17760898]]
 +
text = text.replace(/([a-zA-Z][۱۲۳۴۵۶۷۸۹۰]+) *\=/g, function (x) {
 +
var i = 0;
 +
for (i = 0; i <= 9; i = i + 1) {
 +
x = x.replace(new RegExp('[' + persianDigits[i] + ']', 'g'), arabicDigits[i]);
 +
}
 +
return x;
 +
});
 +
// ISBN, ISSN and PMID's numbers should in english
 +
text = text.replace(/\b(ISBN|ISSN|PMID|PubMed) *:? *([۱۲۳۴۵۶۷۸۹۰0-9–—−ـ_\-]+)([^۱۲۳۴۵۶۷۸۹۰0-9–—−ـ_\-]|$)/gi, function (x) {
 +
x=x.replace(/[–—−ـ_\-]+/g,'-')
 +
var i = 0;
 +
for (i = 0; i <= 9; i = i + 1) {
 +
x = x.replace(new RegExp('[' + persianDigits[i] + ']', 'g'), arabicDigits[i]);
 +
}
 +
x = x.replace(/\b(ISBN|ISSN|PMID|PubMed) *:? *([۱۲۳۴۵۶۷۸۹۰\-0-9]+)([^۱۲۳۴۵۶۷۸۹۰\-0-9]|$)/gi,'$1 $2$3')
 +
x = x.replace('PubMed','PMID')
 +
return x;
 +
});
 +
// تبدیل عددهای فارسی در عدد ترتیبی انگلیسی
 +
text = text.replace(/(?:^|["\'\s_«\(\[\{])([۱۲۳۴۵۶۷۸۹۰]+)(st|nd|rd|th)[\s_\.,»"\'\)\]\}]/g, function (x) {
 +
var i = 0;
 +
for (i = 0; i <= 9; i = i + 1) {
 +
x = x.replace(new RegExp('[' + persianDigits[i] + ']', 'g'), arabicDigits[i]);
 +
}
 +
return x;
 +
});
 +
return text
 +
.replace(new RegExp('([' + arabicDigits + ']) ?٪', 'g'), '$1%')
 +
.replace(new RegExp('([' + arabicDigits + '])٫(?=[' + arabicDigits + '])', 'g'), '$1.') // English decimal separator
 +
}
  
    function wikitranslateEnMonth(text) {
+
function superTool(text) {
        text=autoFormatCleanDates(text)
+
text = persianWikiTools.wikiConvertToPersianCharacters(text);
        return replaceExcept(
+
text = persianWikiTools.wikiApplyZwnj(text);
            text,
+
text = persianWikiTools.wikiApplyOrthography(text);
            function translateEnMonth(text) {
+
text = persianWikiTools.wikitranslateEnMonth(text);
                var enMonthRegex = '(آگست|آگوست|جولای|مارچ|آپریل|january|jan|february|feb|march|mar|april|apr|may|jun|june|july|august|aug|sep|sept|september|oct|october|nov|november|december|dec)';
+
if (mw.config.get('wgNamespaceNumber') !== 10) {
                return text.replace(new RegExp('([^a-zA-Z])(\^|\\||\\s|\\=|\\n|\\(|«|\\:)' + enMonthRegex + ' (\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2})\\, (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|\$|\\)|\\}|»)([\^a\-zA\-Z])', 'ig'),
+
text = persianWikiTools.wikiTextDigitsToPersian(text);
                        function (x) {
+
}
                            x=x.replace(new RegExp('([\^a\-zA\-Z])(\^|\\||\\s|\\=|\\n|\\(|«|\\:)' + enMonthRegex + ' (\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2})\\, (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|\$|\\)|\\}||»)([^a-zA-Z])', 'ig'),
+
text = persianWikiTools.wikiUrlMinifier(text);
                            '$1$2$4 $3 $5$6$7')
+
text = persianWikiTools.wikiDictation(text);
                            x = persianTools.toPersianDigits(x);
+
text = persianWikiTools.wikiPunctuation(text);
                            x = replaceEnMonth(x);
+
text = persianWikiTools.wikiSubsection(text);
                            return x;
+
//ابزارهای بیشتر برگرفته از ویکی‌پدیای انگلیسی [[Mediawiki:Gadget-Extra-Editbuttons-autoed.js]]
                        })
+
text = autoEd.autoEdISBN(text);
                    .replace(new RegExp('([\^a\-zA\-Z])(\^|\\||\\s|\\=|\\n|\\(|«)((\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2}) |)' + enMonthRegex + ' (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|$|\\)|\\}|»|\\:)([\^a\-zA\-Z])', 'ig'),
+
text = autoEd.autoEdWhitespace(text);
                        function(x) {
+
text = autoEd.autoEdHTMLtoWikitext(text);
                            x = persianTools.toPersianDigits(x);
+
text = autoEd.autoEdHeadlines(text);
                            x = replaceEnMonth(x);
+
text = autoEd.autoEdTablestoWikitext(text);
                            return x;
+
text = autoEd.autoEdExtraBreaks(text);
                        }
+
text = persianWikiTools.addColumnToRefTemplate(text);
                    );
+
return text;
            }, [patterns.globalExceptionTag, patterns.fileNames, patterns.ref, patterns.fileParameter, patterns.galleryTag, patterns.mathTag, patterns.sourceTag, patterns.templateWithEnglishName, patterns.citation]
+
}
        )
+
    };
+
function superToolMove(text) {
    function superTool(text) {
+
text = ' ' + text + ' '; // بعضی از کدها اگر فاصله در انتها یا اول نباشد عمل نمی‌کنند مانند افزودن تنوین به کلمه بعدا
        text = persianWikiTools.wikiConvertToPersianCharacters(text);
+
text = persianWikiTools.wikiConvertToPersianCharacters(text);
        text = persianWikiTools.wikiApplyZwnj(text);
+
text = persianTools.applyZwnj(text);
        text = persianWikiTools.wikiApplyOrthography(text);
+
text = persianWikiTools.wikiApplyOrthography(text);
        if (mw.config.get('wgNamespaceNumber') !== 10) {
+
text = persianWikiTools.wikiTextDigitsToPersian(text);
            text = persianWikiTools.wikiTextDigitsToPersian(text);
+
text = persianWikiTools.wikiUrlMinifier(text);
        }
+
text = persianWikiTools.wikiDictation(text);
        text = persianWikiTools.wikiUrlMinifier(text);
+
text = persianWikiTools.wikiPunctuation(text);
        text = persianWikiTools.wikiDictation(text);
+
return text.trim();
        text = persianWikiTools.wikiPunctuation(text);
+
}
        text = persianWikiTools.wikiSubsection(text);
 
        text = persianWikiTools.wikitranslateEnMonth(text);
 
        //ابزارهای بیشتر برگرفته از ویکی‌پدیای انگلیسی [[Mediawiki:Gadget-Extra-Editbuttons-autoed.js]]
 
        text = autoEd.autoEdISBN(text);
 
        text = autoEd.autoEdWhitespace(text);
 
        text = autoEd.autoEdHTMLtoWikitext(text);
 
        text = autoEd.autoEdHeadlines(text);
 
        text = autoEd.autoEdTablestoWikitext(text);
 
        text = autoEd.autoEdExtraBreaks(text);
 
        text = persianWikiTools.addColumnToRefTemplate(text);
 
        return text;
 
    }
 
   
 
    function superToolMove(text) {
 
        text=' '+ text+' '//بعضی از کدها اگر فاصله در انتها یا اول نباشد عمل نمی‌کنند مانند افزودن تنوین به کلمه بعدا
 
        text = persianWikiTools.wikiConvertToPersianCharacters(text);
 
        text = persianTools.applyZwnj(text);
 
        text = persianWikiTools.wikiApplyOrthography(text);
 
        text = persianWikiTools.wikiTextDigitsToPersian(text);
 
        text = persianWikiTools.wikiUrlMinifier(text);
 
        text = persianWikiTools.wikiDictation(text);
 
        text = persianWikiTools.wikiPunctuation(text);
 
        return text.trim();
 
    }
 
  
    return {
+
return {
        superTool: superTool,
+
superTool: superTool,
        superToolMove: superToolMove,
+
superToolMove: superToolMove,
        dictation: dictation,
+
dictation: dictation,
        wikiApplyOrthography: wikiApplyOrthography,
+
wikiApplyOrthography: wikiApplyOrthography,
        wikiApplyZwnj: wikiApplyZwnj,
+
wikiApplyZwnj: wikiApplyZwnj,
        wikiConvertToPersianCharacters: wikiConvertToPersianCharacters,
+
wikiConvertToPersianCharacters: wikiConvertToPersianCharacters,
        wikiDictation: wikiDictation,
+
wikiDictation: wikiDictation,
        wikiPunctuation: wikiPunctuation,
+
wikiPunctuation: wikiPunctuation,
        wikiSubsection:wikiSubsection,
+
wikiSubsection:wikiSubsection,
        wikiUrlMinifier: wikiUrlMinifier,
+
wikiUrlMinifier: wikiUrlMinifier,
        wikiTextDigitsToPersian: wikiTextDigitsToPersian,
+
wikiTextDigitsToPersian: wikiTextDigitsToPersian,
        wikitranslateEnMonth: wikitranslateEnMonth,
+
wikitranslateEnMonth: wikitranslateEnMonth,
        addColumnToRefTemplate: addColumnToRefTemplate,
+
addColumnToRefTemplate: addColumnToRefTemplate,
        fixBadLinks: fixBadLinks,
+
fixBadLinks: fixBadLinks,
    };
+
robustToEnglishDigits: robustToEnglishDigits,
 +
toEnglishDigits: toEnglishDigits
 +
};
 
}());
 
}());
 
if (typeof window !== "undefined") {
 
if (typeof window !== "undefined") {
    window.persianWikiTools = persianWikiTools;
+
window.persianWikiTools = persianWikiTools;
 
}
 
}
 +
// </nowiki>

نسخهٔ کنونی تا ‏۱۳ دسامبر ۲۰۱۶، ساعت ۱۷:۴۲

// <nowiki> // DO NOT REMOVE THIS LINE EVER
/**
 * Wikipedia specific Persian text style improvement tools
 * Tests: [[مدیاویکی:Gadget-Extra-Editbuttons-tests.js]] [[وپ:تست]]
 * See also: [[مدیاویکی:Gadget-Extra-Editbuttons-persiantools.js]]
 */
/*global persianTools, persianToolsDictionary, autoEd*/
var persianWikiTools = (function () {
	'use strict';
	var patterns = {
		arabicDigitsEnglishContext: /[a-z]([\|a-z %"'\._:\;,\-\\\/\(\)\#\^\+\d><–\[\]&?{}](?!\|\|))*\d|(\d|[a-z])[a-z %"'\._:\;\|,\-\\\/\(\)\#\^\+\d><–\[\]&?{}]*[a-z]\d*/gi,
		arabicTagEnclosed: /\{\{(?:عربی|شروع عربی|آغاز عربی)\}\}([\s\S]*?)\{\{(?:پایان عربی)\}\}/g,
		LtRTagEnclosed: /\{\{(?:چپ چین|چپ‌چین)\}\}([\s\S]*?)\{\{(?:پایان چپ‌چین|پایان چپ چین|پایان)\}\}/g,
		argumentsBlacklist: /(?:accessdate|namespace|image|تصویر|doi|style|شابک|عرض|bibcode|isbn|issn|pmid|arxiv|upright|upleft|padding|spacing|border|filename|نام پرونده)\s*\=\s*[^\|\}\]]*/gi,
		color: /#(?:[abcdef0-9]{8}|[abcdef0-9]{6}|[abcdef0-9]{3})/gi,
		//colorAsParameter: /\=\s*(?:[abcdef0-9]{8}|[abcdef0-9]{6}|[abcdef0-9]{3})(?:[\s\|\}]|$)/gi,
		// space, ", \t, \n, {, |, }, ... they will interfere with wiki markup
		decodeUriBlacklist: /(?:%20|%27|%5C|%5E|%60|%23|%25|%3C|%3E|%5B|%5D|%22|%09|%0A|%7B|%7C|%7D)/gi,
		diffLink: /\[\[(?:ویژه|Special):(?:تفاوت|Diff)\/[^\|\]]*/gi,
		englishDate: /\d{1,2},? [a-z]{3,} \d{2,4}/gi, // 3, May 2013
		fileNames: /(?:پرونده|File|تصویر|Image)\:.*?(?=\||\]|\n|$)/gi, // don't capture | after
		fileParameter: /\|\s*(image|تصویر)\s*\=\s*.*/g,
		ipSign: /\[\[ویژه:مشارکت\u200cها.*?\]\]/g,
		isbn: /(?:ISBN|ISSN|PMID) [\d\-]*/gi,
		galleryTag: /<gallery.*?>[\s\S]*?<\/gallery>/g,
		htmlAttributes: /(?:style|perrow|colspan|color|rowspan|cellpadding|cellspacing|height|width|size|border|thumbtime|name|perrow|upright|upleft)\s*[\=\:]\s*(?:['\"].*?['\"]|[\da-z]+)/gi,
		htmlEntity: /&#\d+;/,
		imagePixelSize: /[\|=] *[x\d]+?(px|پیکسل)[\]\|\s]/g, // means it will capture |10px| and |10x10px|
		insideQuote: /[^ا]".*?"/g,
		wikilinkTargets: /\[[^\[|\]]+/g,
		nowikiTag:/<nowiki>.+?<\/nowiki>/g,
		preTag:/<pre.*?>.*?<\/pre>/g,
		insideHtmlComment: /<\!\-\-[\s\S]*?\-\->/g,
		linksOnEnglishContext: /[a-z][\:\,\. ]*\[\[[\da-z\-\, ]*/gi,
		mathTag: /<math.*?>[\s\S]*?<\/math>/g,
		otherLanguagesInline: /\{\{(?:به .+?|به انگلیسی|انگلیسی|عربی|متن عربی|عبارت عربی|حدیث|به عربی|به اردو|اردو|lang\-[au]r|پینگ|ping)[\s\S]*?\}\}/g,
		parameter: /\{\{\{\d+/gi,
		parenthesesAfterDigits: /\w\s?\([\w\s\.\-]*?\)/g,
		parenthesesHa: /\)ها/g,
		ref: /(?:<ref[^\/]*?>[\s\S]*?<\/ref>|<ref[^\/]*?\/>)/g, // inside <ref></ref> and <ref/>
		refname: /\<ref name\=.*?\>/g,
		citation:/\{\{\s*(?:[Cc]it|یادکرد).*?[_\s]*(?:\{\{.*?\}\}|[^\}])*\}\}/g,
		signatures: /\[\[(?:کاربر|User|بحث[ _]کاربر|User[_ ]talk)\:.*?\]\]/gi,
		sourceTag: /(<source.*?>[\s\S]*?<\/source>|<syntaxhighlight.*?>[\s\S]*?<\/syntaxhighlight>|<code.*?>[\s\S]*?<\/code>|<timeline.*?>[\s\S]*?<\/timeline>)/g,
		tagNames: /<\/?[a-zA-Z\d]*/g,
		templateEnglishName: /(الگو|Template):[a-z][a-z\d\-\+_]+/gi,
		templateWithEnglishName: /\{\{[ \_]*(?:(?:الگو|Template):)?(?:start\-date)[ \_]*\|.*?\}\}/gi,
		templateParameterName: /\|\s*(?=[a-z_]*\d)[a-z_\d]*\s*\=/gi,
		globalExceptionTag: /(<nowiki>.+?<\/nowiki>|<!--[\s]*ابر[\s]*-->.+?<!--[\s]*\/[\s]*ابر[\s]*-->)/gi,
		translatedUrl: /.(کام|نت|آی‌آر)/g,
		boxVar: /([a-zA-Z][۱۲۳۴۵۶۷۸۹۰]+) *\=/g,
		url: /\/\/.*?(?=[\s\n\|\}\]<]|$)/gi,	 // بدون https?: هم ممکن است
		articleTitleParts: new RegExp('\\s' + mw.config.get('wgTitle').split(' ').join('\\s|\\s') + '\\s', 'g')
	};

	function escapeRE( s ) {
		return s.replace( /([$()*+\-.?[\\\]^{|}])/g, '\\$1' );
	}

	function descendingFromComparetor(x, y) {
		return x.from - y.from;
	}

	function replaceExcept(text, callback, excepts) {
		var match, result = [], i, ranges, minRange, to, min, max;
		while (text !== '') {
			ranges = [];

			for (i in excepts) {
				if (excepts.hasOwnProperty(i)) {
					// a global regex should be reset before calls
					excepts[i].lastIndex = 0;
					match = excepts[i].exec(text);
					if (match !== null) {
						ranges.push({
							from: match.index,
							to: match.index + match[0].length
						});
					}
				}
			}

			// so nothing is matched
			if (ranges.length === 0) {
				result.push(callback(text));
				break;
			}

			minRange = ranges.sort(descendingFromComparetor)[0];
			min = minRange.from;

			to = [];
			for (i in ranges) {
				if (ranges.hasOwnProperty(i)) {
					if (ranges[i].from <= minRange.to) {
						to.push(ranges[i].to);
					}
				}
			}
			max = Math.max.apply(null, to);

			result.push(callback(text.substr(0, min)));
			result.push(text.substr(min, max - min));
			// console.log('Excepted: "' + text.substr(min, max - min) + '"');
			text = text.substr(max);
		}
		return result.join('');
	}

	function wikiConvertToPersianCharacters(text) {
		return replaceExcept(
			text,
			persianTools.toStandardPersianCharacters,
			[patterns.globalExceptionTag, patterns.otherLanguagesInline, patterns.arabicTagEnclosed, patterns.fileNames, patterns.signatures, patterns.url]
		);
	}

	if (!String.prototype.trim) { // if is not available currently
		String.prototype.trim = function () {
			return this.replace(/^\s+|\s+$/g, '');
		};
	}

	function autoFormatCleanReferences ( str ) {
		// تمیزکاری autoFormater.js > cleanReferences
		str = str.replace(
			/<\s*references\s*(\s\b[^<>]*?)?\s*(?:\/|>\s*<\s*\/\s*references)\s*>/gi,
			'<references$1 />'
		);
		str = str.replace( /<\s*references\s*(\s\b[^<\/>]*?)?\s*>/gi, '<references$1>' );
		str = str.replace( /<\s*\/\s*references\s*>/gi, '<\/references>' );
		var re = /(<references[^<\/>]*)>/g, m;
		while ( m = re.exec( str ) ) {
			if ( str.indexOf( '<\/references>', m.index ) < 0 ) {
				str = str.slice( 0, m.index ) + m[1] + ' />' + str.slice( m.index + m[0].length );
			}
		}
		str = str.replace( /< *ref\s*(\s\b[^<>]*?)\s*(?:\/+|>\s*<\s*\/+\s*ref) *>/gi, '<ref$1 />' );

		/* remove line breaks with assays only the top of the article */
		var i = str.indexOf( '<references' ),
			slice;
		if ( i > 0 ) {
			slice = str.slice( i );
			slice = slice.replace( /< *ref\s*(\s\b[^<\/>]*?)?\s*>[\t ]*/gi, '<ref$1>' );
			slice = slice.replace( /(?:(\n[\t ]*)|[\t ]*)<\s*\/+\s*ref\s*>/gi, '$1<\/ref>' );
			str = str.slice( 0, i );
		}
		str = str.replace( /< *ref\s*(\s\b[^<\/>]*?)?\s*>\s*/gi, '<ref$1>' );
		str = str.replace( /\s*<\s*\/+\s*ref\s*>/gi, '<\/ref>' );
		if ( slice ) {
			str += slice;
		}

		/* Space between the end of block and remove <ref> or two <ref> */
		str = str.replace( /([!,.;?]|<ref\b[^<>]*(?:\/|>[^<>]*<\/ref)>) +(?=<ref[ >])/gi, '$1' );
		/* Two identical punctuation before and cut after a <ref> on one */
		return str.replace( /([!,.:;?])(<ref\b[^<>]*(?:\/|>[^<>]*<\/ref)>)\1/gi, '$1$2' );
	}

	function autoFormatCleanTags(str) {
		str = str.replace( /(<\/?s)trike\b/gi, '$1' );
		str = str.replace(
			/<sub\s*(>[^<>]*<)\s*(?:su[bp]\s*[.\/\\]+|[.\/\\]+\s*su[bp])\s*>/gi,
			'<sub$1/sub>'
		);
		str = str.replace(
			/<sup\s*(>[^<>]*<)\s*(?:su[bp]\s*[.\/\\]+|[.\/\\]+\s*su[bp])\s*>/gi,
			'<sup$1/sup>'
		);

		/* Drop default font attributes */
		str = str.replace(
			/(<font\b[^<>]*?)\s+fa\w+(?:[\s"',=]*(?:Arial|Helvetica(?:\W?N\w*)?|sans\W?serif)\b)+[\s"';]*(?=\s\w+\s*=|>)/gi,
			'$1'
		);
		str = str.replace(
			/(<font\b[^<>]*?)\s+size[\s"',=]*(?:-1\b|2\b|100\b[ ,.]*\d*%|1(?:\.0*)?em\b)["';]*/gi,
			'$1'
		);
		/* Remove inline elements with no attributes */
		while ( /<(font|span)\s*>\s*(?:<(?!\1)|[^<])*?\s*<\/\1[^<>]*>/i.test( str ) ) {
			str = str.replace( /<(font|span)\s*>\s*((?:<(?!\1)|[^<])*?)\s*<\/\1[^<>]*>/gi, '$2' );
		}
		str = str.replace(
			/<font\s+color[\s"',=]*(#[\dA-F]{3,6}|[a-z]{3,20})[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
			'<span style="color:$1;">$2<\/span>'
		);
		str = str.replace(
			/<font\s+size[\s"',=]*(?:-[2-9]|[01])[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
			'<small>$1<\/small>'
		);
		str = str.replace(
			/<font\s+size[\s"',=]*(?:[+-]0|3)[\s"';]*>((?:<(?!font)|[^<])*?)<\/font[^<>]*>/gi,
			'<span style="font-size:larger;">$1<\/span>'
		);
		/* Merge nested inline tags */
		str = str.replace(
			/<(abbr|cite|mark|q|s|small|u)\s*><(font|span)\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*>([^<>]*)<\/\2\s*>\s*(?=<\/\1\s*>)/gi,
			'<$1 style="$3;">$4'
		);
		str = str.replace(
			/(<span\b[^<>]*?)\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*><span\s+style\s*=\s*["']?([^\n"<>]*?);?["']?\s*>([^<>]*)<\/span\s*>\s*(?=<\/span\s*>)/gi,
			'$1 style="$2; $3;">$4'
		);

		/* Verschiedenste Formen von HTML-Zeilenumbrüchen durch einheitliche ersetzen */
		str = str.replace( /<(?:[\s\/\\]*br\b)+\s*(\s\w[^<>]*?)?[\s.\/\\]*>/gi, '<br$1 />' );
		/* Unnötige HTML-Zeilenumbrüche entfernen, wenn sowieso ein Absatz folgt */
		str = str.replace( / *(?:{{سخ}}|<br \/>)(?=[\r\n][\n#*:;\|}\]])/gi, '' );
		str = str.replace(
			/<(ref|small|su[bp])\b\s*(\s\w[^<>]*?)?\s*><small\s*>([^<>]*)<\/small\s*><\/\1\s*>/gi,
			'<$1$2>$3<\/$1>'
		);
		str = str.replace(
			/<small\s*><(ref|small|su[bp])\b\s*(\s\w[^<>]*?)?\s*?( ?\/|>[^<>]*<\/\1)\s*><\/small\s*>/gi,
			'<$1$2$3>'
		);
		/* Drop old navigation bar wrapper, see [[Template:NaviBlock]] */
		return str.replace(
			/<div\s+class[^<>\w]*BoxenVerschmelzen[^<>\w]*>\s*(\{\{[^#:<>{}]*\}\})\s*<\/div>/gi,
			'$1'
		);
	}

	function autoFormatCleanDuplicateLinks(str) {
		/* Exclude files and infoboxes from the start of the article */
		var m = /^(?:\s*\[\[\w+:(?:\[\[[^\n\]]*\]\]|[^\n\]])*\]\])*(?:\s*\{\{(?:\{\{[^}]*\}\}|[^}])*\}\})+/.exec( str ),
			start = m ? m[0].length : 0,
			found = [],
			a = [];
		/* Unlink years that are linked more than one time */
		var re = /\[\[ *([۱۲][۱۲۳۴۵۶۷۸۹۰]{3}|[۱۲][۱۲۳۴۵۶۷۸۹۰]{3} \((میلادی|قمری)\)) *\]\]/g;
		/* In each case the first discovery of a year noted entlinken thereafter */
		while ( m = re.exec( str ) ) {
			if ( m.index >= start ) {
				found[m[1]] ? a.push( m ) : found[m[1]] = true;
			}
		}
		var r = '',
			p = 0;
		for ( var i = 0; i < a.length; i++ ) {
			r += str.slice( p, a[i].index ) + a[i][1];
			p = a[i].index + a[i][0].length;
		}
		return p ? r + str.slice( p ) : str;
	}

	function autoFormatCleanDates(str){
		var months = ["ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر", 'فروردین', 'اردیبهشت', 'خرداد', 'تیر',
			'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند',"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

		/* Add missing space between day and month */
		str = str.replace( new RegExp( '([\\s!\'(>|„](?:3[01]|[12]\\d|0?[1-9])\\.?)(?=(?:' +
			months.join( '|' ) + ')\\b)', 'g' ), '$1 ' );
		/* No non-breaking space between month and year */
		str = str.replace( new RegExp( '(\\b(?:3[01]|[12]\\d|0?[1-9])\\.?(?:[\\s\\xA0]|&nbsp;)+(?:' +
			months.join( '|' ) + '))(?:\xA0|&nbsp;)(?=[12]\\d{3}\\b)', 'g' ), '$1 ' );
		/* Missverständliches deutsches Datumsformat durch Langform ersetzen */
		var separator= ' ';
		str = str.replace(
			/([\s'(>„])(3[01]|[12]\d|0?[1-9])\. *(1[012]|0?[1-9])\. *(?=[12]\d{3}[!,.:;?]?[\s')<\]“])/g,
			function( $0, $1, $2, $3 ) {
				return $1 + ( $2 | 0 ) + separator + months[$3 | 0] + ' ';
			}
		);
		// عدد فارسی
		str = str.replace( new RegExp( '([\\s!\'(>|„](?:۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\\.?)(?=(?:' +
			months.join( '|' ) + ')[\\s\')<\\]»}|])', 'g' ), '$1 ' );
		/* No non-breaking space between month and year */
		str = str.replace( new RegExp( '([\\s\'(>«](?:۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\\.?(?:[\\s\\xA0]|&nbsp;)+(?:' +
			months.join( '|' ) + '))(?:\xA0|&nbsp;)(?=[۱۲][۱۲۳۴۵۶۷۸۹]{3}[\\s\')<\\]»}|])', 'g' ), '$1 ' );
		/* Missverständliches deutsches Datumsformat durch Langform ersetzen */
		var separator= ' ';
		str = str.replace(
			/([\s'(>«])(۳[۰۱]|[۱۲][۱۲۳۴۵۶۷۸۹]|۰?[۱۲۳۴۵۶۷۸۹])\. *(۱[۰۱۲]|۰?[۱۲۳۴۵۶۷۸۹])\. *(?=[۱۲][۱۲۳۴۵۶۷۸۹]{3}[!,.:;?]?[\s')<\]»}|])/g,
			function( $0, $1, $2, $3 ) {
				return $1 + ( $2 | 0 ) + separator + months[$3 | 0] + ' ';
			}
		);
		return str
	}

	function quotation(text) {
		// این تابع زمانی گیومه را به فارسی تیدیل می‌کند که در پاراگراف مورد نظر تعداد گیومهٔ لاتین زوج باشد.
		var lines = text.split(/\n\n/);
		var result = [];
		for (var i = 0; i < lines.length; ++i) {
			var line = lines[i];
			if ((line.match(/"/g) || []).length % 2 === 0) { // count of quote marks
				// تبدیل گیومهٔ لاتین به فارسی
				// این دستور در ابتدا باشد تا فاصله‌های قبل و بعد گیومه هم اصلاح شود
				line = line.replace(
					new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.\\)]+)"((?:\\[\\[|).*?[' + persianTools.persianCharacters + '؛\\n،]+?(?:\\]\\]|\\.|\\<|\\:|))"([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{\\(]|$)', 'g'),
					'$1«$2»$3'
				);
				// if some of quote marks are remained from conversion, something might wrong, revert
				var testline=line.replace(/(?:<ref[^\/]*?>[\s\S]*?<\/ref>|<ref[^\/]*?\/>)/g,'')

				if (testline.match(/"/g)) {
					line = lines[i];
				}
			}
			// رفع مشکل استفاده از ـً به جای گیومه لاتین در متن فارسی
			line=line.replace(new RegExp('ا\\"([ ]*[' +persianTools.persianCharacters + '])', 'g'), 'اً$1')
			// ”“ تبدیل 
			line = line.replace(
				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)“((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))”([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
				'$1«$2»$3'
			);
			//وارونه ”“ تبدیل 
			line = line.replace(
				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)”((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))“([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
				'$1«$2»$3'
			);
			// ‘’ تبدیل 
			line = line.replace(
				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)‘((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))’([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
				'$1«$2»$3'
			);
			//وارونه ‘’ تبدیل 
			line = line.replace(
				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)’((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))‘([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
				'$1«$2»$3'
			);
			// ‚’ تبدیل 
			line = line.replace(
				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)‚((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|\\{|\\[|))’([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
				'$1«$2»$3'
			);
			// „” تبدیل 
			line = line.replace(
				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)„((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))”([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
				'$1«$2»$3'
			);
			// << >> تبدیل 
			line = line.replace(
				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)\\<\\<((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))\\>\\>([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
				'$1«$2»$3'
			);
			// (()) تبدیل 
			line = line.replace(
				new RegExp('(^|[' + persianTools.persianCharacters + '\\:>،»؛\\s\\n\\}\\]\\.]+)\\(\\(((?:\\[\\[|).*?[' + persianTools.persianCharacters + '\\n]+?(?:\\]\\]|\\.|\\<|\\:|))\\)\\)([' + persianTools.persianCharacters + '،«؛\\s\\n\\.\\[\\{]|$)', 'g'),
				'$1«$2»$3'
			);
			result.push(line);
		}
		return result.join('\n\n');
	}
	/**
	 * افزودن ستون به الگوی پانویس
	 * @param {string} text محتوا
	*/
	function addColumnToRefTemplate(text) {
		if ((text.match(/<ref>/gi) || []).length >= 6) {
			var refTemplate = /\{{2}پانویس([^\}\{]+)?\}{2}/i.exec(text), needChange = false;
			if (refTemplate) {
				if (refTemplate[1] !== undefined) {
					var refParams = refTemplate[1].split('|');
					for (var i = refParams.length - 1; i >= 0; i--) {
						// اگر از پیش ستون یا پارامتر عرض تعریف شده‌باشد تغییری ایجاد نمی‌شود.
						if (refParams[i].length == 1 || refParams[i].indexOf('عرض') > -1) {
							needChange = true;
							break;
						}
					}
				}
				if (refTemplate[1] === undefined || !needChange) {
					return text.replace(refTemplate[0], refTemplate[0].replace('}}', '|۲}}'));
				}
			}
		}
		
		return text;
	}
	
	/**
	 * اصلاح پیوندها
	 * @param  {string} text محتوا
	 * @return {string}
	 */
	function fixBadLinks(text) {
		// حذف متن جایگزین پیوند اگر با نشانی پیوند برابر باشد؛ مانند [[سلام|سلام]]
		text = text.replace(/\[{2}([^\|]+)\|\1\]{2}/gi, '[[$1]]');

		// حذف پیوند سال و روز ماه
		text = text.replace(/\[{2}([۰-۹]+|[۰-۹]+ [\u0621-\u0655\u067E\u0686\u0698\u06AF\u06A9\u0643\u06AA\uFED9\uFEDA\u06CC\uFEF1\uFEF2]+)(?:\|(.+))?\]{2}/g, function (match, p1, p2) {
		// اگر فقط سال پیوند شده‌باشد یا به شکل [[سال|همان سال]] باشد فقط سال را می‌گرداند.
		if (p2 === undefined || p1 === p2) {
			// اگر پیوند به روز و ماه بود، برای جلوگیری از اشتباه و تداخل، بررسی می‌شوند که حتما یکی از ماه‌ها داخل رشته باشد.
			if (p1.indexOf(" ") > -1) {
				var
					months = ["فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند",
	"ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر",
	"محرم", "صفر", "ربیع‌الاول", "ربیع‌الثانی", "جمادی‌الاول", "جمادی‌الثانی", "رجب", "شعبان", "رمضان", "شوال", "ذیقعده", "ذیحجه"],
					i;
				for (i = months.length - 1; i >= 0; i--) {
					if (p1.indexOf(months[i]) > -1) {
						return p1;
					}
				}
				return "[[" + p1 + "]]";
			}
			return p1;
		}
		// اگر متن جایگزین پیوند مخالف پیوند سال بود، متن جایگزین را برمی‌گرداند.
		return p2;
	});

	return text;
}

	function wikiPunctuation(text) {
		text = autoFormatCleanReferences (text)
		text = autoFormatCleanTags(text)
		text = autoFormatCleanDuplicateLinks(text)
		text = replaceExcept(
			text,
			function (text) {
				return quotation(text);
			},
			[patterns.ref]
		);
		if (mw.config.get('wgNamespaceNumber') === 0){
			var old_text=text.replace(/\=\=/g, '')
			if (old_text==text){//در صورتی که در مقاله بخش‌بندی وجود نداشته باشد
				text=text.replace(/(\n\{\{سخ\}\}|\n\n)(\s|_|)\'\'\'(.*?)\'\'\'(\s|_|)(\{\{سخ\}\}|\n)([\n\#\*])/g, '\n\n== $3 ==\n$6')
			}
		}
		text = replaceExcept(
			text,
			function (text) {
				text = text.replace(
					new RegExp('([' + persianTools.persianCharactersNoVowels + '])ـ+([' + persianTools.persianCharactersNoVowels + '])', 'g'),
					'$1$2'
				);
				return text.replace(new RegExp('([' + persianTools.persianCharacters + '])(\\]\\]|), (\\[\\[|)?(?=[' + persianTools.persianCharacters + "])", 'g'), '$1$2، $3');
			},
			[patterns.globalExceptionTag, patterns.fileNames, patterns.url, patterns.galleryTag, patterns.sourceTag, patterns.translatedUrl, patterns.parenthesesHa]
		);
		text = replaceExcept(
			text,
			function (text) {
				return text.replace(/(<\/ref>)\s+(<ref)/g, '$1$2').replace(/([^=])\s+<ref(?!erences)/g, '$1<ref');
			},
			[/\{\{(پانویس|پانویس‌ها|پی‌نوشت)\s*\|[\s\S]*/]
		);
		return replaceExcept(
			text,
			function (text) {
				return persianTools.punctuation(text)
					.replace(/^([*#]+)([^*#\:\s])/mg, '$1 $2') // Adds a space after the # or * for lists
					.replace(/^([*#]+) {2,}([^*#\:\s])/mg, '$1 $2'); // Trim more that one space after the # or * for lists
			},
			[patterns.globalExceptionTag, patterns.fileNames, patterns.url, patterns.wikilinkTargets, patterns.galleryTag, patterns.sourceTag, patterns.translatedUrl, patterns.parenthesesHa]
		)
			.replace(/\u00A0/g, ' ') // convert implicit nbsp to space, probably is being added by some bug on ContentTranslation
			.replace(/٬ /g, '، ')
			.replace(new RegExp('([' + persianTools.persianCharacters + '\]])٬', 'g'), '$1،')
			.replace(new RegExp('([' + persianTools.persianCharacters + '])(\]\]|»|)[ ]*[,]', 'g'), '$1$2، ')
			.replace(new RegExp('\\[\\[(' + escapeRE(mw.config.get('wgPageName')) + ')\\]\\]', 'g'), '$1') // پیوندزدایی از خود صفحه
			//برگرفته از https://tools.wmflabs.org/checkwiki/cgi-bin/checkwiki.cgi?project=fawiki&view=project
			.replace(/\[\[([^\|\]]+)\|\1([\u200c ]*(های?))\]\]/g, '[[$1]]$2')//[[Special:Diff/17515365/17865938]]
			.replace(/([\S]*)[\s\u200c]*-[\s\u200c]*(تاکنون)(?![ ]+)/g, '$1-اکنون')//[[Special:Diff/17515365/17865938]]
			//مشکل در نشانی اینترنتی
			.replace(/(\<ref.*?\>) *(\[|)\www(3|)\./gi, '$1$2http://www$3.')
			.replace(/\[\[ *(https?\:\/\/.*?) *\]\]/g, '[$1]')
			.replace(/\[\[ *(\/\/.*?) *\]\]/g, '[$1]')
			.replace(/(https?:\/?\/?){2,}/g, '$1')
			// تمیزکاری autoFormatter.js > cleanExternalLinks
			.replace(/\b(?:http(s?)(?::+\/*|\/\/+:*)\b)+/gi, 'http$1://')
			// repair links with vertical stroke
			.replace(/(\[https?:\/\/[^\s[\]|]*?) *\| *(?=[^\s=[\]|]+\])/gi, '$1 ')
			// supplement slashes at the end easier Domains
			.replace(/(\[https?:\/\/\w[\w.-]*\w\.\w+) +/gi, '$1/ ')
			// Domains lowercase, whether labeled or not
			.replace(/\bhttps?:\/\/\b[0-9a-z.-]*[A-Z][\w.-]*/g, function ($0) {
				return $0.toLowerCase();
			})
			// پیوند به بیرون‌هایی که در میان پیوند نویسهٔ رفتن به خط بعد، وجود داشته باشد
			.replace(/\[(?:https?\:|)\/\/[^\]\[]+\]/g, function (x) {
				x = x.replace(/[\n\r]/g,'');
				return x
			})
			// فاصله اول زیربخش
			.replace(/^ +(\=+[^\=]+\=+)/mg, '$1')
			.replace(/\[\[\|/g, '[[')
			.replace(/(\< *\/ *br *\>|\< *br *\\ *\>|\< *br *\. *\>)/g, '<br/>')
			.replace(/(\<br *\/\>|\{\{سخ\}\})([\r\n])(\*|\#|\=\=)/g, '$2$3')
			.replace(/(\<br *\/\>|\{\{سخ\}\}) *\]\]/g, ']]')
			.replace(/\[\[ *(\<br *\/\>|\{\{سخ\}\})/g, '[[')
			.replace(/\[\[([^\]]+)\{\{\!\}\}([^\]]+)\]\]/g, '[[$1|$2]]')//وجود {{!}} درون پیوند
			.replace(/\[{2}([^\|]+)\|\1\]{2}/gi, '[[$1]]')//زمانی که بخش هدف و نمایه پیوند یکی باشند
			.replace(/\[\[(.+)\|('+)(.+\b)('+)\]\]/gi, '$2[[$1|$3]]$4')// انتقال ''' به بیرون پیوند
			// تمیزکاری autoFormatter.js > CleanGalleries
			.replace(/<gallery\b([^<>]*)>([^<>]+)<\/gallery\b[^<>]*>/gi,
				function( $0, $1, $2 ) {
					return '<gallery' + $1 + '>' + $2
						.replace( /^(\s*)\[+([^[\]]*)\]\]?\s*$/gm, '$1$2' )
						.replace( /^(\s*)\[+/gm, '$1' ) + '<\/gallery>';
				}
			)
			// تمیزکاری الگو autoFormater.js > cleanTemplates
			.replace( /\{\{\s*:?\s*(?:الگو|Template)\s*:\s*/gi, '{\{' )
			// حذف خط زیر از عنوان الگو
			.replace(/(?:^|[^{])\{\{[ 0-9a-z\xC0-\u024F-]*_[ \w\xC0-\u024F-]*/gi,
				function( $0 ) {
					return $0.replace( /_+$/, '' ).replace( /[ _]+/g, ' ' ).replace( /\{ +/, '{' );
				}
			)
			//سایر موارد
			.replace(/\[\[(رده|الگو|ویکی\u200cپدیا)\: +/g, '[[$1:')
			.replace(/[\n\s]*\{\{[•·ن](w?)\}\}\s*/g, '{{•$1}} ')
			.replace(/\=\{\{[•·ن](w?)\}\}\s*/g, '=\n{{•$1}} ')//رفع باگ [[Special:Diff/14799178/16387261]] در خط بالا 
			.replace(/ *(<\/? ?br ?\/?>|\{\{بر\}\}) */g, '{{سخ}}')
			.replace(/\{\{سخ\}\}\n\n/g, '\n\n')
			.replace(/\n\n\{\{سخ\}\}/g, '\n\n')
			.replace(/\n\n(\*|\#)/g,'\n$1')
			.replace(/\n(\#|\*)( |)\n/g,'\n$1')
			.replace(/\n(\*|\#)( |)(\={2,})/g,'\n$3')
			.replace(/(\n?)\s+?<\/ref>/g, '$1</ref>')
			.replace( /^=.*&nbsp;.*=$/gim, function( $0 ) {
						return $0.replace( /(?:&nbsp;|\s)+/gi, ' ' );
			})
			.replace(/([^=])\n+(\=.*?\=\n+)/g, '$1\n\n$2')
			.replace(/^(=+([^=].*?)=+)[\t\s]{1,}\n/g, '$1\n')
			.replace(/^(\={2,}) +[\:,;>&\^#@•→←↔↑↓—–…~٫،؛ٔ]/mg, '$1') // Cleanup headers
			.replace(/[\:,;<&\^#@•→←↔↑↓—–…~٫،؛ٔ] +(\={2,})$/mg, '$1')
			.replace(/^(\={2,}\s*)(«)([^\n«»]*?)(»)(\s*\={2,})/mg, '$1 $3 $5')
			.replace(/^(\={2,}) *'+(.*?)'+ *(\={2,})/mg, '$1 $2 $3')
			.replace(/^[•●⚫⬤]/mg, '*') // Wikify bullets in start of lines
			.replace(/^#\s*(REDIRECT|تغییر[ _]?مسیر)/gi, '#تغییرمسیر')
			.replace(/^#تغییرمسیر(?=\S)/g, '#تغییرمسیر ') // Adds a space after #REDIRECT
			.replace(/(\={2,}) *([^\n\r]*?) *(\={2,})/g, '$1 $2 $3') // Format headings level 2 and above
			// فاصله‌های اضافی را از داخل پیوند به بیرون منتقل کند تا اگر اضافه بودند در کدهای دیگر حذف شوند
			.replace(/\[\[(\s*)(.*?)(\s*)\]\]/g, '$1[[$2]]$3')
			//حذف فاصلهٔ اضافی درون {{}}
			.replace(/\{\{(\s*)(.*?)(\s*)\}\}/g, '{{$2}}')
			// تبدیل به نویسه / یکی کردن فاصله های مجازی پشت سرهم
			.replace(/(\{\{فم\}\}|\&zwnj\;|\u200c+)/g, '\u200c')
			// Full stop and comma should be before citation. See en:WP:REFPUNC
			.replace(/ *((?:<ref[^\/]*?>.*?<\/ref>)+)([\.،,:])?/g, '$2$1')
			.replace(/([^.])([\.،,:]){2}((?:<ref[^\/]*?>.*?<\/ref>)+)/g, '$1$2$3')
			.replace(/ *((?:<ref[^\/]*?\/>)+)([\.،,:])/g, '$2$1')
			.replace(/([^.])([\.،,:]){2}(((?:<ref[^\/]*?\/>)+)+)/g, '$1$2$3')
			/* هر رده در یک خط */
			.replace( /([^\s>-]) *(\[\[رده:[^\n[\]]*\]\])/gi, '$1\n$2' )
			.replace( /(\[\[رده:[^\n[\]]*\]\]) *(?![\s<-]|$)/gi, '$1\n' )
			.replace( /(\[\[رده:[^\n[\]]*\]\]\n) *(?!\[\[رده:|[\s<-]|$)/gi,'$1\n')
			//ترتیب‌پیش‌فرض
			.replace(/\{\{(?:DEFAULTSORT|[Dd]efaultsort|ترتیب|ترتیب[‌ ]پیش[‌ ]?فرض) *[|:] *(?=.*?}})/g, '{{ترتیب‌پیش‌فرض:')
			.replace(/\{\{(ترتیب‌پیش‌فرض|DEFAULTSORT)\:[-\w,\s\(\)]+\}\}\n?/g, '')
			.replace(/(\{\{(?:ترتیب‌پیش‌فرض|DEFAULT\w*SORT\w*):[^\n{}]*\}\})\s*(?=\[\[رده:)/gi,'$1\n')
			.replace(/(\{\{ترتیب‌پیش‌فرض\:)\s/g, '$1')
			.replace( /(==\n)\n+(?=<references[^\n<>]*\/>\n\n)/gi, '$1' )
			//نچسبیدن و+فاصله به براکت که محصول اشتباه در تایپ کردن است
			.replace(/\]\]و /g, ']] و ')
			.replace(/(\s|^)\'\'\'(\s|)(.*?)(\s|)\'\'\'(\s)/g, "$1'''$3'''$5") // حذف فاصلهٔ اضافی درون ویکی کد
			.replace(/'''\{\{به /g, "''' {{به ")
			.replace(/\*(\s+|\n)?\{\{پانویس/g, "{{پانویس")
			.replace(/((?:^|\n\s)\=+\s+\=+(?:\s+|)\n)/g, "\n\n")
			.replace(/\n{3,}/g, '\n\n')

			.trim();
	}

	function wikiSubsection(text) {
		return text.replace(/\<(?:\s*)references?(?:\s*\/|\s*\/\s*)\>/g, '{{پانویس}}')
			   .replace(/\{\{(?:[Rr]eflist|[Rr]eferences?|پانویس[‌ ]?ها)(?=\||\})/g, '{{پانویس')
			   .replace(/\{\{راست(| |‌)چین\}\}\s*\{\{پانویس(.*?)\}\}\s*\{\{(پایان راست(| |‌)چین|پایان)\}\}/g, '{{پانویس$2}}')
			   .replace(/\{\{چپ(| |‌)چین\}\}\s*\{\{پانویس(.*?)\}\}\s*\{\{(پایان چپ(| |‌)چین|پایان)\}\}/g, '{{پانویس$2|چپ‌چین=بله}}')
			   .replace(/\<small\>\s*\{\{پانویس(.*?)\}\}\s*\<\/small\>/g, '{{پانویس$1|اندازه=کوچک}}')
			   .replace(/(({\{پانویس.*?\}\})(\n|)){1,}/g, '$1')
			   .replace(/\=\s*لیست\s*\=/g, '= فهرست =')
			   .replace(/\=\s*(?:[gG]allery|نگارستان|گالری (تصویر|عکس|))\s*\=/g, '= نگارخانه =')
			   .replace(/\=\s*(?:بیوگرافی|زندگینامه)\s*\=/g, '= زندگی‌نامه =')
			   .replace(/\=\s*(?:[eE]xternal links|لینک‌?های بیرونی|پیوندهای خارجی|لینک‌?های خارجی|پیوندهای بیرونی)\s*\=/g, '= پیوند به بیرون =')
			   .replace(/\=\s*(?:[nN]otes|[fF]ootnotes?|پاورقی|پاورقی‌ها|پانوشت|پانویس‌ها)\s*\=/g, '= پانویس =')
			   .replace(/\=\s*(?:[Ss]ee [Aa]lso|همچنین ببینی[مد]|بیشتر ببینی[مد]|بیشتر بخوانی[مد]|همچنین نگاه کنید|بیشتر بدانی[مد]|مراجعات مرتبط|جستار وابسته|مطلب مرتبط|مطالب مرتبط|مطالعه بیشتر|جستارهای مشابه)\s*\=/g, '= جستارهای وابسته =')
			   .replace(/\=\s*(?:منبع|منبع[‌ ]?ها|رفرنس|رفرنس[‌ ]?ها|ارجاع[‌ ]?ها|ارجاع|مرجع[‌ ]?ها|رفرنس|برگرفته از|مراجع|منابع و یادداشت[‌ ]?ها|منبع|مرجع|م[آا]خذ|منابع و م[آا]خذ|منابع و پانویس‌ها|فهرست مراجع|لیست مراجع|فهرست ارجاع[‌ ]?ها|فهرست ارجاع|[rR]eferences)\s*\=/g, '= منابع =')
			   .replace(/^\={3,}\s*(جستارهای وابسته|پانویس|منابع)\s*\={3,}$/g, '== $1 ==');
	}
	function wikiUrlMinifier(text) {
		return text
			.replace(patterns.url, function (x) {
				return replaceExcept(
					x,
					function (x) {
						try {
							x = decodeURI(x);
						} catch (e) {
							try {
								x = decodeURIComponent(unescape(x));
							} catch (e) {mw.notify(e); }
						}
						return x;
					},
					[patterns.globalExceptionTag, patterns.decodeUriBlacklist]
				);
			})

			// Strip the http(s) prefix
			.replace(/\[(https?\:)(?=\/\/(?:[\w\-]+)\.(wiki(pedia|media|data|source|news|oyage|quote)|wiktionary)\.org\/[^\s\]]*)/g, '[')
			.replace(/\[(?:https?\:|)\/\/[\w\-]{2,}\.wikipedia\.org\/wiki\/([^\n?]*?)\]/g, function (x) {
				x = x.replace(/\[(?:https?\:|)\/\/([\w\-]{2,})\.wikipedia\.org\/wiki\/(.*?) (.*?)\]/g,'[[:$1:$2|$3]]')
				x = x.replace(/\[(?:https?\:|)\/\/([\w\-]{2,})\.wikipedia\.org\/wiki\/(.*?)\]/g,'[[:$1:$2]]')
				x = x.replace(/\_/g,' ').replace(/\[\[\:fa\:/g,'[[')
				return x
			});
	}

	function wikiTextDigitsToPersian(text) {
		text = replaceExcept(
			text,
			toEnglishDigits,
			[patterns.argumentsBlacklist,patterns.fileNames,patterns.fileParameter]);
		text = replaceExcept(
			text,
			persianTools.toPersianDigits,
			[patterns.globalExceptionTag, patterns.url, patterns.argumentsBlacklist, patterns.mathTag, patterns.imagePixelSize, patterns.fileNames, patterns.ref,
				patterns.sourceTag, patterns.arabicDigitsEnglishContext, patterns.signatures, patterns.htmlEntity, patterns.diffLink,
				patterns.htmlAttributes, patterns.fileParameter, patterns.templateParameterName, patterns.ipSign,
				patterns.parenthesesAfterDigits, patterns.otherLanguagesInline, patterns.isbn, patterns.englishDate,
				patterns.parameter, patterns.color, patterns.templateEnglishName, patterns.linksOnEnglishContext, patterns.citation, patterns.refname,
				patterns.LtRTagEnclosed, patterns.boxVar]
		);
		return text
			// Decimal point, and thousands' separator
			.replace(/([۱۲۳۴۵۶۷۸۹۰])\.([۱۲۳۴۵۶۷۸۹۰])/g, '$1٫$2')
			.replace(/([۱۲۳۴۵۶۷۸۹۰]),([۱۲۳۴۵۶۷۸۹۰])/g, '$1٬$2')
			.replace(/([۱۲۳۴۵۶۷۸۹۰])( |)\u0652/g, '$1°')//تبدیل نویسه سکون+عدد فارسی به نویسه درجه و عدد فارسی
			.replace(/\u0652( |)([۱۲۳۴۵۶۷۸۹۰])/g, '°$2')
			//فاصله بین نویسه درجه و حروف الفبای فارسی به جز عدد فارسی
			.replace(/([\u0621-\u064A\u0653-\u0655\u067E\u0686\u0698\u06AF\u06A9\u0643\u06AA\uFED9\uFEDA\u06CC\uFEF1\uFEF2])°/g, '$1 °');
	}

	function dictationReplace(x, y, extensions, text) {
		return text.replace(
			new RegExp(
				'(^|[^' + persianTools.persianCharacters + '])(\\s|\u200c|_|)(' + x + ')(\\s|_)(' + y + ')(\\s|\u200c|_|)(' +
					extensions + ')($|[^' + persianTools.persianCharacters + '])',
				'g'
			),
			'$1$2$3\u200c$5$6$7$8'
		);
	}

	// it has dependency to MediaWiki:Gadget-Extra-Editbuttons-Dictionary.js
	function dictation(text) {
		var i,
			dictionary = persianToolsDictionary,
			NASB = '\u064b', // ًـ
			ZAMM = '\u064c'; // ُـ
		for (i in dictionary.complexes) {
			if (dictionary.complexes.hasOwnProperty(i)) {
				text = dictationReplace(
					i,
					dictionary.complexes[i],
					'ی|یی|ها|های|هایی|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
					text
				);
			}
		}
		// for last name
		text = dictationReplace(
			dictionary.personNames,
			'ی|یی|زاده|نیا|گان|فر|نژاد|یان|ی\u200cها|یها',
			'ی|',
			text
		);
		// for 'آباد's
		text = dictationReplace(
			dictionary.personNames + '|' + dictionary.addToAbad,
			'آباد',
			'زاده|نیا|پور|گان|فر|نژاد|ی|یان|ها|های|یی|هایی|ی\u200cها|یها|',
			text
		);
		// for first names
		for (i in dictionary.firstNameComplex) {
			if (dictionary.firstNameComplex.hasOwnProperty(i)) {
				text = text.replace(
					new RegExp(
						'(^|[^' + persianTools.persianCharacters + ']|\\s|_)(' + i + ')(\\s|_)(' +
							dictionary.firstNameComplex[i] + ')(\\s|_)($|[^' + persianTools.persianCharacters + ']|[^' +
							persianTools.persianCharacters + '])',
						'g'
					),
					'$1$2\u200c$4$5$6'
				);
			}
		}
		// for colors
		text = dictationReplace(
			dictionary.colorsNames,
			'فام|گون',
			'زاده|نیا|پور|گان|فر|نژاد|ی|یی|ها|های|هایی|ی\u200cها|یها|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
			text
		);
		// for numbers
		text = dictationReplace(
			dictionary.persianNumbers,
			'گانه|ماهه',
			'زاده|نیا|پور|گان|فر|نژاد|ی|یی|ها|های|هایی|هایم|هایت|هایش|هایمان|هایتان|هایشان|',
			text
		);
		// wrong dictation
		for (i in dictionary.forReplace) {
			if (dictionary.forReplace.hasOwnProperty(i)) {
				text = text.replace(
					new RegExp(
						'(^|[^' + persianTools.persianCharacters + '])(\\s|\u200c|_|)(' + i + ')(\\s|\u200c|_|)($|[^' +
							persianTools.persianCharacters + '])',
						'g'
					),
					'$1$2' + dictionary.forReplace[i] + '$4$5'
				);
			}
		}

		// کلماتی که آ دارند
		text = text.replace(
			new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.wordsWithA + ")(ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\]|\\s|\\:|\\)|\\<|\\>|؟|\\'|\\!|$)", 'g'),
			function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
		);
		// بن مضارع که آ دارند
		text = text.replace(
			new RegExp("(^|\u200c|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.PresentVerbsWithA + ")(م|ی|د|یم|ید|ند)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
			function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
		);

		// بن ماضی که آ دارند
		text = text.replace(
			new RegExp("(^|\u200c|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.PastVerbsWithA + ")(م|ی|یم|ید|ند|ه|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
			function (x) { return x.replace(/ا/i, 'آ'); } // 'i' is just to trick bidi algorithm on code view
		);

		// همزه ضم
		text = text.replace(
			new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehZam + ")(‌ها|ها|ین|ان|ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
			function (x) { return x.replace(/وء/, 'ؤ').replace(/و/i, 'ؤ'); } // 'i' is just to trick bidi algorithm on code view
		);
		//همزه نصب
		text = text.replace(
			new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehNasb + ")(ی|ئی|یی|ٔ|)(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
			function (x) { return x.replace(/ا/i, 'أ'); } // 'i' is just to trick bidi algorithm on code view
		);

		//همزه وسط کلمه
		for (i in dictionary.HamzehAtInside) {
			text = text.replace(new RegExp(
				"(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + i + ')(| )(' + dictionary.HamzehAtInside[i] + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)",
				'g'
			), '$1$2ء$4');
		}

		// در مورد افزودن یا حذف همزهٔ پایانی اجماعی وجود ندارد.
		/* text = text.replace(new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.HamzehAtEnd + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$2ء'); */

		//الف مقصوره
		text = text.replace(
			new RegExp("(^|\\s|_|«|»|\\[|\\(|\\<|\\>|\\')(" + dictionary.AlefMaghsooreh + ")(?= |«|»|\\.|،|_|\\s|\\]|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),
			function (x) { return x.replace(/ا/i, 'ی'); } // 'i' is just to trick bidi algorithm on code view
		);

		// صفت+تر
		text = text.replace(new RegExp("(^|\\s|_|«|»|\\]|\\[|\\(|\\<|\\>|\\')(" + dictionary.adjective + ")( |_)تر(?= |«|»|\\.|\\[|\\]|،|_|\\s|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$2\u200cتر');
		
		// اسامی رنگ‌ها (به‌عنوان صفت)+تر
		text = text.replace(new RegExp("(^|\\s|_|«|»|\\]|\\[|\\(|\\<|\\>|\\')(" + dictionary.colorsNames + ")( |_)تر(?= |«|»|\\.|\\[|\\]|،|_|\\s|\\:|\\)|\\<|\\>|؟|\\!|\\'|$)", 'g'),'$1$2\u200cتر');
		
		text = text.replace(/به دست\u200cآورد/g, 'به دست آورد'); // Solving a bug!
		text = persianTools.normalizeZwnj(text);
		return text.replace(new RegExp("(^|[؛\\s\\n\\.،«»\'\\<\\>؟])(" + dictionary.needsNasb + ')[' + NASB + ZAMM + ']?([؛؟\\s\\n\\.،«»\'"\\<\\>]|$)', 'g'), function (match) {
			return match
				.replace(new RegExp('ا([\\s\\n\\.،«»؟؛"\'\\>\\<' + ZAMM + '])', 'i'), 'ا' + NASB + '$1')
				.replace(new RegExp(NASB + '["' + NASB + ZAMM + ']'), NASB);
		});
	}

	function wikiDictation(text) {
		return replaceExcept(
			text,
			dictation,
			[patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag, patterns.insideQuote, patterns.argumentsBlacklist, patterns.articleTitleParts]
		);
	}
	function wikiApplyOrthography(text) {
		text=text //en:Wikipedia:HTML5
				//big
				.replace(/((?:\<big\>){5})([^<]+)((?:\<\/big\>){5})/g,'<span style="font-size: 56px;">$2</span>')
				.replace(/((?:\<big\>){4})([^<]+)((?:\<\/big\>){4})/g,'<span style="font-size: 38px;">$2</span>')
				.replace(/((?:\<big\>){3})([^<]+)((?:\<\/big\>){3})/g,'{{خیلی بزرگ|$2}}')
				.replace(/((?:\<big\>){2})([^<]+)((?:\<\/big\>){2})/g,'{{بزرگ|$2}}')
				.replace(/((?:\<big\>){1})([^<]+|[\s\S]+)((?:\<\/big\>){1})/g,'{{درشت|$2}}')
				//center
				.replace(/<center><gallery>([\S\s]+?)\<\/gallery><\/center>/g,'<gallery class="center">$1</gallery>')
				//.replace(/<center>([\S\s]+?)<\/center>/g,'{{وسط|$1}}')
				//empty tag
				.replace(/<span style="font-size: [^>]+"><\/span>/g,'')
				.replace(/{{(?:درشت|خیلی بزرگ|بزرگ|وسط)\|}}/g,'')

		//حذف برچسب‌های خالی نرم‌افزار مدیاویکی
		var tags = ['math', 'code', 'nowiki', 'pre', 'syntaxhighlight' ,'source', 's', 'su[bp]', 'noinclude', 'includeonly', 'big', 'small','gallery'];
		text = replaceExcept(
		  text,
		  function (text) {
			for (var i = 0; i < tags.length; ++i) {
			  text = text.replace(new RegExp('\<' + tags[i] + '[^\>]*\>(\\n|\\s|\u200c)*?\<\\/' + tags[i] + '\>', 'g'), '');
			  // remove the tags if they occurred multiple times consequently
			  if (mw.config.get('wgNamespaceNumber') === 0 || mw.config.get('wgNamespaceNumber') === 4) {
				text = text.replace(new RegExp('(\<' + tags[i] + '\>){2,}', 'g'), '$1')
				  .replace(new RegExp('(\<\\/' + tags[i] + '\>){2,}', 'g'), '$1');
			  }
			}
			if (mw.config.get('wgNamespaceNumber') === 0) {
				 text=text.replace(/\<ref\>[\s\n]*\<\/ref\>/g,'');
			};
			return text
		  },
		  [patterns.insideHtmlComment]
		);
		return replaceExcept(
			text,
			persianTools.applyOrthography,
			[patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag, patterns.wikilinkTargets]
		).replace(patterns.galleryTag, function (gallery) {
			// apply `applyOrthography` on gallery descriptions separately
			return gallery.replace(/^([^\|]*?\|)(.*)$/mg, function (x, y, z) {
				return y + persianTools.applyOrthography(z);
			});
		});
	}
	
	// probably should be exactly same above but for applyZwnj
	function wikiApplyZwnj(text) {
		return replaceExcept(
			text,
			persianTools.applyZwnj,
			[patterns.globalExceptionTag, patterns.fileNames, patterns.signatures, patterns.url, patterns.galleryTag]
		).replace(patterns.galleryTag, function (gallery) {
			// apply `applyOrthography` on gallery descriptions separatly
			return gallery.replace(/^([^\|]*?\|)(.*)$/mg, function (x, y, z) {
				return y + persianTools.applyZwnj(z);
			});
		});
	}

	function replaceEnMonth(text) {
		var enMonth = {
			'آگست':'اوت',
			'آگوست':'اوت',
			'جولای':'ژوئیه',
			'مارچ':'مارس',
			'آپریل':'آوریل',
			'فوریوری':'فوریه',
			'january': 'ژانویه',
			'jan': 'ژانویه',
			'february': 'فوریه',
			'feb': 'فوریه',
			'march': 'مارس',
			'mar': 'مارس',
			'april': 'آوریل',
			'apr': 'آوریل',
			'may': 'مه',
			'june': 'ژوئن',
			'jun': 'ژوئن',
			'july': 'ژوئیه',
			'august': 'اوت',
			'aug': 'اوت',
			'september': 'سپتامبر',
			'sept': 'سپتامبر',
			'sep': 'سپتامبر',
			'october': 'اکتبر',
			'oct': 'اکتبر',
			'november': 'نوامبر',
			'nov': 'نوامبر',
			'december': 'دسامبر',
			'dec': 'دسامبر'
		};
		for (var i in enMonth) {
			var text_new = text.replace(new RegExp(i, 'ig'), enMonth[i])
			if (text_new != text) {
				return text_new
			}
		}
		return text
	};

	function wikitranslateEnMonth(text) {
		text=autoFormatCleanDates(text)
		return replaceExcept(
			text,
			function translateEnMonth(text) {
				var enMonthRegex = '(آگست|آگوست|جولای|مارچ|آپریل|january|jan|february|feb|march|mar|april|apr|may|jun|june|july|august|aug|sep|sept|september|oct|october|nov|november|december|dec)';
				return text.replace(new RegExp('([^a-zA-Z])(\^|\\||\\s|\\=|\\n|\\(|«|\\:)' + enMonthRegex + ' (\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2})\\, (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|\$|\\)|\\}|»)([\^a\-zA\-Z])', 'ig'),
						function (x) {
							x=x.replace(new RegExp('([\^a\-zA\-Z])(\^|\\||\\s|\\=|\\n|\\(|«|\\:)' + enMonthRegex + ' (\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2})\\, (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|\$|\\)|\\}||»)([^a-zA-Z])', 'ig'),
							'$1$2$4 $3 $5$6$7')
							x = persianTools.toPersianDigits(x);
							x = replaceEnMonth(x);
							return x;
						})
					.replace(new RegExp('([\^a\-zA\-Z])(\^|\\||\\s|\\=|\\n|\\(|«)((\\d{1,2}|[۱۲۳۴۵۶۷۸۹۰]{1,2}) |)' + enMonthRegex + ' (\\d{3,4}|[۱۲۳۴۵۶۷۸۹۰]{3,4})(\\||\\s|\\n|$|\\)|\\}|»|\\:)([\^a\-zA\-Z])', 'ig'),
						function(x) {
							x = persianTools.toPersianDigits(x);
							x = replaceEnMonth(x);
							return x;
						}
					);
			}, [patterns.globalExceptionTag, patterns.fileNames, patterns.ref, patterns.fileParameter, patterns.galleryTag, patterns.mathTag, patterns.sourceTag, patterns.templateWithEnglishName, patterns.citation]
		)
	}
	
	var arabicDigits = '0123456789', persianDigits = '۰۱۲۳۴۵۶۷۸۹';
	function robustToEnglishDigits(text) {
		var i = 0;
		for (i = 0; i <= 9; i = i + 1) {
			text = text.replace(new RegExp('[' + persianDigits[i] + ']', 'g'), arabicDigits[i]);
		}
		return text;
	}
		
	function toEnglishDigits(text) {
		text = text.replace(/[a-zA-Z]([\_\s\:\.\,\;\]\[\"\'\)\(\}\{\/\\]+|)([۱۲۳۴۵۶۷۸۹۰٪\.٫\-\—\–°÷×\+\,\s\_\:]+)([\_\s\:\.\,\;\]\[\"\'\)\(\}\{\/\\\<\>]+|)([a-zA-Z\>]|$)/g, function (x) {
			var i = 0;
			for (i = 0; i <= 9; i = i + 1) {
				x = x.replace(new RegExp('[' + persianDigits[i] + ']', 'g'), arabicDigits[i]);
			}
			return x;
		});
		// bug [[Special:Diff/17760890/17760898]]
		text = text.replace(/([a-zA-Z][۱۲۳۴۵۶۷۸۹۰]+) *\=/g, function (x) {
			var i = 0;
			for (i = 0; i <= 9; i = i + 1) {
				x = x.replace(new RegExp('[' + persianDigits[i] + ']', 'g'), arabicDigits[i]);
			}
			return x;
		});
		// ISBN, ISSN and PMID's numbers should in english
		text = text.replace(/\b(ISBN|ISSN|PMID|PubMed) *:? *([۱۲۳۴۵۶۷۸۹۰0-9–—−ـ_\-]+)([^۱۲۳۴۵۶۷۸۹۰0-9–—−ـ_\-]|$)/gi, function (x) {
			x=x.replace(/[–—−ـ_\-]+/g,'-')
			var i = 0;
			for (i = 0; i <= 9; i = i + 1) {
				x = x.replace(new RegExp('[' + persianDigits[i] + ']', 'g'), arabicDigits[i]);
			}
			x = x.replace(/\b(ISBN|ISSN|PMID|PubMed) *:? *([۱۲۳۴۵۶۷۸۹۰\-0-9]+)([^۱۲۳۴۵۶۷۸۹۰\-0-9]|$)/gi,'$1 $2$3')
			x = x.replace('PubMed','PMID')
			return x;
		});
		// تبدیل عددهای فارسی در عدد ترتیبی انگلیسی
		text = text.replace(/(?:^|["\'\s_«\(\[\{])([۱۲۳۴۵۶۷۸۹۰]+)(st|nd|rd|th)[\s_\.,»"\'\)\]\}]/g, function (x) {
			var i = 0;
			for (i = 0; i <= 9; i = i + 1) {
				x = x.replace(new RegExp('[' + persianDigits[i] + ']', 'g'), arabicDigits[i]);
			}
			return x;
		});
		return text
			.replace(new RegExp('([' + arabicDigits + ']) ?٪', 'g'), '$1%')
			.replace(new RegExp('([' + arabicDigits + '])٫(?=[' + arabicDigits + '])', 'g'), '$1.') // English decimal separator
	}

	function superTool(text) {
		text = persianWikiTools.wikiConvertToPersianCharacters(text);
		text = persianWikiTools.wikiApplyZwnj(text);
		text = persianWikiTools.wikiApplyOrthography(text);
		text = persianWikiTools.wikitranslateEnMonth(text);
		if (mw.config.get('wgNamespaceNumber') !== 10) {
			text = persianWikiTools.wikiTextDigitsToPersian(text);
		}
		text = persianWikiTools.wikiUrlMinifier(text);
		text = persianWikiTools.wikiDictation(text);
		text = persianWikiTools.wikiPunctuation(text);
		text = persianWikiTools.wikiSubsection(text);
		//ابزارهای بیشتر برگرفته از ویکی‌پدیای انگلیسی [[Mediawiki:Gadget-Extra-Editbuttons-autoed.js]]
		text = autoEd.autoEdISBN(text);
		text = autoEd.autoEdWhitespace(text);
		text = autoEd.autoEdHTMLtoWikitext(text);
		text = autoEd.autoEdHeadlines(text);
		text = autoEd.autoEdTablestoWikitext(text);
		text = autoEd.autoEdExtraBreaks(text);
		text = persianWikiTools.addColumnToRefTemplate(text);
		return text;
	}
	
	function superToolMove(text) {
		text = ' ' + text + ' '; // بعضی از کدها اگر فاصله در انتها یا اول نباشد عمل نمی‌کنند مانند افزودن تنوین به کلمه بعدا
		text = persianWikiTools.wikiConvertToPersianCharacters(text);
		text = persianTools.applyZwnj(text);
		text = persianWikiTools.wikiApplyOrthography(text);
		text = persianWikiTools.wikiTextDigitsToPersian(text);
		text = persianWikiTools.wikiUrlMinifier(text);
		text = persianWikiTools.wikiDictation(text);
		text = persianWikiTools.wikiPunctuation(text);
		return text.trim();
	}

	return {
		superTool: superTool,
		superToolMove: superToolMove,
		dictation: dictation,
		wikiApplyOrthography: wikiApplyOrthography,
		wikiApplyZwnj: wikiApplyZwnj,
		wikiConvertToPersianCharacters: wikiConvertToPersianCharacters,
		wikiDictation: wikiDictation,
		wikiPunctuation: wikiPunctuation,
		wikiSubsection:wikiSubsection,
		wikiUrlMinifier: wikiUrlMinifier,
		wikiTextDigitsToPersian: wikiTextDigitsToPersian,
		wikitranslateEnMonth: wikitranslateEnMonth,
		addColumnToRefTemplate: addColumnToRefTemplate,
		fixBadLinks: fixBadLinks,
		robustToEnglishDigits: robustToEnglishDigits,
		toEnglishDigits: toEnglishDigits
	};
}());
if (typeof window !== "undefined") {
	window.persianWikiTools = persianWikiTools;
}
// </nowiki>