Communitygithub.com

KiaroSama/Revayat-Novel-Skill

Compétence d'agent qui traduit un livre entier en persan de qualité publication et génère un fichier Word professionnel : OCR pour PDF scannés et mixtes, illustrations en taille réelle, notes de bas de page natives Word, table des matières cliquable, typographie RTL, glossaire de noms verrouillé. S'installe dans 8 agents de codage.

Qu'est-ce que Revayat-Novel-Skill ?

Revayat Novel est une compétence d'agent IA spécialisée dans la traduction de livres complets de l'anglais vers le persan, produisant un fichier Word de qualité publication. Elle prend en charge les PDF natifs numériques, les PDF scannés et les formats mixtes grâce à une OCR intégrée via Tesseract et OCRmyPDF. La compétence extrait le texte, détecte les illustrations dans les scans à l'aide de MinerU, et construit un fichier Word professionnel avec une typographie RTL (de droite à gauche), des notes de bas de page natives Word, une table des matières cliquable, et un glossaire de noms verrouillé pour assurer la cohérence des traductions. Elle inclut un processus de révision en plusieurs étapes : découpage par page, fusion des traductions, prévisualisation et QA visuel comparant chaque page source à sa traduction. Destinée aux traducteurs professionnels et aux éditeurs, elle s'intègre dans des agents comme Claude Code, Cursor ou Codex, et suit des règles strictes pour ne pas inverser le texte persan, ne pas modifier les identifiants des blocs, ni raccourcir le contenu. L'ensemble du pipeline est piloté par des scripts Python, avec des étapes bien définies allant de la vérification des outils à l'acceptation finale des pages traduites.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add KiaroSama/Revayat-Novel-Skill

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Revayat Novel — Traduction de livre anglais → persan

Exécutez les neuf étapes ci-dessous dans l'ordre. Chacune est une commande plus une règle sur ce qu'il faut faire avec sa sortie. N'improvisez pas un ordre différent et ne sautez pas une étape parce que la précédente semblait correcte.

Définissez quatre variables une fois, puis utilisez-les partout :

  • SKILL_DIR — le dossier contenant ce fichier. Dans un plugin Claude Code, il s'agit de ${CLAUDE_PLUGIN_ROOT}/skills/revayat-novel.
  • WORK — un dossier de travail pour ce livre, par ex. work/.
  • PY — l'interpréteur Python. Résolvez-le une fois ; python3 n'existe pas sur la plupart des installations Windows, donc une ligne de commande qui le code en dur fonctionne sur deux plateformes sur trois :
    • macOS / Linux : PY=python3
    • Windows : PY=python — ou PY="py -3" si le lanceur est ce qui est installé
    • si aucun ne fonctionne, doctor à l'étape 1 ne démarrera pas, et c'est le signal
  • OCR_LANG — le code Tesseract pour la langue imprimée dans le livre que vous traduisez, pas la langue dans laquelle vous traduisez. Pour le travail habituel anglais → persan, c'est eng. Une source persane est fas ; allemand deu, français fra, arabe ara. La même valeur doit être utilisée à chaque étape d'OCR. Reconnaître des pages anglaises avec le modèle persan renvoie un non-sens qui a l'air confiant, ce qui est pire qu'un score faible car rien en aval ne peut le voir.

Chaque commande est $PY $SKILL_DIR/scripts/revayat-novel.py <étape> ….


Les cinq règles qui ne doivent jamais être enfreintes

  1. N'inversez jamais le texte persan pour le faire lire de droite à gauche. La direction est définie par le générateur. Inverser produit un fichier qui est cassé partout sauf sur un seul visualiseur.
  2. N'inventez, ne supprimez, ne fusionnez, ne divisez et ne réordonnez jamais un en-tête @@ id. Renvoyez exactement ceux que vous avez reçus.
  3. Ne supprimez jamais un marqueur [[fn:…]], **gras**, *italique* ou `littéral`. Ils sont comptés ; une discordance échoue à l'AQ.
  4. Ne modifiez jamais manuellement book.json pour corriger une traduction. Corrigez la feuille de travail et relancez la fusion.
  5. Ne raccourcissez jamais le livre. Pas de résumé, pas de saut d'une phrase difficile, pas d'adoucissement. Si une étape signale un contenu manquant, relancez ce morceau.

Étape 1 — Vérifier les outils

$PY $SKILL_DIR/scripts/revayat-novel.py doctor
  • "ready": true → continuer.
  • "ready": false → exécutez pip install -r $SKILL_DIR/requirements.txt, puis relancez doctor.
  • optional_tools affichant not found est acceptable pour l'instant. L'étape 2 vous dira si l'OCR est réellement nécessaire.

