BookTranslator
BookTranslator

چگونه فایل‌های مارک‌داون را بدون خراب کردن کد، پیوندها یا فراداده ترجمه کنیم

چه چیزی را در یک فایل مارک‌داون یا MDX ترجمه کنیم، چه چیزی را دست نزنیم، و چگونه نتیجه را بررسی کنیم. همراه با یک فایل نمونه، یک بررسی‌کننده رایگان، و یک آزمون ۹ باره با مدل زبانی محلی.

BookTranslator

BookTranslator Team

14 min read

برای ترجمه یک فایل مارک‌داون، متن اصلی را ترجمه کنید و ساختار فنی را دست نزنید: کلیدهای فراداده، کد، نشانی‌های اینترنتی، برچسب‌های پیوند، تگ‌های کامپوننت، و برچسب‌های پانویس باید بایت به بایت بازگردانده شوند. سپس سه چیز را بررسی کنید که حتی یک ترجمه دقیق هم خراب می‌کند: پیوندها به سرتیترها، توضیحات کد، و در زبان‌های چینی، ژاپنی یا کره‌ای، فاصله‌گذاری اطراف متن پررنگ و بازه‌های عددی.

ما یک صفحه MDX ۷۳ خطی را نه بار با یک مدل محلی به چینی ساده‌شده ترجمه کردیم، با استفاده از سه اعلان مختلف، و هر نتیجه را با یک اسکریپت بررسی کردیم. بخش‌هایی که معمولاً نگرانی ایجاد می‌کنند در هر نه اجرا سالم ماندند: کد، کد درون‌خطی، نشانی‌های اینترنتی، جدول، کامپوننت JSX، و فهرست وظایف. سه چیز دیگر اشتباه پیش رفت. پیوند به یک سرتیتر در هر نه اجرا خراب شد. توضیحات کد در هر شش اجرایی که کل فایل ارسال شد ترجمه شدند، از جمله سه اجرا که در اعلان گفته شده بود به کد دست نزنید. و اعلانی که نحو را پشت جایگزین‌کننده‌ها پنهان می‌کرد، که به نظر ایمن‌ترین گزینه می‌رسد، فراداده را در هر سه اجرایش خراب کرد.

پاسخ سریع: چه چیزی را ترجمه کنیم و چه چیزی را دست نزنیم

بخشی از فایلنمونه از فایل نمونه ماترجمه شود؟
کلیدهای فرادادهslug:, sidebar_position:, tags:خیر
مقادیر فرادادهtitle: "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] و نشانی اینترنتی را نگه دارید؛ متن قابل مشاهده را ترجمه کنید
عنوان‌ها## 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. دستورالعمل‌دار. همان، به‌علاوه شش قانون: کلیدهای فراداده را حفظ کن، هیچ چیز داخل کد را تغییر نده، URLها و تعاریف مرجع را حفظ کن، importها، تگ‌ها و نظرات را حفظ کن، برچسب‌های پانویس و نشانگرهای هشدار را حفظ کن، و عنوان‌ها، متن پیوند، متن جایگزین و ویژگی title را ترجمه کن.
  3. محافظت‌شده. کد، کد درون‌خطی، URLها، تگ‌ها، نظرات، برچسب‌های پانویس، نشانگرهای هشدار و خطوط فراداده را با جای‌نگهدارهای شماره‌دار مانند ⟦12⟧ جایگزین کنید، بقیه را ترجمه کنید، سپس اصل‌ها را برگردانید. مقادیر title و description برای ترجمه در معرض دید قرار گرفتند، و همان‌طور که معلوم شد، خطوط --- فراداده و علامت‌های نقل‌قول پایانی نیز.

مدل Qwen 3.6 27B (Q4_K_M) در LM Studio بود، با تفکر خاموش و دمای 0.3، روی یک Apple M4 Max با 64 گیگابایت حافظه. هر شرایط را سه بار اجرا کردیم، در مجموع نه اجرا، در 25 اکتبر 2026. اسکریپت run_llm_markdown_test.py است، و هر نه خروجی ویرایش‌نشده منتشر شده‌اند؛ README هر فایل را فهرست می‌کند. اگر هرگز مدل محلی راه‌اندازی نکرده‌اید، راهنمای ترجمه با LLM محلی ما تنظیمات را پوشش می‌دهد.

