تفاوت میان نسخههای «مدیاویکی: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'; | |
− | + | 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]| )+(?:' + | ||
+ | months.join( '|' ) + '))(?:\xA0| )(?=[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]| )+(?:' + | ||
+ | months.join( '|' ) + '))(?:\xA0| )(?=[۱۲][۱۲۳۴۵۶۷۸۹]{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( /^=.* .*=$/gim, function( $0 ) { | ||
+ | return $0.replace( /(?: |\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") { | if (typeof window !== "undefined") { | ||
− | + | 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]| )+(?:' + months.join( '|' ) + '))(?:\xA0| )(?=[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]| )+(?:' + months.join( '|' ) + '))(?:\xA0| )(?=[۱۲][۱۲۳۴۵۶۷۸۹]{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( /^=.* .*=$/gim, function( $0 ) { return $0.replace( /(?: |\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>