سرویس Pastebin (نسخه آزمایشی)
import re
import xml.etree.ElementTree as ET
import uno
from com.sun.star.awt import MessageBoxButtons as MBButtons
from com.sun.star.awt.MessageBoxType import MESSAGEBOX

# ← تبدیل اعداد انگلیسی به فارسی
def en_to_fa_numbers(text):
    return text.translate(str.maketrans("0123456789", "۰۱۲۳۴۵۶۷۸۹"))

# ← بارگذاری واژه‌های غلط/درست از DocumentList.xml
def load_replacements(path):
    tree = ET.parse(path)
    root = tree.getroot()
    replacements = {}
    ns = {"bl": "http://openoffice.org/2001/block-list"}
    for block in root.findall("bl:block", ns):
        wrong = block.get("{http://openoffice.org/2001/block-list}abbreviated-name")
        correct = block.get("{http://openoffice.org/2001/block-list}name")
        if wrong and correct:
            replacements[wrong] = correct
    return replacements

REPLACEMENTS = load_replacements("/home/afshin/.config/libreoffice/4/user/Scripts/python/DocumentList.xml")

def fix_text_full(event=None):
    ctx = uno.getComponentContext()
    smgr = ctx.ServiceManager
    desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
    doc = desktop.getCurrentComponent()

    if not doc.supportsService("com.sun.star.text.TextDocument"):
        return

    text_obj = doc.getText()
    full_text = text_obj.getString()

    report_counts = {
        "می‌": 0, "ك→ک": 0, "ي→ی": 0, "،؛؟": 0, "گیومه": 0,
        "اعداد EN→FA": 0, "اعداد عربی→FA": 0, "ه ی → هٔ": 0,
        "؟؟؟": 0, "فاصله قبل از علائم": 0, "غلط‌های املایی (بانک)": 0,
        "نیم‌فاصله پسوندها": 0, "فاصله‌های اضافی": 0,
        "فاصله قبل/بعد علائم": 0,
    }

    def fix_all(text):
        # ۱. اصلاح «می + فاصله»
        text, n = re.subn(r"می(?!\u200c)\s+([\u0600-\u06FF]+)",
                          lambda m: "می\u200c" + m.group(1), text)
        report_counts["می‌"] += n

        # ۲. ك → ک
        c_before = text.count("ك")
        if c_before:
            report_counts["ك→ک"] += c_before
            text = text.replace("ك", "ک")

        # ۳. ي → ی
        y_before = text.count("ي")
        if y_before:
            report_counts["ي→ی"] += y_before
            text = text.replace("ي", "ی")

        # ۴. علائم لاتین → فارسی
        punct_map = {",": "،", ";": "؛", "?": "؟"}
        for en_punct, fa_punct in punct_map.items():
            n = text.count(en_punct)
            if n:
                report_counts["،؛؟"] += n
                text = text.replace(en_punct, fa_punct)

        # ۵. گیومه انگلیسی → گیومه فارسی
        if '"' in text:
            result, open_q, cnt = [], True, 0
            for ch in text:
                if ch == '"':
                    result.append("«" if open_q else "»")
                    open_q = not open_q
                    cnt += 1
                else:
                    result.append(ch)
            text = "".join(result)
            report_counts["گیومه"] += cnt

        # ۶. اعداد انگلیسی → فارسی
        for d in "0123456789":
            report_counts["اعداد EN→FA"] += text.count(d)
        text = text.translate(str.maketrans("0123456789", "۰۱۲۳۴۵۶۷۸۹"))

        # ۷. اعداد عربی → فارسی
        for d in "٠١٢٣٤٥٦٧٨٩":
            report_counts["اعداد عربی→FA"] += text.count(d)
        text = text.translate(str.maketrans("٠١٢٣٤٥٦٧٨٩", "۰۱۲۳۴۵۶۷۸۹"))

        # ۸. «ه ی» → «هٔ»
        text, n = re.subn(r"(\S*ه)[\s\u200c]ی\b", lambda m: m.group(1) + "ٔ", text)
        report_counts["ه ی → هٔ"] += n

        # ۹. چند علامت سؤال → یکی
        text, n = re.subn(r"؟{2,}", "؟", text)
        report_counts["؟؟؟"] += n

        # ۱۰. حذف فاصله قبل از علائم (، ؛ ؟ . و پرانتز شکسته ⟨ ⟩)
        text, n = re.subn(r"\s+([،؛؟.\(\)⟨⟩])", r"\1", text)
        report_counts["فاصله قبل از علائم"] += n

        # ۱۱. غلط‌های املایی بانک
        for wrong, correct in REPLACEMENTS.items():
            pat = r"\b" + re.escape(wrong) + r"\b"
            text, n = re.subn(pat, correct, text)
            report_counts["غلط‌های املایی (بانک)"] += n

        # ۱۲. نیم‌فاصله قبل از پسوندهای رایج
        ZWNJ = "\u200c"
        def fix_suffixes(m):
            word = m.group(1)
            suffix = m.group(2)
            if word.endswith(ZWNJ):
                return word + suffix
            return word + ZWNJ + suffix

        suffixes = r"(تر(?:ین)?|ها|ام|ات|اش|ایم|اید|اند)"
        pattern2 = rf"(\S+?)(?:\s|{ZWNJ})?{suffixes}\b"
        text, n2 = re.subn(pattern2, fix_suffixes, text)
        report_counts["نیم‌فاصله پسوندها"] += n2

        # ۱۳. حذف فاصله‌های اضافی بین کلمات
        text, n = re.subn(r"[ ]{2,}", " ", text)
        report_counts["فاصله‌های اضافی"] += n
        if text.startswith(" "):
            text = text.lstrip()
            report_counts["فاصله‌های اضافی"] += 1
        if text.endswith(" "):
            text = text.rstrip()
            report_counts["فاصله‌های اضافی"] += 1

        # ۱۴. حذف فاصله‌های اضافی اطراف علائم
        # شامل: پرانتز ()، گیومه «»، کروشه []، آکولاد {}، پرانتز شکسته ⟨⟩
        # پرانتز
        text, n1 = re.subn(r"\(\s+", "(", text)
        report_counts["فاصله قبل/بعد علائم"] += n1
        text, n2 = re.subn(r"\s+\)", ")", text)
        report_counts["فاصله قبل/بعد علائم"] += n2
        # گیومه
        text, n3 = re.subn(r"«\s+", "«", text)
        report_counts["فاصله قبل/بعد علائم"] += n3
        text, n4 = re.subn(r"\s+»", "»", text)
        report_counts["فاصله قبل/بعد علائم"] += n4
        # کروشه
        text, n5 = re.subn(r"\[\s+", "[", text)
        report_counts["فاصله قبل/بعد علائم"] += n5
        text, n6 = re.subn(r"\s+\]", "]", text)
        report_counts["فاصله قبل/بعد علائم"] += n6
        # آکولاد
        text, n7 = re.subn(r"\{\s+", "{", text)
        report_counts["فاصله قبل/بعد علائم"] += n7
        text, n8 = re.subn(r"\s+\}", "}", text)
        report_counts["فاصله قبل/بعد علائم"] += n8
        # پرانتز شکسته ⟨⟩
        text, n9 = re.subn(r"⟨\s+", "⟨", text)
        report_counts["فاصله قبل/بعد علائم"] += n9
        text, n10 = re.subn(r"\s+⟩", "⟩", text)
        report_counts["فاصله قبل/بعد علائم"] += n10

        return text

    fixed_text = fix_all(full_text)
    text_obj.setString(fixed_text)

    # ← گزارش نهایی
    total = sum(report_counts.values())
    if total > 0:
        lines = [f"{k}: {en_to_fa_numbers(str(v))}"
                 for k, v in report_counts.items() if v > 0]
        report = f"مجموع اصلاحات: {en_to_fa_numbers(str(total))}\n" + "\n".join(lines)

        parent_win = doc.CurrentController.Frame.ContainerWindow
        mb = parent_win.getToolkit().createMessageBox(
            parent_win, MESSAGEBOX, MBButtons.BUTTONS_OK,
            "گزارش اصلاح متن", report
        )
        mb.execute()