Étape 2 — Extraire

$PY $SKILL_DIR/scripts/revayat-novel.py extract "<fichier d'entrée>" --out $WORK --ocr-lang $OCR_LANG

$OCR_LANG est la langue imprimée dans le livre, définie une fois ci-dessus. Se tromper ici n'est pas un échec visible : l'OCR renvoie toujours du texte, c'est simplement le mauvais texte.

Lisez le JSON qu'il imprime et suivez le tableau :

Ce que vous voyezCe qu'il faut faire
"kind": "digital"rien ; aucune OCR n'était nécessaire
"kind": "scanned" ou "mixed"l'OCR s'est exécutée automatiquement ; vérifiez que ocr.probe_after.text_share est supérieur à 0.7
une erreur nommant OCRmyPDFinstallez-la comme le message le dit, puis relancez cette étape
clean_scan.cleaned supérieur à 0un filigrane couleur a été supprimé de ce nombre de pages
ocr.warning n'est pas nullisez-le ; le fichier était toujours utilisable, donc continuez
page_scans_dropped supérieur à 0ce nombre de rasters pleine page ont été reconnus comme le scan lui-même, pas comme des images

Le nettoyeur ne modifie jamais votre fichier : l'original reste intact et la copie nettoyée est écrite dans $WORK/cleaned.pdf, avec un enregistrement par page dans clean_scan de ce qui a été supprimé et de ce qui a été laissé intact. Passez --clean-scan off pour l'ignorer complètement, ou --clean-scan force lorsqu'un tampon a survécu.

Si le livre a été scanné, effectuez ces deux passes supplémentaires maintenant.

Confiance de reconnaissance — sans elle, un mot mal lu est impossible à distinguer d'un mot correct, car les deux sont des mots ordinaires de la langue source, situés dans une phrase grammaticale. Rien plus tard dans le pipeline ne peut les différencier, et le traducteur rendra fidèlement le mauvais.

$PY $SKILL_DIR/scripts/revayat-novel.py ocr-sidecar \
  --pdf $WORK/ocr.pdf --out $WORK --lang $OCR_LANG --book $WORK/book.json

--lang ici est le même $OCR_LANG que vous avez donné à extract. Il doit l'être : cette passe re-reconnaît les mêmes pages pour savoir à quel point le moteur était sûr, donc un modèle différent lit des mots différents et note quelque chose que le livre ne dit pas.

Ceci écrit source.ocr.json — boîte, confiance et ordre de lecture pour chaque mot, agrégés jusqu'à la ligne, le bloc et la page, plus le prétraitement qui a été exécuté — et source.ocr.txt, puis estampe chaque bloc dans book.json avec la confiance de la région dont il provient. Les blocs classés low sont signalés par qa check comme ocr-low-confidence, et en accepter un signifie regarder l'image de la page. Les seuils par défaut sont 85 et 60 et se déplacent avec --high / --low.

Illustrations à l'intérieur d'un scan — une page scannée est une image plate unique, donc une photographie dessus n'est pas une image séparée tant que quelque chose ne la trouve pas :

mineru -p $WORK/cleaned.pdf -o $WORK/mineru -b pipeline -l en
$PY $SKILL_DIR/scripts/revayat-novel.py extract "<fichier d'entrée>" --out $WORK \
  --figures-from-mineru $WORK/mineru

Le -l de MinerU prend ses propres codes, pas ceux de Tesseract : en pour une source anglaise, arabic pour l'écriture persane ou arabe. Faites-le correspondre au livre, de la même manière que $OCR_LANG est mis en correspondance — la détection de la mise en page utilise l'écriture pour segmenter la page.

Exécutez MinerU sur cleaned.pdf, pas sur l'original, sinon il recadre le filigrane comme s'il s'agissait d'une figure. Ne prenez que les images de MinerU. Mesuré sur un vrai scan persan, son propre texte reconnu est revenu avec les mots et les lettres à l'intérieur inversés, tandis que Tesseract a lu la même page correctement — donc le texte continue de provenir de la passe OCR ci-dessus et MinerU n'est utilisé que pour la seule chose que l'OCR ne peut pas faire, qui est de trouver où se trouve une image dans un raster plat. Utilisez --figures-page-offset N lorsque MinerU a été exécuté sur une plage de pages.

Ensuite, regardez le résultat avant d'aller plus loin :

$PY $SKILL_DIR/scripts/revayat-novel.py qa check --book $WORK/book.json --allow-incomplete

