لماذا تفقد ترجمة DOCX الخط العريض؟ استمر في التشغيل أولاً، ثم تحدث عن استبدال القسم بأكمله.

DOCX بالخط العريض والمائل المفقود بعد الترجمة؟ ربما تكمن المشكلة في استبدال القسم بأكمله وغسله. تستخدم هذه المقالة python-docx لحفظ تنسيق التشغيل واحدًا تلو الآخر، وإعادة قراءته وقبوله بعد الحفظ. إذا واجه بنية معقدة أو كان الجزء غير متطابق، فسوف يرفض استبداله مباشرة.

يتم فقدان الخط الغامق والمائل وحجم الخط بعد ترجمة DOCX. السبب الشائع هو أنه يتم استبدال محتوى الفقرة مباشرةً بالنص بأكمله، مما يؤدي إلى إزالة تنسيق مستوى التشغيل الأصلي. بعد حصول العديد من الفرق على الترجمة، يكون رد الفعل الشائع هو أن تنسيق التركيز في Word مفقود. هذه المقالة مناسبة للمطورين الذين يستخدمون python-docx لمعالجة DOCX، وكذلك المحررين الذين يحتاجون إلى تسليم مستندات ثنائية اللغة.

يبدو أن الفقرة تحتوي على جملة واحدة فقط في Word، ولكن في DOCX قد تتكون من عدة عمليات تشغيل: نص عادي، ونص مؤكد، وتغييرات في حجم الخط، وارتباطات تشعبية وهياكل أخرى لا تنتمي إلى قائمة التشغيل العادية. بعد قراءة هذا، ستعرف أين تكمن المشكلة عادةً، وكيفية إعادة كتابة الترجمات تشغيلاً تلو الآخر، ومتى يجب عليك رفض الاستبدال التلقائي.

ماذا علي أن أفعل إذا فقدت تنسيق DOCX بعد الترجمة؟ استنتاج جملة واحدة

أولاً، قم بقصر المعالجة على فقرات تشغيل النص العادي فقط، ثم أعد كتابة الترجمة واحدة تلو الأخرى وفقًا لرقم تسلسل التشغيل الأصلي، واحفظها وأعد قراءتها للقبول؛ إذا واجه بنية معقدة أو كان المقطع غير متطابق، فارفض الاستبدال مباشرة.

حالتكالممارسات الموصى بهاسبب
تحتوي الفقرات على نص عادي فقطأعد كتابة الترجمات واحدة تلو الأخرى وفقًا لرقم تسلسل التشغيليتم الاحتفاظ بحدود التنسيق لكل تشغيل
تحتوي الفقرات على ارتباطات تشعبية أو صور أو حقول أو فواصل أسطر أو علامات تبويبرفض صراحة ونقل إلى عملية خاصةلا يقوم الكود بتسوية هذه العناصر بهدوء
عدد أو ترتيب مقاطع الترجمة غير متوافق مع التشغيل الأصليبدلاً من استخدام عمليات التشغيل الحالية، استخدم إستراتيجيات إعادة التنسيق أو المراجعة اليدويةالمراسلات القسرية سوف تعطل التنسيق
تحتاج إلى تأكيد نتيجة الكتابة مرة أخرىبعد الحفظ، أعد فتح الملف وقبوله.تجنب فحص الكائنات الموجودة في الذاكرة فقط
قم بتعيين القيمة مباشرة إلى paragraph.textتجنب الاستخدامسيتم استبدال المحتوى الحالي للفقرة بنص جديد، ولن يتم الاحتفاظ بالتنسيق على مستوى التشغيل تلقائيًا.

أين تكمن المشكلة: سيؤدي استبدال الفقرة بأكملها إلى محو تنسيق التشغيل

