BookTranslator
BookTranslator

איך לתרגם קובצי Markdown בלי לשבור קוד, קישורים או Front Matter

מה לתרגם בקובץ Markdown או MDX, מה להשאיר כמו שהוא, ואיך לבדוק את התוצאה. עם קובץ לדוגמה, בודק חינמי ובדיקה של 9 הרצות עם מודל שפה מקומי.

BookTranslator

BookTranslator Team

12 min read

כדי לתרגם קובץ Markdown, תרגמו את הטקסט והשאירו את המנגנון כמו שהוא: מפתחות Front Matter, קוד, כתובות URL, תוויות קישורים, תגי קומפוננטות ותוויות הערות שוליים חייבים לחזור בדיוק בייט אחר בייט. לאחר מכן בדקו שלושה דברים שתרגום זהיר עדיין שובר: קישורים לכותרת, הערות בקוד, ובסינית, יפנית או קוריאנית – הריווח סביב טקסט מודגש וטווחי מספרים.

תרגמנו עמוד MDX בן 73 שורות לסינית מפושטת תשע פעמים עם מודל מקומי, תוך שימוש בשלוש הנחיות שונות, ובדקנו כל תוצאה עם סקריפט. החלקים שבדרך כלל מדאיגים אנשים שרדו בכל תשע ההרצות: קוד, קוד בתוך שורה, כתובות URL, הטבלה, קומפוננטת ה-JSX ורשימת המשימות. שלושה דברים אחרים השתבשו. הקישור לכותרת נשבר בכל תשע ההרצות. הערות הקוד תורגמו בכל שש ההרצות ששלחו את הקובץ כולו, כולל שלוש הרצות שבהן ההנחיה אמרה לא לגעת בקוד. וההנחיה שהסתירה את התחביר מאחורי מצייני מקום, שנשמעת כמו האפשרות הבטוחה ביותר, שברה את ה-Front Matter בכל שלוש ההרצות שלה.

תשובה מהירה: מה לתרגם ומה להשאיר כמו שהוא

