Arabic-ready 輸出
目標:阿拉伯語在任何輸出格式中都能於第一次嘗試時正確渲染、可讀且感覺自然。
1. 撰寫任何內容前先決定三件事
| 決定 | 預設值 | 何時變更 |
|---|---|---|
| 受眾地區設定 | ar + 已知的地區(如 ar-SA、ar-EG、ar-AE、ar-MA...) | 使用者指定國家/城市/市場 |
| 數字系統 | 西部數字 0-9 用於 UI、價格、電話、程式碼、圖表。阿拉伯-印度數字 ٠-٩ 用於針對埃及、沙烏地阿拉伯、伊拉克、黎凡特、蘇丹、葉門的正式/編輯文字 | 使用者要求,或品牌/地區明確使用 ٠-٩。馬格里布(MA/DZ/TN)一律使用 0-9 |
| 語言風格 | 現代標準阿拉伯語(فصحى),清晰且現代,非古典 | 使用者要求方言(埃及、海灣、黎凡特...)或管道為非正式場合(WhatsApp 推廣、社群貼文):請參閱 references/writing.md |
切勿在同一份輸出中混合使用兩種數字系統。
2. 核心規則(適用於所有輸出類型)
- 在根元素宣告方向一次。 然後讓所有元素繼承。
❌
<html>+ 分散在各元素上的style="direction:rtl"✅<html lang="ar" dir="rtl">· docx<w:bidi/>+<w:rtl/>· pptxrtl="1"· FlutterDirectionality(textDirection: TextDirection.rtl)/locale: Locale('ar') - 使用邏輯方向,絕不使用左/右。 在阿拉伯語中「起始」是右側。
❌
margin-left、ml-4、text-left、left: 0、EdgeInsets.only(left:)✅margin-inline-start、ms-4、text-start、inset-inline-start: 0、EdgeInsetsDirectional.only(start:) - 隔離 LTR 孤島(電話號碼、電子郵件、URL、程式碼、數字旁的英文名稱、負數)。
❌
اتصل على +966 50 123 4567.→ 顯示為4567 123 50 966+✅اتصل على <bdi dir="ltr">+966 50 123 4567</bdi>.· 純文字:包裹在 LRI…PDI(…)中,或在-5前放置 LRM - 電話、電子郵件、URL、程式碼、IBAN、密碼的輸入框應保持
dir="ltr",即使在 RTL 表單內(使用text-end對齊)。 - 僅鏡像方向性圖示。 前進/後退箭頭、V 形符號、傳送、回覆、復原/重做、進度方向會翻轉。播放/暫停、媒體控制、勾選標記、時鐘、搜尋、標誌、品牌標記和數字則不變。
- 排版: 使用專為阿拉伯語設計的字體(列表見
references/typography.md),正文行高 ≥ 1.6,並為上下加符號(tashkeel)預留空間。切勿對阿拉伯語套用字母間距/tracking-*、uppercase、italic或緊密的overflow:hidden高度。 - 字形整形:原始文字給整形渲染器,整形後文字給其他渲染器。絕不兩者皆用。
瀏覽器、Word、LibreOffice、PowerPoint、WeasyPrint、Chromium PDF、matplotlib ≥ 3.11、具 libraqm 的 Pillow、具
set_text_shaping()的 fpdf2 會自行處理阿拉伯語整形:傳入原始字串。 reportlab、PyMuPDF 的insert_text、OpenCV、matplotlib ≤ 3.10、不具 raqm 的 Pillow 則逐個字形繪製:傳入scripts/shape_text.py中prepare(text)的結果。 對已進行整形的渲染器再次整形會導致反向(已在 matplotlib 3.11 及 Pillow+raqm 中驗證)。 - 阿拉伯語標點符號: 使用
،逗號、؛分號、؟問號、«»引號。保留.和!。標點符號前不空格,後加一個空格。 - 以阿拉伯語原生寫法撰寫,不要逐字翻譯。 按鈕使用命令式動詞(
أرسل、احفظ、ابدأ الآن),不要使用英文語序。請參閱references/writing.md。 - 使用地區設定格式化數字/日期/貨幣,不要用字串串接。 使用
Intl.NumberFormat('ar-SA', ...)/Intl.DateTimeFormat('ar-EG-u-nu-latn', ...),並務必明確設定nu(數字)和ca(曆法)。
3. 根據你的輸出類型載入參考文件
僅閱讀任務所需的文件:
| 輸出 | 閱讀 |
|---|---|
| HTML、CSS、Tailwind、React、Next.js、Vue、React Native、Flutter、電子郵件 HTML | references/web.md + references/bidi.md |
| 任何地方混合阿拉伯語 + 英語/數字(包括 markdown、純文字、SMS、JSON 字串) | references/bidi.md |
| 字體、行高、加符號、字重、左右對齊 | references/typography.md |
| Word (.docx)、PowerPoint (.pptx)、PDF | references/documents.md |
| matplotlib、Pillow、SVG、canvas、OpenCV、Plotly、任何包含文字的圖片 | references/charts-images.md |
| 文案寫作、翻譯、方言、數字、日期、貨幣、姓名、伊斯蘭曆 | references/writing.md |
4. RTL 中什麼會翻轉、什麼不會
| 翻轉(鏡像版面) | 保持不變 |
|---|---|
| 閱讀順序、文字對齊、導航順序、側邊欄位置 | 電話號碼、信用卡號、IBAN(始終為 LTR) |
麵包屑導航、分頁、步驟指示器:「下一頁」指向左。文字 › > ( 會自動鏡像,但 → 與 SVG 圖示則否 | 程式碼區塊、終端機輸出、URL、電子郵件 |
| 返回/下一頁箭頭、V 形符號、輪播/滑桿滑動方向 | 時間序列圖表 x 軸(時間從左往右)。類別軸可能翻轉 |
| 表格欄位順序(第一欄在右側) | 媒體控制(播放 ▶、快轉)、時鐘、勾選標記 |
| 進度條與範圍滑桿從右側開始填充 | 標誌、品牌標記、照片、地圖 |
表單標籤在右側,對話框關閉按鈕 × 在左側 | 數學表達式與數字本身(1,234.5 保持 1,234.5) |
| Toast/抽屜滑入側、頭像上的徽章、列表項目符號 | 鍵盤快捷鍵(Ctrl+S) |
5. 完成前
- 對你產生的任何程式碼執行 linter(它僅需 Python 標準程式庫):
python <skill-dir>/scripts/rtl_check.py <file-or-folder>修正所有error。除非有意為之,否則修正warning,並對有意為之的警告加上rtl-ok註解。 - 盡可能渲染並檢視,然後檢查字母是否相連、第一個單字是否在右側、標點符號是否在左端、數字是否以正確順序顯示:
- HTML:
python -m playwright screenshot --full-page file://$PWD/index.html shot.png(或npx playwright screenshot …)。若無瀏覽器可用,則使用weasyprint index.html out.pdf產生靜態渲染。 - docx/pptx:
soffice --headless --convert-to pdf file.docx,然後將 PDF 轉為點陣圖。 - PDF → PNG:
python -c "import pymupdf; pymupdf.open('f.pdf')[0].get_pixmap(dpi=110).save('f.png')" - 圖片/圖表:開啟您寫入的 PNG 檔案。
- HTML:
- 若指令稿無法執行(無 Python、無 shell),請手動檢查此檢查清單:
- 根元素
dir="rtl"+lang="ar…"(或該格式的等效設定) - 間距、定位或對齊中未使用
left/right - 電話/電子郵件/URL/程式碼已隔離且為 LTR
- 方向性圖示已鏡像,其餘未更動
- 已載入阿拉伯字體,行高 ≥ 1.6,無字母間距、斜體或大寫
- 圖片/PDF 文字:整形路徑與渲染器相符(規則 7)
- 使用
،؛؟,採用單一數字系統,使用自然的 MSA(或要求的方言)
- 根元素
指令稿
scripts/rtl_check.py <path>:對 HTML/CSS/Tailwind/JSX/TSX/Vue/Svelte/React Native/Flutter 進行 RTL 錯誤檢查。輸出檔案:行號、問題與確切修復方式。錯誤時 exit code 為 1。僅使用標準程式庫。scripts/shape_text.py:prepare(text, target)用於不進行阿拉伯語整形的渲染器。它會偵測 matplotlib/Pillow 的原生支援,並在不需要整形時原樣回傳文字。它使用arabic-reshaper+python-bidi(按需 pip 安裝),或回退至內建的 stdlib 整形器。執行python shape_text.py --check可報告此機器所需內容。