مدیاویکی:Gadget-Extra-Editbuttons-Functions.js
پرش به ناوبری
پرش به جستجو
نکته: پس از ذخیره کردن ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.
- فایرفاکس / سافاری: کلید Shift را نگه دارید و روی دکمهٔ Reload کلیک کنید، یا کلیدهای Ctrl-F5 یا Ctrl-R را با هم فشار دهید (در رایانههای اپل مکینتاش کلیدهای ⌘-R)
- گوگل کروم: کلیدهای Ctrl+Shift+R را با هم فشار دهید (در رایانههای اپل مکینتاش کلیدهای ⌘-Shift-R)
- اینترنت اکسپلورر: کلید Ctrl را نگهدارید و روی دکمهٔ Refresh کلیک کنید، یا کلیدهای Ctrl-F5 را با هم فشار دهید
- اپرا: بروید به Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
// <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));