Skip to content

Draw list markers as text; engine v0.18.0 (escapes, counters) - #44

Merged
tannevaled merged 1 commit into
mainfrom
fix/list-markers
Oct 28, 2026
Merged

tannevaled merged 1 commit into
mainfrom
fix/list-markers

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Three defects found on 2026-10-28 rendering a report through html2pdf.Export:

  1. List markers were not painted — <ul><li> and <ol><li> showed the item text and its indent, no bullet, no number.
  2. CSS string escapes in content were painted literally — content: "\2022\00a0" printed \2022\00a0.
  3. counter() painted nothing.

Fix

  • paintBox now draws layout.Box.Marker: the engine lays an outside marker out there, outside the line boxes this package walked. Engine v0.18.0 gives every marker its text (a bullet too) with TextX/TextY/Ascent, and paintMarker draws it through the same text path as a line's words (text, factored out of paintLine), so the marker is real, extractable text. An inside marker is already an inline item of the first line.
  • github.com/go-webengine/engine v0.17.3 → v0.18.0 (css,layout,paint: list markers as text, CSS escapes, counters go-webengine/engine#323): CSS escapes decoded everywhere, counter()/counters() with counter-reset/-increment/-set, list-style-type counter styles and strings, ::marker.
  • README: a paragraph on list markers and generated content.

Tests

lists_test.go reads the PDF back with go-pdfkit/extract: markers for disc, start=3, upper-roman, inside, the escaped ::before, counter(item), counters() over nested lists, and a marker that follows its item across a page break. Planted witness: with the paintMarker call removed the tests fail.

Note: the extractor joins two drawn words with no space ("plain words" → "plainwords", on main too), so the test compares without spaces; pdftotext reads the spaces.

🤖 Generated with Claude Code

List markers were never drawn: the engine lays an outside marker out on
layout.Box.Marker, outside the line boxes paintBox walked. paintBox now
draws Marker.Text (engine v0.18.0 gives every marker its text, a bullet
too, with TextX/TextY/Ascent) through the same text path as a line's
words, so the marker is real, extractable text in the PDF. An inside
marker is already an inline item of the item's first line.

Engine v0.18.0 also decodes CSS escapes (content: "\2022\00a0" painted
the literal escape) and supports counter()/counters() with
counter-reset/-increment/-set (go-webengine/engine#323).

The tests read the PDF back with go-pdfkit/extract: markers in every
list-style-type, start=, inside, escaped content, counter() and
counters(), and a marker that follows its item to the next page. Without
the paintMarker call they fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit d32b111 into main Oct 28, 2026
1 check passed
@tannevaled
tannevaled deleted the fix/list-markers branch October 28, 2026 14:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant