PDF-export: sub-hoofdstuk (##/###/####) geen weeskop, houdt 1-2 regels mee #1758

Closed
opened 2026-08-24 07:34:29 +00:00 by brenno · 0 comments
Owner

Wat wordt gevraagd

Bij de PDF-export mag een sub-hoofdstuk (##, ###, ####) nooit als laatste regel onderaan een pagina staan (weeskop / orphan). Bovendien: als er onder zon kop maar 1-2 regels tekst op dezelfde pagina passen, dan verhuist het geheel (kop + die regels) naar de volgende pagina (keep-with-next).

Onderzoek

De PDF-export gebruikt pw.MultiPage uit package:pdf voor paginering (lib/services/pdf/document_pdf_renderer.dart:200-238). MultiPage deelt de blokken zelf over bladzijden — er is geen keep-with-next- of widow/orphan-logica aanwezig.

De blokkenlaag (lib/services/pdf/document_pdf_blocks.dart) kent wel PdfPageBreakBlock (een expliciet pagina-einde), maar geen "blijf-met-het-volgende-blok"-markering. Een PdfHeadingBlock is gewoon het volgende blok in de lijst; MultiPage plaatst het waar het past, ook als dat de laatste regel van een bladzijde is.

De widgets-laag (lib/services/pdf/document_pdf_widgets.dart) zet elk blok om in één pw.Widget en geeft die lijst aan MultiPage.build. Er is geen hook om te zeggen "deze kop hoort bij het blok eronder."

package:pdfs MultiPage biedt geen native keep-with-next. De enige widgets die over een bladovergang mogen lopen zijn Flex, Table, Wrap, Column en RichText op span (zie de kop-opmerking in document_pdf_widgets.dart:8-16). Een Column die de kop én het volgende blok samen houdt, zou dus over een bladzijde heen mogen lopen — maar breekt dan wél binnen het blok, wat bij een lange alinea niet de bedoeling is.

Voorgestelde oplossing

Voeg een "keep-with-next"-regel toe in de blokkenlaag, zodat deze toetsbaar is zonder een PDF te hoeven renderen:

  1. Nieuw blok of markering: voeg een keepWithNext-veld toe aan PdfHeadingBlock (of een aparte PdfKeepWithNextBlock-wrapper), dat aangeeft dat dit blok niet als laatste op een pagina mag staan. Voor H2-H4 zet de converter dit op true.

  2. Pagineringslogica: in document_pdf_widgets.dart de blokkenlijst groeperen: een kop met keepWithNext wordt samen met het volgende blok in één pw.Column geplaatst. Omdat Column over een bladovergang mag lopen, schuift MultiPage het geheel naar de volgende pagina wanneer het niet meer past. Voor de "1-2 regels"-regel: de Column bevat de kop + het eerste volgende blok (alinea). Past dat geheel niet, dan verhuist de hele Column.

  3. Begrenzing: de Column bevat maximaal de kop + één blok (niet de hele sectie), anders kan een lange sectie niet meer breken en slaat de export stuks. De ponytail:-commentaarregel benoemt dit plafond.

  4. Tests: in test/pdf/ een test die een blokkenlijst met een H2 onderaan een bijna-vol vel voert aan de renderer en controleert dat de H2 op de volgende pagina landt. De blokkenlaag-test controleert dat keepWithNext op H2-H4 staat en niet op H1.

Impact

  • Enkel de PDF-export; de .md-bron verandert niet.
  • De LaTeX-export heeft dit gedrag van nature (\section/\subsection hebben al keep-with-next in LaTeX), dus daar is geen wijziging nodig.
  • De HTML-export kent geen paginering, dus daar evenmin.
## Wat wordt gevraagd Bij de PDF-export mag een sub-hoofdstuk (`##`, `###`, `####`) nooit als laatste regel onderaan een pagina staan (weeskop / orphan). Bovendien: als er onder zon kop maar 1-2 regels tekst op dezelfde pagina passen, dan verhuist het geheel (kop + die regels) naar de volgende pagina (keep-with-next). ## Onderzoek De PDF-export gebruikt `pw.MultiPage` uit `package:pdf` voor paginering (`lib/services/pdf/document_pdf_renderer.dart:200-238`). `MultiPage` deelt de blokken zelf over bladzijden — er is geen keep-with-next- of widow/orphan-logica aanwezig. De blokkenlaag (`lib/services/pdf/document_pdf_blocks.dart`) kent wel `PdfPageBreakBlock` (een expliciet pagina-einde), maar geen "blijf-met-het-volgende-blok"-markering. Een `PdfHeadingBlock` is gewoon het volgende blok in de lijst; `MultiPage` plaatst het waar het past, ook als dat de laatste regel van een bladzijde is. De widgets-laag (`lib/services/pdf/document_pdf_widgets.dart`) zet elk blok om in één `pw.Widget` en geeft die lijst aan `MultiPage.build`. Er is geen hook om te zeggen "deze kop hoort bij het blok eronder." `package:pdf`s `MultiPage` biedt geen native keep-with-next. De enige widgets die over een bladovergang mogen lopen zijn `Flex`, `Table`, `Wrap`, `Column` en `RichText` op `span` (zie de kop-opmerking in `document_pdf_widgets.dart:8-16`). Een `Column` die de kop én het volgende blok samen houdt, zou dus over een bladzijde heen mogen lopen — maar breekt dan wél binnen het blok, wat bij een lange alinea niet de bedoeling is. ## Voorgestelde oplossing Voeg een "keep-with-next"-regel toe in de blokkenlaag, zodat deze toetsbaar is zonder een PDF te hoeven renderen: 1. **Nieuw blok of markering:** voeg een `keepWithNext`-veld toe aan `PdfHeadingBlock` (of een aparte `PdfKeepWithNextBlock`-wrapper), dat aangeeft dat dit blok niet als laatste op een pagina mag staan. Voor H2-H4 zet de converter dit op `true`. 2. **Pagineringslogica:** in `document_pdf_widgets.dart` de blokkenlijst groeperen: een kop met `keepWithNext` wordt samen met het volgende blok in één `pw.Column` geplaatst. Omdat `Column` over een bladovergang mag lopen, schuift `MultiPage` het geheel naar de volgende pagina wanneer het niet meer past. Voor de "1-2 regels"-regel: de `Column` bevat de kop + het eerste volgende blok (alinea). Past dat geheel niet, dan verhuist de hele `Column`. 3. **Begrenzing:** de `Column` bevat maximaal de kop + één blok (niet de hele sectie), anders kan een lange sectie niet meer breken en slaat de export stuks. De `ponytail:`-commentaarregel benoemt dit plafond. 4. **Tests:** in `test/pdf/` een test die een blokkenlijst met een H2 onderaan een bijna-vol vel voert aan de renderer en controleert dat de H2 op de volgende pagina landt. De blokkenlaag-test controleert dat `keepWithNext` op H2-H4 staat en niet op H1. ## Impact - Enkel de PDF-export; de `.md`-bron verandert niet. - De LaTeX-export heeft dit gedrag van nature (`\section`/`\subsection` hebben al keep-with-next in LaTeX), dus daar is geen wijziging nodig. - De HTML-export kent geen paginering, dus daar evenmin.
brenno 2026-08-24 09:02:59 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
LibreKAT/Ocideck#1758
No description provided.