سيؤدي تعيين قيمة إلى paragraph.text مباشرة إلى استبدال المحتوى الحالي للفقرة بنص جديد. يمكن الاحتفاظ بالأنماط على مستوى الفقرة، ولكن لن يتم الاحتفاظ بالتنسيق الأصلي على مستوى التشغيل تلقائيًا. تم توثيق هذا السلوك بشكل صريح في واجهة برمجة تطبيقات النص بيثون-دوكإكس.

تبدو نتيجة الترجمة دقيقة، لكن التنسيق اختفى تمامًا. ربما هذا هو السبب.

نطاق التطبيق: يتم الحفاظ على التنسيق، لكن هذا لا يعني أنه تم حل المشكلات الأخرى.

تأتي سجلات الاختبار الخاصة بهذه المقالة من DOCX المُصنَّع محليًا، وليس من لقطات شاشة محرك التنضيد. ما يحله هو "الاستبدال المقيد دون فقدان التنسيق". فهو لا يحل تلقائيًا عمليات إعادة ترتيب بناء الجملة عبر اللغات، ولا يضمن بقاء الترحيل دون تغيير بعد الترجمة.

حدد أولاً النطاق الذي يمكن تعديله بأمان

لا يقبل هذا المثال المكثف سوى الفقرات التي تتكون من نص عادي. عندما تحتوي فقرة على ارتباطات تشعبية أو صور أو حقول أو فواصل أسطر أو علامات تبويب أو عقد XML معقدة أخرى، ارفضها صراحةً وأعد توجيه المتصل إلى عملية متخصصة. لن يقوم الكود بتسوية هذه العناصر بصمت.

مدخلات الترجمة ليست قائمة عشوائية من السلاسل: يجب أن تحتوي كل نتيجة على الرقم التسلسلي للتشغيل الأصلي، ويجب أن يتطابق الرقم والترتيب والنوع قبل بدء التعديل. يتم التحقق من الصحة قبل الكتابة لتجنب اكتشاف مشاكل في الحقول اللاحقة بعد التحديث في منتصف الطريق.

اختبار بسيط يمكن إجراؤه بشكل متكرر

بيئة الاختبار هي python-docx==1.2.0. تأتي اللغة الإنجليزية هنا من مقارنة ثابتة مكتوبة بخط اليد، والتي تُستخدم للتحقق من البنية ولا تستدعي الترجمة الآلية.

from docx import Document
from docx.oxml.ns import qn

def replace_plain_runs(paragraph, translated):
    if any(child.tag not in {qn("w:pPr"), qn("w:r")}
           for child in paragraph._p):
        raise ValueError("paragraph contains unsupported structures")
    runs = paragraph.runs
    for run in runs:
        if any(child.tag not in {qn("w:rPr"), qn("w:t")}
               for child in run._r):
            raise ValueError("run contains a field, image or control")
    if len(translated) != len(runs):
        raise ValueError("segment count mismatch")
    for index, item in enumerate(translated):
        if (not isinstance(item, dict) or item.get("id") != index
                or not isinstance(item.get("text"), str)
                or any(ch in item["text"] for ch in "\t\r\n")):
            raise ValueError("segment identity or text mismatch")
    for run, item in zip(runs, translated):
        run.text = item["text"]

def signature(paragraph):
    return [(r.text, r.bold, r.italic) for r in paragraph.runs]

doc = Document()
p = doc.add_paragraph()
p.add_run("请在 ")
p.add_run("周五之前").bold = True
p.add_run(" 提交报告。")
before = signature(p)
try:
    replace_plain_runs(p, [{"id": 0, "text": "Incomplete"}])
    raise AssertionError("bad segments accepted")
except ValueError:
    assert signature(p) == before

replace_plain_runs(p, [
    {"id": 0, "text": "Submit the report "},
    {"id": 1, "text": "before Friday"},
    {"id": 2, "text": "."},
])
doc.save("translated-runs.docx")
restored = Document("translated-runs.docx").paragraphs[0]
assert restored.text == "Submit the report before Friday."
assert restored.runs[1].bold is True
assert len(restored.runs) == 3
complex_p = doc.add_paragraph("keep")
complex_p.runs[0].add_break()
try:
    replace_plain_runs(complex_p, [{"id": 0, "text": "reject"}])
    raise AssertionError("line break accepted")