Ignorez untranslated-block ici — rien n'est encore traduit. Vous cherchez asset-missing. Si stats.text_blocks est inférieur à 20 pour un vrai livre, l'extraction a échoué : voir references/extraction.md.

Étape 3 — Glossaire

$PY $SKILL_DIR/scripts/revayat-novel.py glossary scan \
  --book $WORK/book.json --out $WORK/glossary.json

Le rapport liste needs_persian, les plus fréquents en premier. Ouvrez $WORK/glossary.json et pour chacune des 20 premières entrées, remplissez quatre champs :

"target":      "الیزابت بنت",
"later_form":  "الیزابت بنت",
"first_form":  "الیزابت بنت (Elizabeth Bennet)",
"locked":      true

Lorsqu'une entrée a des aliases — un nom de famille ou un prénom que le livre utilise seul — mettez leur persan dans alias_targets :

"aliases":       ["Ashcroft", "Margaret"],
"alias_targets": ["اشکرافت", "مارگارت"]

Là où la source dit seulement « Ashcroft », le persan doit dire seulement « اشکرافت ». Laisser ceci vide fait que la vérification de dérive exige le nom complet à chaque fois, ce qui est à la fois un pire persan et une fausse alerte.

Laissez first_block_id exactement comme il est — le pipeline l'utilise pour décider quel seul morceau introduit le nom. Ne le modifiez pas et ne décidez pas vous-même des premières mentions.

Supprimez les entrées qui ne sont pas de vrais noms. Ensuite, continuez.

Étape 4 — Découper en feuilles de travail

Un roman entier ne doit jamais atteindre le contexte d'un modèle, donc il est d'abord découpé. Il y a deux façons de découper, et la source décide laquelle — ce n'est pas une préférence :

SourceChemin
PDF, natif numérique ou scannépar page — ci-dessous
EPUB, DOCX, texte brutpar budget de caractères — étape 4b

Découpez un PDF par page. Une page est une frontière que le livre a déjà : stable entre les exécutions, l'unité qu'un relecteur regarde, et la seule unité avec laquelle une page rendue peut être comparée. Une feuille de travail découpée par budget de caractères se casse là où le budget s'épuise, ce qui n'est nulle part en particulier — et une page qui n'existe pas dans la source ne peut pas être vérifiée par rapport à la source. Les formats en dessous de la ligne n'ont pas de pages propres sur lesquelles découper, donc ils prennent la voie du budget et abandonnent cette vérification.

$PY $SKILL_DIR/scripts/revayat-novel.py pages build \
  --book $WORK/book.json --out $WORK/pages --glossary $WORK/glossary.json

Ceci écrit une feuille de travail par page source — page0001.md, et sa traduction va dans out_page0001.md à côté. Utilisez ces noms, pas le chunkNNNN.md de l'étape 5 : le format est identique, seuls les noms de fichiers diffèrent, et pages next vous dit exactement quel fichier ouvrir, donc il n'y a rien à deviner.

Il écrit aussi $WORK/pages/source/page-0001.pdf — chaque page source comme son propre PDF, copié plutôt que re-rendu, donc les boîtes, la rotation et la qualité d'image sont celles du livre. Le manifeste enregistre chacune avec son SHA-256, et nomme le reference_pdf à partir duquel l'ensemble de la série a été lu. Lisez le PDF source à partir du manifeste ; c'est l'original pour un livre natif numérique et la copie OCRisée pour un scan, et coder en dur l'un ou l'autre est faux pour l'autre.

Chaque travail de page ne transporte que ce dont il a besoin : les lignes du glossaire qui s'appliquent à cette page, les voix qui y parlent, les mots dont l'OCR n'était pas sûr, et une tranche limitée des pages voisines marquées à ne pas traduire. Une page dont le propre texte dépasse le budget est divisée en parties numérotées plutôt que tronquée — part et parts dans le manifeste le disent — et les parties se rejoignent avant que la page ne soit jugée.

Un paragraphe que la césure de page a coupé en deux appartient à la page sur laquelle il a commencé et est traduit exactement une fois ; la page sur laquelle il se poursuit ne le voit que comme contexte. Ne traduisez jamais un bloc qui apparaît sous l'en-tête de contexte voisin — il appartient déjà à la feuille de travail d'une autre page.

$PY $SKILL_DIR/scripts/revayat-novel.py pages status --pages $WORK/pages
$PY $SKILL_DIR/scripts/revayat-novel.py pages next   --pages $WORK/pages

status rapporte l'état de chaque page ; next nomme la première page encore à faire, donc une exécution interrompue reprend là où elle s'est arrêtée plutôt qu'au début.

