Tại sao bản dịch DOCX lại mất chữ đậm? Tiếp tục chạy trước và sau đó nói về việc thay thế toàn bộ phần.
DOCX mất chữ in đậm và in nghiêng sau khi dịch? Vấn đề có lẽ là toàn bộ phần được thay thế và đường chạy bị cuốn trôi. Bài viết này sử dụng python-docx để lưu từng định dạng chạy và đọc lại và chấp nhận sau khi lưu. Nếu gặp cấu trúc phức tạp hoặc phân đoạn không khớp, nó sẽ trực tiếp từ chối thay thế.
Độ đậm, in nghiêng và cỡ chữ bị mất sau khi dịch DOCX. Lý do phổ biến là nội dung đoạn văn được thay thế trực tiếp bằng toàn bộ văn bản, làm mất đi định dạng cấp độ chạy ban đầu. Sau khi nhiều đội nhận được bản dịch, phản ứng chung là thiếu định dạng nhấn mạnh trong Word. Bài viết này phù hợp với các nhà phát triển sử dụng python-docx để xử lý DOCX, cũng như các biên tập viên cần cung cấp tài liệu song ngữ.
Một đoạn văn dường như chỉ có một câu trong Word, nhưng trong DOCX, nó có thể bao gồm nhiều dòng: văn bản thông thường, văn bản được nhấn mạnh, thay đổi kích thước phông chữ, siêu liên kết và các cấu trúc khác không thuộc danh sách chạy thông thường. Sau khi đọc phần này, bạn sẽ biết vấn đề thường nằm ở đâu, cách viết lại các bản dịch từng lần một và khi nào bạn nên từ chối thay thế tự động.
##Tôi phải làm gì nếu mất định dạng DOCX sau khi dịch? Một câu kết luận
Đầu tiên, giới hạn việc xử lý chỉ ở các đoạn văn bản chạy thông thường, viết lại bản dịch từng đoạn một theo số thứ tự chạy ban đầu, lưu lại và đọc lại để chấp nhận; nếu nó gặp cấu trúc phức tạp hoặc phân đoạn không khớp, hãy trực tiếp từ chối thay thế.
| hoàn cảnh của bạn | Các phương pháp được đề xuất | lý do |
|---|---|---|
| Đoạn văn chỉ có văn bản chạy bình thường | Viết lại từng bản dịch theo số thứ tự chạy | Ranh giới định dạng cho mỗi lần chạy được giữ nguyên |
| Đoạn văn chứa siêu liên kết, hình ảnh, trường, ngắt dòng hoặc tab | Từ chối rõ ràng và chuyển sang quy trình đặc biệt | Mã không lặng lẽ làm phẳng các phần tử này |
| Số lượng hoặc thứ tự của các đoạn dịch không nhất quán với lần chạy ban đầu | Thay vì tập trung vào các hoạt động hiện có, hãy sử dụng chiến lược định dạng lại hoặc xem xét thủ công | Sự tương ứng bắt buộc sẽ phá vỡ định dạng |
| Cần xác nhận kết quả ghi lại | Sau khi lưu, mở lại file và chấp nhận nó. | Tránh chỉ kiểm tra các đối tượng trong bộ nhớ |
Gán trực tiếp giá trị cho paragraph.text | tránh sử dụng | Nội dung hiện có của đoạn văn sẽ được thay thế bằng văn bản mới và định dạng cấp chạy sẽ không được tự động giữ lại. |
Vấn đề ở đâu: Thay thế toàn bộ đoạn văn sẽ xóa định dạng chạy
Việc gán trực tiếp giá trị cho paragraph.text sẽ thay thế nội dung hiện có của đoạn văn bằng văn bản mới. Kiểu cấp độ đoạn văn có thể được giữ lại, nhưng định dạng cấp độ chạy ban đầu sẽ không được tự động giữ lại. Hành vi này được ghi lại rõ ràng trong API văn bản python-docx.
Kết quả dịch có vẻ chính xác nhưng định dạng đã biến mất hoàn toàn. Đây có lẽ là lý do.
Phạm vi áp dụng: Định dạng được giữ nguyên nhưng không có nghĩa là các vấn đề khác đã được giải quyết.
Hồ sơ kiểm tra của bài viết này đến từ DOCX tổng hợp cục bộ, không phải ảnh chụp màn hình công cụ sắp chữ. Những gì nó giải quyết được là "thay thế hạn chế mà không làm mất định dạng". Nó không tự động giải quyết việc sắp xếp lại cú pháp giữa các ngôn ngữ và cũng không đảm bảo rằng việc phân trang không thay đổi sau khi dịch.
Đầu tiên hãy giới hạn phạm vi có thể sửa đổi một cách an toàn
Ví dụ cô đọng này chỉ chấp nhận các đoạn văn bản thuần túy. Khi một đoạn chứa siêu liên kết, hình ảnh, trường, ngắt dòng, tab hoặc các nút XML phức tạp khác, hãy từ chối nó một cách rõ ràng và chuyển hướng người gọi đến một quy trình chuyên biệt. Mã sẽ không làm phẳng các phần tử này một cách âm thầm.
Đầu vào dịch không phải là một danh sách các chuỗi tùy ý: mỗi kết quả phải có số sê-ri của lần chạy ban đầu và số, thứ tự và loại phải khớp nhau trước khi bắt đầu sửa đổi. Việc xác thực được thực hiện trước khi ghi để tránh phát hiện sự cố với các trường tiếp theo sau khi cập nhật giữa chừng.
Một thử nghiệm tối thiểu có thể chạy nhiều lần
Môi trường thử nghiệm là python-docx==1.2.0. Tiếng Anh ở đây xuất phát từ một so sánh cố định viết tay, được sử dụng để xác minh cấu trúc và không sử dụng dịch máy.
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))
Sau khi lưu, hãy mở lại translated-runs.docx rồi chấp nhận nó để tránh chỉ kiểm tra các đối tượng trong bộ nhớ.
Tại sao không giao từng lượt cho người dịch riêng lẻ?
run là ranh giới định dạng, không phải ranh giới ngữ nghĩa. Lịch sử chỉnh sửa của Word cũng có thể chia một từ thành nhiều lần chạy. Các bản dịch tách biệt sẽ mất ngữ cảnh; thứ tự từ của các ngôn ngữ khác nhau cũng có thể chuyển trọng tâm sang đầu hoặc cuối câu.
Quá trình tạo bản dịch thực tế phải cung cấp ngữ cảnh dưới dạng các phân đoạn hoàn chỉnh và sau đó trả về các phân đoạn có cấu trúc đã được xác thực. Khi kết quả trả về không giống với độ dài ban đầu, đừng ép nó vào lần chạy hiện có. Cần có chiến lược định dạng lại rõ ràng hoặc xem xét thủ công. Ví dụ đơn giản trong bài viết này chỉ có thể giữ lại ba đoạn, nhưng điều này không thể khái quát cho tất cả các ngôn ngữ.
Chia sự chấp nhận thành ba cấp độ
| mức độ | Kiểm tra nội dung | Bài viết này có bao gồm |
|---|---|---|
| cấu trúc dữ liệu | Chạy số lượng, thứ tự, chữ ký đậm và phục hồi sau khi lưu | Ghi đè ví dụ bị hạn chế này |
| nội dung ngữ nghĩa | Thuật ngữ, từ phủ định, ngày tháng, số tiền, thiếu sót | Không được che chắn; yêu cầu hiệu đính độc lập |
| bố cục trực quan | Khôi phục phông chữ, ngắt dòng, đánh số trang, tràn bảng | Không được che chắn; cần phải được hiển thị và kiểm tra lại |
_p và _r là các thuộc tính nội bộ được sử dụng ở đây để kiểm tra XML. Khi nâng cấp python-docx, bạn cần sửa phiên bản và chạy lại thử nghiệm. Bạn không thể cho rằng cấu trúc bên trong sẽ không bao giờ thay đổi. Khi bạn cần xử lý bảng, đầu trang, chân trang, hộp văn bản và dấu vết sửa đổi, bạn cũng phải liệt kê các phạm vi nội dung một cách riêng biệt vì document.paragraphs không thể biểu thị tất cả văn bản trong tài liệu.
Dừng tình trạng trước khi giao hàng
Cấu trúc không được hỗ trợ, phân đoạn không khớp, thiếu phông chữ, thay đổi đối với các trường quan trọng, bất kỳ điều nào trong số này sẽ ngăn việc phân phối tự động. Lưu tệp gốc dưới dạng chỉ đọc, viết bản dịch sang tệp mới và đính kèm ngôn ngữ, phiên bản xử lý và bản ghi chấp nhận thủ công. Đây là một chỉ báo chất lượng tốt hơn so với "lưu thành công".
Nếu bạn cần chuyển từ tải tài liệu lên sang quá trình dịch và đánh giá, bạn có thể xem Cổng thông tin sản phẩm OmniDoc. Các ví dụ mã trong bài viết này là các mẫu giảng dạy thư viện nguồn mở độc lập và không đại diện cho việc triển khai công cụ bố cục hoặc nhập khẩu hiện tại của OmniDoc. Chỉ có một nguyên tắc cốt lõi: coi định dạng này là dữ liệu được chấp nhận chứ không phải là phần thưởng được dịch.
📊 So sánh cốt lõi
| luyện tập | Rủi ro chính | Những gợi ý được đưa ra trong bài viết |
|---|---|---|
Gán trực tiếp giá trị cho paragraph.text | Định dạng cấp độ chạy không được bảo tồn tự động | Không dùng cho những đoạn văn cần giữ nguyên định dạng |
| Chạy từng bản dịch riêng biệt | Ngữ cảnh bị mất, thay đổi thứ tự từ có thể làm thay đổi sự nhấn mạnh | Cung cấp bối cảnh dưới dạng các phân đoạn hoàn chỉnh |
| Sau khi dịch xong toàn bộ đoạn, nhấn run để xác minh và viết lại. | Nếu kết quả trả về không có độ dài bằng lần chạy ban đầu thì không thể khó tương ứng. | Thay vào đó hãy sử dụng chiến lược định dạng lại hoặc xem xét thủ công |
🎯 Phương pháp nào phù hợp với bạn?
Nếu đoạn văn của bạn chỉ chạy văn bản bình thường
Theo ví dụ tối thiểu trong bài viết này, trước tiên hãy xác minh số sê-ri, số lượng, thứ tự và loại, sau đó viết lại từng cái một, lưu lại và đọc lại để chấp nhận.
Nếu đoạn văn của bạn chứa siêu liên kết, trường hoặc hình ảnh
Trực tiếp từ chối việc thay thế tự động và chuyển nó sang một quy trình đặc biệt. Mã không lặng lẽ làm phẳng các cấu trúc này.
Nếu bạn đang cung cấp tài liệu song ngữ chính thức
Lưu tệp gốc dưới dạng chỉ đọc, viết bản dịch sang tệp mới và đính kèm ngôn ngữ, phiên bản xử lý và hồ sơ chấp nhận thủ công. Thiếu phông chữ, thay đổi trong các trường quan trọng, phân đoạn không khớp, v.v. đều sẽ ngăn việc phân phối tự động.
❓ Câu hỏi thường gặp (FAQ)
1. Độ đậm có bị mất nếu bạn trực tiếp gán giá trị cho đoạn văn.văn bản không?
cuộc họp. Kiểu cấp độ đoạn văn có thể được giữ lại, nhưng định dạng cấp độ chạy ban đầu sẽ không được tự động giữ lại.
2. Tại sao không giao từng lượt cho người dịch riêng lẻ?
run là ranh giới định dạng chứ không phải ranh giới ngữ nghĩa. Bản dịch riêng lẻ lần lượt sẽ làm mất ngữ cảnh và thứ tự từ của các ngôn ngữ khác nhau cũng có thể chuyển trọng tâm về đầu hoặc cuối câu.
3. Lưu thành công có nghĩa là định dạng ổn phải không?
không thể. Cấu trúc dữ liệu chấp nhận tệp phải được mở lại sau khi lưu; nội dung ngữ nghĩa và bố cục hình ảnh cần được kiểm tra riêng.
4. Khi nâng cấp python-docx tôi cần chú ý những gì?
Mã sử dụng các thuộc tính bên trong của _p và _r. Bạn cần sửa phiên bản và chạy lại thử nghiệm. Bạn không thể cho rằng cấu trúc bên trong sẽ không bao giờ thay đổi.
📝 Tóm tắt
Chỉ có một nguyên tắc cốt lõi: coi định dạng này là dữ liệu được chấp nhận chứ không phải là phần thưởng được dịch. Các ví dụ mã trong bài viết này là các mẫu giảng dạy thư viện nguồn mở độc lập và không đại diện cho việc triển khai công cụ bố cục hoặc nhập khẩu hiện tại của OmniDoc.
Thử ngay: Tải tài liệu lên để bắt đầu dịch, giữ nguyên bố cục ban đầu