این یک آزمایش کوچک از یک مدل، یک جفت زبان و یک صفحه بود. نشان می‌دهد چه مشکلاتی رخ می‌دهد و چگونه آن‌ها را بگیریم. مدل‌ها یا دستورالعمل‌ها را رتبه‌بندی نمی‌کند.

نتیجه: نحو جان سالم به در برد؛ پیوندها و تصمیم‌ها نه

ما هر خروجی را با check_markdown_translation.py بررسی کردیم و هر یک را با remark و کامپایلر MDX رندر کردیم. خروجی کامل بررسی‌کننده در check-results.txt است، و results.csv یک ردیف به ازای هر اجرا دارد.

بررسیکل فایلدستور داده شدهمحافظت شده
به عنوان MDX کامپایل می‌شود۳ از ۳۳ از ۳۳ از ۳
کد، کد درون‌خطی، URLها، جدول، تگ‌ها، لیست وظایف بدون تغییر۳ از ۳۳ از ۳۳ از ۳
پررنگ و کج همچنان نمایش داده می‌شوند۳ از ۳۳ از ۳۳ از ۳
فرانت‌متر دست‌نخورده۳ از ۳۳ از ۳۰ از ۳
لینک درون‌صفحه‌ای همچنان به سرتیتر خود اشاره می‌کند۰ از ۳۰ از ۳۰ از ۳
کامنت‌های کد همان‌طور که نوشته شده‌اند باقی می‌مانند۰ از ۳۰ از ۳۳ از ۳
عنوان title کال‌اوت ترجمه شد۳ از ۳۳ از ۳۰ از ۳

ردیف‌های اول خبر خوب هستند. این مدل وقتی کل فایل را جای‌گذاری کردیم، نحو Markdown را دست‌نخورده برگرداند؛ در کد، URLها یا جدول‌ها چیزی برای اصلاح پیدا نکردیم. چهار ردیف آخر جایی است که کار واقعی آنجاست، و هیچ‌کدام از آن‌ها هنگام ساخت سایت به‌عنوان خطا ظاهر نمی‌شود.

۱. عنوان‌های ترجمه‌شده پیوندهای منتهی به آن‌ها را می‌شکنند