except ValueError:
    assert complex_p.text == "keep\n"
print("PASS count mismatch: no partial write")
print("PASS save/reopen: 3 runs, emphasis preserved")
print("PASS unsupported control: rejected")
print(signature(restored))

بعد الحفظ، أعد فتح translated-runs.docx ثم اقبله لتجنب التحقق من الكائنات الموجودة في الذاكرة فقط.

لماذا لا نعطي كل شوط للمترجم على حدة؟

run هو حد تنسيق، وليس حدًا دلاليًا. قد يقوم سجل تحرير Word أيضًا بتقسيم الكلمة إلى عمليات تشغيل متعددة. ستفقد الترجمات المعزولة سياقها؛ قد يؤدي ترتيب الكلمات في اللغات المختلفة أيضًا إلى نقل التركيز إلى بداية الجملة أو نهايتها.

يجب أن يوفر توليد الترجمة الفعلي السياق كمقاطع كاملة ثم يُرجع المقاطع المنظمة التي تم التحقق من صحتها. عندما تكون النتيجة التي تم إرجاعها ليست هي نفس الطول الأصلي، لا تجبرها على التشغيل الحالي. مطلوب استراتيجية إعادة تنسيق واضحة أو مراجعة يدوية. يمكن للمثال البسيط في هذه المقالة الاحتفاظ بثلاثة أجزاء فقط، ولكن لا يمكن تعميم ذلك على كافة اللغات.

##تقسيم القبول إلى ثلاثة مستويات

مستوىالتحقق من المحتوىهل تغطي هذه المقالة
بنية البياناتتشغيل الكمية والأمر والتوقيع الجريء والاسترداد بعد الحفظتجاوز هذا المثال المقيد
المحتوى الدلاليالمصطلحات، الكلمات السلبية، التواريخ، المبالغ، السهوغير مغطاة؛ يتطلب التدقيق اللغوي المستقل
التخطيط البصريالتراجع عن الخط، فواصل الأسطر، أرقام الصفحات، تجاوز الجدولغير مغطاة؛ يحتاج إلى تقديم والتحقق مرة أخرى

_p و_r هي الخصائص الداخلية المستخدمة هنا لفحص XML. عند ترقية python-docx، تحتاج إلى إصلاح الإصدار وإعادة تشغيل الاختبار. لا يمكنك الافتراض أن الهيكل الداخلي لن يتغير أبدًا. عندما تحتاج إلى معالجة الجداول والرؤوس والتذييلات ومربعات النص وتتبعات المراجعة، يجب عليك أيضًا تعداد نطاقات المحتوى بشكل منفصل، لأن document.paragraphs لا يمكنه تمثيل كل النص في المستند.

شرط التوقف قبل التسليم

الهياكل غير المدعومة، والأجزاء غير المتطابقة، والخطوط المفقودة، والتغييرات في الحقول المهمة، أي من هذه الأشياء يجب أن تمنع التسليم التلقائي. احفظ الملف الأصلي للقراءة فقط، واكتب الترجمة في ملف جديد، وأرفق اللغة ونسخة المعالجة وسجل القبول اليدوي. وهذا مؤشر للجودة أفضل من "الحفظ بنجاح".

إذا كنت تريد الانتقال من تحميل المستندات إلى عملية الترجمة والمراجعة، فيمكنك مراجعة بوابة منتج OmniDoc. أمثلة التعليمات البرمجية الموجودة في هذه المقالة هي نماذج تعليمية مستقلة لمكتبة مفتوحة المصدر ولا تمثل تنفيذ مستورد OmniDoc الحالي أو محرك التخطيط. هناك مبدأ أساسي واحد فقط: التعامل مع التنسيق كبيانات يجب قبولها، وليس كمكافأة مترجمة.

📊 المقارنة الأساسية

