feat(documentmodus): werken op echte pagina's, alle ISO-maten en een drukkersafloop #1505

Merged
brenno merged 13 commits from feature/document-paginas into main 2026-08-16 19:34:13 +00:00
Owner

Waarom

Drie dingen die samen één vraag beantwoorden: wat komt er op welke bladzijde te staan.

1. Pagina-weergave

Naast Visueel en Bron staat nu Pagina's: het document op vellen van de gekozen maat, met de marges, de kop-/voetband en het paginanummer.

De einden worden gemeten, niet geschat. Het document wordt één keer doorlopend gerenderd, elk blok meldt via de nieuwe blockWrapper-haak zijn eigen hoogte, en documentPageOffsets bepaalt daaruit waar de vellen breken. Een blok dat nog past schuift heel door; alleen een blok dat op géén pagina past wordt gesneden.

Het is dezelfde DocumentMarkdownView als de andere twee standen — geen extra renderpad (DOCUMENT_MODE.md §2.1), alleen een ander vel eronder.

2. Alle ISO-216-maten

De vaste lijst van tien formaten liet wie op B1 of C6 drukt in de kou staan. Reeks, nummer en richting staan nu los van elkaar: alle drie de reeksen maal elf nummers, met hun afmetingen erbij — "B7" zegt niemand iets, "88 × 125 mm" wel.

3. Drukkersafloop

Een drukker snijdt op maat en snijdt nooit exact: loopt er inkt tot aan de rand, dan moet die dóór de snijlijn heen. Met een afloop wordt het vel rondom groter dan het snijformaat en schuift de tekstspiegel mee zodat hij op zijn plek blijft. Werkt in de HTML-export (@page size + bleed) en de LaTeX-export (geometry paperwidth/paperheight). Standaard 0.

Snijtekens zitten er bewust niet in. Ze stonden er eerst wél, en de bewaker blokkeerde daarop — terecht. marks:crop cross is CSS Paged Media, en de gedocumenteerde PDF-route van een document is het afdrukken van de HTML-export; geen browser kent die eigenschap. Het LaTeX-pad zou het crop-pakket nodig hebben, dat niet in elke TeX-opzet zit en hier niet te verifiëren was. Twee van de twee paden lieten de schakelaar dus vallen — en een vergroot vel zonder tekens is voor een drukker erger dan geen afloop. Eruit tot er een uitvoerpad is dat ze wél zet; een test pint vast dat de @page-regel ze niet belooft.

De afloop geldt app-breed en werkte stil door op het volgende document. Dat staat nu in de paginamaat-indicator in beeld, en de uitleg zegt het met zoveel woorden.

Wat de beeldkeuring vond (en wat daarop is hersteld)

De app is echt gedraaid en dat leverde twee fouten op die geen test zag:

  1. Elk vel toonde onderaan het begin van het blok dat juist was doorgeschoven, doormidden gesneden — en op de volgende pagina stond datzelfde blok nog eens, compleet. Het venster liep tot een volle paginahoogte in plaats van tot waar het volgende vel begint.
  2. Met een kop-/voetband verdween er tekst. De banden stonden in dezelfde kolom als de tekst en aten hoogte op waar de paginaverdeling al over had beschikt; onderaan elk vel viel een stuk tekst weg dat nergens meer terugkwam. De banden staan nu in de marge, waar ze op papier ook horen.

Twee tests pinnen het: geen venster hoger dan het tekstvlak, en een vel mét banden houdt exact dezelfde teksthoogte als een vel zonder.

Ook uit die keuring: het vel kreeg dezelfde papierkleur als het tekstvlak. Het hardgecodeerde wit was terecht vervangen door de themakleur (donkere modus), maar de weergave schildert het tekstvlak met de profielachtergrond — dat gaf een donkere rand rondom een wit tekstblok.

Bewaker

