{"_id":"@astratra/pdf","name":"@astratra/pdf","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@astratra/pdf","version":"0.1.0","description":"Layout primitives for PDFKit: text that never overruns its box, and tables that paginate without splitting a row.","engines":{"node":">=20"},"main":"src/index.js","types":"src/index.d.ts","type":"commonjs","scripts":{"test":"jest"},"jest":{"testMatch":["**/__tests__/**/*.test.js"]},"keywords":["astratra","pdf","pdfkit","layout"],"license":"MIT","publishConfig":{"access":"public"},"peerDependencies":{"pdfkit":">=0.15"},"peerDependenciesMeta":{"pdfkit":{"optional":true}},"devDependencies":{"jest":"30.4.2","pdfkit":"^0.18.0"},"gitHead":"a3f7c737294561ba8651e14d507a18b41e199999","_id":"@astratra/pdf@0.1.0","_nodeVersion":"24.16.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-xFnum2C3uqf66ZX1NQn9xphjCjUohxyabiCQurwUYCCXz63gWLMKnXaqq9K399ly/R1Llzbis6VeQ8zV9nw/YA==","shasum":"7f9427d5f950c59735e5cca9479378ce7ef0cef1","tarball":"https://registry.npmjs.org/@astratra/pdf/-/pdf-0.1.0.tgz","fileCount":8,"unpackedSize":19545,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDcqliti2kqgquk1YDwLRv8LqakRvDME91ZQeGqTSvxWAiEAtYRmYB/Uyx76eWYS72wUTPBpGeM/fX37L3y1/4e5xng="}]},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"directories":{},"maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pdf_0.1.0_1787666115200_0.11095426591306379"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-25T13:55:15.005Z","0.1.0":"2026-08-25T13:55:15.328Z","modified":"2026-08-25T13:55:15.518Z"},"maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"description":"Layout primitives for PDFKit: text that never overruns its box, and tables that paginate without splitting a row.","keywords":["astratra","pdf","pdfkit","layout"],"license":"MIT","readme":"# @astratra/pdf\n\nDeux problèmes de PDFKit, résolus une fois pour toutes : du texte qui déborde de\nsa case, et des tableaux qui se coupent au mauvais endroit.\n\nCe package **n'importe pas PDFKit**. Tu lui passes ton document, il travaille\ndessus. Aucune dépendance à l'exécution.\n\n## Le texte qui déborde\n\nPDFKit, à qui l'on donne une position absolue sans largeur, laisse la chaîne\ncourir jusqu'au bord de la page puis la replie — et la ligne suivante se pose\npar-dessus ce qui était dessous. C'est ainsi qu'un nom d'école trop long passe\nsous le bandeau du titre, et qu'un libellé d'article se pose sur la colonne des\nprix.\n\nDonner une largeur ne suffit pas : depuis la 0.18, PDFKit ignore\n`lineBreak: false` dès qu'une largeur est fournie, replie quand même, et son\noption `ellipsis` ne se déclenche jamais.\n\n```js\nconst { fitText, line } = require('@astratra/pdf');\n\n// Coupé, points de suspension compris, mesuré avec la police ACTIVE.\nline(doc, school.name, 40, 100, 195);\n```\n\nUtilise `line` partout où la valeur vient de données que tu ne contrôles pas :\nun nom, un libellé, une adresse. Bornée et coupée, elle ne peut plus mordre sur\nsa voisine.\n\n### Pourquoi la mesure porte sur la hauteur\n\n`fitText` juge en demandant « est-ce que ça tient encore sur UNE ligne ? », pas\nen comparant des largeurs. Le replieur de PDFKit accumule la largeur mot à mot\net casse une ligne qui tient pourtant au point près selon la mesure d'ensemble.\nLa hauteur est la seule question dont la réponse correspond à ce qui est\nréellement dessiné — et elle vaut pour toutes les versions.\n\nLa coupe se fait par dichotomie : une recherche linéaire ferait un appel aux\nmétriques de police par caractère, et ces documents ont des centaines de\ncellules.\n\n## Le tableau qui se pagine\n\n```js\nconst { drawTable } = require('@astratra/pdf');\n\nconst { y } = drawTable(doc, {\n  x: 40, y: 170, width: 515,\n  columns: [\n    { key: 'subject', label: 'MATIÈRE', width: 200 },\n    { key: 'score',   label: 'NOTE',    width: 60, align: 'right',\n      format: (v) => `${v} / 20` },\n    { key: 'comment', label: 'APPRÉCIATION', wrap: true, fontSize: 7 },\n  ],\n  rows: results,\n  // Réserve la place du bloc de synthèse qui suit.\n  bottom: doc.page.height - 200,\n  zebra: '#FAFAFA',\n});\n```\n\nTrois comportements, chacun appris à la dure :\n\n**L'en-tête se redessine sur chaque page.** Sinon la page deux est un mur de\nchiffres sans étiquette.\n\n**La hauteur d'une rangée suit sa cellule la plus haute.** Une appréciation\nd'enseignant est une information ; la tronquer la perdrait. C'est le rôle de\n`wrap: true` — tout le reste est coupé, parce qu'une valeur qui grandit en\nsilence est une valeur qui chevauche.\n\n**Une rangée ne chevauche jamais une coupure de page.** La moitié en bas d'une\npage et la moitié en haut de la suivante se lisent comme deux rangées\ndifférentes.\n\n`bottom` est l'autre moitié de cette dernière règle : il réserve la place de ce\nqui vient **après** le tableau. Sans lui, un bloc de totaux part sur une page à\nlui tout seul, ou pire, sur le pied de page.\n\nLes colonnes sans `width` se partagent ce qui reste du cadre — déclarer chaque\nlargeur à la main est la façon dont un tableau cesse de faire la somme de son\npropre cadre après une modification.\n\n`drawTable` renvoie `{ y, pages, rows }` : `y` est le curseur pour la suite.\n\n## Le bloc qui ne se coupe pas\n\n```js\nconst { keepTogether } = require('@astratra/pdf');\n\n// Un panneau de synthèse, une ligne de signature, un total.\nlet y = keepTogether(doc, { y: cursor, height: 130 });\ndoc.rect(350, y, 205, 60).stroke();\n```\n\nLa moitié d'un bloc en bas d'une page est pire qu'une coupure avant lui.\n\n## Ce que ce package ne fait pas\n\n- Il ne **dessine pas** tes documents : facture, reçu, bulletin, c'est ton métier.\n- Il n'impose ni police, ni couleur, ni format de page.\n- Il n'importe pas PDFKit — c'est une dépendance de pair, optionnelle.\n- Il ne génère ni QR code, ni code-barres, ni image.\n\n## Tests\n\n```bash\nnpm test --workspace @astratra/pdf\n```\n\nLes tests tournent sur un vrai document PDFKit : chaque affirmation porte sur ce\nque PDFKit fait réellement des métriques de police, pas sur notre arithmétique.\n","readmeFilename":"README.md","_rev":"1-5535fe2ddcd5c8367f27b2873746d808"}