7. Espace de noms `codes::` — codes-barres et QR codes
13 fonctions pour détecter, décoder et vérifier les codes-barres et QR codes d’un document.
La lecture rend les pages en haute résolution et n’a lieu qu’une fois, au premier appel d’une fonction
codes::. Un script qui n’utilise pas cet espace de noms ne paie pas ce coût.
Formats reconnus : EAN-8/13, UPC-A/E, Code 128, Code 39, ITF, QR Code, Data Matrix, Aztec et PDF417.
7.1 Détection
Section intitulée « 7.1 Détection »| Fonction | Rôle |
|---|---|
codes::detect_barcodes() |
Vrai s’il y a un code-barres |
codes::detect_qrcodes() |
Vrai s’il y a un QR code |
codes::count_barcodes() |
Nombre total de codes lus |
codes::get_barcode_type(n) |
Format du n-ième code ("EAN_13", "QR_CODE"…) |
codes::get_barcode_location(n) |
Position [page, x, y] en points, origine en bas à gauche |
check "Codes present" { assert codes::detect_barcodes(), "no barcode found in the artwork" assert codes::detect_qrcodes(), "the traceability QR code is missing"
total = codes::count_barcodes() assert total == 2, "expected 2 codes (EAN + QR), found #{total}"
type = codes::get_barcode_type(1) assert type == "EAN_13", "the main code should be EAN-13, it is #{type}"
endroit = codes::get_barcode_location(1) assert endroit.first() == 1, "barcode is not on the cover"}7.2 Décodage et vérification
Section intitulée « 7.2 Décodage et vérification »| Fonction | Rôle |
|---|---|
codes::decode_barcode(n) |
Contenu du n-ième code |
codes::validate_barcode_checksum(n) |
Clé GTIN du n-ième code |
codes::validate_gtin(text) / codes::validate_ean(text) |
Clé GTIN d’une chaîne |
codes::validate_code128() |
Vrai s’il existe un Code 128 décodé avec succès |
check "Code integrity" { code = codes::decode_barcode(1) print("code read:", code)
// Un GTIN à clé fausse est rejeté en caisse assert codes::validate_barcode_checksum(1), "invalid check digit in code #{code}" assert code.starts_with("789"), "GTIN is not Brazilian (should start with 789): #{code}"
// Recoupement avec le numéro imprimé sous le code imprime = text::extract_from_region(1, region(400, 20, 180, 15)).trim() assert codes::validate_ean(imprime), "the printed number is not a valid GTIN: #{imprime}"}7.3 Recoupements
Section intitulée « 7.3 Recoupements »| Fonction | Rôle |
|---|---|
codes::compare_barcode_with_text() |
Vrai si le contenu de chaque code apparaît dans le texte |
codes::validate_barcode_format(regex) |
Vrai si tous les contenus correspondent à l’expression |
codes::validate_barcode_position(region) ou (x0, y0, x1, y1) |
Vrai si tous les codes sont dans la zone |
compare_barcode_with_text attrape l’erreur la plus coûteuse du secteur : le
code pointe un produit, le texte imprimé en annonce un autre.
check "Cross-checks" { assert codes::compare_barcode_with_text(), "the barcode number does not appear in the text — artwork with swapped data?"
// Seul l'EAN-13 est admis : exactement 13 chiffres assert codes::validate_barcode_format("^\d{13}$"), "there is a code outside the EAN-13 pattern"
// Une région nommée se relit mieux zone = region(400, 20, 180, 80, "barcode area") assert codes::validate_barcode_position(zone), "barcode outside the reserved area of the packaging"}7.4 Exemple complet
Section intitulée « 7.4 Exemple complet »// notice.pdfl — contrôle des codes d'une notice de médicament// Usage : pdfl run notice.pdfl notice.pdfprofile "medicine-insert" {
check "Codes present" tags: ["codes"] { assert codes::detect_barcodes(), "insert has no barcode" assert codes::count_barcodes() >= 1, "expected at least the product EAN" }
check "Code integrity" tags: ["codes"] { code = codes::decode_barcode(1) type = codes::get_barcode_type(1) print("code:", type, "=", code)
assert type == "EAN_13", "main code is not EAN-13 (it is #{type})" assert codes::validate_barcode_checksum(1), "invalid check digit: #{code}" assert code.starts_with("789"), "GTIN is not Brazilian: #{code}" }
check "Cross-check with the text" tags: ["codes", "critical"] { assert codes::compare_barcode_with_text(), "the code number does not appear in the insert text" }
check "Position in the artwork" tags: ["codes", "layout"] { reservee = region(400, 20, 180, 90, "barcode area") assert codes::validate_barcode_position(reservee), "code outside the reserved area — risk of being trimmed off" }
check "Cross-check with the product database" tags: ["data"] { // Se combine avec data:: — voir le chapitre 9 code = codes::decode_barcode(1) produit = data::query_gtin(code) assert produit, "GTIN #{code} is not in the approved product database" print("product:", produit.get(2)) }}