חלק בקובץדוגמה מהקובץ שלנולתרגם?
מפתחות Front Matterslug:, sidebar_position:, tags:לא
ערכי Front Mattertitle: "Export Your Library"רק אלה שמיועדים לקורא, כגון title ו-description
ייבוא וייצוא (MDX)import Callout from '@site/src/components/Callout';לא
בלוקי קודshelfmark export --format epubלא. החליטו בנפרד לגבי הערות ומחרוזות שמיועדות למשתמש.
קוד בתוך שורהlibrary.json, --coversלא
יעדי קישורים ותמונות(./export-options.md), (https://www.w3.org/TR/epub-33/ "EPUB 3.3")לא, למעט הכותרת האופציונלית במירכאות
טקסט קישור וטקסט חלופי לתמונה[glossary section], ![Folder layout after an export]כן
תוויות והגדרות של הפניות[project glossary][glossary], [glossary]: ./glossary.md#termsהשאירו את התווית [glossary] ואת כתובת ה-URL; תרגמו את הטקסט הנראה
כותרות## Keep one glossary for the whole bookכן, אבל קודם תנו להן מזהים קבועים (ראו להלן)
רכיבי JSX<Callout type="warning" title="Back up first">השאירו את שמות התגיות והמאפיינים; תרגמו ערכי מאפיינים הפונים לקורא כגון title
סמני אדמונישן:::tip ו-:::לא
תוויות הערות שוליים[^sync]לא
הערות MDX{/* Translator note: ... */}אופציונלי. הקוראים לעולם לא רואים אותן.

כל השאר הוא טקסט רגיל: פסקאות, פריטי רשימה, תאי טבלה וציטוטים.

מה בדקנו

כתבנו את sample-source.mdx, עמוד תיעוד לאפליקציית קריאה בדיונית בשם Shelfmark. הוא כתוב בסגנון MDX המשמש את Docusaurus ואתרי תיעוד דומים, עם דוגמה אחת מכל מבנה בטבלה שלמעלה, בתוספת שבירת שורה קשיחה של שני רווחים, קישור מודגש, ביטוי מודגש המסתיים בסוגריים, שני טווחי מספרים הכתובים במקפים, וקישור פנימי לעמוד לכותרת "שמרו על מילון מונחים אחד לכל הספר."

לאחר מכן ביקשנו ממודל מקומי לתרגם אותו לסינית מפושטת בשלוש דרכים:

  1. קובץ שלם. הדביקו את הקובץ כולו ובקשו בחזרה את הקובץ המתורגם.
  2. עם הנחיות. אותו דבר, בתוספת שישה כללים: שמרו על מפתחות ה-front matter, אל תשנו דבר בתוך קוד, שמרו על כתובות URL והגדרות הפניה, שמרו על ייבוא, תגיות והערות, שמרו על תוויות הערות שוליים וסמני אדמונישן, ותרגמו כותרות, טקסט קישור, טקסט חלופי ואת המאפיין title.
  3. מוגן. החליפו קוד, קוד בתוך שורה, כתובות URL, תגיות, הערות, תוויות הערות שוליים, סמני אדמונישן ושורות front matter במצייני מקום ממוספרים כגון ⟦12⟧, תרגמו את השאר, ואז החזירו את המקור. ערכי title ו-description נותרו חשופים לתרגום, וכך, כפי שהתברר, גם שורות ה---- של ה-front matter ומירכאות הסוגרות.

המודל היה Qwen 3.6 27B (Q4_K_M) ב-LM Studio, עם חשיבה כבויה וטמפרטורה 0.3, על Apple M4 Max עם 64 GB זיכרון. הרצנו כל תנאי שלוש פעמים, תשע הרצות בסך הכול, ב-25 באוקטובר 2026. הסקריפט הוא run_llm_markdown_test.py, וכל תשע הפלטים פורסמו ללא עריכה; ה-README מפרט כל קובץ. אם מעולם לא הגדרתם מודל מקומי, מדריך התרגום עם LLM מקומי שלנו מכסה את ההגדרות.

זה היה מבחן קטן של מודל אחד, זוג שפות אחד ועמוד אחד. הוא מראה אילו בעיות מתרחשות ואיך לתפוס אותן. הוא לא מדרג מודלים או פרומפטים.

תוצאה: התחביר שרד; הקישורים וההחלטות לא

בדקנו כל פלט עם check_markdown_translation.py והצגנו כל אחד מהם עם remark ומהדר ה-MDX. הפלט המלא של הבודק נמצא ב-check-results.txt, ול-results.csv יש שורה לכל הרצה.

בדיקהקובץ שלםהונחהמוגן
מתקמפל כ-MDX3 מתוך 33 מתוך 33 מתוך 3
קוד, קוד מוטבע, כתובות URL, טבלה, תגיות, רשימת משימות ללא שינוי3 מתוך 33 מתוך 33 מתוך 3
מודגש ונטוי עדיין מוצגים3 מתוך 33 מתוך 33 מתוך 3
Front matter שלם3 מתוך 33 מתוך 30 מתוך 3
קישור בתוך העמוד עדיין מצביע לכותרת שלו0 מתוך 30 מתוך 30 מתוך 3
הערות קוד נשארו כפי שנכתבו0 מתוך 30 מתוך 33 מתוך 3
כותרת ה-title של תיבת ההערה תורגמה3 מתוך 33 מתוך 30 מתוך 3

השורות הראשונות הן החדשות הטובות. המודל הזה החזיר את תחביר ה-Markdown כשהוא שלם כשהדבקנו את כל הקובץ; לא מצאנו שום דבר לתקן בקוד, בכתובות URL או בטבלאות. ארבע השורות האחרונות הן המקום שבו נמצאת העבודה, ואף אחת מהן לא מוצגת כשגיאה כשאתם בונים את האתר.

1. כותרות מתורגמות שוברות קישורים אליהן

הדוגמה מקשרת לקטע המילון שלה עם [glossary section](#keep-one-glossary-for-the-whole-book). כל הרצה תרגמה את הכותרת, כמצופה, וכל הרצה שמרה על יעד הקישור, כמצופה. התוצאה היא קישור למזהה שכבר לא קיים.

רוב כלי ה-Markdown בונים מזהי כותרות מטקסט הכותרת. התיעוד של Pandoc מתאר את המזהה כ"מבוסס על טקסט הכותרת", ו-Docusaurus מזהיר שאולי תרצו לשנות או לתרגם כותרת "בלי לעדכן את המזהה הקיים כדי למנוע שבירת קישורים". ברגע שהכותרת היא 为整本书保留一个术语表, המזהה שנוצר שלה הוא בסינית, ו-#keep-one-glossary-for-the-whole-book לא גולל לשום מקום. הדף עדיין נבנה, כך ששום דבר לא מיידע אתכם.

אי אפשר לתקן את זה על ידי עריכת הקישור לאחר התרגום. לאורך תשע הרצות המודל כתב את אותה כותרת בארבע דרכים שונות, כך שהמזהה שנוצר היה משתנה שוב עם כל תרגום מחדש. התיקון שייך לשלב שלפני התרגום: תנו לכל כותרת שמקשרים אליה מזהה קבוע.

  • ב-MDX של Docusaurus, השתמשו ב-## Keep one glossary for the whole book {/* #keep-one-glossary */}. Docusaurus מציין שהצורה הישנה {#id} "אינה תחביר MDX תקף יותר", ופקודת write-heading-ids שלו מוסיפה מזהים לכל מסמך עבורכם.
  • ב-Pandoc ובמעבדי Markdown שעוקבים אחרי PHP Markdown Extra, השתמשו ב-{#keep-one-glossary} בסוף הכותרת.

המזהה נשאר אז זהה בכל שפה, והבודק מתייחס אליו כיעד הקישור.

2. הערות בקוד מתורגמות, והמחרוזת הנראית לעין לא

בדוגמה יש הערת shell והערת YAML:

library:
  name: "My books"   # shown in the sidebar
  sort: title

כל שש ההרצות ששלחו את כל הקובץ תרגמו את שתי ההערות, כולל שלוש שבהן ההנחיה אמרה "אל תשנה דבר בתוך בלוקי קוד מגודרים." הקוד עצמו לא נגע לרעה בכל תשע ההרצות. בינתיים "My books", שההערה אומרת שמוצג בסרגל הצד, נשאר באנגלית בכל תשע ההרצות. המודל עשה את ההיפך ממה שדף מתורגם צריך: הוא תרגם את ההערה למפתחים והשאיר את התווית שהקוראים יראו.

אף אחת מהבחירות אינה שגויה בכל מקרה. במדריך שהקוראים שלו יעתיקו את הקוד לפרויקט שלהם, הערות מתורגמות עוזרות. בתיעוד עזר שהקוד שלו חייב להתאים למאגר, הן גורמות לדף שלא להסכים עם המקור. קבלו את ההחלטה פעם אחת עבור הפרויקט, ובדקו בעין ערכי מחרוזות בדוגמאות תצורה, כי שום כלי לא יכול להבחין בין תווית תצוגה למזהה. הבודק מדווח על שינויים בהערות בלבד כאזהרות מהסיבה הזו.

3. השיטה שנראית בטוחה שברה את ה-front matter

התנאי המוגן עשה מה שהבטיח: כל 32 ממלאי המקום חזרו בכל שלוש ההרצות, כך שהקוד, כתובות ה-URL והתגים שוחזרו בצורה מושלמת. אבל הסקריפט שלנו השאיר שני דברים קטנים מחוץ לממלאי המקום: שורת ה---- שפותחת את ה-front matter, וסימן הציטוט הסוגר אחרי הכותרת והתיאור המתורגמים. המודל השמיט את כולם בכל שלוש ההרצות. הקובץ התחיל כך:

title: "导出您的书库
description: "在更换设备之前,请备份您的笔记和书籍。
slug: export-library

בלי ה---- הפותח, מנתח Markdown כבר לא רואה front matter. הוא קורא את שש שורות ה-YAML יחד עם ה---- הסוגר ככותרת, כך שהדף ייפתח עם כותרת גדולה שמכילה את ה-YAML. הוא עדיין הידור כ-MDX. גם החזרת ה---- לא מספיקה: מנתח ה-YAML דוחה את שני הציטוטים הלא סגורים.

הלקח אינו להימנע מממלאי מקום. הלקח הוא שכל מה שאתם משאירים חשוף עלול לחזור כששונה, ושה-front matter לא צריך ללכת למודל כחלק מהדף בכלל. נתחו אותו, שלחו רק את הערכים הפונים לקורא (title, description) כמחרוזות נפרדות, וכתבו את התרגומים חזרה לתוך המבנה המקורי. זה כמה שורות קוד ומסיר את כל סוג הבעיות.

טקסט מודגש וטווחים בסינית, יפנית וקוריאנית

שתי בעיות נוספות מעולם לא הופיעו בתשע ההרצות שלנו, אבל כדאי לבדוק אותן כי הן שוברות דפים בשקט, ושתיהן פגעו בבלוג של BookTranslator עצמו. הבלוג כתוב ב-MDX ומתורגם במכונה ל-27 שפות, ובהרצת תרגום מתוזמנת אחת שני מאמרים בקוריאנית נכשלו בבדיקת המבנה שלנו שלוש פעמים ברצף. הסיבות היו שתי התבניות שלהלן.

מודגש שמסתיים בפיסוק. ‏CommonMark מחליט אם ** יכול לפתוח או לסגור מודגש לפי התווים משני צדדיו. ** סוגר שמופיע מיד אחרי פיסוק חייב להיות אחריו רווח, פיסוק או סוף השורה; זהו כלל הצד הימני. באנגלית תמיד יש שם רווח. בסינית, ביפנית ובקוריאנית לרוב אין. לכן 打开**设置 → 导出(测试版)**并选择 מציג כוכביות ממשיות, כי המודגש מסתיים בסוגריים ברוחב מלא ומיד אחריו בא 并. אותה שורה בלי הסוגריים מוצגת כמודגשת, וכך גם השורה עם רווח אחרי ה-**. לקישור מודגש יש אותה בעיה, כי קישור מסתיים ב-): ‏点击**[导出](./export-options.md)**打开 נכשל, וכך גם הקוריאני **[API](./api.md)**는.

המודל שלנו במקרה שם רווח משני צדי כל ביטוי מודגש, כך שהפלט שלו הוצג כראוי. עורך שמאוחר יותר מסיר את הרווחים האלה כדי לפעול לפי מוסכמות הסדר הטיפוגרפי הסיני מחזיר את הבאג. אפשר לנסות את כל שבעת הווריאנטים ב-render-cases.md.

טווחי מספרים עם טילדה. טקסט סיני ויפני מרבה לכתוב טווחים כ-3~5. אתרי GitHub Flavored Markdown המבוססים על remark הופכים טילדות בודדות לקו חוצה כברירת מחדל: האפשרות singleTilde של remark-gfm היא true אלא אם משנים אותה. שני טווחים בפסקה אחת, כגון 需要 3~5 分钟,生成 10~20 MB 的文件夹, מוצגים כשהטקסט שביניהם מחוצה. הדוגמה שלנו השתמשה במקפים ארוכים, ושמונה הרצות שמרו עליהם בעוד התשיעית כתבה 3 到 5. בקשו מקפים ארוכים או מילים בטווחים, או הגדירו singleTilde: false בהגדרות ה-remark שלכם.

הבודק המבני מסמן את שני הדפוסים. כדי לאמת מה באמת מוצג, render_check.mjs סופר מודגש, נטוי, קו חוצה וכוכביות שנותרו במקור ובתרגום, ומנסה קומפילציית MDX:

npm install @mdx-js/mdx@3 unified@11 remark-parse@11 remark-gfm@4
node render_check.mjs source.mdx translated.mdx

פחות צמתי מודגש או יותר כוכביות ממשיות בתרגום פירושם שההדגשה הפסיקה להיסגר.

תהליך עבודה שעומד במבחן

  1. תקנו קודם את מזהי הכותרות. הוסיפו מזהים מפורשים לכל כותרת שמשהו מקשר אליה, בתחביר שהמחולל של האתר שלכם תומך בו. עשו זאת בשפת המקור, פעם אחת, וקבעו זאת ב-commit לפני שמתרגמים משהו.

  2. הוציאו את ה-front matter מהעמוד. תרגמו רק ערכים הפונים לקורא כגון title ו-description, כמחרוזות נפרדות, וכתבו אותם חזרה ל-YAML המקורי.

  3. החליטו את מדיניות הקוד. הערות מתורגמות או לא; מחרוזות תצוגה בדוגמאות תצורה מתורגמות או לא. כתבו זאת במילון התרגום שלכם לצד שמות המוצרים שאסור לשנות, כגון Shelfmark בדוגמה שלנו.

  4. תרגמו את הגוף. השתמשו בכלי שמנתח Markdown, או שלחו את העמוד כולו עם כללים מפורשים. בבדיקה שלנו, שליחת העמוד כולו שמרה על התחביר intact; אם אתם משתמשים במצייני מקום, הגנו על מבנים שלמים ואל תשאירו דבר חשוף למחצה.

  5. הריצו את הבדיקה המבנית.

    python3 check_markdown_translation.py source.mdx translated.mdx --keep Shelfmark
    

    היא משווה מפתחות וערכים של front matter, ייבואים, בלוקי קוד, קוד בתוך שורה, יעדי קישורים, הגדרות ייחוס, רמות כותרות, יעדי קישורים בתוך העמוד, תגי JSX ותכונותיהם, הערות MDX, סמני admonition, תוויות הערות שוליים, צורת טבלה, תיבות רשימת משימות, שבירות שורה קשיחות, הדגשה שאינה יכולה להיסגר, טווחי טילדה ומונחים שביקשתם לשמור. היא אינה שופטת את איכות התרגום.

  6. בדקו את ההצגה עבור יעדי CJK עם render_check.mjs, והוסיפו רווח אחרי כל ** סוגר שבא אחרי פיסוק.

  7. בנו את האתר ולחצו על הקישורים. פתחו את העמוד בכל שפה, לחצו על כל קישור בתוך העמוד וקראו את דוגמאות התצורה. בנייה שמצליחה מוכיחה רק שהקובץ מתקמפל.

עבור תיעוד שבו�יוק חשוב, שלבי המינוח והסקירה בתהליך העבודה לתרגום טכני שלנו חלים בנוסף לזה.

איפה BookTranslator משתלב

מתרגם ה-TXT של BookTranslator מקבל קבצי .txt, .md ו-.mdx. לפי עמוד המוצר, הוא מתרגם אותם תוך שמירה על פסקאות, שבירות שורה, תווים מיוחדים ומבנה הטקסט, והוא מפצל קבצים גדולים למקטעים לתרגום מודע-הקשר, כך שאפשר להעלות מדריך שלם או ספר שנכתב ב-Markdown במקום להדביק אותו בחתיכות.

עמוד המוצר אינו מתאר טיפול מיוחד ב-front matter, בבלוקי קוד או ברכיבי MDX, ולא הרצנו את הדוגמה הזו דרך BookTranslator עבור מאמר זה. בכל כלי שתשתמשו, עשו את שלבים 1 עד 3 לפני התרגום ואת שלבים 5 עד 7 אחריו. כותרת בלי מזהה קבוע עדיין מאבדת את הקישורים שלה, וטווח שנכתב עם טילדות עדיין הופך לקו חוצה. אם אתם מפרסמים ספר בכמה שפות, המדריך שלנו לפרסום עצמי בכמה שפות מכסה את שאר העבודה.

קבלו את קבצי הבדיקה

הכול מהבדיקה הזו חופשי לשימוש חוזר:

פוסטים קשורים