feat(documentmodus): paginaopmaak kan met het document meereizen #1525

Merged
brenno merged 6 commits from feat/paginaopmaak-per-document into main 2026-08-17 13:50:53 +00:00
Owner

Sluit #1511. Ontwerp v2, na een blokkade van de bewaker op v1.

Waarom

Paginamaat, marges en drukkersafloop stonden alleen app-breed. Hetzelfde .md pagineerde bij een ander dus anders, en van een verstuurde PDF was nergens terug te vinden met welke instellingen hij was gemaakt. De afloop is bovendien geen voorkeur maar een eigenschap van dít drukwerk.

De sleutels: vocabulaire dat elders werkt

---
theme: LibreKAT
papersize: a4
geometry: top=25mm,bottom=25mm,left=20mm,right=20mm
---

Pandoc voert dit uit: wie het bestand door zijn eigen Pandoc haalt krijgt dezelfde pagina, zonder OciDeck.

Wat v1 blokkeerde: het eerste voorstel gebruikte ocideck_page_size: en ocideck_page_margins: 25,25,20,20,3. FILE_FORMAT.md §14.1 belooft dat OciDeck géén eigen sleutels toevoegt — theme: was daar geen uitzondering op, want die kennen Pandoc, Obsidian en GitHub al. En de compacte cijferreeks was een interne opslagvorm die publiek werd, met een echte val: die volgorde is boven,onder,links,rechts terwijl cssMargin in dezelfde klasse de CSS-volgorde boven,rechts,onder,links schrijft. Wie dat als CSS-achtig leest drukt stil een verkeerde tekstspiegel af.

Met afloop of liggend dragen expliciete maten het verhaal (paperwidth=216mm,paperheight=303mm,…), want dan is het vel niet meer het snijformaat en zou een papiernaam liegen. Bij inlezen wordt de maat teruggeleid uit het ISO-rooster en het verschil als afloop herkend.

Volgorde en schrijfgedrag

Document → instelling (effectiveDocumentPageSetup), zoals effectiveDocumentStyleName dat voor de stijl doet. Maat en marges gelden los van elkaar.

Schrijven gebeurt alleen op verzoek: de indicator in de hoek toont nu ook wáár de opmaak vandaan komt (speld = uit dit document), en een klik vraagt expliciet om bevestiging. De sleutels landen in het bestand van de gebruiker; dat hoort een besluit te zijn, geen schakelaar.

Het documentpad heeft nu een eigendomsregister (kDocumentOwnedKeys + kDocumentRetiredKeys), zoals het deckpad al had, en een ingetrokken sleutel verdwijnt bij het eerstvolgende bewuste schrijven. Zonder dat is er geen pad om een sleutel ooit nog uit bestaande bestanden te krijgen.

Twee bugs die de documentatieplicht vond

Door de code naast de tekst te leggen:

  1. De round-trip was stuk waar het het meest telde. Bij afloop of liggend schrijven we geen papersize:, maar het leespad keek alleen naar díe sleutel — dus precies de documenten die OciDeck zelf had vastgelegd vielen bij het inlezen terug op de instelling. De zoektocht over het ISO-rooster vond de maat al en gooide hem weg.
  2. De indicator merkte de verkeerde documenten aan (zelfde wortel): een document mét afloop toonde "komt uit je instellingen" en bood aan vast te leggen wat er al stond.

Beide vastgepind, inclusief een test over alle vier de combinaties staand/liggend × met/zonder afloop.

Eén die de gate vond, en die erger was dan hij leek

De klikbare indicator was een kale InkWell, en dat liet de semantiek-opbouw van Flutter vastlopen (identical(childRenderObject, parentRenderObject)). Met een schermlezer aan was dat een crash geweest, niet alleen een rode test. Het is nu een TextButton — inhoudelijk ook het juiste widget, want hij opent een dialoog en hoort dus knop-semantiek, toetsenbordfocus en een focusring te hebben. De poortwachter heeft de oorzaak vastgesteld door te bisecten en daarna gericht te variëren, niet door te gokken.

Daarnaast trapte de speld op de contrastpoort (colorScheme.primary als icoonkleur) en is dat nu AppPalette.accentInk.

Documentatie

