مدیاویکی:Gadget-Extra-Editbuttons-Functions.js
پرش به ناوبری
پرش به جستجو
نکته: پس از انتشار ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.
- فایرفاکس / سافاری: کلید Shift را نگه دارید و روی دکمهٔ Reload کلیک کنید، یا کلیدهای Ctrl-F5 یا Ctrl-R را با هم فشار دهید (در رایانههای اپل مکینتاش کلیدهای ⌘-R)
- گوگل کروم: کلیدهای Ctrl+Shift+R را با هم فشار دهید (در رایانههای اپل مکینتاش کلیدهای ⌘-Shift-R)
- اینترنت اکسپلورر/ Edge: کلید Ctrl را نگهدارید و روی دکمهٔ Refresh کلیک کنید، یا کلیدهای Ctrl-F5 را با هم فشار دهید
- اپرا: Ctrl-F5 را بفشارید.
// <nowiki>
/*!
* Persian Wikipedia tools
* http://fa.wikipedia.org/wiki/MediaWiki:PersianTools.js
* Released under the CC-by-SA 3.0 license
* Copyright (c) 2006-2013 Persian Wikipedia
* @author: ebraminio
* @contributors: See http://fa.wikipedia.org/w/index.php?title=MediaWiki:Gadget-Extra-Editbuttons-Functions.js&action=history
*/
/*jslint indent: 2, regexp: true, node: true*/
(function (root) {
'use strict';
var persianGlyphs, persianDigits, arabicIndicDigits, arabicDigits,
persianCharacters, persianPastVerbs, persianPresentVerbs;
arabicDigits = '0123456789';
arabicIndicDigits = '٠١٢٣٤٥٦٧٨٩';
persianCharacters = 'ءآأؤإئابپةتثجحخچدذرزژسشصضطظعغفقكکگلمنهوىیي' + 'ًٌٍَُِّْ';
persianDigits = '۰۱۲۳۴۵۶۷۸۹';
function normalizeZwnj(text) {
return text
// Replace LRM، RLM characters with ZWNJ and it will remove unneeded ZWNJ at next lines
// .replace(/(\u202A|\u202B|\u202C|\u202D|\u202E|\u200F|\¬)/g, '\u200c')
.replace(new RegExp('([' + persianCharacters + '] *)\u200F+( *[' + persianCharacters + '])', 'g'), '$1\u200c$2')
// Remove more than a ZWNJs
.replace(/\u200c{2,}/g, '\u200c')
// Convert ¬ to zwnj in Persian context
.replace(new RegExp('([' + persianCharacters + '])¬(?=[' + persianCharacters + '])', 'g'), '$1\u200c')
// Clean ZWNJs after characters that don't conncet to the next letter
.replace(/([۰-۹0-9إأةؤورزژاآدذ،؛,\:«»\\\/@#$٪×\*\(\)ـ\-=\|])\u200c/g, '$1')
// Clean ZWNJs before English characters
.replace(/\u200c([\w])/g, '$1')
.replace(/([\w])\u200c/g, '$1')
// Clean ZWNJs after and before punctuation
.replace(/\u200c([\n\s\[\]\.،«»\:\(\)\؛\؟\?\;\$\!\@\-\=\+\\\|])/g, '$1')
.replace(/([\n\s\[\.،«»\:\(\)\؛\؟\?\;\$\!\@\-\=\+\\\|])\u200c/g, '$1')
//Clean ZWNJs before brakets which have sapce after\before them
.replace(/\u200c(\]\][\s\n])/g, '$1')
.replace(/([\n\s]\[\[)\u200c/g, '$1');
}
persianGlyphs = {
// these two are for visually available ZWNJ #visualZwnj
'\u200cه': 'ﻫ',
'ی\u200c': 'ﻰﻲ',
'ﺃ': 'ﺄﺃ',
'ﺁ': 'ﺁﺂ',
'ﺇ': 'ﺇﺈ',
'ا': 'ﺎا',
'ب': 'ﺏﺐﺑﺒ',
'پ': 'ﭖﭗﭘﭙ',
'ت': 'ﺕﺖﺗﺘ',
'ث': 'ﺙﺚﺛﺜ',
'ج': 'ﺝﺞﺟﺠ',
'چ': 'ﭺﭻﭼﭽ',
'ح': 'ﺡﺢﺣﺤ',
'خ': 'ﺥﺦﺧﺨ',
'د': 'ﺩﺪ',
'ذ': 'ﺫﺬ',
'ر': 'ﺭﺮ',
'ز': 'ﺯﺰ',
'ژ': 'ﮊﮋ',
'س': 'ﺱﺲﺳﺴ',
'ش': 'ﺵﺶﺷﺸ',
'ص': 'ﺹﺺﺻﺼ',
'ض': 'ﺽﺾﺿﻀ',
'ط': 'ﻁﻂﻃﻄ',
'ظ': 'ﻅﻆﻇﻈ',
'ع': 'ﻉﻊﻋﻌ',
'غ': 'ﻍﻎﻏﻐ',
'ف': 'ﻑﻒﻓﻔ',
'ق': 'ﻕﻖﻗﻘ',
'ک': 'ﮎﮏﮐﮑﻙﻚﻛﻜ',
'گ': 'ﮒﮓﮔﮕ',
'ل': 'ﻝﻞﻟﻠ',
'م': 'ﻡﻢﻣﻤ',
'ن': 'ﻥﻦﻧﻨ',
'ه': 'ﻩﻪﻫﻬ',
'هٔ': 'ﮤﮥ',
'و': 'ﻭﻮ',
'ﺅ': 'ﺅﺆ',
'ی': 'ﯼﯽﯾﯿﻯﻰﻱﻲﻳﻴ',
'ئ': 'ﺉﺊﺋﺌ',
'لا': 'ﻼ',
'ﻹ': 'ﻺ',
'ﻷ': 'ﻸ',
'ﻵ': 'ﻶ'
};
function toStandardPersianCharacters(text) {
var i;
for (i in persianGlyphs) {
if (persianGlyphs.hasOwnProperty(i)) {
text = text.replace(new RegExp('[' + persianGlyphs[i] + ']', 'g'), i);
}
}
return normalizeZwnj(text) // needed because of #visualZwnj
.replace(/ك/g, 'ک') // Arabic
.replace(/ي/g, 'ی')
.replace(/ى/g, 'ی') // Urdu
.replace(/ۍ/g, 'ی') // Pushtu
.replace(/ې/g, 'ی') // Uyghur
.replace(/ہ/g, 'ه') // Convert ہ to ه ہہہہ to ههه
.replace(/ە/g, 'ه\u200c') // Kurdish
.replace(/ھ/g, 'ه'); // Kurdish
}
function toPersianDigits(text) {
var i = 0;
for (i = 0; i <= 9; i = i + 1) {
text = text.replace(new RegExp('[' + arabicIndicDigits[i] + arabicDigits[i] + ']', 'g'), persianDigits[i]);
}
return text
.replace(new RegExp('([' + persianDigits + ']) ?%', 'g'), '$1٪')
.replace(new RegExp('([' + persianDigits + '])\\.(?=[' + persianDigits + '])', 'g'), '$1٫'); // persian decimal separator
}
function applyOrthography(text) {
return text
// Replace ه followed by (space|ZWNJ|lrm) follow by ی with هٔ
.replace(/ه[\u200c\u200e\s]+ی([\s\n])/g, 'هٔ$1')
// Replace ه followed by (space|ZWNJ|lrm|nothing) follow by ء or with هٔ
.replace(/ه[\u200c\u200e\s]*[ءٔ]([\s\n])/g, 'هٔ$1')
// Replace هٓ or single-character ۀ with the standard هٔ
.replace(/(ۀ|هٓ)/g, 'هٔ')
// Replace ه followed by ئ or ی, and then by ی, with ه\u200cای, example: خانهئی becomes خانه\u200cای
.replace(/ه\u200c[ئی]ی/g, 'ه\u200cای')
// Function for removing incorrect ZWNJs
.replace(/([\u200c\u200e])([\s\n])/g, '$2')
.replace(/([\s\n])([\u200c\u200e])/g, '$1');
}
/**
* Replaces Persian characters with Arabic's ones so an Arabic sorter can sort Persian lines
*/
function dePersian(text) {
return text
.replace(/ی/g, 'ي')
.replace(/ک/g, 'ك')
.replace(/گ/g, 'كی')
.replace(/ژ/g, 'زی')
.replace(/چ/g, 'جی')
.replace(/پ/g, 'بی');
}
function persianSortText(text) {
return text.split('\n').sort(function (x, y) {
var keyX = dePersian(x),
keyY = dePersian(y);
if (keyX < keyY) { return -1; }
if (keyX > keyY) { return 1; }
return 0;
}).join('\n');
}
persianPastVerbs = '(' +
'ارزید|افتاد|افراشت|افروخت|افزود|افسرد|افشاند|افکند|انباشت|انجامید|انداخت|اندوخت|اندود|اندیشید|انگاشت|انگیخت|انگیزاند|اوباشت|ایستاد'+
'|آراست|آراماند|آرامید|آرمید|آزرد|آزمود|آسود|آشامید|آشفت|آشوبید|آغازید|آغشت|آفرید|آکند|آگند|آلود|آمد|آمرزید|آموخت|آموزاند'+
'|آمیخت|آهیخت|آورد|آویخت|باخت|باراند|بارید|بافت|بالید|باوراند|بایست|بخشود|بخشید|برازید|برد|برید|بست|بسود|بسیجید|بلعید'+
'|بود|بوسید|بویید|بیخت|پاشاند|پاشید|پالود|پایید|پخت|پذیراند|پذیرفت|پراکند|پراند|پرداخت|پرستید|پرسید|پرهیزید|پروراند|پرورد|پرید'+
'|پژمرد|پژوهید|پسندید|پلاسید|پلکید|پناهید|پنداشت|پوسید|پوشاند|پوشید|پویید|پیچاند|پیچانید|پیچید|پیراست|پیمود|پیوست|تاباند|تابید|تاخت'+
'|تاراند|تازاند|تازید|تافت|تپاند|تپید|تراشاند|تراشید|تراوید|ترساند|ترسید|ترشید|ترکاند|ترکید|تکاند|تکانید|تنید|توانست|جَست|جُست'+
'|جست|جنباند|جنبید|جنگید|جهاند|جهید|جوشاند|جوشید|جوید|چاپید|چایید|چپاند|چپید|چراند|چربید|چرخاند|چرخید|چرید|چسباند|چسبید'+
'|چشاند|چشید|چکاند|چکید|چلاند|چلانید|چمید|چید|خاراند|خارید|خاست|خایید|خراشاند|خراشید|خرامید|خروشید|خرید|خزید|خست|خشکاند'+
'|خشکید|خفت|خلید|خمید|خنداند|خندانید|خندید|خواباند|خوابانید|خوابید|خواست|خواند|خوراند|خورد|خوفید|خیساند|خیسید|داد|داشت|دانست'+
'|درخشانید|درخشید|دروید|درید|دزدید|دمید|دواند|دوخت|دوشید|دوید|دید|دیدم|راند|ربود|رخشید|رساند|رسانید|رست|رَست|رُست'+
'|رسید|رشت|رفت|رُفت|رقصاند|رقصید|رمید|رنجاند|رنجید|رندید|رهاند|رهانید|رهید|روبید|روفت|رویاند|رویید|ریخت|رید|ریسید'+
'|زاد|زارید|زایید|زد|زدود|زیست|سابید|ساخت|سپارد|سپرد|سپوخت|ستاند|ستد|سترد|ستود|ستیزید|سرایید|سرشت|سرود|سرید'+
'|سزید|سفت|سگالید|سنجید|سوخت|سود|سوزاند|شاشید|شایست|شتافت|شد|شست|شکافت|شکست|شکفت|شکیفت|شگفت|شمارد|شمرد|شناخت'+
'|شناساند|شنید|شوراند|شورید|طپید|طلبید|طوفید|غارتید|غرید|غلتاند|غلتانید|غلتید|غلطاند|غلطانید|غلطید|غنود|فرستاد|فرسود|فرمود|فروخت'+
'|فریفت|فشاند|فشرد|فهماند|فهمید|قاپید|قبولاند|کاست|کاشت|کاوید|کرد|کشاند|کشانید|کشت|کشید|کفت|کفید|کند|کوبید|کوچید'+
'|کوشید|کوفت|گَزید|گُزید|گایید|گداخت|گذارد|گذاشت|گذراند|گذشت|گرازید|گرایید|گرداند|گردانید|گردید|گرفت|گروید|گریاند|گریخت|گریست'+
'|گزارد|گزید|گسارد|گستراند|گسترد|گسست|گسیخت|گشت|گشود|گفت|گمارد|گماشت|گنجاند|گنجانید|گنجید|گندید|گوارید|گوزید|لرزاند|لرزید'+
'|لغزاند|لغزید|لمباند|لمدنی|لمید|لندید|لنگید|لهید|لولید|لیسید|ماسید|مالاند|مالید|ماند|مانست|مرد|مکشید|مکید|مولید|مویید'+
'|نازید|نالید|نامید|نشاند|نشست|نکوهید|نگاشت|نگریست|نمایاند|نمود|نهاد|نهفت|نواخت|نوردید|نوشاند|نوشت|نوشید|نیوشید|هراسید|هشت'+
'|ورزید|وزاند|وزید|یارست|یازید|یافت'+
')';
persianPresentVerbs = '(' +
'ارز|افت|افراز|افروز|افزا|افزای|افسر|افشان|افکن|انبار|انباز|انجام|انداز|اندای|اندوز|اندیش|انگار|انگیز|انگیزان'+
'|اوبار|ایست|آرا|آرام|آرامان|آرای|آزار|آزما|آزمای|آسا|آسای|آشام|آشوب|آغار|آغاز|آفرین|آکن|آگن|آلا|آلای'+
'|آمرز|آموز|آموزان|آمیز|آهنج|آور|آویز|آی|بار|باران|باز|باش|باف|بال|باوران|بای|باید|بخش|بخشا|بخشای'+
'|بر|بَر|بُر|براز|بساو|بسیج|بلع|بند|بو|بوس|بوی|بیز|بین|پا|پاش|پاشان|پالا|پالای|پذیر|پذیران'+
'|پر|پراکن|پران|پرداز|پرس|پرست|پرهیز|پرور|پروران|پز|پژمر|پژوه|پسند|پلاس|پلک|پناه|پندار|پوس|پوش|پوشان'+
'|پوی|پیچ|پیچان|پیرا|پیرای|پیما|پیمای|پیوند|تاب|تابان|تاران|تاز|تازان|تپ|تپان|تراش|تراشان|تراو|ترس|ترسان'+
'|ترش|ترک|ترکان|تکان|تن|توان|توپ|جنب|جنبان|جنگ|جه|جهان|جو|جوش|جوشان|جوی|چاپ|چای|چپ|چپان'+
'|چر|چران|چرب|چرخ|چرخان|چسب|چسبان|چش|چشان|چک|چکان|چل|چلان|چم|چین|خار|خاران|خای|خر|خراش'+
'|خراشان|خرام|خروش|خز|خست|خشک|خشکان|خل|خم|خند|خندان|خواب|خوابان|خوان|خواه|خور|خوران|خوف|خیز|خیس'+
'|خیسان|دار|در|درخش|درخشان|درو|دزد|دم|ده|دو|دوان|دوز|دوش|ران|ربا|ربای|رخش|رس|رسان'+
'|رشت|رقص|رقصان|رم|رنج|رنجان|رند|ره|رهان|رو|روب|روی|رویان|ریز|ریس|رین|زا|زار|زای|زدا'+
'|زدای|زن|زی|ساب|ساز|سای|سپار|سپر|سپوز|ستا|ستان|ستر|ستیز|سر|سرا|سرای|سرشت|سز|سگال|سنب'+
'|سنج|سوز|سوزان|شاش|شای|شتاب|شکاف|شکف|شکن|شکوف|شکیب|شمار|شمر|شناس|شناسان|شنو|شو|شور|شوران|شوی'+
'|طپ|طلب|طوف|غارت|غر|غلت|غلتان|غلط|غلطان|غنو|فرسا|فرسای|فرست|فرما|فرمای|فروش|فریب|فشار|فشان|فشر'+
'|فهم|فهمان|قاپ|قبولان|کار|کاه|کاو|کش|کَش|کُش|کِش|کشان|کف|کن|کوب|کوچ|کوش|گا|گای|گداز'+
'|گذار|گذر|گذران|گرا|گراز|گرای|گرد|گردان|گرو|گری|گریان|گریز|گز|گزار|گزین|گسار|گستر|گستران|گسل|گشا'+
'|گشای|گمار|گنج|گنجان|گند|گو|گوار|گوز|گوی|گیر|لرز|لرزان|لغز|لغزان|لم|لمبان|لند|لنگ|له|لول'+
'|لیس|ماس|مال|مان|مک|مول|موی|میر|ناز|نال|نام|نشان|نشین|نکوه|نگار|نگر|نما|نمای|نمایان|نه'+
'|نهنب|نواز|نورد|نوش|نوشان|نویس|نیوش|هراس|هست|هل|ورز|وز|وزان|یاب|یار|یاز'+
')';
function applyZwnj(text) {
return normalizeZwnj(text)
.replace(
new RegExp('(^|[^' + persianCharacters + '])(می|نمی) ?' + persianPastVerbs +
'(م|ی|یم|ید|ند|)($|[^' + persianCharacters + '])', 'g'),
'$1$2\u200c$3$4$5'
)
.replace(
new RegExp('(^|[^' + persianCharacters + '])(می|نمی) ?' + persianPresentVerbs +
'(م|ی|د|یم|ید|ند)($|[^' + persianCharacters + '])', 'g'),
'$1$2\u200c$3$4$5'
)
// ای «توان» ناقلا!
.replace(/(\s)(می|نمی) ?توان/g, '$1$2\u200cتوان')
// چسباندن تمام «ها»ها با فاصلهٔ مجازی
.replace(/\sها([\]\.،\:»\)\s])/g, '\u200cها$1')
.replace(/\sها(ی|یی|یم|یت|یش|مان|تان|شان)([\]\.،\:»\)\s])/g, '\u200cها$1$2')
// برای حذف علامت ستاره اضافی قبل از عنوان ها
.replace(/\n\*\s*(\=+.+?\=+\n)/g, '\n$1')
// عضو علامت های نقل قول تکی از عنوان ها
.replace(/(\n=+)(.*?)(?:'+)(.*?)(?:'+)(.*?)(=+\n)/g, '$1$2$3$4$5')
// اول و آخر هم خط اگر فاصلهٔ مجازی باشد، حذف شود
.replace(/(^\u200c|\u200c$)/mg, '')
// شناسه ها
// توجه: «است» تعدماً از شناسه ها حذف شده چون به عنوان فعل مستقل هم کاربرد دارد و در آن موارد باید جدا نوشته شود
// مثال: «این یک خانه است» که است در آن باید از خانه جدا نوشته شود
.replace(new RegExp('ه\\s+(ام|ای|ایم|اید|اند)($|[^' + persianCharacters + '\u200c])', 'g'), 'ه\u200c$1$2')
// موارد جزئی دیگر و بی ربط به فاصلهٔ مجازی، باید منتقل شود
.replace(/ا\sً/g, 'اً');
}
function punctuation(text) {
return text
.replace(/([،\.])([^\s\.\(\)«»\"\[\]<>\d\w\{\}\|۰-۹])/g, '$1 $2')
.replace(/ː/g, ':') //Replace incorrect : character
.replace(/([\(«])\s/g, '$1')
.replace(/\s([\)»])/g, '$1')
.replace(/٬\s/g, '، ')
.replace(/\n\s{1,}\n/g, '\n\n')
.replace(/(\n\*.*?)\n+(?=\n\*)/g, '$1') // Removes extra line between two items list
.replace(/(\n#.*?)\n+(?=\n#)/g, '$1') // Removes extra line between two items list
.replace(/([^=]) *$/mg, '$1')
.replace(/ +\( +/g, ' (')
.replace(new RegExp('([' + persianCharacters + ']) *\\( *(?=[' + persianCharacters + '])(?!ها\\)|ان\\))', 'g'), '$1 (')
.replace(new RegExp('([' + persianCharacters + ']) *\\) *(?=[' + persianCharacters + '])', 'g'), '$1) ')
// Convert , to ، if there are Persian characters on both sides of it
.replace(new RegExp('([' + persianCharacters + ']) ?, ?(?=[' + persianCharacters + '])', 'g'), '$1، ')
.replace(/([^ \.]) +([؟،\:؛!\.])(\s[^ \.])/g, '$1$2$3') // Remove space preceding punctuations, except for ellipses
// Add Space After Punctuation
.replace(new RegExp('([' + persianCharacters + ']+)([؟،؛!\\.])([' + persianCharacters + ']+)', 'g'), '$1$2 $3');
}
(function () {
var tools = {
applyOrthography: applyOrthography,
applyZwnj: applyZwnj,
normalizeZwnj: normalizeZwnj,
persianSortText: persianSortText,
punctuation: punctuation,
toPersianDigits: toPersianDigits,
toStandardPersianCharacters: toStandardPersianCharacters
}, i;
function Chain(text) {
this.text = text;
this.toString = this.value = function () {
return this.text;
};
}
function persianTools(text) {
return new Chain(text);
}
function applyTool(tool) {
return function () {
this.text = tool(this.text);
return this;
};
}
for (i in tools) {
if (tools.hasOwnProperty(i)) {
persianTools[i] = tools[i];
Chain.prototype[i] = applyTool(tools[i]);
}
}
if (typeof module === 'object') {
module.exports = persianTools;
} else {
root.persianTools = persianTools;
}
}());
}(this));
// Wikipedia specific extension
/*global persianTools, persianToolsDictionary, console*/
(function (root) {
'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 "'\._:\|,\-\\\/\(\)\#\^\+\d><–\[\]]*[a-z]\d*/gi,
arabicTagEnclosed: /\{\{(?:عربی|شروع عربی|آغاز عربی)\}\}([\s\S]*?)\{\{(?:پایان عربی)\}\}/g,
argumentsBlacklist: /(?:accessdate|namespace|doi|style|شابک|عرض|bibcode|isbn|pmid|arxiv)\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,
decodeUriBlacklist: /(?:%20|%5C|%5E|%60|%23|%25|%3C|%3E|%5B|%5D|%22|%09|%0A|%7B|%7C|%7D)/gi, // space, ", \t, \n, {, |, }, ... they will interfere with wiki markup
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,
htmlAttributes: /(?:style|colspan|color|rowspan|cellpadding|cellspacing|height|width|size|border|thumbtime|name|perrow)\s*\=\s*(?:['\"].*?['\"]|[\da-z]+)/gi,
htmlEntity: /&#\d+;/,
imagePixelSize: /[\|=] *[x\d]+?(px|پیکسل)[\]\|\s]/g, // means it will capture |10px| and |10x10px|
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,
ref: /(?:<ref[^\/]*?>[\s\S]*?<\/ref>|<ref[^\/]*?\/>)/g, // inside <ref></ref> and <ref/>
signatures: /\[\[(?:کاربر|User|بحث[ _]کاربر|User[_ ]talk)\:.*?\]\]/gi,
sourceTag: /(<source.*?>[\s\S]*?<\/source>|<syntaxhighlight.*?>[\s\S]*?<\/syntaxhighlight>|<code.*?>[\s\S]*?<\/code>)/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,
url: /\/\/.*?(?=[\s\n\|\}\]<]|$)/gi // بدون https?: هم ممکن است
},
vowels = 'ًٌٍَُِّْ',
persianCharactersNoVowels = 'ءآأؤإئابپةتثجحخچدذرزژسشصضطظعغفقكکگلمنهوىیي',
persianCharacters = persianCharactersNoVowels + vowels;
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 wikiPunctuation(text) {
return replaceExcept(
text,
function (text) {
text = text.replace(
new RegExp('([' + persianCharactersNoVowels + '])ـ+([' + persianCharactersNoVowels + '])', 'g'),
'$1$2'
);
return persianTools.punctuation(text);
},
[patterns.fileNames, patterns.url] // Other patterns should be added here also
)
.replace(/\n{3,}/g, '\n\n') // Cosmetic changes bot replaces
.replace(/\[\[(رده|الگو|ویکی\u200cپدیا)\: +/g, '[[$1:')
.replace(/[\n\s]*\{\{[•·ن](w?)\}\}\s*/g, '{{•$1}} ')
.replace(/ *(<\/? ?br ?\/?>|\{\{بر\}\}) */g, '{{سخ}}')
.replace(/(<\/ref>)\s+(<ref)/g, '$1$2')
.replace(/[\s\n]+<ref(?!erences)/g, '<ref')
.replace(/(\n?)[\s\n]+?<\/ref>/g, '$1</ref>')
.replace(/([^=])\n+(\=.*?\=\n+)/g, '$1\n\n$2')
.replace(/^(\={2,}) +[\:,;<>&\^#@•→←↔↑↓—–…~٫،؛ٔ]/mg, '$1') // Cleanup headers
.replace(/[\:,;<>&\^#@•→←↔↑↓—–…~٫،؛ٔ] +(\={2,})$/mg, '$1')
.replace(/^(\={2,}) *«(.*?)» *(\={2,})/mg, '$1 $2 $3')
.replace(/^(\={2,}) *'+(.*?)'+ *(\={2,})/mg, '$1 $2 $3')
.replace(/^[●⚫⬤]/mg, '*') // Wikify bullets in start of lines
.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
.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]]')
// تبدیل به نویسه / یکی کردن فاصله های مجازی پشت سرهم
.replace(/(\{\{فم\}\}|\&zwnj\;|\u200c+)/g, '\u200c')
// Full stop and comma should be before citation. See en:WP:REFPUNC
.replace(/ *((?:<ref[^\/]*?>.*?<\/ref>)+)([\.،,])?/g, '$2$1')
.replace(/ *((?:<ref[^\/]*?\/>)+)([\.،,])/g, '$2$1')
.trim();
}
function wikiUrlMinifier(text) {
return text
.replace(patterns.url, function (x) {
return replaceExcept(
x,
function (x) {
try {
x = decodeURI(x);
} catch (e) { console.error(e); }
return x;
},
[patterns.decodeUriBlacklist]
);
})
// Shorten Wikipedia diff URLs
.replace(/(\/\/[\w\-]+\.wikipedia\.org\/w\/index\.php\?)title=[^&\s\]]*&(?=(?:diff=[^&\s]+&|)(?:oldid=\d+))/g, '$1')
// Strip the http(s) prefix
.replace(/\[(https?\:)(?=\/\/(?:[\w\-]+)\.(wikipedia|wikimedia|wikidata|wiktionary|wikisource|wikinews|wikivoyage|wikiquote)\.org\/[^\s\]]*)/g, '[');
}
function wikiTextDigitsToPersian(text) {
text = replaceExcept(
text,
persianTools.toPersianDigits,
[patterns.argumentsBlacklist, patterns.mathTag, patterns.imagePixelSize, patterns.fileNames, patterns.ref,
patterns.sourceTag, patterns.url, patterns.signatures, patterns.arabicDigitsEnglishContext, patterns.htmlEntity,
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.colorAsParameter, patterns.tagNames]
);
return text
// Decimal point, and thousands' separator
.replace(/([۱۲۳۴۵۶۷۸۹۰])\.([۱۲۳۴۵۶۷۸۹۰])/g, '$1٫$2')
.replace(/([۱۲۳۴۵۶۷۸۹۰]),([۱۲۳۴۵۶۷۸۹۰])/g, '$1٬$2');
}
function dictationReplace(x, y, extensions, text) {
return text.replace(
new RegExp(
'(^|[^' + persianCharacters + '])(\\s|\u200c|_|)(' + x + ')(\\s|_)(' + y + ')(\\s|\u200c|_|)(' +
extensions + ')($|[^' + 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;
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(
'(^|[^' + persianCharacters + ']|\\s|_)(' + i + ')(\\s|_)(' +
dictionary.firstNameComplex[i] + ')(\\s|_)($|[^' + persianCharacters + ']|[^' +
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(
'(^|[^' + persianCharacters + '])(\\s|\u200c|_|)(' + i + ')(\\s|\u200c|_|)($|[^' +
persianCharacters + '])',
'g'
),
'$1$2' + dictionary.forReplace[i] + '$4$5'
);
}
}
return persianTools.normalizeZwnj(text);
}
function wikiDictation(text) {
return replaceExcept(
text,
dictation,
[patterns.fileNames, patterns.signatures, patterns.url]
);
}
root.persianWikiTools = {
applyZwnj: persianTools.applyZwnj,
convertDigitsToPersian: persianTools.toStandardPersianCharacters,
cleanUselessZwnj: persianTools.normalizeZwnj,
nonStandard: persianTools.applyOrthography,
dictation: dictation,
persianSortText: persianTools.persianSortText,
wikiConvertToPersianCharacters: wikiConvertToPersianCharacters,
wikiDictation: wikiDictation,
wikiPunctuation: wikiPunctuation,
wikiUrlMinifier: wikiUrlMinifier,
wikiTextDigitsToPersian: wikiTextDigitsToPersian
};
}(this));