"""File containing all standard fixes.
.. versionremoved:: 11.0
The ``yu-tld`` predefined fix was removed.
"""
#
# (C) Pywikibot team, 2008-2025
#
# Distributed under the terms of the MIT license.
#
from __future__ import annotations
from pathlib import Path
from textwrap import dedent
from pywikibot import config
parameter_help = """
Currently available predefined fixes:
* HTML - Convert HTML tags to wiki syntax, and \
fix XHTML.
* isbn - Fix badly formatted ISBNs.
* syntax - Try to fix bad wiki markup. Do not run \
this in automatic mode, as the bot may \
make mistakes.
* syntax-safe - Like syntax, but less risky; can be run \
in automatic mode.
* case-de - Fix upper/lower case errors in German.
* grammar-de - Fix grammar and typography in German.
* vonbis - Replace hyphens or dashes with "bis" \
in German.
* music - Links to disambiguation pages in German.
* datum - Specific date formats in German.
* correct-ar - Typo corrections for Arabic Wikipedia \
and other Arabic wikis.
* fckeditor - Convert FCKeditor HTML tags to wiki syntax.
"""
__doc__ += dedent(parameter_help)
fixes = {
# These replacements will convert HTML to wiki syntax where possible, and
# make remaining tags XHTML compliant.
'HTML': {
'regex': True,
'msg': 'pywikibot-fixes-html',
'replacements': [
# Everything case-insensitive (?i)
# Keep in mind that MediaWiki automatically converts <br> to <br />
# when rendering pages, so you might comment the next two lines out
# to save some time/edits.
(r'(?i)<br *>', r'<br />'),
# linebreak with attributes
(r'(?i)<br ([^>/]+?)>', r'<br \1 />'),
(r'(?i)<b>(.*?)</b>', r"'''\1'''"),
(r'(?i)<strong>(.*?)</strong>', r"'''\1'''"),
(r'(?i)<i>(.*?)</i>', r"''\1''"),
(r'(?i)<em>(.*?)</em>', r"''\1''"),
# horizontal line without attributes in a single line
(r'(?i)([\r\n])<hr[ /]*>([\r\n])', r'\1----\2'),
# horizontal line without attributes with more text in same line
# (r'(?i) +<hr[ /]*> +', r'\r\n----\r\n'),
# horizontal line with attributes; can't be done with wiki syntax
# so we only make it XHTML compliant
(r'(?i)<hr ([^>/]+?)>', r'<hr \1 />'),
# a header where only spaces are in the same line
(r'(?i)([\r\n]) *<h1> *([^<]+?) *</h1> *([\r\n])', r'\1= \2 =\3'),
(r'(?i)([\r\n]) *<h2> *([^<]+?) *</h2> *([\r\n])',
r'\1== \2 ==\3'),
(r'(?i)([\r\n]) *<h3> *([^<]+?) *</h3> *([\r\n])',
r'\1=== \2 ===\3'),
(r'(?i)([\r\n]) *<h4> *([^<]+?) *</h4> *([\r\n])',
r'\1==== \2 ====\3'),
(r'(?i)([\r\n]) *<h5> *([^<]+?) *</h5> *([\r\n])',
r'\1===== \2 =====\3'),
(r'(?i)([\r\n]) *<h6> *([^<]+?) *</h6> *([\r\n])',
r'\1====== \2 ======\3'),
# TODO: maybe we can make the bot replace <p> tags with \r\n's.
],
'exceptions': {
'inside-tags': [
'nowiki',
'comment',
'math',
'pre',
'syntaxhighlight',
],
}
},
# Grammar fixes for German language
# Do NOT run this automatically!
'grammar-de': {
'regex': True,
'msg': {
'de': 'Bot: korrigiere Grammatik',
},
'replacements': [
# Vorsicht bei Substantiven, z. B. 3-Jähriger!
(r'(\d+)(minütig|stündig|tägig|wöchig|jährig|minütlich|stündlich'
r'|täglich|wöchentlich|jährlich|fach|mal|malig|köpfig|teilig'
r'|gliedrig|geteilt|elementig|dimensional|bändig|eckig|farbig'
r'|stimmig)', r'\1-\2'),
# zusammengesetztes Wort, Bindestrich wird durchgeschleift
(r'(?<!\w)(\d+|\d+[.,]\d+)(\$|€|DM|£|¥|mg|g|kg|ml|cl|l|t|ms|min'
r'|µm|mm|cm|dm|m|km|ha|°C|kB|MB|GB|TB|W|kW|MW|GW|PS|Nm|eV|kcal'
r'|mA|mV|kV|Ω|Hz|kHz|MHz|GHz|mol|Pa|Bq|Sv|mSv)([²³]?-[\w\[])',
r'\1-\2\3'),
# Größenangabe ohne Leerzeichen vor Einheit
# weggelassen wegen vieler falsch Positiver: s, A, V, C, S, J, %
(r'(?<!\w)(\d+|\d+[.,]\d+)(\$|€|DM|£|¥|mg|g|kg|ml|cl|l|t|ms|min'
r'|µm|mm|cm|dm|m|km|ha|°C|kB|MB|GB|TB|W|kW|MW|GW|PS|Nm|eV|kcal'
r'|mA|mV|kV|Ω|Hz|kHz|MHz|GHz|mol|Pa|Bq|Sv|mSv)(?=\W|²|³|$)',
r'\1 \2'),
# Temperaturangabe mit falsch gesetztem Leerzeichen
(r'(?<!\w)(\d+|\d+[.,]\d+)° C(?=\W|²|³|$)', r'\1 °C'),
# Kein Leerzeichen nach Komma
(r'([a-zäöüß](\]\])?,)((\[\[)?[a-zäöüA-ZÄÖÜ])', r'\1 \3'),
# Leerzeichen und Komma vertauscht
(r'([a-zäöüß](\]\])?) ,((\[\[)?[a-zäöüA-ZÄÖÜ])', r'\1, \3'),
# Plenks (Leerzeichen vor Komma/Punkt/Ausrufezeichen/Fragezeichen)
# Achtung bei Französisch:
# https://de.wikipedia.org/wiki/Plenk#Franz.C3.B6sische_Sprache
# Leerzeichen vor Doppelpunkt/Semikolon kann korrekt sein,
# z.B. nach Quellenangaben
(r'([a-zäöüß](\]\])?) ([,.!?]) ((\[\[)?[a-zäöüA-ZÄÖÜ])',
r'\1\3 \4'),
],
'exceptions': {
'inside-tags': [
'nowiki',
'comment',
'gallery', # because of filenames
'hyperlink', # e.g. commas in URLs
'math',
'pre', # because of code examples
'startspace', # because of code examples
'syntaxhighlight', # because of code examples
'timeline',
],
'text-contains': [
r'sic!',
r'20min.ch', # Schweizer News-Seite
],
'inside': [
r'<code>.*</code>', # because of code examples
r'{{[Zz]itat\|.*?}}',
r'{{§\|.*?}}', # Gesetzesparagraph
r'§?\d+[a-z]', # Gesetzesparagraph
r'Ju 52/1m', # Flugzeugbezeichnung
r'Ju 52/3m', # Flugzeugbezeichnung
r'AH-1W', # Hubschrauberbezeichnung
r'ZPG-3W', # Luftschiffbezeichnung
r'8mm', # Filmtitel
r'802.11g', # WLAN-Standard
r'DOS/4GW', # Software
r'ntfs-3g', # Dateisystem-Treiber
r'/\w(,\w)*/', # Laut-Aufzählung in der Linguistik
# Variablen in der Mathematik
# (unklar, ob Leerzeichen hier Pflicht sind)
r'[xyz](,[xyz])+',
# Definitionslisten, dort gibt es oft absichtlich Leerzeichen
# vor Doppelpunkten
r'(?m)^;(.*?)$',
r'\d+h( | )\d+m',
# Schreibweise für Zeiten, vor allem in Film-Infoboxen.
# Nicht korrekt, aber dafür schön kurz.
r'(?i)\[\[(Bild|Image|Media):.+?\|', # Dateinamen auslassen
r'{{bgc\|.*?}}', # Hintergrundfarbe
r'<sup>\d+m</sup>', # bei chemischen Formeln
r'\([A-Z][A-Za-z]*(,[A-Z][A-Za-z]*'
r'(<sup>.*?</sup>|<sub>.*?</sub>|))+\)'
# chemische Formel, z. B. AuPb(Pb,Sb,Bi)Te.
# Hier sollen keine Leerzeichen hinter die Kommata.
],
'title': [
r'Arsen', # chemische Formel
],
}
},
# Do NOT run this automatically!
# Recommendation: First run syntax-safe automatically, afterwards
# run syntax manually, carefully checking that you're not breaking
# anything.
'syntax': {
'regex': True,
'msg': 'pywikibot-fixes-syntax',
'replacements': [
# external link in double brackets
(r'\[\[(?P<url>https?://[^\]]+?)\]\]', r'[\g<url>]'),
# external link starting with double bracket
(r'\[\[(?P<url>https?://.+?)\]', r'[\g<url>]'),
# external link with forgotten closing bracket
# (r'\[(?P<url>https?://[^\]\s]+)\r\n', r'[\g<url>]\r\n'),
# external link ending with double bracket.
# do not change weblinks that contain wiki links inside
# inside the description
(r'\[(?P<url>https?://[^\[\]]+?)\]\](?!\])', r'[\g<url>]'),
# external link and description separated by a dash.
# ATTENTION: while this is a mistake in most cases, there are some
# valid URLs that contain dashes!
(r'\[(?P<url>https?://[^\|\]\s]+?) *\| *(?P<label>[^\|\]]+?)\]',
r'[\g<url> \g<label>]'),
# wiki link closed by single bracket.
# ATTENTION: There are some false positives, for example
# Brainfuck code examples or MS-DOS parameter instructions.
# There are also sometimes better ways to fix it than
# just putting an additional ] after the link.
(r'\[\[([^\[\]]+?)\](?!\])', r'[[\1]]'),
# wiki link opened by single bracket.
# ATTENTION: same as above.
(r'(?<!\[)\[([^\[\]]+?)\]\](?!\])', r'[[\1]]'),
# template closed by single bracket
# ATTENTION: There are some false positives, especially in
# mathematical context or program code.
(r'{{([^{}]+?)}(?!})', r'{{\1}}'),
],
'exceptions': {
'inside-tags': [
'nowiki',
'comment',
'math',
'pre',
'startspace', # because of code examples
'syntaxhighlight', # because of code examples
],
'text-contains': [
r'http://.*?object=tx\|', # regular dash in URL
r'http://.*?allmusic\.com', # regular dash in URL
r'http://.*?allmovie\.com', # regular dash in URL
r'http://physics.nist.gov/', # regular dash in URL
r'http://www.forum-seniorenarbeit.de/', # regular dash in URL
r'http://kuenstlerdatenbank.ifa.de/', # regular dash in URL
r'&object=med', # regular dash in URL
r'\[CDATA\[' # lots of brackets
],
}
},
# The same as syntax, but restricted to replacements that should
# be safe to run automatically.
'syntax-safe': {
'regex': True,
'msg': 'pywikibot-fixes-syntax',
'replacements': [
# external link in double brackets
(r'\[\[(?P<url>https?://[^\]]+?)\]\]', r'[\g<url>]'),
# external link starting with double bracket
(r'\[\[(?P<url>https?://.+?)\]', r'[\g<url>]'),
# external link with forgotten closing bracket
# (r'\[(?P<url>https?://[^\]\s]+)\r\n', r'[\g<url>]\r\n'),
# external link and description separated by a dash, with
# whitespace in front of the dash, so that it is clear that
# the dash is not a legitimate part of the URL.
(r'\[(?P<url>https?://[^\|\] \r\n]+?) +\| *(?P<label>[^\|\]]+?)\]',
r'[\g<url> \g<label>]'),
# dash in external link, where the correct end of the URL can
# be detected from the file extension. It is very unlikely that
# this will cause mistakes.
(r'\[(?P<url>https?://[^\|\] ]+?'
r'(\.pdf|\.html|\.htm|\.php|\.asp|\.aspx|\.jsp)) *\|'
r' *(?P<label>[^\|\]]+?)\]', r'[\g<url> \g<label>]'),
],
'exceptions': {
'inside-tags': [
'nowiki',
'comment',
'math',
'pre',
'startspace', # because of code examples
'syntaxhighlight', # because of code examples
],
}
},
'case-de': { # German upper / lower case issues
'regex': True,
'msg': {
'de': 'Bot: Korrigiere Groß-/Kleinschreibung',
},
'replacements': [
(r'\batlantische(r|n|) Ozean', r'Atlantische\1 Ozean'),
(r'\bdeutsche(r|n|) Bundestag\b', r'Deutsche\1 Bundestag'),
# Aufpassen, z. B. 'deutsche Bundestagswahl'
(r'\bdeutschen Bundestags\b', r'Deutschen Bundestags'),
(r'\bdeutsche(r|n|) Reich\b', r'Deutsche\1 Reich'),
# Aufpassen, z. B. 'deutsche Reichsgrenzen'
(r'\bdeutschen Reichs\b', r'Deutschen Reichs'),
(r'\bdritte(n|) Welt(?!krieg)', r'Dritte\1 Welt'),
(r'\bdreißigjährige(r|n|) Krieg', r'Dreißigjährige\1 Krieg'),
(r'\beuropäische(n|) Gemeinschaft', r'Europäische\1 Gemeinschaft'),
(r'\beuropäische(n|) Kommission', r'Europäische\1 Kommission'),
(r'\beuropäische(n|) Parlament', r'Europäische\1 Parlament'),
(r'\beuropäische(n|) Union', r'Europäische\1 Union'),
(r'\berste(r|n|) Weltkrieg', r'Erste\1 Weltkrieg'),
(r'\bkalte(r|n|) Krieg', r'Kalte\1 Krieg'),
(r'\bpazifische(r|n|) Ozean', r'Pazifische\1 Ozean'),
(r'Tag der deutschen Einheit', r'Tag der Deutschen Einheit'),
(r'\bzweite(r|n|) Weltkrieg', r'Zweite\1 Weltkrieg'),
],
'exceptions': {
'inside-tags': [
'nowiki',
'comment',
'math',
'pre',
],
'text-contains': [
r'sic!',
],
}
},
'vonbis': {
'regex': True,
'msg': {
'de': 'Bot: Ersetze Binde-/Gedankenstrich durch "bis"',
},
'replacements': [
# Bindestrich, Gedankenstrich, Geviertstrich
(r'(von \d{3,4}) *(-|–|–|—|—) *(\d{3,4})',
r'\1 bis \3'),
],
},
# some disambiguation stuff for de:
# python pwb.py replace -fix:music -subcat:Album
'music': {
'regex': False,
'msg': {
'de': 'Bot: korrigiere Links auf Begriffsklärungen',
},
'replacements': [
('[[CD]]', '[[Audio-CD|CD]]'),
('[[LP]]', '[[Langspielplatte|LP]]'),
('[[EP]]', '[[Extended Play|EP]]'),
('[[MC]]', '[[Musikkassette|MC]]'),
('[[Single]]', '[[Single (Musik)|Single]]'),
],
'exceptions': {
'inside-tags': [
'hyperlink',
]
}
},
# format of dates of birth and death, for de:
# python pwb.py replace -fix:datum -ref:Vorlage:Personendaten
'datum': {
'regex': True,
'msg': {
'de': 'Bot: Korrigiere Datumsformat',
},
'replacements': [
(r'\[\[(\d+\. (?:Januar|Februar|März|April|Mai|Juni|Juli|August|'
r'September|Oktober|November|Dezember)) (\d{1,4})\]\]',
r'[[\1]] [[\2]]'),
# Keine führende Null beim Datum
# (erst einmal nur bei fehlenden Leerzeichen)
(r'0(\d+)\.(Januar|Februar|März|April|Mai|Juni|Juli|August|'
r'September|Oktober|November|Dezember)', r'\1. \2'),
# Kein Leerzeichen zwischen Tag und Monat
(r'(\d+)\.(Januar|Februar|März|April|Mai|Juni|Juli|August|'
r'September|Oktober|November|Dezember)', r'\1. \2'),
# Kein Punkt vorm Jahr
(r'(\d+)\. (Januar|Februar|März|April|Mai|Juni|Juli|August|'
r'September|Oktober|November|Dezember)\.(\d{1,4})', r'\1. \2 \3'),
],
'exceptions': {
'inside': [
r'\[\[20. Juli 1944\]\]', # Hitler-Attentat
r'\[\[17. Juni 1953\]\]', # Ost-Berliner Volksaufstand
r'\[\[1. April 2000\]\]', # Film
r'\[\[11. September 2001\]\]', # Anschläge in den USA
r'\[\[7. Juli 2005\]\]', # Terroranschläge in Spanien
],
}
},
'isbn': {
'generator': [
r'-search:insource:/nowiki\>ISBN:? *(?: |&\#160;)? *[0-9]/',
'-namespace:0'],
'regex': True,
'msg': 'pywikibot-fixes-isbn',
'replacements': [
# Remove colon between the word ISBN and the number
(r'ISBN: (\d+)', r'ISBN \1'),
# superfluous word "number"
(r'ISBN(?: [Nn]umber| [Nn]o\.?|-Nummer|-Nr\.):? (\d+)',
r'ISBN \1'),
# Space, minus, dot, hyphen, en dash, em dash, etc. instead of
# hyphen-minus as separator,
# or spaces between digits and separators.
# Note that these regular expressions also match valid ISBNs, but
# these won't be changed.
# These two regexes don't verify that the ISBN is of a valid format
# but just change separators into normal hyphens. The isbn script
# does checks and similar but does only match ISBNs with digits and
# hyphens (and optionally a X/x at the end).
(r'ISBN (978|979) *[\- −.‐-―] *(\d+) *[\- −.‐-―] *(\d+) '
r'*[\- −.‐-―] *(\d+) *[\- −.‐-―] *(\d)(?!\d)',
r'ISBN \1-\2-\3-\4-\5'), # ISBN-13
(r'ISBN (\d+) *[\- −.‐-―] *(\d+) *[\- −.‐-―] *(\d+) *'
r'[\- −.‐-―] *(\d|X|x)(?!\d)',
r'ISBN \1-\2-\3-\4'), # ISBN-10
# missing space before ISBN-10 or before ISBN-13,
# or multiple spaces or non-breaking space.
(r'ISBN(?: *| )((\d(-?)){12}\d|(\d(-?)){9}[\dXx])',
r'ISBN \1'),
# remove <nowiki /> tags
(r'<nowiki>ISBN:? *(?: | )? *([0-9\-xX]+)</nowiki>',
r'ISBN \1'),
],
'exceptions': {
'inside-tags': [
'comment',
'hyperlink',
],
'inside': [
r'ISBN (97[89]-?)(\d-?){9}\d', # matches valid ISBN-13s
r'ISBN (\d-?){9}[\dXx]', # matches valid ISBN-10s
],
}
},
# Typo corrections for Arabic Wikipedia and any Arabic wiki.
# python pwb.py replace -fix:correct-ar -start:! -always
'correct-ar': {
'regex': False,
'msg': {
'ar': 'بوت: تدقيق إملائي',
},
'replacements': [
(' إمرأة ', ' امرأة '),
(' الى ', ' إلى '),
(' إسم ', ' اسم '),
(' الأن ', ' الآن '),
(' اول ', ' أول '),
(' الة ', ' آلة '),
(' فى ', ' في '),
(' اثقل ', ' أثقل '),
(' إبن ', ' ابن '),
(' إبنة ', ' ابنة '),
(' إقتصاد ', ' اقتصاد '),
(' إجتماع ', ' اجتماع '),
(' انجيل ', ' إنجيل '),
(' اجماع ', ' إجماع '),
(' امريكا ', ' أمريكا '),
(' اوروبا ', ' أوروبا '),
(' انجلترا ', ' إنجلترا '),
(' اكتوبر ', ' أكتوبر '),
(' اسرائيل ', ' إسرائيل '),
(' المانيا ', ' ألمانيا '),
(' ايطاليا ', ' إيطاليا '),
(' ايران ', ' إيران '),
(' إستخراج ', ' استخراج '),
(' إستعمال ', ' استعمال '),
(' إستبدال ', ' استبدال '),
(' إشتراك ', ' اشتراك '),
(' إستعادة ', ' استعادة '),
(' إستقلال ', ' استقلال '),
(' إنتقال ', ' انتقال '),
(' إتحاد ', ' اتحاد '),
(' الإتحاد ', ' الاتحاد '),
(' املاء ', ' إملاء '),
(' إستخدام ', ' استخدام '),
(' أحدى ', ' إحدى '),
(' لاكن ', ' لكن '),
(' الاردن ', ' الأردن '),
(' إثنان ', ' اثنان '),
(' شيئ ', ' شيء '),
(' إحتياط ', ' احتياط '),
(' إقتباس ', ' اقتباس '),
(' الامارات ', ' الإمارات '),
(' اكثر ', ' أكثر '),
(' افضل ', ' أفضل '),
(' اكبر ', ' أكبر '),
(' اشهر ', ' أشهر '),
(' ادارة ', ' إدارة '),
(' ابناء ', ' أبناء '),
(' الانصار ', ' الأنصار '),
(' اشارة ', ' إشارة '),
(' إقرأ ', ' اقرأ '),
(' إمتياز ', ' امتياز '),
(' ارق ', ' أرق '),
(' أرثوذوكس ', ' أرثوذكس '),
(' الأرثوذوكس ', ' الأرثوذكس '),
(' أرثوذوكسية ', ' أرثوذكسية '),
(' الأرثوذوكسية ', ' الأرثوذكسية '),
(' الأرثوذوكسي ', ' الأرثوذكسي '),
(' ارثوذوكس ', ' أرثوذكس '),
(' ارثوذوكسي ', ' أرثوذكسي '),
(' ارثوذوكسية ', ' أرثوذكسية '),
(' الارثوذوكسية ', ' الأرثوذكسية '),
(' اللة ', ' الله '),
(' إختبار ', ' اختبار '),
(' ارسال ', ' إرسال '),
(' إتصالات ', ' اتصالات '),
(' اسامة ', ' أسامة '),
(' ابراهيم ', ' إبراهيم '),
(' اسماعيل ', ' إسماعيل '),
(' ايوب ', ' أيوب '),
(' ايمن ', ' أيمن '),
(' ابو ', ' أبو '),
(' ابا ', ' أبا '),
(' اخو ', ' أخو '),
(' اخا ', ' أخا '),
(' اخي ', ' أخي '),
(' احد ', ' أحد '),
(' اربعاء ', ' أربعاء '),
(' اهم ', ' أهم '),
(' اوزبكستان ', ' أوزبكستان '),
(' اذربيجان ', ' أذربيجان '),
(' افغانستان ', ' أفغانستان '),
(' امجد ', ' أمجد '),
(' اوسط ', ' أوسط '),
(' اشقر ', ' أشقر '),
(' انور ', ' أنور '),
(' اصعب ', ' أصعب '),
(' اسهل ', ' أسهل '),
(' اجمل ', ' أجمل '),
(' اقبح ', ' أقبح '),
(' اطول ', ' أطول '),
(' اقصر ', ' أقصر '),
(' اسمن ', ' أسمن '),
(' اذكى ', ' أذكى '),
(' اماني ', ' أماني '),
(' احلام ', ' أحلام '),
(' اسماء ', ' أسماء '),
(' ابطأ ', ' أبطأ '),
(' اوربا ', ' أوروبا '),
(' أوربا ', ' أوروبا '),
(' امريكي ', ' أمريكي '),
(' امريكية ', ' أمريكية '),
(' امريكيان ', ' أمريكيان '),
(' امريكيتان ', ' أمريكيتان '),
(' امريكيون ', ' أمريكيون '),
(' امريكيات ', ' أمريكيات '),
(' الامريكي ', ' الأمريكي '),
(' الامريكية ', ' الأمريكية '),
(' الامريكيان ', ' الأمريكيان '),
(' الامريكيتان ', ' الأمريكيتان '),
(' الامريكيون ', ' الأمريكيون '),
(' الامريكيات ', ' الأمريكيات '),
(' اوروبي ', ' أوروبي '),
(' اوروبية ', ' أوروبية '),
(' اوروبيان ', ' أوروبيان '),
(' اوروبيتان ', ' أوروبيتان '),
(' اوروبيون ', ' أوروبيون '),
(' اوروبيات ', ' أوروبيات '),
(' الاوروبي ', ' الأوروبي '),
(' الاوروبية ', ' الأوروبية '),
(' الاوروبيان ', ' الأوروبيان '),
(' الاوروبيتان ', ' الأوروبيتان '),
(' الاوروبيون ', ' الأوروبيون '),
(' الاوروبيات ', ' الأوروبيات '),
(' اسرائيلي ', ' إسرائيلي '),
(' اسرائيلية ', ' إسرائيلية '),
(' اسرائيليان ', ' إسرائيليان '),
(' اسرائيليتان ', ' إسرائيليتان '),
],
'exceptions': {
'inside-tags': [
'file', # because of filenames
'gallery', # because of filenames
'header', # section headers
'hyperlink', # URLs
'interwiki',
'ref',
],
}
},
# TODO: Support dynamic replacement from Special pages to the localized one
'specialpages': {
'regex': False,
'msg': {
'ar': 'روبوت: إصلاح حالة حروف الصفحات الخاصة',
'arz': 'روبوت: تصليح حاله الحروف بتاعه الصفحات الخصوصيه',
'en': 'Robot: Fixing special page capitalisation',
'fa': 'ربات: تصحیح بزرگی و کوچکی حروف صفحههای ویژه',
},
'replacements': [
('Special:Allpages', 'Special:AllPages'),
('Special:Blockip', 'Special:BlockIP'),
('Special:Blankpage', 'Special:BlankPage'),
('Special:Filepath', 'Special:FilePath'),
('Special:Globalusers', 'Special:GlobalUsers'),
('Special:Imagelist', 'Special:ImageList'),
('Special:Ipblocklist', 'Special:IPBlockList'),
('Special:Listgrouprights', 'Special:ListGroupRights'),
('Special:Listusers', 'Special:ListUsers'),
('Special:Newimages', 'Special:NewImages'),
('Special:Prefixindex', 'Special:PrefixIndex'),
('Special:Protectedpages', 'Special:ProtectedPages'),
('Special:Recentchanges', 'Special:RecentChanges'),
('Special:Specialpages', 'Special:SpecialPages'),
('Special:Unlockdb', 'Special:UnlockDB'),
('Special:Userlogin', 'Special:UserLogin'),
('Special:Userlogout', 'Special:UserLogout'),
('Special:Whatlinkshere', 'Special:WhatLinksHere'),
],
},
# These replacements will convert HTML tag from FCK-editor to wiki syntax.
#
'fckeditor': {
'regex': True,
'msg': 'pywikibot-fixes-fckeditor',
'replacements': [
# replace <br> with a new line
(r'(?i)<br>', r'\n'),
# replace with a space
(r'(?i) ', r' '),
],
},
}
[docs]
def _load_file(filename: str) -> bool:
"""Load the fixes from the given filename.
Returns True if the file existed and was loaded, False otherwise.
:meta public:
"""
path = Path(filename)
if path.exists():
# Read file as binary, so that compile can detect encoding from header
with path.open('rb') as f:
code = compile(f.read(), filename, 'exec')
exec(code, globals()) # intentionally in globals
return True
return False
# Load the user fixes file.
filename = config.datafilepath('user-fixes.py')
user_fixes_loaded = _load_file(filename)