Geraadpleegd, want dit raakt een publieke belofte. Zijn oordeel over de plek van de instelling: paginamaat en marges in AppSettings zijn verdedigbaar (een .md heeft geen pagina's — dat is de winst van het formaat, niet een gebrek), maar de afloop is een eigenschap van dít drukwerk en hoort eigenlijk bij het document. Advies: één front-matter-sleutel met prefix, naar het model van de bestaande theme: — als apart, eerst ontworpen vervolg, niet in deze PR. FILE_FORMAT.md §14.7 legt nu expliciet vast dat maat, marges en afloop niet in het .md landen, zodat de byte-getrouwe round-trip uit §14.3 en de "theme: is de enige sleutel"-belofte uit §14.5 blijven staan.

Documentatie

USER_GUIDE (+ .nl), DOCUMENT_MODE §14, FILE_FORMAT §14.7, GLOSSARY (snijformaat, afloop), SOURCE_MAP en CHANGELOG. Twee restpunten staan in de commit: FILE_FORMAT.nl.md loopt structureel achter (kent hoofdstuk 14 niet) en hoort via de vertaalketen bijgewerkt, en de "laatst nagekeken"-datums zijn niet opgehoogd voor documenten die maar deels zijn nagelopen.

l10n

Elf nieuwe sleutels × 31 talen; de weesgeraakte Snijtekens is overal opgeruimd. De drukkersvakterm is niet in elke taal even vast: zeker bij de/fr/it/es/pt/pl/cs/sk/sv/da/fi/hu/hr/lt/sl/tr; voor ro/mt/id is bewust het leenwoord bleed aangehouden; el en bg kregen de eigen term terwijl drukkers daar vaak "bleed" zeggen — die twee verdienen een blik van iemand uit het vak.

Bekende gaten (niet in deze PR)

  • Vellen tonen alleen een paginanummer als het stijlprofiel een band draagt.
  • De schaal staat vast op 1,0, dus A2 en groter vallen buiten beeld.

Beide komen in de vervolgtak met de pagina-einden in de schrijfstand.

Poorten

make check groen (9500 tests, dekking 86,9%, per-bestandsvloer 0 onder de vloer). make check-secrets groen, make sast groen (0 findings). DAST niet gedraaid — geen geserveerd oppervlak geraakt.

## Waarom Drie dingen die samen één vraag beantwoorden: wat komt er op welke bladzijde te staan. ## 1. Pagina-weergave Naast Visueel en Bron staat nu **Pagina's**: het document op vellen van de gekozen maat, met de marges, de kop-/voetband en het paginanummer. De einden worden **gemeten, niet geschat**. Het document wordt één keer doorlopend gerenderd, elk blok meldt via de nieuwe `blockWrapper`-haak zijn eigen hoogte, en `documentPageOffsets` bepaalt daaruit waar de vellen breken. Een blok dat nog past schuift heel door; alleen een blok dat op géén pagina past wordt gesneden. Het is dezelfde `DocumentMarkdownView` als de andere twee standen — geen extra renderpad (DOCUMENT_MODE.md §2.1), alleen een ander vel eronder. ## 2. Alle ISO-216-maten De vaste lijst van tien formaten liet wie op B1 of C6 drukt in de kou staan. Reeks, nummer en richting staan nu los van elkaar: alle drie de reeksen maal elf nummers, met hun afmetingen erbij — "B7" zegt niemand iets, "88 × 125 mm" wel. ## 3. Drukkersafloop Een drukker snijdt op maat en snijdt nooit exact: loopt er inkt tot aan de rand, dan moet die dóór de snijlijn heen. Met een afloop wordt het vel rondom groter dan het snijformaat en schuift de tekstspiegel mee zodat hij op zijn plek blijft. Werkt in de HTML-export (`@page size` + `bleed`) en de LaTeX-export (`geometry paperwidth/paperheight`). Standaard 0. **Snijtekens zitten er bewust niet in.** Ze stonden er eerst wél, en de bewaker blokkeerde daarop — terecht. `marks:crop cross` is CSS Paged Media, en de gedocumenteerde PDF-route van een document is het afdrukken van de HTML-export; geen browser kent die eigenschap. Het LaTeX-pad zou het `crop`-pakket nodig hebben, dat niet in elke TeX-opzet zit en hier niet te verifiëren was. Twee van de twee paden lieten de schakelaar dus vallen — en een vergroot vel zonder tekens is voor een drukker erger dan geen afloop. Eruit tot er een uitvoerpad is dat ze wél zet; een test pint vast dat de `@page`-regel ze niet belooft. De afloop geldt app-breed en werkte stil door op het volgende document. Dat staat nu in de paginamaat-indicator in beeld, en de uitleg zegt het met zoveel woorden. ## Wat de beeldkeuring vond (en wat daarop is hersteld) De app is echt gedraaid en dat leverde twee fouten op die geen test zag: 1. **Elk vel toonde onderaan het begin van het blok dat juist was doorgeschoven, doormidden gesneden** — en op de volgende pagina stond datzelfde blok nog eens, compleet. Het venster liep tot een volle paginahoogte in plaats van tot waar het volgende vel begint. 2. **Met een kop-/voetband verdween er tekst.** De banden stonden in dezelfde kolom als de tekst en aten hoogte op waar de paginaverdeling al over had beschikt; onderaan elk vel viel een stuk tekst weg dat nergens meer terugkwam. De banden staan nu in de marge, waar ze op papier ook horen. Twee tests pinnen het: geen venster hoger dan het tekstvlak, en een vel mét banden houdt exact dezelfde teksthoogte als een vel zonder. Ook uit die keuring: het vel kreeg dezelfde papierkleur als het tekstvlak. Het hardgecodeerde wit was terecht vervangen door de themakleur (donkere modus), maar de weergave schildert het tekstvlak met de profielachtergrond — dat gaf een donkere rand rondom een wit tekstblok. ## Bewaker Geraadpleegd, want dit raakt een publieke belofte. Zijn oordeel over de plek van de instelling: paginamaat en marges in AppSettings zijn verdedigbaar (een `.md` heeft geen pagina's — dat is de winst van het formaat, niet een gebrek), maar de *afloop* is een eigenschap van dít drukwerk en hoort eigenlijk bij het document. Advies: één front-matter-sleutel met prefix, naar het model van de bestaande `theme:` — als apart, eerst ontworpen vervolg, niet in deze PR. FILE_FORMAT.md §14.7 legt nu expliciet vast dat maat, marges en afloop **niet** in het `.md` landen, zodat de byte-getrouwe round-trip uit §14.3 en de "`theme:` is de enige sleutel"-belofte uit §14.5 blijven staan. ## Documentatie USER_GUIDE (+ .nl), DOCUMENT_MODE §14, FILE_FORMAT §14.7, GLOSSARY (snijformaat, afloop), SOURCE_MAP en CHANGELOG. Twee restpunten staan in de commit: `FILE_FORMAT.nl.md` loopt structureel achter (kent hoofdstuk 14 niet) en hoort via de vertaalketen bijgewerkt, en de "laatst nagekeken"-datums zijn niet opgehoogd voor documenten die maar deels zijn nagelopen. ## l10n Elf nieuwe sleutels × 31 talen; de weesgeraakte `Snijtekens` is overal opgeruimd. De drukkersvakterm is niet in elke taal even vast: zeker bij de/fr/it/es/pt/pl/cs/sk/sv/da/fi/hu/hr/lt/sl/tr; voor ro/mt/id is bewust het leenwoord `bleed` aangehouden; el en bg kregen de eigen term terwijl drukkers daar vaak "bleed" zeggen — die twee verdienen een blik van iemand uit het vak. ## Bekende gaten (niet in deze PR) - Vellen tonen alleen een paginanummer als het stijlprofiel een band draagt. - De schaal staat vast op 1,0, dus A2 en groter vallen buiten beeld. Beide komen in de vervolgtak met de pagina-einden in de schrijfstand. ## Poorten `make check` groen (9500 tests, dekking 86,9%, per-bestandsvloer 0 onder de vloer). `make check-secrets` groen, `make sast` groen (0 findings). DAST niet gedraaid — geen geserveerd oppervlak geraakt.
Drie dingen die samen één vraag beantwoorden: wat komt er op welke
bladzijde te staan.

Pagina-weergave. Naast Visueel en Bron staat nu Pagina's: het document op
vellen van de gekozen maat, met de marges, de kop- en voetband en het
paginanummer erop. De einden worden niet geschat maar gemeten — het
document wordt één keer doorlopend gerenderd, elk blok meldt zijn eigen
hoogte, en documentPageOffsets bepaalt daarmee waar de vellen breken. Een
blok dat nog past schuift heel door; alleen een blok dat op geen enkele
pagina past wordt gesneden. Het is dezelfde DocumentMarkdownView als de
andere twee standen: geen extra renderpad (DOCUMENT_MODE.md §2.1), alleen
een ander vel eronder.

Alle ISO-maten. De vaste lijst met tien veelgebruikte formaten liet wie op
B1 of C6 drukt in de kou staan. Reeks, nummer en richting staan nu los van
elkaar, wat alle drie de reeksen maal elf nummers geeft — met hun
afmetingen erbij, want "B7" zegt niemand iets en "88 × 125 mm" wel.

Drukkersafloop. Een drukker snijdt op maat en snijdt nooit exact: loopt er
inkt tot aan de rand, dan moet die dóór de snijlijn heen. Met een afloop
wordt het vel rondom groter dan het snijformaat, schuift de tekstspiegel
mee zodat hij op zijn plek blijft, en kunnen er snijtekens bij. Werkt door
in de HTML- en LaTeX-export en is te zien in de pagina-weergave. Standaard
0: wie op kantoorpapier afdrukt merkt er niets van.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
De pagina-modus duwde _DocumentEditorScreenState en het bestand over hun
plafond. De rail heeft niets van het scherm nodig behalve zijn stand en wat
er bij een tik moet gebeuren — dus verhuist hij naar de part waar
_outlineItem al staat, en het scherm houdt alleen de bedrading over.
Basislijnen meegezakt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Het Semantics-label van een vel stond hardgecodeerd in het Nederlands.
Nu via l10n.d('Pagina {n} van {m}'); de vertalingen moeten er nog bij.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Drie poorten uit de suite: het vel stond op hardgecodeerd wit (in donkere
modus een verblindend blok) en gaat nu door AppTheme.paper; de basislijn
voor _DocumentEditorScreenState kon helemaal weg nu de klasse onder het
plafond zit; document_pagination.dart en paged_document_view.dart hebben
een regel in docs/SOURCE_MAP.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Als twee aan elkaar geplakte literals leest de l10n-scanner alleen het
eerste stuk, en dan is de sleutel die de vertalers krijgen een halve zin.
Nergens anders in lib/ staat een d()-sleutel gesplitst.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Het hardgecodeerde wit van het vel was terecht vervangen door de
themakleur — een verblindend blok in donkere modus is geen vel. Maar de
weergave schildert het tekstvlak met de achtergrond uit het stijlprofiel,
en die twee liepen daarmee uiteen: een donkere rand rondom een wit
tekstblok. Het vel volgt nu dezelfde kleur als waar de tekst op staat, en
valt alleen terug op de themakleur als er geen profiel is.

Een test pint de twee aan elkaar, want dit is precies het soort verschil
dat stil terugkomt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Elf nieuwe bronstrings uit de documentmodus — de knop Pagina's, het
maat-label, staand/liggend, de omschrijvingen bij de ISO-reeksen, de
afloop- en snijtekeninstellingen met hun uitleg, en het schermlezer-label
per vel — in alle 31 talen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
De bewaker blokkeerde hierop, terecht. De schakelaar zette `marks:crop
cross` in de @page-regel, maar de gedocumenteerde PDF-route van een
document is het afdrukken van de HTML-export, en geen browser kent die
eigenschap. Het LaTeX-pad zou het crop-pakket nodig hebben, dat hier niet
te verifiëren is en niet in elke TeX-opzet zit. Twee van de twee paden
lieten de schakelaar dus vallen.

Dat is erger dan hem niet hebben: de drukker krijgt een vergroot vel
zonder te weten waar het snijformaat ligt. Eruit dus, tot er een
uitvoerpad is dat ze wél zet.

De afloop zelf blijft: die werkt in beide paden, want de vergrote `size`
en `paperwidth/paperheight` worden overal gehonoreerd. Een opgeslagen
waarde uit de korte periode dat de vlag bestond wordt nog gelezen, zodat
niemands marges stil terugvallen op de standaard.

Twee dingen die de bewaker verder aanwees: de afloop geldt app-breed en
werkte stil door op het volgende document — hij staat nu in de
paginamaat-indicator, en de uitleg zegt het met zoveel woorden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
De afloopuitleg kreeg er een zin bij die waarschuwt dat de instelling
app-breed geldt en op je volgende export doorwerkt; de 31 vertalingen
volgen de nieuwe bronsleutel. De oude sleutel is verwijderd.

'Snijtekens' hoorde bij de schakelaar die in ce800701 uit de interface
verdween. Geen enkele d()-aanroep, poort of test raakte hem nog aan, dus
gaat hij uit alle 31 talen weg.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
De tak voegde een derde editorstand, het hele ISO-216-raster en een
drukkersafloop toe, maar alleen docs/SOURCE_MAP.md was bijgewerkt.

- USER_GUIDE (en + nl): de Pagina's-stand met de gemeten pagina-einden en
  de eerlijke grens (drie pagineerders, geen exacte exportvoorspelling);
  de paginamaat in reeks/nummer/richting met alle 66 maten; de afloop,
  dat er geen snijtekens zijn en dat de instelling app-breed doorwerkt.
- FILE_FORMAT: nieuwe §14.7 — maat, marges en afloop zijn instellingen en
  landen niet in het `.md`, dus de byte-getrouwe round-trip blijft heel;
  het vel reist niet mee met het bestand. De verouderde regeltelling in de
  inleiding weggehaald in plaats van hem opnieuw fout te laten worden.
- design/DOCUMENT_MODE: §14 over waarom Pagina's dezelfde render gebruikt
  (§2.1), waarom hoogtes gemeten en niet geschat worden, de snijregels, en
  waarom snijtekens er bewust niet in zitten.
- SOURCE_MAP: page_size.dart-regel klopte niet meer (tien formaten,
  widthMm/heightMm) en kende de afloop nog niet; blockWrapper en de derde
  editorstand toegevoegd.
- GLOSSARY: snijformaat en afloop uitgelegd.
- CHANGELOG: Development log-entry.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
De beeldkeuring keurde de pagina-weergave af, met reden. Twee fouten.

Elk vel toonde onderaan de eerste regels van het blok dat juist naar de
volgende pagina was geschoven, doormidden gesneden — en op de volgende
pagina stond datzelfde blok nog eens, compleet. Het venster liep tot een
volle paginahoogte in plaats van tot waar het volgende vel begint. Nu
blijft de onderkant wit, zoals op papier.

Erger: met een kop- of voetband verdween er tekst. De banden stonden in
dezelfde kolom als de tekst en aten hoogte op waar de paginaverdeling al
over had beschikt, waardoor er onderaan elk vel een stuk tekst wegviel dat
nergens meer terugkwam. De banden staan nu in de marge — waar ze op papier
ook horen — en het tekstvlak is weer het volle tekstvlak.

Twee tests pinnen het: geen venster hoger dan het tekstvlak, en een vel
mét banden houdt exact dezelfde teksthoogte als een vel zonder.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
De afloop-toevoeging aan de indicator duwde document_editor_screen.dart
en _DocumentEditorScreenState net over hun plafond. De indicator heeft
niets van het scherm nodig behalve de maat en de marges, dus staat hij
nu — net als de Overzicht-rail — als top-level bouwer in het part.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
fix(documentmodus): paginamaat-indicator krijgt zijn typen expliciet mee
All checks were successful
scans / scans (pull_request) Successful in 2m0s
static-gate / static-gate (pull_request) Successful in 4m19s
2fd11096c1
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
brenno merged commit 9cf63bb3f2 into main 2026-08-16 19:34:13 +00:00
Sign in to join this conversation.
No description provided.