integrate the skills
split the review skills into self- and other- the self- variant makes informational comments the other- variant makes nice comments Google docs is a failure
This commit is contained in:
@@ -0,0 +1,248 @@
|
||||
---
|
||||
name: self-review
|
||||
description: Review your own CN→EN translations — three-pass review (terminology → mechanical → flow). Edit commented.dj with patch. For reviewing someone else's work, load other-review.
|
||||
---
|
||||
|
||||
{% Serves AGENTS.md Workflow B1 (Self-Review) %}
|
||||
|
||||
# Self-Review(自审)
|
||||
|
||||
Review YOUR OWN translations. You created the English — you can edit freely.
|
||||
For reviewing someone else's work, load `other-review` instead.
|
||||
|
||||
Two input formats: CSV/XLSX batch, or `.dj` comparison file.
|
||||
|
||||
`bilingual.dj` is script-generated ground truth — **never edit it.**
|
||||
Copy to `commented.dj` for all review work. Always use `patch` (mode='replace')
|
||||
for edits — not regex-based string replacement in `execute_code`.
|
||||
|
||||
## Workflow A: CSV/XLSX batch review
|
||||
|
||||
Use when input is a CSV/XLSX with `Chinese`/`English` columns. Produces an `edit-suggestions.dj` file.
|
||||
|
||||
### 1. Get the data into CSV
|
||||
|
||||
If XLSX, export to CSV (or use `openpyxl`). CSV is faster.
|
||||
|
||||
### 2. Read the full file
|
||||
|
||||
Use `read_file` with offsets for complete coverage. Don't sample.
|
||||
|
||||
### 3. Write a systematic analysis script
|
||||
|
||||
Write to `/tmp/script.py`, run with `python3 /tmp/script.py`. No heredocs or `-c`.
|
||||
The script should:
|
||||
- Parse CSV with `csv.DictReader`
|
||||
- Apply detection rules per category
|
||||
- Collect issues: row number, CN text, EN text, problem, suggested fix
|
||||
- Group/deduplicate identical issues
|
||||
|
||||
Common detection categories:
|
||||
- **Buddhist terminology**: 正念→mindfulness (not "righteous thoughts"), 布施→generosity (not "alms")
|
||||
- **Identity terms**: 学士/修士/胜士/智士 are practice stages, not titles
|
||||
- **Literal machine translations**: "hard drive" for 硬盘 (endurance)
|
||||
- **四摄法 terms**: 同事→"acting in harmony", 爱语→"kind speech"
|
||||
- **Grammar**: subject-verb agreement, unbalanced quotes
|
||||
- **Typos/formatting**: Chinese punctuation in English, "IOS"→"iOS"
|
||||
- **Inconsistency**: same CN term translated differently across rows
|
||||
|
||||
### 4. Write edit-suggestions.dj
|
||||
|
||||
Format:
|
||||
```
|
||||
# 1
|
||||
|
||||
original: <Chinese text or key term>
|
||||
translated: <current English>
|
||||
|
||||
<Explanation and suggested fix.>
|
||||
|
||||
# 2
|
||||
...
|
||||
```
|
||||
|
||||
One entry per problem category, not per row. Mention affected row numbers.
|
||||
|
||||
## Workflow B: .dj file review (self-review)
|
||||
|
||||
Use when you translated the text and want to review your own work.
|
||||
|
||||
### File rules
|
||||
|
||||
1. `bilingual.dj` — extracted from script. **Never edit.**
|
||||
2. `cp bilingual.dj commented.dj` — all edits go here
|
||||
3. `{% ... %}` comments document non-obvious translation choices
|
||||
|
||||
### 1. Read the full file
|
||||
|
||||
Use `read_file` with `offset` and `limit` for full coverage of large files
|
||||
(this session had 322 lines, 93KB). For files >200 lines, paginate
|
||||
explicitly rather than reading the whole thing at once.
|
||||
|
||||
If you have already read part of the file with `read_file` earlier in the
|
||||
session, use `terminal: cat` (or `sed -n 'A,Bp'`) to get an un-deduped view
|
||||
of the rest. `read_file` deduplicates within a session.
|
||||
|
||||
### 2. Scan for problems — three passes, in order
|
||||
|
||||
The review is best done in three distinct passes, each catching a different
|
||||
category of error. Don't try to catch everything in one scan.
|
||||
|
||||
**Pass 1 — terminology + consistency + line count** (fast, mechanical):
|
||||
- **Line count**: source and target must match exactly. Mismatch means paragraphs were dropped, merged, or split.
|
||||
- Same CN term translated differently across the file (e.g. 人生佛教/人间佛教 conflation, 恨→resentment, 修行/修学)
|
||||
- Buddhist terminology against the MPI terms DB (see terms-db-alignment below)
|
||||
- Mistranslation of key terms, wrong proper names, garbled text
|
||||
- Mid-paragraph truncation: CN covers 3–5 clauses but EN stops after 1–2 sentences. Signal: CN has quoted speech, poems, or a rhetorical climax absent from EN. Flag as "Missing Content" not "Incomplete."
|
||||
- Use `references/common-issues-taxonomy.md` as a structured checklist for accuracy issues
|
||||
|
||||
**Pass 2 — mechanical/formatting** (also mechanical, but easy to skip):
|
||||
- TOC format: AGENTS.md says TOC must be plain bullet list, no link targets. Strip `[I. Heading](#...)` markdown links if present.
|
||||
- Double words, double punctuation, capitalisation typos, processing artifacts, stray spacing in Chinese text
|
||||
- Numbering mismatches between CN and EN headings
|
||||
- Redundant English calques: when the target mirrors a Chinese grammar pattern literally, it can read as a typo (e.g. "mind of death-mindfulness" for 念死之心 — should be "mindfulness of death"). Clunky idioms: 一念之差 → "a single thought of difference" is unidiomatic. Standard renderings exist (e.g. "a single errant thought," "a moment's carelessness," or rephrase as "a single thought can make all the difference").
|
||||
|
||||
**Pass 3 — flow/tonal/calques** (read the whole English as prose):
|
||||
- Re-read the full English target. Does it hang together as prose, or does it read as "translationese"?
|
||||
- Dramatic verbs that are calques of Chinese: "draw forth," "into full play," "shoulder," "look to with hope." See `references/translation-pitfalls.md` for the full calque checklist.
|
||||
- Subject-shift calques: English substitutes a concrete agent (practitioners, people) for an abstract system noun (Buddhism, religion) — see pitfalls.
|
||||
- Factual inconsistencies across paired descriptions of the same person/place/thing.
|
||||
- Tonal coherence inside parallel lists: verb choice should be identical across First/Second/Third items.
|
||||
- Intensifier drift: same intensifier ("profoundly important") used 3+ times in one section reads as over-translation.
|
||||
- The user may explicitly request this pass ("are the words together nicely?", "does it read well?"). Treat such prompts as a signal to do the full re-read, not just spot-check.
|
||||
|
||||
**Terms database drift** (cross-cutting — apply during Pass 1):
|
||||
- Cross-reference glossary terms against the MPI terms database
|
||||
- CLI preferred: `python3 $MPI_PROJECT_ROOT/terms-search/search.py <query>`. For a review, batch many queries in one `execute_code` script (subprocess loop) — one terminal call per term is slow and noisy.
|
||||
- Source priority: DoT定稿 > 内部特色词 > 佛教术语 > 经论名
|
||||
- Fix both glossary comments AND body text
|
||||
- See `references/terms-db-alignment.md` for batch-lookup patterns
|
||||
|
||||
### 3. Dump findings
|
||||
|
||||
Write to `translation-findings.dj` for issues that don't fit as inline fixes:
|
||||
|
||||
```
|
||||
Finding N — Title (line numbers)
|
||||
Chinese: ...
|
||||
English: ...
|
||||
Issue: description
|
||||
```
|
||||
|
||||
### 4. Apply fixes with `patch`
|
||||
|
||||
Surgical string replacement in `commented.dj` with `patch` (mode='replace').
|
||||
Never use regex-based string replacement in `execute_code` for .dj edits.
|
||||
`patch` is safer, surfaces conflicts, and produces a reviewable diff.
|
||||
Verify with `cat` — never rely on `read_file` (session dedup).
|
||||
|
||||
### 5. Add inline edit suggestions
|
||||
|
||||
Copy `bilingual.dj` → `commented.dj`, then apply inline corrections + `{% %}` comments.
|
||||
|
||||
### 6. Final sweep
|
||||
|
||||
Run `python3 scripts/sweep.py <source.dj> <target.dj> [--stale term1,term2] [--new term1,term2]`. This runs all mechanical checks in one call: line parity, heading parity, Unicode em/en-dashes, Markdown bold, Chinese punctuation, TOC link artifacts, unbalanced quotes, and stale/new term assertions. Run even when no content patches were needed — it serves as final validation.
|
||||
|
||||
## Buddhist terminology reference
|
||||
|
||||
See `references/buddhist-terminology.md` for Chinese-English term mappings and common pitfalls.
|
||||
|
||||
## Workflow C: Typeset proofread (DOCX manuscript vs PDF layout)
|
||||
|
||||
Use when the user gives a manuscript DOCX and a typeset PDF and asks to proofread.
|
||||
Goal: catch typesetting errors (missing text, typos, wrong special characters, bad line
|
||||
breaks), not translation quality.
|
||||
|
||||
### 0. Clarify scope FIRST
|
||||
|
||||
Before any extraction: ask what they want checked. "Proofread" can mean:
|
||||
- Text accuracy (missing/doubled words, typos introduced by typesetter)
|
||||
- Special characters (quotes, dashes, ellipses)
|
||||
- Formatting (page numbers, headers, TOC layout)
|
||||
- All of the above
|
||||
|
||||
Do not run extraction pipelines until scope is clear.
|
||||
|
||||
### 1. Extract text
|
||||
|
||||
- DOCX → plain: `pandoc file.docx -f docx -t plain --wrap=none`
|
||||
- PDF → plain: `pdftotext -layout file.pdf` (preserves positional info)
|
||||
|
||||
### 2. Clean PDF artifacts
|
||||
|
||||
- Strip InDesign slug lines, page headers, page numbers
|
||||
- Join hyphenated line breaks (line ending `-` + next line starting lowercase)
|
||||
- Fix drop-cap artifacts (e.g. `L iving` → `Living`)
|
||||
|
||||
### 3. Compare
|
||||
|
||||
- Extract English paragraphs from DOCX (skip Chinese lines, match blank-line pattern)
|
||||
- Check each DOCX paragraph exists as substring in PDF body text
|
||||
- Flag paragraphs not found; investigate each (may be heading renumbering, not missing)
|
||||
|
||||
### Pitfalls specific to this workflow
|
||||
|
||||
- **PDF paragraph joining is lossy** — page breaks split paragraphs. Don't expect
|
||||
perfect paragraph matching; check content coverage, not paragraph identity.
|
||||
- **Heading numbering differs** — DOCX has `1.`, `(1)`; PDF has `I`, `1)`. Ignore
|
||||
heading-only differences.
|
||||
- **InDesign PDFs insert extra spaces** around drop caps and special characters.
|
||||
Normalize multi-space to single space before comparison.
|
||||
|
||||
### Pitfalls
|
||||
|
||||
- **Never edit `bilingual.dj`** — it's script-generated ground truth. Copy to `commented.dj` first.
|
||||
- **Use `patch`, not regex** — for all `.dj` edits. `patch` surfaces conflicts and produces diffs.
|
||||
- **`commented.dj` comments must not split paragraphs** — always place `{% %}` after the FULL EN paragraph, not mid-sentence. Scan for merged comments after insertions and split them. Collapse triple+ blank lines created by comment insertions.
|
||||
- **Clarify scope before diving into extraction pipelines** — if the user says
|
||||
"proofread this" or "校对这篇文章", ask what specifically they want checked
|
||||
before running pandoc/pdftotext. Getting interrupted mid-pipeline wastes
|
||||
context.
|
||||
- **Don't use heredocs or `-c`** — write to `/tmp/script.py` first
|
||||
- **Deduplicate aggressively** — group by problem type, not per-row
|
||||
- **Buddhist terminology is technical** — don't guess. When uncertain, flag for review
|
||||
- **Never delete .dj comparison files** — intentional work artifacts
|
||||
- **Verify patches with `cat`** — `read_file` dedup makes it unreliable
|
||||
- **Re-read before fixing** — user may have made interim edits
|
||||
- **Batch terminology lookups** — when checking many terms against the terms DB, run them in one `execute_code` script that loops over a query list and calls `search.py` via `subprocess.run`. One terminal call per term floods the context with repetitive output.
|
||||
|
||||
## Human Review Protocol (审议)
|
||||
|
||||
When giving feedback to human translators — whether in a review team or as an AI
|
||||
assistant flagging issues — follow the Oriental Translation Workshop protocol.
|
||||
See `references/deliberation-protocol.md` for full guidance.
|
||||
|
||||
Key points:
|
||||
- **Rejoice first** (随喜): affirm what works before flagging issues
|
||||
- **Three-tier issues**: Level 1 (spelling/grammar/format) — fix directly. Level 2
|
||||
(omission/mistranslation/wordiness) — suggest or fix with tracked changes. Level 3
|
||||
(citation versions / marginal wording) — discuss with translator
|
||||
- **Tone**: questions, not commands; collaborative inquiry, not correction
|
||||
- **Address translator as 菩萨** (Bodhisattva) — respectful peer
|
||||
|
||||
## Common Issues Taxonomy
|
||||
|
||||
Use `references/common-issues-taxonomy.md` as a structured checklist when reviewing.
|
||||
Categories:
|
||||
|
||||
- **Accuracy**: omission, mistranslation (over-free, over-literal, misunderstanding,
|
||||
wrong word choice), overtranslation, terminology errors
|
||||
- **Readability**: redundancy (long sentences, passive voice, nominalization),
|
||||
poor structure (top-heavy sentences), wrong register, weak transitions
|
||||
|
||||
## References
|
||||
|
||||
- `references/buddhist-terminology.md` — Chinese-English Buddhist term mappings and pitfalls
|
||||
- `references/terms-db-alignment.md` — Batch-aligning glossary terms against the MPI terms database
|
||||
- `references/translation-pitfalls.md` — Recurring CN→EN mistranslation patterns (关爱→compassion, 生生增上, etc.)
|
||||
- `references/proofreading-patterns.md` — DOCX/PDF extraction techniques, block-based pairing, common manuscript issues
|
||||
- `references/docx-md-extraction.md` — Extracting `.docx.md` (pandoc markdown) to bilingual, TOC guards, CN/EN boundary regex
|
||||
- `references/edit-suggestions-in-bilingual.md` — Inline edit suggestions + `{% %}` comments, two-file comparison (commented.dj / bilingual.dj)
|
||||
- `references/deliberation-protocol.md` — Oriental Translation Workshop review protocol: tiers, rejoicing, tone
|
||||
- `references/common-issues-taxonomy.md` — Structured taxonomy of accuracy and readability issues with examples
|
||||
|
||||
## Scripts
|
||||
|
||||
- `scripts/sweep.py` — Mechanical validation sweep for completed reviews
|
||||
- `scripts/review_csv.py` — Batch CSV/XLSX translation review
|
||||
@@ -0,0 +1,47 @@
|
||||
# Buddhist Text Translation — Terminology
|
||||
|
||||
Terms encountered in Chinese-English translation of Dharma study materials. These may vary by translator/context; document actual usage per-project.
|
||||
|
||||
## Section headers (common triad)
|
||||
|
||||
| Chinese | English options seen | Notes |
|
||||
|---------|---------------------|-------|
|
||||
| 法义 | Understanding, Dharma Teachings | |
|
||||
| 思考 | Contemplation, Reflection | Consistency within a document matters more than which word |
|
||||
| 练习 | Practice, Application, Exercises | "Application" seen as section header; "Practice"/"Exercise" in running text |
|
||||
|
||||
## Key Buddhist terms
|
||||
|
||||
| Chinese | English | Pitfalls |
|
||||
|---------|---------|----------|
|
||||
| 慈经 | Metta Sutta (Karaniya Metta Sutta) | NOT "Mettavihari Sutta" |
|
||||
| 回向 | Dedication (of merit) | |
|
||||
| 因缘之网 | Web of Causes and Conditions | Also "Network of Causes and Conditions" |
|
||||
| 感恩 | Gratitude | |
|
||||
| 众生 | sentient beings | Consistent throughout |
|
||||
| 使人内心调柔 | makes one's heart gentle | 使人 = makes ONE(self), never "makes others" |
|
||||
| 利益思维 | benefit-oriented thinking | NOT "mindset of benefiting others" — it's about considering benefits TO oneself |
|
||||
| 恩田 | field of gratitude / gratitude as a field of merit | |
|
||||
| 观照 | attend to the mind / mindful observation | Contemplative practice, not intellectual study. NOT "observe" (passive) or "study" (analytical). |
|
||||
| 闻思修 | hearing, contemplating, cultivating | 修 = broad cultivation/practice, not specifically 禅 (meditation). Distinct from 禅修 (meditative cultivation). |
|
||||
| 八步三禅 | Eight Steps and Three Meditations | Community-specific structured contemplative method |
|
||||
| 传帮带 | transmit, help, guide (three-part mentoring) | Core community methodology |
|
||||
| 分灯 | lamp-dividing (decentralization) | Deliberate decentralization of authority across nodes |
|
||||
| 自觉 | self-awareness, voluntary commitment | First of the "Three Spirits" |
|
||||
| 法治 | rule-based governance | Second of the "Three Spirits" |
|
||||
| 无我利他 | selfless service to others | Third of the "Three Spirits" |
|
||||
| 凡夫心 | ordinary mind | Mind governed by afflictions, contrasted with awakened mind |
|
||||
| 贪嗔痴 | greed, anger, ignorance (三毒) | The three root poisons: rāga, dveṣa, moha |
|
||||
| 愿心 | mind of vows, bodhicitta aspiration | Plural "vows" in English |
|
||||
| 重要感、优越感、主宰欲 | sense of importance, superiority, desire to control | Three ego-driven motivations |
|
||||
|
||||
## Structural patterns
|
||||
|
||||
- Section numbering: Chinese uses 一、二、三... English should pick one style (Part One/Two, First/Second, I/II) and stick with it.
|
||||
- Poetry/prayer blocks: Chinese uses parallel structures (感恩... 感恩...; 愿... 愿...). English must match the parallelism.
|
||||
- 愿 (yuàn) at sentence start = optative "May..." — not "we hope that", not "we should".
|
||||
|
||||
## Formatting artifacts
|
||||
|
||||
- Stray spaces between Chinese characters (eg. `感 恩 研 究`) are justified-text paste artifacts from the source document — remove them.
|
||||
- `<!-- === Progress : Below are unprocessed === -->` is a processing marker — remove from final file.
|
||||
@@ -0,0 +1,174 @@
|
||||
# Common Translation Issues Taxonomy
|
||||
|
||||
From 译文常见问题与案例示范 (Common Issues in Translation, 2026-03-30).
|
||||
Categorized by accuracy and readability.
|
||||
|
||||
## Accuracy Issues
|
||||
|
||||
Standard: convey meaning at the content level, not word-by-word correspondence.
|
||||
"Translation is not simply word conversion."
|
||||
"You must understand what thought it is actually trying to express."
|
||||
|
||||
### 1. Omission (漏翻)
|
||||
|
||||
Content present in source but absent from target.
|
||||
|
||||
Example:
|
||||
> 随着黑白牌的运用,象征这部分已能为大家提供系统的学习和训练资料。
|
||||
>
|
||||
> With the help of the Black-and-White Cards, this approach now offers a structured
|
||||
> system of study.
|
||||
>
|
||||
> *Missing:* 学习和训练 (learning and training) — "study" only covers half.
|
||||
> Also: 象征这部分 (symbolizing this aspect) is dropped.
|
||||
|
||||
### 2. Mistranslation (错翻)
|
||||
|
||||
#### a. Over-free translation, weakening the original
|
||||
|
||||
> "道德"一词,人们耳熟能详。即使在道德日渐边缘化的今天,人们依然会用"这人
|
||||
> 很有道德""这么做太缺德了"来评价周遭人事。
|
||||
>
|
||||
> "Morality" is a familiar term, and even in today's world, where it has become
|
||||
> increasingly marginalized, expressions like "immorality" are still commonly used
|
||||
> to describe certain behaviors and individuals.
|
||||
>
|
||||
> *Issue:* The source gives two concrete colloquial expressions ("这人很有道德" /
|
||||
> "这么做太缺德了") — the target collapses them into a single abstract "expressions
|
||||
> like 'immorality'." The vividness and specificity are lost.
|
||||
|
||||
#### b. Over-literal translation, harming comprehension
|
||||
|
||||
> 作为素菜馆,应该尽量提供绿色食品。
|
||||
>
|
||||
> A vegetarian restaurant should strive to offer green food.
|
||||
>
|
||||
> *Issue:* 绿色食品 = "safe and healthy food" (Chinese idiom), not
|
||||
> "green food" (color of food in English). → `safe and healthy options`
|
||||
|
||||
#### c. Misunderstanding the source
|
||||
|
||||
> 政府现在倡导文化自信,习主席提出的"讲仁爱,重民本,守诚信,崇正义,尚和合,求大同"。
|
||||
>
|
||||
> President Xi Jinping has called for a confident embrace of Chinese culture,
|
||||
> highlighting virtues such as...
|
||||
>
|
||||
> *Issue:* Two different subjects: the government advocates cultural confidence;
|
||||
> Xi proposed the six virtues. The target merges both into Xi alone.
|
||||
|
||||
#### d. Wrong word choice causing misunderstanding
|
||||
|
||||
> 提供一些通俗易懂的法宝
|
||||
>
|
||||
> with easy Buddhist materials
|
||||
>
|
||||
> *Issue:* 通俗易懂 means "accessible to a general audience," not "easy/simple."
|
||||
> The Dharma can be accessible but is never "simple." → `accessible`
|
||||
|
||||
### 3. Overtranslation (多翻)
|
||||
|
||||
Adding parentheticals or expansions not in the source.
|
||||
|
||||
> 出家人不仅要对三宝、师长、道友建立没有染污的情感
|
||||
>
|
||||
> Monastics should cultivate pure and untainted emotions not only toward the Three
|
||||
> Jewels (the Buddha, the Dharma, the Sangha), their teachers (The Head Monk and
|
||||
> Abbot), and fellow practitioners...
|
||||
>
|
||||
> *Issue:* Parenthetical expansions like "(the Buddha, the Dharma, the Sangha)"
|
||||
> and "(The Head Monk and Abbot)" are not in the source and should be removed.
|
||||
|
||||
### 4. Terminology Errors
|
||||
|
||||
- 身心 → `body and heart mind` → should be `body and mind`
|
||||
- 甘露别院 → `Ganlu Bieyuan The Amrita Retreat Center` → official: `Amrita Retreat Center`
|
||||
- "六字" → `six characters` → should be `six words`
|
||||
|
||||
### 5. Detail-Level Issues
|
||||
|
||||
- Tone appropriateness
|
||||
- Citation source authority
|
||||
- CN→EN conversion rules: numerals, units, date formats
|
||||
- Proper noun handling: transliteration vs. translation
|
||||
|
||||
## Readability Issues
|
||||
|
||||
Standard: fluent sentences, graceful expression, matching target reader habits.
|
||||
"Conform to what foreign readers find readable."
|
||||
"Concise, clear, accurate, not draggy, meaning clear."
|
||||
|
||||
### 1. Redundancy & Wordiness
|
||||
|
||||
#### a. Long / nested sentences
|
||||
|
||||
Sentences with too many clauses that can't be read in one breath. Split them.
|
||||
|
||||
#### b. Passive voice overuse
|
||||
|
||||
> 如果对肉食消费得少,乃至完全不消费,那么从业者自然随之减少,很多动物就可以摆脱被屠宰、割截的厄运。
|
||||
>
|
||||
> If meat consumption were reduced, or even eliminated entirely, then the number of
|
||||
> businesses involved would naturally be lessened. This way, many animals could be
|
||||
> spared from the adversity of being slaughtered and butchered.
|
||||
>
|
||||
> *Issue:* Three passives in two sentences. Active rewrite is more concise:
|
||||
> *If people consume less meat — or none at all — fewer will work in the industry,
|
||||
> and many animals will be spared the fate of slaughter and dismemberment.*
|
||||
|
||||
#### c. Nominalization (动词名词化)
|
||||
|
||||
> 我们前期倡导的正念禅修,比较重视培养觉知。
|
||||
>
|
||||
> In the early stages of mindfulness practice, we placed greater emphasis on
|
||||
> cultivating awareness.
|
||||
>
|
||||
> *Issue:* "placed greater emphasis on" is nominalized. → `we emphasized`
|
||||
|
||||
### 2. Poor Structure (结构不当)
|
||||
|
||||
Top-heavy sentences — the main clause arrives too late.
|
||||
|
||||
> 没有如法的生活,不能严格要求自己,在今天这个红尘滚滚的时代,我们简直是没希望的。
|
||||
>
|
||||
> Weathering today's deluge of worldly temptation, without a Dharma-aligned lifestyle
|
||||
> and strict self-discipline, we have no hope.
|
||||
>
|
||||
> *Issue:* The condition clauses pile up before the main point. Restructure:
|
||||
> *Without a Dharma-aligned lifestyle and strict self-discipline, we have no hope
|
||||
> of weathering today's deluge of worldly temptations.*
|
||||
|
||||
### 3. Wrong Word Choice (用词不当)
|
||||
|
||||
> 当一个人开始关心生命的大问题时,对小问题自然云淡风轻。
|
||||
>
|
||||
> when we begin to contemplate the profound questions of existence, the banal
|
||||
> iterations of daily life lose their significance.
|
||||
>
|
||||
> *Issue:* "banal iterations" is obscure. Simplify.
|
||||
|
||||
### 4. Weak Flow & Transitions (流畅性 & 连接词)
|
||||
|
||||
> 修行的核心就是止恶行善。为什么某种行为能成为生命的主导?就是因为不断重复。
|
||||
>
|
||||
> The essence of cultivation lies in ceasing unwholesome actions and promoting
|
||||
> wholesome ones. But why do certain behaviors dominate our lives? Because of
|
||||
> constant repetition.
|
||||
>
|
||||
> *Issue:* Adding transition words improves flow. The "But" here creates a false
|
||||
> contrast — the second sentence is explanation, not counterpoint.
|
||||
|
||||
## Detection Checklist
|
||||
|
||||
When reviewing, run through:
|
||||
- [ ] Any missing content? (compare paragraph-by-paragraph)
|
||||
- [ ] Any added content? (parentheticals, expansions not in source)
|
||||
- [ ] Any over-literal renderings that don't work in English? (idioms, set phrases)
|
||||
- [ ] Any over-free renderings that lose specificity? (concrete examples → abstract)
|
||||
- [ ] Subject confusion? (two actors merged into one)
|
||||
- [ ] Buddhist terminology checked against terms DB?
|
||||
- [ ] Sentences too long to read in one breath? (split at natural breaks)
|
||||
- [ ] Passive voice clustering? (3+ in a paragraph)
|
||||
- [ ] Nominalized verbs? ("placed emphasis on" → "emphasized")
|
||||
- [ ] Top-heavy sentence structure? (main clause buried after long preamble)
|
||||
- [ ] Obscure word choices? (would a general reader understand?)
|
||||
- [ ] Missing or misleading transition words?
|
||||
@@ -0,0 +1,90 @@
|
||||
# Deliberation Protocol (审议规程)
|
||||
|
||||
From 东方译场审议手册 (Oriental Translation Review Manual, 2026-03-25).
|
||||
Guidance from Ven. Jiqun on translation review culture and process.
|
||||
|
||||
## Core Standards
|
||||
|
||||
1. **Accuracy (准确性)** — primary. Convey content-level meaning, not word-by-word
|
||||
correspondence. Deepen accuracy iteratively; grasp the "inner spirit" rather than
|
||||
fixating on literal vs free translation.
|
||||
|
||||
2. **Readability (可读性)** — secondary. Fluent sentences, graceful expression. Do
|
||||
not pursue endless revision; what is achievable now is the best for now.
|
||||
|
||||
**Test**: invite 5–10 readers to read aloud and give feedback — is it clear or
|
||||
obscure? Is it concise? Is the meaning clear?
|
||||
|
||||
## Decision-Making
|
||||
|
||||
When opinions differ:
|
||||
- Compare which version is more accurate and more readable
|
||||
- Do NOT cling to your own view (不执着于己见)
|
||||
- If two people cannot decide, invite 5–10 to read and vote
|
||||
- Remember: the translation is for the READERS, not for yourself
|
||||
|
||||
## Core Principle: Rejoice First (随喜)
|
||||
|
||||
Before flagging issues, affirm what is good. Professional translation companies
|
||||
emphasize positive feedback to build translator confidence and good collaboration.
|
||||
Criticism alone — however precise — breeds resistance and harms the final result.
|
||||
|
||||
In the Oriental Translation Workshop, rejoicing in others' merits cultivates
|
||||
sympathetic joy (随喜), compassion, selflessness, and boundless merit — while
|
||||
encouraging others' wholesome efforts.
|
||||
|
||||
**Practice**: develop eyes that SEE the merits in a translation. Rejoice with
|
||||
genuine gladness. Examples:
|
||||
- "So many technical terms and complex logic here — you handled it beautifully!"
|
||||
- "This word choice is exactly right."
|
||||
- "The prose is so clean and fluid!"
|
||||
- "Excellent!" / "Good word choice!"
|
||||
|
||||
## Three Principles for Giving Suggestions
|
||||
|
||||
1. **Lower the self** — use compassionate, gentle, skillful language
|
||||
2. **Be diligent and attentive** — find the actual problems
|
||||
3. **Tier your suggestions** — make clear what MUST change, what COULD improve,
|
||||
and what needs DISCUSSION
|
||||
|
||||
## Three-Tier Issue System
|
||||
|
||||
### Level 1: Spelling, Grammar, Format (拼写、语法、格式)
|
||||
|
||||
**Action**: fix directly, keep tracked changes visible.
|
||||
|
||||
May annotate for translator development:
|
||||
- "MPI format uses American English — `toward` not `towards`."
|
||||
- "Use `Chan` here, not `Zen`."
|
||||
- "MPI format does not use diacritics — `Yogacara` not `Yogācāra`."
|
||||
|
||||
### Level 2: Omission, Mistranslation, Wordiness, Tone, Word Choice
|
||||
(漏翻、错翻、啰嗦、语气问题、用词问题)
|
||||
|
||||
**Action**: preferably flag for translator to fix themselves; may also fix
|
||||
directly with tracked changes.
|
||||
|
||||
Suggested language:
|
||||
- "Did we miss something here?"
|
||||
- "This sentence is quite long — could we split it into 2–3?"
|
||||
- "The translation here differs from the original. It reads as if the teacher
|
||||
is saying X, but I think he means Y. What do you think?"
|
||||
- "This word feels a bit strong here — your thoughts?"
|
||||
- (After direct adjustment) "I tightened this sentence — does this work?"
|
||||
|
||||
### Level 3: Citation Versions, Slightly Awkward Wording, Marginal Readability
|
||||
(引用版本不当、用词稍微不当、阅读体验略差)
|
||||
|
||||
**Action**: flag and discuss with translator.
|
||||
|
||||
Suggested language:
|
||||
- "I found another citation version that may be more concise — which do you prefer?"
|
||||
- "Could we use this word instead? Might fit better."
|
||||
- "Could you take another look at this passage? I feel readability could improve
|
||||
but I'm not sure how — your thoughts?"
|
||||
|
||||
## Tone Guide
|
||||
|
||||
- Address the translator as 菩萨 (Bodhisattva) — respectful peer address
|
||||
- Use questions, not commands: "Could we...?" "What do you think?" "Would this work?"
|
||||
- Frame as collaborative inquiry, not correction
|
||||
@@ -0,0 +1,171 @@
|
||||
# Extracting `.docx.md` to `source.dj` + `bilingual.dj`
|
||||
|
||||
When the input is a `.docx.md` file (already pandoc markdown, not plain text), the
|
||||
extraction differs from the standard DOCX→plain workflow. The markdown preserves
|
||||
formatting artifacts that need specific handling.
|
||||
|
||||
## CN/EN boundary detection in merged lines
|
||||
|
||||
Pandoc markdown often merges CN and EN text on heading lines where the DOCX had
|
||||
multiple runs in the same paragraph:
|
||||
|
||||
```
|
||||
# **三、重视文化教育,重塑人生价值** Prioritize Cultural Education; Reshape Life Values {#三、...}
|
||||
```
|
||||
|
||||
The boundary regex must account for whitespace on BOTH sides of `**` markers:
|
||||
|
||||
```python
|
||||
# WRONG: \** then \s* — fails when there's space BEFORE * (值 *Realizing)
|
||||
r'[\u4e00-\u9fff](?:\*{0,2})\s*([A-Za-z])'
|
||||
|
||||
# WRONG: \s* then \** — fails when there's space AFTER ** (值** Prioritize)
|
||||
r'[\u4e00-\u9fff]\s*\**([A-Za-z])'
|
||||
|
||||
# CORRECT: whitespace on both sides of optional *
|
||||
r'[\u4e00-\u9fff]\s*\**\s*([A-Za-z])'
|
||||
```
|
||||
|
||||
Include CJK punctuation ranges in the character class:
|
||||
`[\u4e00-\u9fff\u3000-\u303f\uff00-\uffef]`
|
||||
|
||||
## Anchor stripping
|
||||
|
||||
Strip BOTH `{#anchor}` (pandoc heading anchors) AND `[text](#link)` (markdown TOC links)
|
||||
before further processing:
|
||||
|
||||
```python
|
||||
def strip_anchors(s):
|
||||
s = re.sub(r'\{#[^}]*\}', '', s) # {#anchor}
|
||||
s = re.sub(r'\[([^\]]*)\]\([^)]*\)', r'\1', s) # [text](#link) → text
|
||||
return s
|
||||
```
|
||||
|
||||
## TOC handling — two critical guards
|
||||
|
||||
### Guard 1: Don't pair TOC CN entries with following EN lines
|
||||
|
||||
TOC entries often look like CN-heading-followed-by-EN (the standard pair pattern),
|
||||
but the following EN is actually the next TOC entry or heading:
|
||||
|
||||
```
|
||||
[一、营造禅意氛围,优化工作环境\t1](#anchor)
|
||||
[二、重视慈善关爱...]
|
||||
...
|
||||
1、Create a Chan(Zen) Atmosphere; Optimize Your Environment
|
||||
2、Focus on Compassion and Care; Build Good Relationships
|
||||
```
|
||||
|
||||
If the last CN TOC entry is followed by a blank line then the first EN TOC entry,
|
||||
the "CN → blank → EN" heading pattern will consume the first EN TOC entry.
|
||||
Guard against this:
|
||||
|
||||
```python
|
||||
def is_toc_line(line, cn_raw):
|
||||
if re.search(r'\[.*\]\(.*\)', line): # markdown link
|
||||
return True
|
||||
if re.search(r'\t\d+', cn_raw): # tab + page number
|
||||
return True
|
||||
return False
|
||||
```
|
||||
|
||||
Skip the CN→EN and CN→blank→EN patterns when `is_toc_line()` returns True.
|
||||
These CN TOC entries should stay unpaired (en='') and get their EN from the
|
||||
separate EN TOC list.
|
||||
|
||||
### Guard 2: Pair TOC EN entries forward, not backward
|
||||
|
||||
EN TOC entries appear as standalone non-CJK lines. They must be paired with
|
||||
the FIRST unpaired CN (not the last):
|
||||
|
||||
```python
|
||||
# CORRECT: forward iteration
|
||||
for j in range(len(pairs)):
|
||||
if not pairs[j][1] and has_cjk(pairs[j][0]):
|
||||
pairs[j] = (pairs[j][0], en)
|
||||
break
|
||||
|
||||
# WRONG: reverse iteration (pairs last-first, shifting everything)
|
||||
for j in range(len(pairs)-1, -1, -1):
|
||||
...
|
||||
```
|
||||
|
||||
## Orphaned trailing `*` from italic splits
|
||||
|
||||
When a line has italicized EN text (`*Realizing Ultimate Value*`) and the split
|
||||
point is at the `R` (after the opening `*` is consumed by the CN cleanup), the
|
||||
EN text retains a trailing `*`: `Realizing Ultimate Value*`. Strip it:
|
||||
|
||||
```python
|
||||
def clean_en(s):
|
||||
s = re.sub(r'^\d+[、,.]\s*', '', s)
|
||||
s = re.sub(r'\*+$', '', s) # orphaned italic close
|
||||
return s.strip()
|
||||
```
|
||||
|
||||
## `clean_cn` — operation order matters
|
||||
|
||||
Strip leading numbers BEFORE heading markers. A line like `1. # **营造禅意...`
|
||||
starts with a digit, so `^#+\s*\**` won't match until the number is gone:
|
||||
|
||||
```python
|
||||
def clean_cn(s):
|
||||
s = re.sub(r'^\d+\.\s*', '', s) # leading number FIRST
|
||||
s = re.sub(r'^#+\s*\**', '', s) # then heading markers
|
||||
s = re.sub(r'\**\s*$', '', s) # trailing **
|
||||
s = re.sub(r'\t\d+$', '', s) # trailing page number
|
||||
return s.strip()
|
||||
```
|
||||
|
||||
## Full extraction recipe
|
||||
|
||||
1. Read `.docx.md` text
|
||||
2. For each line: strip anchors, detect CJK/EN
|
||||
3. CJK lines: try `split_cnen()` first (merged CN+EN). If that gives EN, use it.
|
||||
Otherwise look ahead for EN on next line or next+blank — but SKIP if TOC-like.
|
||||
4. EN-only lines: pair forward with first unpaired CN.
|
||||
5. Clean: strip heading markers, leading numbers, trailing page numbers.
|
||||
6. Write `source.dj` (CN only) and `bilingual.dj` with proper markdown structure.
|
||||
|
||||
## bilingual.dj output format
|
||||
|
||||
Must follow the project convention (see reference bilingual.dj in any completed article):
|
||||
|
||||
```
|
||||
# CN Title
|
||||
# EN Title
|
||||
|
||||
---CN Subtitle
|
||||
---EN Subtitle
|
||||
|
||||
CN Author
|
||||
EN Author
|
||||
|
||||
- CN TOC item 1
|
||||
- CN TOC item 2
|
||||
...
|
||||
|
||||
- EN TOC item 1
|
||||
- EN TOC item 2
|
||||
...
|
||||
|
||||
CN body paragraph
|
||||
EN body paragraph
|
||||
|
||||
CN section heading ← plain text, no # prefix
|
||||
EN section heading
|
||||
|
||||
...
|
||||
|
||||
CN sub-heading ← plain text, e.g. "1. 创造精神财富"
|
||||
EN sub-heading
|
||||
```
|
||||
|
||||
- Title: `# ` prefix on both CN and EN
|
||||
- Subtitle: `---` prefix (3 dashes, no space after)
|
||||
- Author: plain text, one pair
|
||||
- TOC: `- ` bullet, CN block then EN block (not interleaved), blank line between blocks
|
||||
- Body headings: plain text, no `#` or `##` markers. Hierarchy conveyed by numbering:
|
||||
`一、二、三、` for major sections, `1. 2. 3.` for sub-sections
|
||||
- Body paragraphs: interleaved (CN line, EN line, blank)
|
||||
- `source.dj` uses `# Title`, `---subtitle`, `## section headings` — different from bilingual.dj which uses plain body headings
|
||||
@@ -0,0 +1,65 @@
|
||||
# Edit Suggestions in bilingual.dj
|
||||
|
||||
When the user asks to add edit suggestions directly into bilingual.dj, use this
|
||||
two-tier approach.
|
||||
|
||||
## Two files
|
||||
|
||||
- `bilingual.dj` — clean: inline corrections applied, NO `{% %}` comment lines
|
||||
- `commented.dj` — same content + `{% ... %}` comment lines interleaved
|
||||
|
||||
This lets the user diff them side by side.
|
||||
|
||||
## Inline corrections
|
||||
|
||||
Apply directly to the English text. These are fixes the reviewer is confident about:
|
||||
|
||||
- Typos, mechanical issues (Chinese punctuation in EN, double periods, stray `*`, unbalanced quotes)
|
||||
- Grammar fixes (subject-verb agreement, missing articles)
|
||||
- Wording improvements (clunky literal translations → idiomatic English)
|
||||
|
||||
Apply with `patch` (mode='replace'). Verify uniqueness before
|
||||
replacing — many EN paragraphs are long single lines, so match a unique
|
||||
substring. Never use regex-based string replacement in `execute_code`.
|
||||
|
||||
## `{% %}` comment lines
|
||||
|
||||
For translation decisions worth documenting but not "correct" per se:
|
||||
|
||||
```
|
||||
CN paragraph
|
||||
EN paragraph
|
||||
{% reason for the choice, alternative renderings %}
|
||||
(blank)
|
||||
```
|
||||
|
||||
The comment goes AFTER the EN line (before the blank separator). One comment per
|
||||
issue. Keep them terse.
|
||||
|
||||
What to comment on:
|
||||
- Literal translation of idioms (`单线程` → "single-threaded")
|
||||
- Translation choices that differ from literal meaning (`精神利益` → "nourishing the spirit")
|
||||
- Standard Buddhist terminology (`正命` → "Right Livelihood")
|
||||
- Glosses added/dropped (`道场` — "(Dojo)" parenthetical removed)
|
||||
- Idiom translations (`甘之若饴` → "as sweet as syrup")
|
||||
- Paired terms where one rendering influences the other (`魔性` → "demon-nature" to parallel "Buddha-nature")
|
||||
- Scripture citations with Sanskrit titles (`普贤行愿品` → "Gaṇḍavyūha Sūtra")
|
||||
|
||||
What NOT to comment on:
|
||||
- Obvious corrections (typos, grammar)
|
||||
- Names, dates, simple connectives
|
||||
- Standard renderings with no interesting choice
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- **Never split a paragraph mid-sentence** with a `{% %}` comment. Comments go
|
||||
AFTER the full EN paragraph, before the blank separator. If a string
|
||||
replacement inserts `\n{% %}` in the middle of a paragraph, it breaks the
|
||||
interleaved structure.
|
||||
|
||||
- **Check for merged comments**: after inserting, scan for `{% ... %} ` followed
|
||||
by EN text on the same line. These must be split so the EN text continues on
|
||||
the next line.
|
||||
|
||||
- **Collapse triple+ blank lines**: comment insertions can create extra blanks.
|
||||
Run `re.sub(r'\n\n\n+', '\n\n', text)` after all insertions.
|
||||
@@ -0,0 +1,116 @@
|
||||
# Proofreading: Manuscript vs Typeset
|
||||
|
||||
AGENTS.md defines two workflows: Translation (A) and Proofread (B).
|
||||
The workflows below are Proofread mode — English comes from an existing
|
||||
manuscript and is authoritative. Only flag mechanical/manuscript-level issues.
|
||||
|
||||
## Two extraction workflows
|
||||
|
||||
### A. Bilingual from DOCX (standard)
|
||||
|
||||
When the DOCX manuscript has both Chinese and English in 1:1 paragraph
|
||||
correspondence, generate `bilingual.dj` directly from the DOCX:
|
||||
|
||||
1. `pandoc docx → plain text`
|
||||
2. Extract Chinese-English pairs from body
|
||||
3. Apply fixes: italicize Sanskrit on first occurrence, fix `N.Letter` → `N. Letter` spacing
|
||||
4. Write bilingual.dj
|
||||
The DOCX English is the authoritative target text. No PDF needed.
|
||||
|
||||
**Extraction approach**: start by adapting `scripts/gen-bilingual-docx.py`.
|
||||
For articles where the body has strict CN→EN→CN→EN alternation, the simple
|
||||
extraction in that script (CN line, blank, EN line, blank) works directly.
|
||||
|
||||
### A2. Bilingual from `.docx.md` (pandoc markdown output)
|
||||
|
||||
When working with an already-converted `.docx.md` file (pandoc markdown, not plain
|
||||
text), use the techniques in `references/docx-md-extraction.md`. Key differences
|
||||
from plain-text extraction: merged CN+EN on heading lines, `{#anchor}` and
|
||||
`[text](#link)` artifacts, TOC pairing guards.
|
||||
|
||||
### B. Bilingual from PDF (when PDF is the typeset target)
|
||||
sections that order CN content before EN content (CN heading → CN body → EN heading →
|
||||
EN body), the simple alternation fails. Use block-based extraction instead:
|
||||
|
||||
1. Tag each non-blank line as CN or EN (via `has_cjk()`)
|
||||
2. Join page-break split paragraphs: merge consecutive same-language paragraphs
|
||||
only when the first is long (>30 chars), doesn't end with CJK/ASCII terminal
|
||||
punctuation (`[。!?:).?!]$`), and isn't heading-like (starts with
|
||||
`^[\dIVX]+[\.\s]` and <60 chars)
|
||||
3. Group consecutive same-language items into blocks
|
||||
4. Walk blocks: for each CN block, pair with the next EN block via `zip()`.
|
||||
`min(len(cn), len(en))` handles translator-introduced paragraph splits.
|
||||
|
||||
**Page-break splits in pandoc plain-text output**: the DOCX→plain conversion
|
||||
sometimes splits a Chinese paragraph mid-sentence (e.g. `白居` + `易、苏轼…`).
|
||||
These appear as two consecutive CN lines separated by a blank. The join heuristic
|
||||
above catches these reliably. For EN text, page-break splits are rare; the heading
|
||||
detection (`^[\dIVX]+[\.\s]`, <60 chars) prevents false merges of EN headings
|
||||
with following EN body paragraphs.
|
||||
The DOCX English is the authoritative target text. No PDF needed.
|
||||
|
||||
### B. Bilingual from PDF (when PDF is the typeset target)
|
||||
|
||||
When the PDF English is the typeset "final" version and should be the target:
|
||||
|
||||
1. Extract DOCX Chinese paragraphs (source)
|
||||
2. Extract PDF body text via `pdftotext -layout`
|
||||
3. Clean PDF: remove slug lines, headers, page numbers, join hyphenation breaks
|
||||
4. Match DOCX English paragraphs against PDF body to find positions
|
||||
5. Segment PDF body at matched positions
|
||||
6. Write bilingual.dj with Chinese source + PDF English target
|
||||
|
||||
**Pitfalls in PDF extraction:**
|
||||
- Consecutive hyphenation breaks (e.g. `thou-` + `sand...al-` + `leviate`) — the join
|
||||
loop must be recursive: after joining pair N, check if result still ends with `-`
|
||||
and join with line N+2
|
||||
- Lines with leading whitespace: use `lstrip()` before checking `n[0].islower()`
|
||||
- Drop-cap artifacts: `L iving` → `Living`
|
||||
- Trailing section numbers: `...viewpoints. 1)` — the ` 1)` is a PDF section marker
|
||||
bleeding into the previous paragraph
|
||||
|
||||
### C. Edit suggestions (edit-suggestions.dj)
|
||||
|
||||
After generating bilingual.dj, scan for issues and write `edit-suggestions.dj`:
|
||||
|
||||
**Format**: follow the original document's section/chapter layout. Group suggestions
|
||||
under the chapter headings where the issues occur. Use diff-style `-/+` notation.
|
||||
|
||||
**What to flag:**
|
||||
- Garbled Chinese text (merged duplicate edits in source DOCX)
|
||||
- Repeated words (`the The`)
|
||||
- Chapter numbering mismatches (e.g. `九` ↔ `VIII`)
|
||||
- Translator notes in headings (`(某某翻,某某审)`)
|
||||
- Missing quotes around dialogue/speech
|
||||
|
||||
## Common source DOCX issues
|
||||
|
||||
- Translator notes in Chinese headings: `(某某翻,某某审)` — delete for publication
|
||||
- Merged duplicate edits: cut-paste errors where old+new text appear together
|
||||
- `N.Letter` without space: `2.How` → `2. How`
|
||||
- `the The` double article
|
||||
- **Numbering mismatches**: CN and EN headings sometimes disagree (e.g. CN `3.` vs EN `2.`).
|
||||
The TOC usually has the correct number — flag the body heading for correction.
|
||||
- **Doubled names**: `岳麓书院岳麓书院` — cut-paste artifacts in Chinese body text.
|
||||
- **EN paragraph splits without CN counterpart**: translator sometimes renders one CN
|
||||
paragraph as two EN paragraphs. The block-based extractor drops the extra EN paragraph
|
||||
(as `min(len_cn, len_en)`). Flag in edit-suggestions so it can be manually merged or
|
||||
the CN paragraph can be split.
|
||||
|
||||
## Sanskrit italicization
|
||||
|
||||
On first occurrence in body text, wrap with `*term*`. Track seen terms across
|
||||
the full body. Terms: bodhisattva, bodhicitta, samsara, Dharma, karma, nirvana,
|
||||
Sangha, sutra, Mahayana, Sravaka, Vinaya, Lamrim, Ksitigarbha, Samantabhadra,
|
||||
Chan, Arhatship, Theravada.
|
||||
|
||||
## Proofread scope boundary
|
||||
|
||||
When proofreading a DOCX manuscript:
|
||||
- **DO flag**: typos, double words, double punctuation, numbering mismatches,
|
||||
garbled text, translator notes, duplicate names, capitalization errors.
|
||||
- **Do NOT flag**: em-dash formatting (`—` vs `---`), terminology choices,
|
||||
translation style, calques, word order. The manuscript English is authoritative.
|
||||
- **Do NOT apply fixes** — write `edit-suggestions.dj` only.
|
||||
- If the user asks for translation review separately, write findings to
|
||||
`translation-findings.dj`.
|
||||
@@ -0,0 +1,64 @@
|
||||
# Terms Database Alignment
|
||||
|
||||
Batch-align translation glossary entries and body text against the MPI terms database.
|
||||
|
||||
## Module API (preferred)
|
||||
|
||||
Import directly in `execute_code` scripts — no subprocess, no server, no text parsing:
|
||||
|
||||
```python
|
||||
import sys
|
||||
sys.path.insert(0, '$MPI_PROJECT_ROOT/terms-search')
|
||||
from search import search
|
||||
|
||||
results = search("三级修学", limit=5)
|
||||
results = search("空性", loc="心经", src="DoT定稿", limit=5)
|
||||
# returns list of {zh, en, loc, source} dicts
|
||||
```
|
||||
|
||||
## Batch lookup pattern
|
||||
|
||||
```python
|
||||
import sys
|
||||
sys.path.insert(0, '$MPI_PROJECT_ROOT/terms-search')
|
||||
from search import search
|
||||
|
||||
terms = ["三无漏学", "八步三禅", "闻思修", ...]
|
||||
author_sources = {"DoT定稿", "内部特色词", "佛教术语", "经论名"}
|
||||
|
||||
for term in terms:
|
||||
results = search(term, limit=10)
|
||||
relevant = [r for r in results if r["source"] in author_sources]
|
||||
for r in relevant:
|
||||
print(f"{r['zh']} → {r['en']} [{r['source']}]")
|
||||
```
|
||||
|
||||
Or filter to a single authoritative source directly:
|
||||
```python
|
||||
results = search("三级修学", src="DoT定稿", limit=5)
|
||||
```
|
||||
|
||||
## Priority ranking
|
||||
|
||||
When the same term has entries in multiple source tables, prefer:
|
||||
1. DoT定稿 (highest authority — final translation decisions)
|
||||
2. 内部特色词 (MPI internal terminology)
|
||||
3. 佛教术语 (general Buddhist terminology)
|
||||
4. 经论名 (sutra/shastra titles)
|
||||
|
||||
## Alignment workflow
|
||||
|
||||
1. Extract all Chinese glossary terms from `{% "TERM" ... %}` blocks in the .dj file
|
||||
2. Extract body-text domain terms that may not have glossary entries
|
||||
3. Batch-query each term against the HTTP API
|
||||
4. Filter results to authoritative source tables
|
||||
5. Compare DB canonical translation against current file translation
|
||||
6. Flag mismatches where DB entry differs materially from current
|
||||
7. Apply fixes with `patch` tool — fix both glossary comments AND body text occurrences
|
||||
8. Verify with `grep` that no old terms remain
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- `replace_all` can create doubled words when the surrounding context already contains the replacement string (e.g., "The Eight Steps" → "The The Eight Steps"). Prefer targeted single-replacement patches.
|
||||
- Start patches from the bottom of the file upward to preserve line numbers.
|
||||
- Some DB entries are contextual phrases (e.g., "珍惜法缘" → a full sentence), not standalone term translations. Use standalone term entries where available.
|
||||
@@ -0,0 +1,284 @@
|
||||
# Translation Pitfalls — MPI Buddhist Texts
|
||||
|
||||
Patterns found in CN→EN translation review. Add to this file as new patterns emerge.
|
||||
|
||||
## Terminology conflation
|
||||
|
||||
### 人生佛教/人间佛教 — distinct concepts
|
||||
|
||||
人生佛教 (Taixu's "Buddhism for Human Life") and 人间佛教 (Yinshun's "Humanistic Buddhism")
|
||||
are distinct doctrinal positions in modern Chinese Buddhism. Do not conflate both into
|
||||
"Humanistic Buddhism." When the source uses 人生佛教, render as "Buddhism for Human Life"
|
||||
or "Human Life Buddhism." User may propose a deliberately non-standard rendering
|
||||
("Buddhism for daily lives") — that's their call. Don't unilaterally pick from
|
||||
the standard set without checking.
|
||||
|
||||
### 心性论 → buddha-nature (WRONG)
|
||||
|
||||
心性 (mind-nature) is broader than 佛性 (buddha-nature / tathāgatagarbha).
|
||||
When a text discusses 心性 in the context of Confucian self-cultivation or general
|
||||
Buddhist psychology, use "mind-nature" or "nature of mind." Reserve "buddha-nature"
|
||||
only when the text explicitly references tathāgatagarbha doctrine.
|
||||
|
||||
### 恨 → resentment (WRONG)
|
||||
|
||||
恨 means "hatred," not "resentment." In the triad 羡慕嫉妒恨 (envy, jealousy, hatred),
|
||||
the force is strong. "Resentment" is too mild.
|
||||
|
||||
### 感悟 → conversant / heartfelt (WRONG)
|
||||
|
||||
感悟 means experiential insight or realization. It is not intellectual familiarity
|
||||
("conversant") or emotional warmth ("heartfelt"). Render as "insight," "realization,"
|
||||
or "deep understanding."
|
||||
|
||||
### 关爱/关怀 → compassion (WRONG)
|
||||
|
||||
Chinese 关爱 and 关怀 mean "care" or "loving care." They are NOT 慈悲 (compassion / karuṇā).
|
||||
Conflating them obscures two distinct Buddhist concepts.
|
||||
|
||||
Check every occurrence of "compassion" in a translation against the source:
|
||||
- If source is 关爱/关怀 → "care"
|
||||
- If source is 慈悲 → "compassion" (correct)
|
||||
- If source is 悬壶济世 → "compassionate mission" (correct — the healing spirit)
|
||||
|
||||
### 生存层面 → making a living (WRONG)
|
||||
|
||||
生存层面 = the existential/survival dimension. Not just earning wages.
|
||||
→ "survival-level needs" or "the level of basic existence"
|
||||
|
||||
### 修学 → "practice" (drops study dimension)
|
||||
|
||||
修学 combines 修 (practice/cultivation) and 学 (study/learning). Rendering only
|
||||
as "practice" loses the study dimension. Use "practice and study" or
|
||||
"cultivation and learning" — especially in 静心学堂/Dharma study contexts where
|
||||
the academic dimension is emphasized.
|
||||
|
||||
### 信仰者 → "believers" (Christian connotation)
|
||||
|
||||
信仰者 = "people of faith" but in Buddhist context, "believers" carries Christian
|
||||
overtones. Use "practitioners" or "adherents" to avoid the implication. Reserve
|
||||
"believers" for contexts where the source explicitly uses 信徒 or where the
|
||||
Christian parallel is the point.
|
||||
|
||||
## Loss of Dharma meaning
|
||||
|
||||
### 生生增上 → continuously elevate our life (INCOMPLETE)
|
||||
|
||||
生生 = life after life (multi-life Buddhist perspective). The single-life rendering
|
||||
"continuously elevate our life" loses the Dharma meaning entirely.
|
||||
→ "continuously elevate our life, life after life"
|
||||
|
||||
## Degree / register shifts
|
||||
|
||||
### "tantamount to" drops 几乎
|
||||
|
||||
几乎 = "almost." "tantamount to" = "is in fact." Dropping 几乎 strengthens the
|
||||
claim. Source "几乎等同于一次全球化运动" = "almost equivalent to a globalization
|
||||
movement," NOT "tantamount to a globalization movement."
|
||||
|
||||
### "untenable" for 都是不行的 (overstates)
|
||||
|
||||
都是不行的 = "is not acceptable / won't do." "Untenable" = "indefensible" or
|
||||
"cannot be maintained." Too strong. Use "impermissible" or "is not acceptable."
|
||||
|
||||
### "monumental event" for 大事 (slight stretch)
|
||||
|
||||
大事 = "a major event" or "an event of importance." "Monumental" is typically
|
||||
reserved for tasks, errors, or achievements (e.g. "monumental task,"
|
||||
"monumental mistake"). "Event of great importance" or "landmark event" is more
|
||||
idiomatic.
|
||||
|
||||
### "perennial" for 永恒 (wrong register)
|
||||
|
||||
永恒 = eternal/ultimate. "Perennial" = recurring (per year, per season). They
|
||||
are not synonyms. Use "eternal" or "ultimate."
|
||||
|
||||
### 学部委员 → Member (UNDERSTATES)
|
||||
|
||||
学部委员 is CASS's highest academic title, equivalent to "Academician."
|
||||
"Member" understates the prestige significantly. → "Academician" or
|
||||
"Member of the Academic Divisions."
|
||||
|
||||
### 文明 → culture (WRONG)
|
||||
|
||||
文明 is "civilization," not 文化 "culture." When a text discusses 文明传播
|
||||
(civilizational transmission), do not substitute "cultural transmission."
|
||||
|
||||
### 教制建设 → reforming (ADDS CONNOTATION)
|
||||
|
||||
教制建设 means "developing/building monastic institutions." Adding "reforming"
|
||||
introduces a connotation of fixing something broken that is not in the source.
|
||||
→ "developing monastic institutions" or "institutional development."
|
||||
|
||||
### 一荣俱荣、一损俱损 → too loose
|
||||
|
||||
This idiom has a conditional structure: "if one prospers, all prosper; if one
|
||||
suffers, all suffer." Rendering as "thrived together and suffered together"
|
||||
loses the mutual-dependence logic. → "shared prosperity and adversity alike"
|
||||
or "rose and fell together."
|
||||
|
||||
### 成圣成贤 collapsing
|
||||
|
||||
圣 (sage) and 贤 (worthy) are distinct Confucian categories. Collapsing both
|
||||
to "a sage" loses the distinction. → "sagehood and worthiness" or "a sage or worthy."
|
||||
|
||||
### "must" overuse from 应当/倡导
|
||||
|
||||
Source patterns 应当 (should), 倡导 (advocate/champion), 今后要 (going forward, should)
|
||||
often get rendered as "must" by reflex. "must" in English is a strong directive
|
||||
appropriate only for 一定要, 必须, 务必. Default to "should" or "ought to" for
|
||||
recommendations. A whole section may be 倡导 without 一定 anywhere — don't
|
||||
manufacture urgency the source doesn't have.
|
||||
|
||||
### 文明 → culture (WRONG)
|
||||
|
||||
文明 is "civilization," not 文化 "culture." When a text discusses 文明传播
|
||||
(civilizational transmission), do not substitute "cultural transmission."
|
||||
|
||||
#### 因病返贫 → "back into poverty"
|
||||
"返贫" means becoming poor due to illness, not returning to previous poverty. Use "into poverty" or "driven into poverty."
|
||||
|
||||
#### Diacritics: use DB form, not academic Sanskrit
|
||||
| Wrong | Right | Source |
|
||||
|---|---|---|
|
||||
| `Mahāsthāmaprāpta` | `Mahasthamaprapta` | 佛教术语 |
|
||||
| `Yogācārabhūmi Śāstra` | `Yogacarabhumi-Sastra` | 经论名 |
|
||||
| `Avalokiteśvara` | `Guanyin` | 佛教术语 |
|
||||
| `pravāraṇā` | `Pavarana` | BAICKZ |
|
||||
|
||||
Exception: `Kṣitigarbha` — DoT定稿 uses diacritics, so keep them.
|
||||
When in doubt, search the DB and follow the highest-priority source. See dharma-translation skill `references/diacritics-convention.md`.
|
||||
|
||||
返贫 = become poor (from a non-poor state) due to medical costs. "Back" implies
|
||||
the person was previously poor — not necessarily true. This is about medical bankruptcy.
|
||||
→ "into poverty" or "fall into poverty" (no "back")
|
||||
|
||||
## Subject-shift calques
|
||||
|
||||
When the source uses an abstract/system noun as the grammatical subject (佛教,
|
||||
文明, 宗教, 文化) and the target reflexively substitutes a more concrete
|
||||
agent (Buddhist practitioners, civilization-builders, religious people, etc.),
|
||||
the English is wrong: the source is *not* talking about people, it's talking
|
||||
about the system.
|
||||
|
||||
**Pattern**: 佛教都被社会大众赋予期望 → EN drifts to "Buddhist practitioners
|
||||
are looked upon with hope." Wrong subject — source is 佛教, not 佛教徒. Right:
|
||||
"Buddhism is regarded with hope by the broader society."
|
||||
|
||||
**Detection**: For each translated sentence, find the *grammatical subject*
|
||||
in the English and check it matches the *grammatical subject* in the Chinese.
|
||||
If the English subject is a concrete agent and the Chinese is an abstract
|
||||
system noun, it's a subject-shift calque.
|
||||
|
||||
## Factual inconsistencies across paired descriptions
|
||||
|
||||
When the same person, place, or thing is described in two different paragraphs
|
||||
(intro + later reference), check that *every* descriptor matches: title,
|
||||
affiliation, role, credentials. A translation can be factually inconsistent
|
||||
even when each individual sentence is correct in isolation.
|
||||
|
||||
**Pattern**: Prof. Wei's credentials in paragraph 1: "Academician of the
|
||||
Chinese Academy of Social Sciences (CASS) and research fellow at the
|
||||
Institute of World Religions." Paragraph 5 (same person, same source
|
||||
reference): "a member of the CASS academic committee and Director of the CASS
|
||||
Buddhist Research Center." Two different titles for the same CASS affiliation.
|
||||
One is right, the other is wrong.
|
||||
|
||||
**Detection**: For each named person, build a dict {name → {credential:
|
||||
sentence_refs}} and check that all credentials in the dict match. Same
|
||||
institution or title can have different renderings in different paragraphs.
|
||||
|
||||
## Calque checklist (subtle English calques of Chinese verbs)
|
||||
|
||||
These are common Chinese-verb → English-verb pairs where the English word
|
||||
sounds natural in isolation but is a direct calque of the Chinese. They're
|
||||
easy to miss in a first-pass review because each one parses correctly:
|
||||
|
||||
| Chinese verb | Wrong (calque) | Right (idiomatic) |
|
||||
|---|---|---|
|
||||
| 赋予 (entrust with) | "look to with hope" | "regard with hope" |
|
||||
| 得到 (obtain) | "draw forth" | "draw on" / "gain" |
|
||||
| 发挥 (bring into play) | "bring into full play" | "make the most of" |
|
||||
| 承担 (assume) | "shoulder" | "take on" |
|
||||
| 重视 | "attach importance to" | "value" / "emphasize" |
|
||||
| 体现 | "embody" / "reflect" | "show" / "demonstrate" (when abstract) |
|
||||
|
||||
**Detection**: When the English uses an unusual verb that maps 1:1 to a
|
||||
Chinese word, and the Chinese word is a high-frequency academic verb (发挥,
|
||||
承担, 体现, 重视), check whether the English reads as a calque. A common
|
||||
smell: the English verb is "correct" but more formal/dramatic than the
|
||||
surrounding prose.
|
||||
|
||||
## Tonal coherence inside a parallel list
|
||||
|
||||
When a list of items in a section should have parallel structure (e.g. three
|
||||
"champion X, oppose Y" items; six "developing X, strengthening Y" items),
|
||||
check that the *verb choice* is consistent across the list. Inconsistency
|
||||
within a parallel structure is a strong signal of drift.
|
||||
|
||||
**Pattern**: Section V lists "First, Buddhism should serve as... Second, it
|
||||
must serve as... Third, it must serve as..." Source has 应当/要做 for all
|
||||
three. The English should match: all three "should serve as" or all three
|
||||
"must serve as." Mixing is a tell.
|
||||
|
||||
**Detection**: For each parallel-list section (First/Second/Third, etc.),
|
||||
extract the verb (or other repeated slot) and verify it's identical. Drift
|
||||
inside a parallel list is one of the easiest flow issues to catch
|
||||
mechanically — just look for variance.
|
||||
|
||||
## Multi-pass review structure
|
||||
|
||||
Translation review benefits from three distinct passes, run separately, each
|
||||
catching a different category of error:
|
||||
|
||||
1. **Pass 1: terminology + consistency + line count** — fast, mechanical.
|
||||
Catches: 人生佛教/人间佛教 conflation, 修行/修学, 恨→resentment,
|
||||
paired inconsistencies (Buddhism vs Buddhist practitioners), missing
|
||||
content, wrong numerals.
|
||||
|
||||
2. **Pass 2: mechanical/formatting** — em-dash convention, double punctuation,
|
||||
numbering mismatches, capitalisation typos, garbled text. Often skipped
|
||||
if the file "looks clean." This pass is what makes the file safe to
|
||||
publish; do it even when no content issues are obvious.
|
||||
|
||||
3. **Pass 3: flow/tonal/calques** — *read the full English as a piece of
|
||||
prose*. Catch: dramatic verbs that read as calques ("draw forth,"
|
||||
"into full play," "shoulder"), intensifier drift ("profoundly important"
|
||||
× 3 in one section), consistency of "must"/"should" inside parallel
|
||||
lists, subject misattribution in calque. Often the user will prompt
|
||||
this pass with "are you sure it reads well?" or "do the words hang
|
||||
together?" Treat that prompt as a signal to re-read the whole English
|
||||
target, not just spot-check.
|
||||
|
||||
Pass 3 in particular is the one that catches the *most embarrassing* errors
|
||||
— the ones where the English is grammatical and faithful but reads as
|
||||
"translationese." Don't skip it.
|
||||
|
||||
## DoT定稿 term drift
|
||||
|
||||
### 念死 → recollection of death (WRONG per DoT定稿)
|
||||
|
||||
DoT定稿 has "Cultivating mindfulness of death" / 佛教术语 has "contemplating the
|
||||
impermanence of death". The established term is "mindfulness of death", not
|
||||
"recollection of death." → "mindfulness of death" / "death-mindfulness"
|
||||
|
||||
### 三级修学 → Three-Level Study Program (WRONG per DoT定稿)
|
||||
|
||||
DoT定稿 has "Three-Stage Practice." → "Three-Stage Practice"
|
||||
|
||||
### 下士道/中士道/上士道
|
||||
|
||||
DoT定稿: "Path for Persons of Small/Medium/Great Capacity" — not "path of the
|
||||
initial/middle/great scope."
|
||||
|
||||
### 观音菩萨 → Avalokiteśvara (AVOID in MPI translations)
|
||||
|
||||
佛教术语 has "Guanshiyin/Guanyin Bodhisattva." Use "Guanyin Bodhisattva."
|
||||
|
||||
## Workflow pitfall
|
||||
|
||||
### Translating before consulting terms DB
|
||||
|
||||
Always search key terms BEFORE translating. The dharma-translation skill says to do
|
||||
this, but it's easy to skip. Use the CLI: `$MPI_PROJECT_ROOT/terms-search/search.py <query>`.
|
||||
Prioritize DoT定稿 > 内部特色词 > 佛教术语 > 经论名.
|
||||
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Reference: reusable detection rules for Chinese→English translation review.
|
||||
Adapt the rules list for each project's domain vocabulary."""
|
||||
|
||||
import csv, re, sys
|
||||
|
||||
def review_csv(csv_path):
|
||||
rows = []
|
||||
with open(csv_path) as f:
|
||||
reader = csv.DictReader(f)
|
||||
for r in reader:
|
||||
rows.append((r.get('page', '') or '', r['Chinese'] or '', r['English'] or ''))
|
||||
|
||||
issues = []
|
||||
|
||||
def add(row_idx, cn, en, problem, suggestion):
|
||||
issues.append({
|
||||
'row': row_idx + 2,
|
||||
'page': rows[row_idx][0],
|
||||
'cn': cn, 'en': en,
|
||||
'problem': problem,
|
||||
'suggestion': suggestion
|
||||
})
|
||||
|
||||
for i, (page, cn, en) in enumerate(rows):
|
||||
if not cn or not en:
|
||||
continue
|
||||
|
||||
# ── Add project-specific detection rules below ──
|
||||
|
||||
# Example: "Is we" → machine translation artifact
|
||||
if re.search(r'\bIs we\b', en):
|
||||
add(i, cn, en,
|
||||
"'Is we' — literal MT of 是否/如果. Should be 'if we' or 'whether we'",
|
||||
re.sub(r'\bIs we\b', 'if we', en))
|
||||
|
||||
# Example: Chinese punctuation in English text
|
||||
if re.search(r'[,。;:!?、]', en):
|
||||
add(i, cn, en,
|
||||
"Chinese punctuation in English text",
|
||||
"[Replace with English punctuation]")
|
||||
|
||||
# Example: unbalanced HTML tags
|
||||
if en.count('<b>') != en.count('</b>'):
|
||||
add(i, cn, en,
|
||||
f"Unbalanced <b> tags (open={en.count('<b>')}, close={en.count('</b>')})",
|
||||
"[Balance tags]")
|
||||
|
||||
# Example: unbalanced double quotes
|
||||
if en.count('"') % 2 != 0:
|
||||
add(i, cn, en,
|
||||
f"Unbalanced quotes ({en.count(chr(34))} total)",
|
||||
"[Balance quotation marks]")
|
||||
|
||||
# Example: term inconsistency check
|
||||
# if re.search(r'TermA', en) and re.search(r'TermB', en) and ...
|
||||
|
||||
# ── Sanity checks ──
|
||||
for i, (page, cn, en) in enumerate(rows):
|
||||
if cn and not en:
|
||||
print(f"WARNING row {i+2}: CN present but EN empty: {cn[:80]}")
|
||||
cn_chars = re.findall(r'[\u4e00-\u9fff]', en)
|
||||
if cn_chars:
|
||||
print(f"WARNING row {i+2}: Chinese chars in EN: {cn_chars}")
|
||||
if cn and en and cn.strip() == en.strip():
|
||||
print(f"WARNING row {i+2}: CN==EN (untranslated): {cn[:60]}")
|
||||
|
||||
return issues
|
||||
|
||||
if __name__ == '__main__':
|
||||
issues = review_csv(sys.argv[1])
|
||||
print(f"Issues found: {len(issues)}")
|
||||
for iss in issues:
|
||||
print(f"\nCSV_ROW_{iss['row']} [{iss['page']}]")
|
||||
print(f" CN: {iss['cn'][:120]}")
|
||||
print(f" EN: {iss['en'][:120]}")
|
||||
print(f" PROBLEM: {iss['problem']}")
|
||||
print(f" SUGGEST: {iss['suggestion'][:150]}")
|
||||
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Mechanical sweep for .dj translation review — run after patches or as final verification.
|
||||
|
||||
Usage: python3 sweep.py <source.dj> <target.dj> [--stale term1,term2] [--new term1,term2]
|
||||
|
||||
Checks:
|
||||
1. Non-empty line count parity (source == target)
|
||||
2. Heading count parity
|
||||
3. Zero Markdown bold (**) in target (djot uses single *)
|
||||
5. Zero common Chinese punctuation in target
|
||||
6. Zero [text](#anchor) link artifacts in target TOC area (first 15 lines)
|
||||
7. Zero unbalanced double-quotes in target
|
||||
8. --stale: each listed string must appear ZERO times in target
|
||||
9. --new: each listed string must appear at least once in target
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
CN_PUNCT = re.compile(r'[\u3000-\u303f\uff00-\uffef\u201c\u201d\u2018\u2019]')
|
||||
|
||||
def read_nonempty(path):
|
||||
with open(path) as f:
|
||||
return [l for l in f.read().rstrip('\n').split('\n') if l.strip()]
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage: sweep.py <source.dj> <target.dj> [--stale a,b,c] [--new x,y,z]")
|
||||
sys.exit(2)
|
||||
|
||||
src_path = sys.argv[1]
|
||||
tgt_path = sys.argv[2]
|
||||
|
||||
stale_terms = []
|
||||
new_terms = []
|
||||
i = 3
|
||||
while i < len(sys.argv):
|
||||
if sys.argv[i] == '--stale' and i + 1 < len(sys.argv):
|
||||
stale_terms = [t.strip() for t in sys.argv[i+1].split(',') if t.strip()]
|
||||
i += 2
|
||||
elif sys.argv[i] == '--new' and i + 1 < len(sys.argv):
|
||||
new_terms = [t.strip() for t in sys.argv[i+1].split(',') if t.strip()]
|
||||
i += 2
|
||||
else:
|
||||
i += 1
|
||||
|
||||
src_lines = read_nonempty(src_path)
|
||||
tgt_lines = read_nonempty(tgt_path)
|
||||
tgt_raw = open(tgt_path).read()
|
||||
|
||||
errors = 0
|
||||
|
||||
# 1. Line count
|
||||
if len(src_lines) != len(tgt_lines):
|
||||
print(f"[FAIL] Line count: src={len(src_lines)} tgt={len(tgt_lines)}")
|
||||
errors += 1
|
||||
else:
|
||||
print(f"[OK] Line count: {len(src_lines)}")
|
||||
|
||||
# 2. Heading count
|
||||
src_h = sum(1 for l in src_lines if l.startswith('## '))
|
||||
tgt_h = sum(1 for l in tgt_lines if l.startswith('## '))
|
||||
if src_h != tgt_h:
|
||||
print(f"[FAIL] Headings: src={src_h} tgt={tgt_h}")
|
||||
errors += 1
|
||||
else:
|
||||
print(f"[OK] Headings: {src_h}")
|
||||
|
||||
# 3. Unicode em/en-dash
|
||||
em = tgt_raw.count('\u2014')
|
||||
en = tgt_raw.count('\u2013')
|
||||
if em or en:
|
||||
print(f"[FAIL] Unicode dashes: em-dash={em} en-dash={en}")
|
||||
errors += 1
|
||||
else:
|
||||
print("[OK] No Unicode em/en-dashes")
|
||||
|
||||
# 4. Markdown bold
|
||||
bold = sum(1 for l in tgt_lines if '**' in l)
|
||||
if bold:
|
||||
print(f"[FAIL] Markdown bold (**): {bold} lines")
|
||||
errors += 1
|
||||
else:
|
||||
print("[OK] No Markdown bold")
|
||||
|
||||
# 5. Chinese punctuation
|
||||
cn = [(i+1, l[:60]) for i, l in enumerate(tgt_lines) if CN_PUNCT.search(l)]
|
||||
if cn:
|
||||
print(f"[FAIL] Chinese/smart punct: {len(cn)} lines")
|
||||
for ln, snippet in cn[:5]:
|
||||
print(f" L{ln}: {snippet}")
|
||||
errors += 1
|
||||
else:
|
||||
print("[OK] No Chinese punctuation")
|
||||
|
||||
# 6. TOC link artifacts (first 15 lines)
|
||||
toc_links = sum(1 for l in tgt_lines[:15] if re.search(r'\[.*?\]\(#', l))
|
||||
if toc_links:
|
||||
print(f"[FAIL] TOC has [text](#anchor) links: {toc_links}")
|
||||
errors += 1
|
||||
else:
|
||||
print("[OK] TOC clean (no link artifacts)")
|
||||
|
||||
# 7. Unbalanced quotes
|
||||
for i, l in enumerate(tgt_lines):
|
||||
if l.count('"') % 2 != 0:
|
||||
print(f"[FAIL] L{i+1}: Unbalanced quotes: {l[:80]}")
|
||||
errors += 1
|
||||
if errors == sum(1 for l in tgt_lines if l.count('"') % 2 != 0):
|
||||
pass # errors already counted above
|
||||
elif not any(l.count('"') % 2 != 0 for l in tgt_lines):
|
||||
print("[OK] No unbalanced quotes")
|
||||
|
||||
# 8. Stale terms (must be absent)
|
||||
for term in stale_terms:
|
||||
count = tgt_raw.count(term)
|
||||
if count > 0:
|
||||
print(f"[FAIL] Stale term '{term}' still present: {count}")
|
||||
errors += 1
|
||||
else:
|
||||
print(f"[OK] Stale term '{term}' absent")
|
||||
|
||||
# 9. New terms (must be present)
|
||||
for term in new_terms:
|
||||
count = tgt_raw.count(term)
|
||||
if count == 0:
|
||||
print(f"[FAIL] New term '{term}' not found")
|
||||
errors += 1
|
||||
else:
|
||||
print(f"[OK] New term '{term}' found: {count}")
|
||||
|
||||
print(f"\n{'ALL CLEAN' if errors == 0 else f'{errors} ISSUE(S) FOUND'}")
|
||||
sys.exit(0 if errors == 0 else 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user