نمونه با [glossary section](#keep-one-glossary-for-the-whole-book) به بخش واژه‌نامه خود پیوند می‌دهد. هر اجرا عنوان را ترجمه کرد، همان‌طور که باید، و هر اجرا هدف پیوند را حفظ کرد، همان‌طور که باید. نتیجه پیوندی به شناسه‌ای است که دیگر وجود ندارد.

بیشتر ابزارهای Markdown شناسه‌های عنوان را از متن عنوان می‌سازند. مستندات Pandoc شناسه را «بر اساس متن عنوان» توصیف می‌کند، و Docusaurus هشدار می‌دهد که ممکن است بخواهید عنوانی را تغییر دهید یا ترجمه کنید «بدون به‌روزرسانی شناسه موجود تا از شکستن پیوندها جلوگیری شود.» وقتی عنوان به 为整本书保留一个术语表 تبدیل شود، شناسه تولیدشده آن چینی است، و #keep-one-glossary-for-the-whole-book به جایی اسکرول نمی‌شود. صفحه هنوز ساخته می‌شود، بنابراین هیچ چیزی به شما نمی‌گوید.

این را نمی‌توانید با ویرایش پیوند پس از ترجمه هم درست کنید. در طول نه اجرا، مدل همان عنوان را به چهار روش مختلف نوشت، بنابراین شناسه تولیدشده با هر ترجمه مجدد دوباره تغییر می‌کرد. راه‌حل باید پیش از ترجمه باشد: به هر عنوانی که به آن پیوند داده می‌شود یک شناسه ثابت بدهید.

  • در Docusaurus MDX، از ## Keep one glossary for the whole book {/* #keep-one-glossary */} استفاده کنید. Docusaurus اشاره می‌کند که شکل قدیمی‌تر {#id} «دیگر نحو معتبر MDX نیست»، و دستور write-heading-ids آن شناسه‌ها را برای شما به هر سند اضافه می‌کند.
  • در Pandoc و در پردازشگرهای Markdown که از PHP Markdown Extra پیروی می‌کنند، از {#keep-one-glossary} در انتهای عنوان استفاده کنید.

سپس شناسه در هر زبانی یکسان می‌ماند، و بررسی‌کننده آن را به‌عنوان هدف پیوند در نظر می‌گیرد.

۲. نظرات کد ترجمه می‌شوند، و رشته قابل مشاهده نمی‌شود

نمونه یک نظر شل و یک نظر YAML دارد:

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

هر شش اجرایی که کل فایل را فرستادند هر دو نظر را ترجمه کردند، از جمله سه موردی که در دستورالعمل گفته بود «هیچ چیزی را داخل بلوک‌های کد محصور تغییر ندهید.» خود کد در هر نه اجرا دست‌نخورده بود. در همین حال "My books" که طبق نظر در نوار کناری نمایش داده می‌شود، در هر نه اجرا به انگلیسی ماند. مدل برعکس آنچه یک صفحه بومی‌سازی‌شده نیاز دارد عمل کرد: یادداشت برای توسعه‌دهندگان را ترجمه کرد و برچسبی را که خوانندگان می‌بینند رها کرد.

هیچ‌کدام از این انتخاب‌ها در همه موارد اشتباه نیست. برای آموزشی که خوانندگانش کد را در پروژه خود کپی می‌کنند، نظرات ترجمه‌شده کمک می‌کنند. برای مستندات مرجعی که کدش باید با یک مخزن مطابقت داشته باشد، باعث می‌شوند صفحه با منبع ناسازگار شود. یک‌بار برای پروژه تصمیم بگیرید، و مقادیر رشته‌ای را در نمونه‌های پیکربندی به‌صورت دستی بررسی کنید، زیرا هیچ ابزاری نمی‌تواند برچسب نمایشی را از شناسه تشخیص دهد. به همین دلیل بررسی‌کننده تغییرات فقط-نظر را به‌عنوان هشدار گزارش می‌دهد.

۳. روش به‌ظاهر ایمن، فرانت‌متر را شکست

شرط محافظت‌شده به وعده‌اش عمل کرد: هر ۳۲ جای‌نگهدار در هر سه اجرا بازگشتند، بنابراین کد، URLها و تگ‌ها کاملاً بازیابی شدند. اما اسکریپت ما دو چیز کوچک را بیرون از جای‌نگهدارها گذاشت: خط --- که فرانت‌متر را باز می‌کند، و علامت نقل‌قول پایانی پس از عنوان و توضیحات ترجمه‌شده. مدل همه آن‌ها را در هر سه اجرا حذف کرد. فایل این‌گونه شروع می‌شد:

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

بدون --- ابتدایی، یک تجزیه‌کننده Markdown دیگر فرانت‌متر را نمی‌بیند. شش خط YAML به‌همراه --- پایانی را به‌عنوان یک عنوان می‌خواند، بنابراین صفحه با یک عنوان بزرگ حاوی YAML باز می‌شود. هنوز به‌عنوان MDX کامپایل می‌شد. برگرداندن --- هم کافی نیست: تجزیه‌کننده YAML دو نقل‌قول بسته‌نشده را رد می‌کند.

درس این نیست که از جای‌نگهدارها اجتناب کنید. این است که هر چیزی که در معرض دید قرار می‌دهید ممکن است تغییرکرده بازگردد، و فرانت‌متر اصلاً نباید به‌عنوان بخشی از صفحه به مدل برود. آن را تجزیه کنید، فقط مقادیر رو به خواننده (title، description) را به‌صورت رشته‌های جداگانه بفرستید، و ترجمه‌ها را دوباره در ساختار اصلی بنویسید. این چند خط کد است و کل این دسته از مشکلات را حذف می‌کند.

متن پررنگ و بازه‌ها در چینی، ژاپنی و کره‌ای

دو مشکل دیگر هرگز در نه اجرای ما ظاهر نشدند، اما ارزش بررسی دارند زیرا صفحات را بی‌صدا می‌شکنند، و هر دو به وبلاگ خود BookTranslator ضربه زده‌اند. وبلاگ به زبان MDX نوشته شده و به ۲۷ زبان به‌صورت ماشینی ترجمه می‌شود، و در یک اجرای ترجمه زمان‌بندی‌شده دو مقاله کره‌ای سه بار پیاپی در بررسی ساختار ما شکست خوردند. علت‌ها دو الگوی زیر بودند.

پررنگ‌هایی که با علامت نگارشی تمام می‌شوند. 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 的文件夹، با متنِ بین آن‌ها خط‌خورده نمایش داده می‌شود. نمونهٔ ما از خط تیرهٔ en استفاده کرد و هشت اجرا آن را حفظ کردند در حالی که اجرای نهم 3 到 5 نوشت. برای بازه‌ها خط تیرهٔ en یا کلمه بخواهید، یا 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. ابتدا شناسه‌های عنوان را اصلاح کنید. به هر عنوانی که چیزی به آن پیوند می‌دهد شناسهٔ صریح بدهید، با نحوی که مولد سایت شما پشتیبانی می‌کند. این کار را در زبان مبدأ، یک بار، انجام دهید و پیش از هر ترجمه‌ای کامیت کنید.

  2. فرانت‌متر را از صفحه بیرون بکشید. فقط مقادیر رو به خواننده مانند title و description را به‌صورت رشته‌های جداگانه ترجمه کنید و آن‌ها را به YAML اصلی برگردانید.

  3. سیاست کد را تعیین کنید. توضیحات ترجمه شوند یا نه؛ رشته‌های نمایشی در نمونه‌های پیکربندی ترجمه شوند یا نه. آن را در واژه‌نامهٔ ترجمه خود کنار نام محصولاتی که نباید تغییر کنند، مانند Shelfmark در نمونهٔ ما، بنویسید.

  4. متن را ترجمه کنید. از ابزاری استفاده کنید که Markdown را تجزیه می‌کند، یا کل صفحه را با قواعد صریح بفرستید. در آزمون ما، فرستادن کل صفحه نحو را دست‌نخورده نگه داشت؛ اگر از جای‌نگهدارها استفاده می‌کنید، ساختارهای کامل را محافظت کنید و هیچ چیز را نیمه‌آشکار نگذارید.

  5. بررسی ساختاری را اجرا کنید.

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

    این بررسی کلیدها و مقادیر فرانت‌متر، importها، بلوک‌های کد، کد درون‌خطی، مقصد پیوندها، تعاریف مرجع، سطوح عنوان، مقصد پیوندهای درون‌صفحه، تگ‌ها و ویژگی‌های JSX، توضیحات MDX، نشانگرهای هشدار، برچسب‌های پانویس، شکل جدول، جعبه‌های فهرست کار، شکست خط سخت، تأکیدهایی که نمی‌توانند بسته شوند، بازه‌های مدک و اصطلاحاتی که می‌خواهید حفظ شوند را مقایسه می‌کند. کیفیت ترجمه را داوری نمی‌کند.

  6. نمایش را برای زبان‌های مقصد CJK با render_check.mjs بررسی کنید و پس از هر ** پایانی که پس از علامت نگارشی می‌آید یک فاصله اضافه کنید.

  7. سایت را بسازید و پیوندها را کلیک کنید. صفحه را در هر زبان باز کنید، هر پیوند درون‌صفحه را کلیک کنید و نمونه‌های پیکربندی را بخوانید. ساختی که موفق می‌شود فقط ثابت می‌کند فایل کامپایل می‌شود.

برای مستنداتی که دقت مهم است، مراحل اصطلاح‌شناسی و بازبینی در گردش کار ترجمهٔ فنی ما روی این افزوده می‌شود.

جایگاه BookTranslator

مترجم TXT BookTranslator فایل‌های .txt، .md و .mdx را می‌پذیرد. طبق صفحهٔ محصول، آن‌ها را با حفظ پاراگراف‌ها، شکست خط، نویسه‌های ویژه و ساختار متن ترجمه می‌کند و فایل‌های بزرگ را به بخش‌هایی برای ترجمهٔ آگاه به زمینه تقسیم می‌کند، بنابراین می‌توانید یک کتابچهٔ راهنمای کامل یا کتابی نوشته‌شده در Markdown را آپلود کنید به‌جای اینکه تکه‌تکه بچسبانید.

صفحهٔ محصول رفتار ویژه‌ای برای فرانت‌متر، بلوک‌های کد یا اجزای MDX توصیف نمی‌کند و ما این نمونه را برای این مقاله از BookTranslator عبور ندادیم. هر ابزاری که استفاده می‌کنید، مراحل ۱ تا ۳ را پیش از ترجمه و مراحل ۵ تا ۷ را پس از آن انجام دهید. عنوانی بدون شناسهٔ ثابت همچنان پیوندهایش را از دست می‌دهد و بازه‌ای که با مدک نوشته شده همچنان به خط‌خورده تبدیل می‌شود. اگر کتابی را به چند زبان منتشر می‌کنید، راهنمای خودانتشار چندزبانه ما بقیهٔ این کار را پوشش می‌دهد.

فایل‌های آزمون را دریافت کنید

همه‌چیز از این آزمون برای استفادهٔ مجدد آزاد است:

مطالب مرتبط