يمارسالمخاطر الرئيسيةالاقتراحات الواردة في المقال
قم بتعيين القيمة مباشرة إلى paragraph.textلا يتم حفظ التنسيق على مستوى التشغيل تلقائيًالا يستخدم للفقرات التي تحتاج إلى الحفاظ على التنسيق
قم بتشغيل الترجمات المعزولة واحدة تلو الأخرىتم فقدان السياق، وقد تؤدي تغييرات ترتيب الكلمات إلى نقل التركيزتوفير السياق كقطاعات كاملة
بعد ترجمة المقطع بالكامل، اضغط على "تشغيل" للتحقق منه ثم قم بكتابته مرة أخرى.إذا لم تكن النتيجة التي تم إرجاعها مساوية للطول الأصلي، فلن يكون من الصعب مطابقتها.استخدم استراتيجية إعادة التنسيق أو المراجعة اليدوية بدلاً من ذلك

🎯 ما هي الطريقة المناسبة لك؟

إذا كانت فقرتك تحتوي على نص عادي فقط

وفقًا للمثال البسيط في هذه المقالة، تحقق أولاً من الرقم التسلسلي والكمية والطلب والنوع، ثم أعد الكتابة واحدًا تلو الآخر، ثم احفظه وأعد قراءته للقبول.

إذا كانت فقرتك تحتوي على ارتباطات تشعبية أو حقول أو صور

رفض الاستبدال التلقائي مباشرة ونقله إلى عملية خاصة. لا يقوم الكود بتسوية هذه الهياكل بهدوء.

إذا كنت تقوم بتسليم مستند رسمي ثنائي اللغة

احفظ الملف الأصلي للقراءة فقط، واكتب الترجمة في ملف جديد، وأرفق اللغة ونسخة المعالجة وسجلات القبول اليدوي. الخطوط المفقودة، والتغييرات في الحقول المهمة، والأجزاء غير المتطابقة، وما إلى ذلك، يجب أن تمنع جميعها التسليم التلقائي.

❓ الأسئلة الشائعة (الأسئلة الشائعة)

1. هل سيتم فقدان الجرأة إذا قمت بتعيين قيمة مباشرة للفقرة.نص؟

مقابلة. يمكن الاحتفاظ بالأنماط على مستوى الفقرة، ولكن لن يتم الاحتفاظ بالتنسيق الأصلي على مستوى التشغيل تلقائيًا.

2. لماذا لا نعطي كل جولة للمترجم على حدة؟

run هو حد تنسيق وليس حدًا دلاليًا. الترجمة المعزولة واحدة تلو الأخرى ستفقد السياق، وقد يؤدي ترتيب الكلمات في اللغات المختلفة أيضًا إلى نقل التركيز إلى بداية الجملة أو نهايتها.

3. هل يعني الحفظ بنجاح أن التنسيق جيد؟

لا أستطيع. يجب إعادة فتح بنيات بيانات قبول الملف بعد الحفظ؛ يجب التحقق من المحتوى الدلالي والتخطيط المرئي بشكل منفصل.

4. ما الذي يجب علي الانتباه إليه عند ترقية python-docx؟

يستخدم الكود الخصائص الداخلية لـ _p و_r. تحتاج إلى إصلاح الإصدار وإعادة تشغيل الاختبار. لا يمكنك الافتراض أن البنية الداخلية لن تتغير أبدًا.

📝 ملخص

هناك مبدأ أساسي واحد فقط: التعامل مع التنسيق كبيانات يجب قبولها، وليس كمكافأة مترجمة. أمثلة التعليمات البرمجية الموجودة في هذه المقالة هي نماذج تعليمية مستقلة لمكتبة مفتوحة المصدر ولا تمثل تنفيذ مستورد OmniDoc الحالي أو محرك التخطيط.

جربه الآن: قم بتحميل المستند لبدء الترجمة، مع الاحتفاظ بالتخطيط الأصلي

تاريخ التحديث: 2026-11-14