§14.1 zegt nu expliciet wat er al gold: geen eigen vocabulaire, wél sleutels die andere gereedschappen uitvoeren. §14.5 gaat van "de enige sleutel" naar een gesloten set met register en uitgang. §14.7 kreeg een zichtbare koerswijzigingsnotitie — die paragraaf legde gisteren nog als bewuste keuze vast dat er niets naar het .md wordt geschreven, en dat stil omkeren zou navolgbaarheid kosten. Verder DOCUMENT_MODE §15, USER_GUIDE, SOURCE_MAP, GLOSSARY en CHANGELOG.

Restpunt: de .nl.md-vertalingen van FILE_FORMAT, USER_GUIDE en GLOSSARY lopen achter; die horen via make translate-docs bijgetrokken te worden, niet met de hand.

l10n

Zeven nieuwe sleutels × 31 talen. De nieuwe wezenpoort herkent ze alle zeven als gebruikt; basislijn blijft 0.

Poorten

make check groen (9585 tests, dekking 86,9%), make check-l10n-orphans groen. make check-secrets groen, make sast groen (0 findings).

Sluit #1511. Ontwerp v2, na een blokkade van de bewaker op v1. ## Waarom Paginamaat, marges en drukkersafloop stonden alleen app-breed. Hetzelfde `.md` pagineerde bij een ander dus anders, en van een verstuurde PDF was nergens terug te vinden met welke instellingen hij was gemaakt. De afloop is bovendien geen voorkeur maar een eigenschap van dít drukwerk. ## De sleutels: vocabulaire dat elders werkt ``` --- theme: LibreKAT papersize: a4 geometry: top=25mm,bottom=25mm,left=20mm,right=20mm --- ``` Pandoc voert dit uit: wie het bestand door zijn eigen Pandoc haalt krijgt dezelfde pagina, zonder OciDeck. **Wat v1 blokkeerde:** het eerste voorstel gebruikte `ocideck_page_size:` en `ocideck_page_margins: 25,25,20,20,3`. FILE_FORMAT.md §14.1 belooft dat OciDeck géén eigen sleutels toevoegt — `theme:` was daar geen uitzondering op, want die kennen Pandoc, Obsidian en GitHub al. En de compacte cijferreeks was een interne opslagvorm die publiek werd, met een echte val: die volgorde is boven,onder,links,rechts terwijl `cssMargin` in dezelfde klasse de CSS-volgorde boven,rechts,onder,links schrijft. Wie dat als CSS-achtig leest drukt stil een verkeerde tekstspiegel af. **Met afloop of liggend** dragen expliciete maten het verhaal (`paperwidth=216mm,paperheight=303mm,…`), want dan is het vel niet meer het snijformaat en zou een papiernaam liegen. Bij inlezen wordt de maat teruggeleid uit het ISO-rooster en het verschil als afloop herkend. ## Volgorde en schrijfgedrag Document → instelling (`effectiveDocumentPageSetup`), zoals `effectiveDocumentStyleName` dat voor de stijl doet. Maat en marges gelden los van elkaar. Schrijven gebeurt alleen op verzoek: de indicator in de hoek toont nu ook wáár de opmaak vandaan komt (speld = uit dit document), en een klik vraagt expliciet om bevestiging. De sleutels landen in het bestand van de gebruiker; dat hoort een besluit te zijn, geen schakelaar. Het documentpad heeft nu een **eigendomsregister** (`kDocumentOwnedKeys` + `kDocumentRetiredKeys`), zoals het deckpad al had, en een ingetrokken sleutel verdwijnt bij het eerstvolgende bewuste schrijven. Zonder dat is er geen pad om een sleutel ooit nog uit bestaande bestanden te krijgen. ## Twee bugs die de documentatieplicht vond Door de code naast de tekst te leggen: 1. **De round-trip was stuk waar het het meest telde.** Bij afloop of liggend schrijven we geen `papersize:`, maar het leespad keek alleen naar díe sleutel — dus precies de documenten die OciDeck zelf had vastgelegd vielen bij het inlezen terug op de instelling. De zoektocht over het ISO-rooster vond de maat al en gooide hem weg. 2. **De indicator merkte de verkeerde documenten aan** (zelfde wortel): een document mét afloop toonde "komt uit je instellingen" en bood aan vast te leggen wat er al stond. Beide vastgepind, inclusief een test over alle vier de combinaties staand/liggend × met/zonder afloop. ## Eén die de gate vond, en die erger was dan hij leek De klikbare indicator was een kale `InkWell`, en dat liet de semantiek-opbouw van Flutter vastlopen (`identical(childRenderObject, parentRenderObject)`). Met een schermlezer aan was dat een **crash** geweest, niet alleen een rode test. Het is nu een `TextButton` — inhoudelijk ook het juiste widget, want hij opent een dialoog en hoort dus knop-semantiek, toetsenbordfocus en een focusring te hebben. De poortwachter heeft de oorzaak vastgesteld door te bisecten en daarna gericht te variëren, niet door te gokken. Daarnaast trapte de speld op de contrastpoort (`colorScheme.primary` als icoonkleur) en is dat nu `AppPalette.accentInk`. ## Documentatie §14.1 zegt nu expliciet wat er al gold: geen eigen vocabulaire, wél sleutels die andere gereedschappen uitvoeren. §14.5 gaat van "de enige sleutel" naar een gesloten set met register en uitgang. §14.7 kreeg een **zichtbare koerswijzigingsnotitie** — die paragraaf legde gisteren nog als bewuste keuze vast dat er niets naar het `.md` wordt geschreven, en dat stil omkeren zou navolgbaarheid kosten. Verder DOCUMENT_MODE §15, USER_GUIDE, SOURCE_MAP, GLOSSARY en CHANGELOG. **Restpunt:** de `.nl.md`-vertalingen van FILE_FORMAT, USER_GUIDE en GLOSSARY lopen achter; die horen via `make translate-docs` bijgetrokken te worden, niet met de hand. ## l10n Zeven nieuwe sleutels × 31 talen. De nieuwe wezenpoort herkent ze alle zeven als gebruikt; basislijn blijft 0. ## Poorten `make check` groen (9585 tests, dekking 86,9%), `make check-l10n-orphans` groen. `make check-secrets` groen, `make sast` groen (0 findings).
Paginamaat, marges en drukkersafloop stonden alleen app-breed. Hetzelfde
.md pagineerde bij een ander dus anders, en van een verstuurde PDF was
nergens terug te vinden met welke instellingen hij was gemaakt.