La boucle de pages

Le PDF source est celui à partir duquel cette exécution a été lue : celui du livre pour un PDF natif numérique, la copie OCRisée pour un scan. Le manifeste l'a enregistré — prenez-le de là plutôt que de nommer un fichier qui peut ne pas exister.

SOURCE_PDF=$($PY -c "import json,sys;print(json.load(open(sys.argv[1]))['reference_pdf'])"   $WORK/pages/manifest.json)

Une page à la fois, dans cet ordre. Chaque commande a besoin de ce que la précédente a produit, donc une étape prise tôt refuse simplement :

P=12   # quel que soit le nom que `pages next` vient de donner

# 3. intégrer la traduction dans le livre
$PY $SKILL_DIR/scripts/revayat-novel.py pages merge \
  --book $WORK/book.json --pages $WORK/pages --page $P --glossary $WORK/glossary.json

# 4. mettre en page cette seule page seule
$PY $SKILL_DIR/scripts/revayat-novel.py pages preview \
  --book $WORK/book.json --pages $WORK/pages --page $P

# 5. la comparer avec la page source
$PY $SKILL_DIR/scripts/revayat-novel.py render-qa \
  --book $WORK/book.json --work $WORK --page $P \
  --docx $WORK/previews/page-0012.docx --source-pdf $SOURCE_PDF

# 6. regarder les deux images (l'étape 8 dit quoi chercher)
$PY $SKILL_DIR/scripts/revayat-novel.py pages review \
  --pages $WORK/pages --page $P \
  --answer figure-placement=yes --answer script-integrity=yes \
  --answer no-source-language=yes --answer hierarchy=yes \
  --answer reads-as-a-book=yes --note "ce que vous avez vu"

# 7. seulement maintenant
$PY $SKILL_DIR/scripts/revayat-novel.py pages accept \
  --book $WORK/book.json --pages $WORK/pages --page $P

Ensuite, pages next à nouveau, jusqu'à ce qu'il dise qu'il ne reste rien.

L'étape 4 n'est pas facultative et l'étape 5 le fera pour vous si vous l'ignorez — laissez --docx de côté et render-qa construit l'aperçu lui-même. La commande explicite est là pour quand vous voulez ouvrir la page dans Word et la regarder vous-même.

L'aperçu est une page source, mise en page seule. Ce n'est en aucun cas le livre entier : le persan se refusionne, donc la page source 12 ne devient pas la page 12 du livre, et au milieu d'un roman, la dérive est de plusieurs pages. Vérifier la douzième feuille du livre par rapport aux attentes de la page 12 signale une page correcte comme manquant tout son texte et portant celui de son voisin. L'aperçu est défini avec le générateur de production — mêmes styles, polices, RTL, dimensionnement des images, logique des en-têtes — donc ce que vous regardez est la véritable composition de contenu réel.

Une page dont le persan est plus long que son anglais ressort sous forme de deux feuilles. C'est normal, les deux sont conservées comme renders/target/page-0012.png et page-0012-2.png, et l'AQ les lit toutes.

accept refuse à moins que chaque porte n'ait réellement passé — il lit les preuves plutôt que de vous croire sur parole, donc une page ne peut pas être marquée comme faite en affirmant qu'elle l'est. Il veut quatre choses : du persan dans le livre pour chaque unité que la page a envoyée, une passe d'AQ de rendu sur l'enregistrement de l'exécution, un rapport qui le dit toujours, et un examen visuel actuel.

La reconstruction est sûre et ne jette jamais une traduction. Une page dont le texte source a changé depuis la dernière découpe est listée sous invalidated — celles-ci, et seulement celles-ci, ont besoin d'être retraduites. Une feuille de travail restante d'une reconstruction à un budget différent est listée sous orphaned : elle est toujours sur le disque, mais plus rien ne la lit, donc sa traduction n'atteindra pas le livre.

Étape 4b — Quand la source n'a pas de pages

EPUB, DOCX et texte brut uniquement. Pour un PDF, utilisez l'étape 4.

$PY $SKILL_DIR/scripts/revayat-novel.py chunk build \
  --book $WORK/book.json --out $WORK/chunks --glossary $WORK/glossary.json

Notez le nombre de morceaux. Chacun devient une tâche de traduction.

Si vous avez déjà traduit des feuilles de travail et qu'une entrée a changé depuis, ceci refuse avec "refused": "stale-worksheets" plutôt que de vous remettre silencieusement des feuilles de travail qui ne correspondent plus au livre.

…

[tronqué pour la traduction]

Skills associés