مدیاویکی:Gadget-Extra-Editbuttons-persianwikitools.js
از پژوهشکده امر به معروف
نکته: پس از ذخیرهکردن ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.
- فایرفاکس / سافاری: کلید Shift را نگه دارید و روی دکمهٔ Reload کلیک کنید، یا کلیدهای Ctrl-F5 یا Ctrl-R را با هم فشار دهید (در رایانههای اپل مکینتاش کلیدهای ⌘-R)
- گوگل کروم: کلیدهای Ctrl+Shift+R را با هم فشار دهید (در رایانههای اپل مکینتاش کلیدهای ⌘-Shift-R)
- اینترنت اکسپلورر: کلید Ctrl را نگهدارید و روی دکمهٔ Refresh کلیک کنید، یا کلیدهای Ctrl-F5 را با هم فشار دهید
- اپرا: حافظهٔ نهانی مرورگر را از طریق منوی Tools → Preferences پاک کنید
// <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';
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('');
}
var patterns = {
arabicDigitsEnglishContext: /[a-z][a-z %"'\._:\;,\-\\\/\(\)\#\^\+\d><–\[\]&?{}]*\d|(\d|[a-z])[a-z %"'\._:\;\|,\-\\\/\(\)\#\^\+\d><–\[\]&?{}]*[a-z]\d*/gi,
arabicTagEnclosed: /\{\{(?:عربی|شروع عربی|آغاز عربی)\}\}([\s\S]*?)\{\{(?:پایان عربی)\}\}/g,
argumentsBlacklist: /(?:accessdate|namespace|image|تصویر|doi|style|شابک|عرض|bibcode|isbn|pmid|arxiv|upright|upleft)\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|%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 [\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: /\{\{(?:به .+?|به انگلیسی|انگلیسی|عربی|حدیث|به عربی)[\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/>
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,
templateParameterName: /\|\s*(?=[a-z_]*\d)[a-z_\d]*\s*\=/gi,
translatedUrl: /.(کام|نت|آیآر)/g,
url: /\/\/.*?(?=[\s\n\|\}\]<]|$)/gi // بدون https?: هم ممکن است
};
function wikiConvertToPersianCharacters(text) {
return replaceExcept(
text,
persianTools.toStandardPersianCharacters,
[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 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
if (line.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'
);
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 = quotation(text);
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.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.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(/\[\[(رده|الگو|ویکی\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(/([^=])\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(/\{\{(?:DEFAULTSORT|[Dd]efaultsort|ترتیب|ترتیب[ ]پیش[ ]?فرض) *[|:] *(?=.*?}})/g, '{{ترتیبپیشفرض:')
.replace(/\{\{(ترتیبپیشفرض|DEFAULTSORT)\:[-\w,\s\(\)]+\}\}\n?/g, '')
.replace(/(\{\{ترتیبپیشفرض\:)\s/g, '$1')
//نچسبیدن و+فاصله به براکت که محصول اشتباه در تایپ کردن است
.replace(']]و ', ']] و ')
.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(/\=\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, '= منابع =');
}
function wikiUrlMinifier(text) {
return text
.replace(patterns.url, function (x) {
return replaceExcept(
x,
function (x) {
try {
x = decodeURI(x);
} catch (e) { mw.notify(e); }
return x;
},
[patterns.decodeUriBlacklist]
);
})
// Strip the http(s) prefix
.replace(/\[(https?\:)(?=\/\/(?:[\w\-]+)\.(wiki(pedia|media|data|source|news|oyage|quote)|wiktionary)\.org\/[^\s\]]*)/g, '[');
}
function wikiTextDigitsToPersian(text) {
text = replaceExcept(
text,
persianTools.toEnglishDigits,
[patterns.argumentsBlacklist,patterns.fileNames,patterns.fileParameter]);
text = replaceExcept(
text,
persianTools.toPersianDigits,
[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]
);
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.fileNames, patterns.signatures, patterns.url, patterns.galleryTag, patterns.insideQuote, patterns.argumentsBlacklist]
);
}
function wikiApplyOrthography(text) {
//حذف برچسبهای خالی نرمافزار مدیاویکی
var tags = ['math', 'code', 'nowiki', 'pre', 'source', 's', 'su[bp]', 'noinclude', 'includeonly', 'ref', 'big', 'small'];
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');
}
}
return text;
},
[patterns.insideHtmlComment]
);
return replaceExcept(
text,
persianTools.applyOrthography,
[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.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) {
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.fileNames, patterns.ref, patterns.fileParameter, patterns.galleryTag, patterns.mathTag, patterns.sourceTag, patterns.citation]
)
};
function superTool(text) {
text = persianWikiTools.wikiConvertToPersianCharacters(text);
text = persianWikiTools.wikiApplyZwnj(text);
text = persianWikiTools.wikiApplyOrthography(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);
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.autoEdTemplates(text);
text = autoEd.autoEdTablestoWikitext(text);
text = autoEd.autoEdExtraBreaks(text);
text = persianWikiTools.addColumnToRefTemplate(text);
return text;
}
function superToolMove(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;
}
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,
};
}());
if (typeof window !== "undefined") {
window.persianWikiTools = persianWikiTools;
}