Een document kan de opmaak nu zelf dragen, in vocabulaire dat Pandoc écht
uitvoert:

    papersize: a4
    geometry: top=25mm,bottom=25mm,left=20mm,right=20mm

Wie het bestand door zijn eigen Pandoc haalt krijgt dezelfde pagina,
zonder OciDeck. Een eigen ocideck_page_size-sleutel zou bytes meesturen
die alleen hier betekenis hebben, en het formaat belooft in §14.1 dat
OciDeck geen eigen sleutels toevoegt.

Met afloop dragen expliciete maten het verhaal (paperwidth/paperheight),
want dan is het vel groter dan het snijformaat en zou een papiernaam
liegen. Bij inlezen wordt de afloop teruggeleid uit het verschil met een
ISO-maat; dat is een gemak voor de interface, geen betekenis in het
bestand.

Schrijven gebeurt alleen op verzoek, via de paginamaat-indicator in de
hoek — die toont nu ook wáár de opmaak vandaan komt. Een dialoog vraagt
het expliciet: de sleutels landen in het bestand van de gebruiker, en dat
hoort een besluit te zijn dat je neemt, niet een dat je per ongeluk
aanzet.

Het documentpad heeft nu een eigendomsregister (kDocumentOwnedKeys plus
een lijst voor ingetrokken sleutels), zoals het deckpad dat al had. Zonder
dat is er geen pad om een sleutel ooit nog uit bestaande bestanden te
krijgen — de uitgang hoort net zo makkelijk te zijn als de ingang.

Ontwerp v2 op #1511, na blokkade van de bewaker op v1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Zeven nieuwe Nederlandse bronstrings uit de documenteditor krijgen een
vertaling in alle 31 talen: de twee tooltips op de paginamaat-indicator,
de dialoogtitel, de twee uitlegteksten en de twee knopstanden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
De paginaopmaak kan sinds dd737dd2 met het document meereizen, in
`papersize:` en `geometry:`. De documentatie liep daarop achter, en op
twee plekken beweerde ze het tegendeel.

