11. Ligne de commande
← Bibliothèque standard · Sommaire · Suivant : recettes →
Douze commandes : quatre pour les PDF, quatre pour les scripts, deux pour la distribution et deux pour les licences.
| Commande | Rôle |
|---|---|
run |
Valide un PDF avec un script |
compare |
Compare deux versions |
watch |
Surveille un dossier et valide ce qui arrive |
fix |
Applique des modifications et enregistre un nouveau PDF |
inspect |
Vue d'ensemble rapide d'un PDF |
lint |
Analyse un script sans l'exécuter |
fmt |
Met en forme un script |
doc |
Génère la documentation d'un script |
pack |
Empaquette profils et données |
add |
Installe un paquet |
fingerprint |
Empreinte de la machine |
license |
Vérification de licence |
Codes de sortie
Communs à toutes les commandes qui valident.
| Code | Signification |
|---|---|
0 |
Tout est passé |
1 |
Avertissements seulement |
2 |
Erreurs de validation, ou PDF illisible |
3 |
Erreur de syntaxe dans le script |
pdfl run profil.pdfl fichier.pdf > rapport.json
case $? in
0) echo "approved" ;;
1) echo "approved with warnings" ;;
2) echo "rejected — see rapport.json" ;;
3) echo "error in the validation script" ;;
esac
pdfl run
Valide un PDF avec un script.
pdfl run <script.pdfl> <entree.pdf> [options]
| Option | Défaut | Rôle |
|---|---|---|
--output json|csv|html|pdf |
json |
Format du rapport |
--output-file <fichier> |
— | Écrit dans un fichier au lieu de la sortie standard |
--fail-on error|warning |
error |
Avec warning, un avertissement donne aussi le code 2 |
--verbose |
— | Informations supplémentaires sur la sortie d'erreur |
pdfl run prepresse.pdfl magazine.pdf # JSON au terminal
pdfl run prepresse.pdfl magazine.pdf --output html --output-file rapport.html
pdfl run prepresse.pdfl magazine.pdf --output pdf --output-file rapport.pdf
pdfl run prepresse.pdfl magazine.pdf --output csv --output-file constats.csv
pdfl run prepresse.pdfl magazine.pdf --fail-on warning # mode strict
Le rapport JSON
{
"script_name": "prepress.pdfl",
"input_file": "magazine.pdf",
"profile": "offset-magazine",
"status": "FAIL",
"total_pages_analyzed": 120,
"error_count": 2,
"warning_count": 0,
"info_count": 0,
"diagnostics": [
{
"id": "PDFL-001",
"severity": "error",
"check_name": "Ink coverage",
"message": "page 7: 324% ink (limit 300%)",
"line": 12
}
]
}
Le même PDF avec le même script produit toujours un rapport identique octet pour octet : on peut le versionner et comparer les différences en CI.
pdfl compare
Compare deux versions : texte, structure et métadonnées.
pdfl compare <v1.pdf> <v2.pdf> [options]
| Option | Défaut | Rôle |
|---|---|---|
--output json|csv|html|pdf |
json |
Format |
--output-file <fichier> |
— | Écrit dans un fichier |
--normalize |
— | Ignore casse et espaces |
--ignore-dates |
— | Masque les dates avant de comparer |
--similarity-threshold <0-100> |
100 |
Similarité minimale acceptable |
pdfl compare approuve_v1.pdf recu_v2.pdf --normalize --ignore-dates
# Tolère jusqu'à 1 % d'écart ; en dessous, c'est une erreur
pdfl compare v1.pdf v2.pdf --similarity-threshold 99 \
--output html --output-file differences.html
Comment ça marche
- Les pages sont mises en correspondance par leur contenu, pas par leur numéro : une page insérée au milieu ne fait pas signaler tout ce qui suit. Fonctionne sur des documents de plus de mille pages.
- Chaque paire reçoit un score de similarité et un échantillon des lignes qui
changent (
-retirée,+ajoutée). - Un changement de métadonnées est un avertissement ; un changement de texte sous le seuil est une erreur, au-dessus un avertissement.
- Le score global figure dans le champ
similaritydu rapport.
page 4 → 4: similarity 97.8% | -original title | +revised title
pdfl watch
Surveille un dossier et valide chaque PDF qui arrive ou change.
pdfl watch <dossier> --script <script.pdfl> [options]
| Option | Défaut | Rôle |
|---|---|---|
--pattern <glob> |
*.pdf |
Quels fichiers traiter |
--exclude <glob> |
— | Quels fichiers ignorer |
--output-dir <dossier> |
à côté du PDF | Où écrire les rapports |
--depth <n> |
1 |
Profondeur des sous-dossiers |
--debounce <ms> |
1000 |
Attente que le fichier se stabilise |
--report json|csv|html|pdf |
json |
Format des rapports |
--fail-fast |
— | S'arrête à la première erreur |
--once |
— | Traite l'existant puis quitte |
# Dossier de réception d'une imprimerie, en continu
pdfl watch inbox/ --script preflight.pdfl --output-dir rapports/ --report html
# Traitement par lot pour la CI : sort avec le pire code rencontré
pdfl watch inbox/ --script preflight.pdfl --once
echo "result: $?"
Le debounce existe parce qu'un gros fichier arrive par morceaux : on ne traite qu'un fichier qui a cessé de changer, donc jamais un PDF à moitié écrit.
Les rapports s'écrivent en <nom>.report.json (ou .csv, .html, .pdf).
pdfl fix
Applique les opérations fix:: et enregistre un nouveau PDF. Détails au
chapitre 8.
pdfl fix original.pdf normaliser.pdfl --output out.pdf --dry-run # voir seulement
pdfl fix original.pdf normaliser.pdfl --output corrige.pdf # appliquer
pdfl inspect
Vue d'ensemble d'un PDF, sans script.
pdfl inspect <fichier.pdf>
File: magazine.pdf
Size: 26 KB (27284713 bytes)
SHA-256: af1029842e5bfeae338ead82fb449ef851be742b1d63117c12596e3ea123a616
Pages: 120
Page size: 496 x 709 pt
Boxes: MediaBox, TrimBox, BleedBox
Metadata:
Title: Example Magazine
Creator: Adobe InDesign 19.3
Fonts: 26
ABCDEF+Helvetica — embedded
Arial — NOT embedded
Images: 81 (minimum DPI 136, spaces: DeviceCMYK, Indexed)
Max. estimated TAC: 300% (RGB render approximation)
Warnings:
! there are non-embedded fonts
! 3 image(s) below 300 DPI
La première commande à lancer quand un fichier arrive : en quelques secondes on sait s'il vaut la peine d'être ouvert.
pdfl lint
Analyse un script sans l'exécuter et signale les problèmes de qualité.
pdfl lint <script.pdfl>
Ce qu'il détecte :
- Variables, paramètres de bloc et fonctions déclarés et jamais utilisés
(préfixez par
_pour taire l'avertissement :_page) - Checks en double ou vides
- Espaces de noms inconnus (
text::,struct::,visual::,prepress::,codes::,fix::,data::) assert/requirehors d'un check- Usage de
fix::(qui ne tourne que souspdfl fix)
$ pdfl lint profil.pdfl
profil.pdfl: warning: variable 'LIMIT' declared and never used
profil.pdfl: warning: check "Fonts" declared 2 times
En présence d'avertissements, le code de sortie est 1 — utilisable en CI.
pdfl fmt
Met en forme un script : indentation de deux espaces, espacement cohérent,
lignes vides compactées. Commentaires et unités (3mm reste 3mm) sont
conservés.
pdfl fmt <script.pdfl> # met en forme sur place
pdfl fmt <script.pdfl> --check # ne modifie rien ; code 1 si non formaté
# Imposer la norme de l'équipe en CI
for f in profils/*.pdfl; do pdfl fmt "$f" --check || exit 1; done
pdfl doc
Génère la documentation à partir du script lui-même.
pdfl doc <script.pdfl> [--output markdown|html]
Il produit : le profil, un tableau des constantes, les fonctions, les imports,
et pour chaque check ses étiquettes et ce qu'il valide (les messages des
assert deviennent les descriptions).
pdfl doc prepresse.pdfl > docs/profil-prepresse.md
pdfl doc prepresse.pdfl --output html > profil.html
C'est le livrable qui explique ce que valide un profil à un responsable de fabrication qui ne lit pas le code.
pdfl pack
Empaquette scripts et données dans un .pdflpkg distribuable.
pdfl pack <dossier> [--name <nom>] [--version <version>] [--output <fichier>]
Il collecte récursivement les .pdfl, .csv, .txt, .json et .xlsx du
dossier et ajoute un manifest.json qui note le SHA-256 de chaque fichier.
L'empaquetage est déterministe : le même dossier produit les mêmes octets.
pdfl pack profils/imprimerie --name profil-impression --version 1.0.0
pdfl add
Installe un paquet local en vérifiant les empreintes du manifeste.
pdfl add profil-impression.pdflpkg
# installe dans ./pdfl_profiles/profil-impression@1.0.0/
pdfl run pdfl_profiles/profil-impression@1.0.0/prepresse.pdfl fichier.pdf
Si l'empreinte d'un fichier ne correspond pas, l'installation est refusée — un paquet corrompu ou altéré n'entre pas.
Dépôts distants et signatures numériques ne font pas partie de cette version :
addinstalle depuis un fichier local.
pdfl fingerprint
L'empreinte de cette machine — la valeur à envoyer au fournisseur pour obtenir une licence.
pdfl fingerprint generate
Elle est écrite seule sur la sortie standard ; le texte d'accompagnement va sur
la sortie d'erreur, donc pdfl fingerprint generate 2>/dev/null donne une
valeur prête à passer dans un tube.
$ pdfl fingerprint generate
Device fingerprint for this machine:
1a7553e711c53306be083ea8927c9cbe
Send it to your vendor to be issued a license.
It changes if the operating system is reinstalled.
L'empreinte vient de l'identifiant machine du système (
/etc/machine-id,IOPlatformUUIDouMachineGuid). Elle ne survit pas à une réinstallation du système, et des machines virtuelles clonées de la même image partagent la valeur. Pour la CI et les conteneurs — où la machine est détruite à chaque exécution — il y a la licenceseatless, qui ne regarde pas la machine.
pdfl license
Vérifie une licence reçue. pdfl ne fait que vérifier : les licences sont
émises par le fournisseur, avec la clé privée, qui n'accompagne pas le binaire.
pdfl license check <token>
$ pdfl license check "$(cat license.txt)"
signature: ok
customer: Example Print Shop
expires: 2027-01-01
features: all
device: 1a7553e711c53306be083ea8927c9cbe
this machine: matches
Sort avec 0 si la licence vaut pour cette machine et 2 sinon — y compris
quand la signature est bonne mais que la licence appartient à une autre machine,
cas où le message le dit explicitement.
| Option | Rôle |
|---|---|
--pubkey <base64> |
Clé publique à utiliser, au lieu de celle compilée |
Où une licence est exigée
run, fix, watch, compare et inspect s'arrêtent avec le code 2 s'il n'y
a pas de licence valable pour cette machine. fingerprint generate n'en exige
jamais — c'est lui qui produit la valeur nécessaire pour en demander une.
lint, fmt, doc et pack ne touchent que des scripts, jamais un PDF, et
n'en exigent pas non plus.
Le jeton est cherché dans cet ordre :
$PDFL_LICENSE— la voie pour la CI, où il devient un secret~/.config/pdfl/licensepdfl.licenseà côté de l'exécutable
$ pdfl run profil.pdfl fichier.pdf
error: no license found
Run 'pdfl fingerprint generate' and send the value to your vendor
to be issued a license. Then set PDFL_LICENSE, or save the token to
/home/vous/.config/pdfl/license.
Une licence
seatlessa un plafond d'exécutions, compté dans~/.config/pdfl/state. Le même fichier retient la date de la dernière exécution et refuse de tourner si l'horloge recule — avec une heure de tolérance, pour ne pas se heurter à la synchronisation de l'heure.