FILE_FORMAT.md §14.1 maakt nu expliciet wat er al gold: OciDeck verzint
geen eigen front-matter-vocabulaire, maar schrijft wel sleutels die
andere gereedschappen uitvoeren. §14.3 en §14.5 gaan van "de enige
sleutel" naar een gesloten set, met het register `kDocumentOwnedKeys` en
de aangekondigde uitgang `kDocumentRetiredKeys` erbij — inclusief de
vermelding dat die laatste nog nergens gelezen wordt. §14.7 stelde het
niet-meereizen als bewuste keuze vast; die is niet stil omgeschreven maar
ingetrokken met een zichtbare koerswijzigingsnotitie, en de feiten staan
in een nieuwe §14.8. DOCUMENT_MODE.md §15 legt het ontwerp vast: waarom
Pandoc-vocabulaire en geen eigen prefix, en waarom de afloop als
expliciete maten gaat.

Eén bevinding staat als open punt opgeschreven (§14.8, §15.4) in plaats
van weggeschreven: het formaat wordt alleen uit `papersize:` afgeleid,
dus een document met afloop of liggend leest zijn formaat niet terug en
valt daarvoor terug op de instelling van de openende machine. Om
dezelfde reden toont de indicator zo'n document als niet-vastgelegd.

Verder USER_GUIDE (de bewering dat geen van deze instellingen iets in je
`.md` schrijft klopte niet meer), SOURCE_MAP, GLOSSARY en de
Development log.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
De documentatieplicht legde de code naast de tekst en vond twee gaten die
elkaars wortel delen.

Met een afloop of een liggende maat schrijven we geen papiernaam — die zou
liegen, want het vel is dan niet meer het snijformaat. Maar het leespad
keek alleen naar `papersize:`, dus precies de documenten die OciDeck zelf
had vastgelegd vielen bij het inlezen terug op de instelling. Een maat die
niet terugkomt maakt het vastleggen zinloos. De maat wordt nu ook uit de
expliciete millimeters in `geometry` afgeleid; de zoektocht over het
ISO-rooster deed dat werk al, maar gooide de gevonden maat weg en hield
alleen de afloop over.

Om dezelfde reden merkte de indicator juist de verkeerde documenten aan:
hij hing aan de papiernaam, dus een document met afloop toonde "komt uit
je instellingen" en bood aan vast te leggen wat er al stond.

En het register doet nu wat het belooft: een ingetrokken sleutel verdwijnt
bij het eerstvolgende bewuste schrijven, in plaats van tot in lengte van
dagen in bestaande bestanden te blijven staan.

Meegenomen: de bewering dat de geometry-string uit dezelfde bron komt als
de LaTeX-export was te stellig — de marges wel, de papiermaat niet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Het bewerkscherm stootte met de nieuwe paginaopmaak-keuze door zijn
klasseplafond (1067 > 1000). De dialoog, de padkeuze voor de export en het
insluiten van afbeeldingen hangen niet aan de staat van het scherm: die staan
nu top-level in dezelfde library, net als _documentOutlineRail en
_documentTitle. Gedrag ongewijzigd.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
fix(documentmodus): de paginamaat-indicator is een echte knop
All checks were successful
scans / scans (pull_request) Successful in 1m51s
static-gate / static-gate (pull_request) Successful in 4m11s
096dfb7e4b
De klikbare indicator was een kale InkWell over het schrijfvlak. Dat liet de
semantiek-opbouw van Flutter vastlopen op identical(childRenderObject,
parentRenderObject) — met een screenreader aan een crash, en in de suite twee
gevallen tests. Een TextButton doet hetzelfde, maar dan met knop-semantiek,
toetsenbordfocus en een focusring.

De speld en de rand gebruiken nu AppPalette.accentInk in plaats van
colorScheme.primary: primary is in een donker profiel de donkere merkkleur en
zou daar wegvallen (app_theme_contrast_test).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
brenno merged commit 8f8273d24a into main 2026-08-17 13:50:53 +00:00
Sign in to join this conversation.
No description provided.