Skip to content

chore(deps): bump github.com/carlos7ags/folio in /broker#625

Open
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/go_modules/broker/go_modules-584c83515d
Open

chore(deps): bump github.com/carlos7ags/folio in /broker#625
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/go_modules/broker/go_modules-584c83515d

Conversation

@dependabot
Copy link
Copy Markdown
Contributor

@dependabot dependabot Bot commented on behalf of github Jun 3, 2026

Bumps github.com/carlos7ags/folio in /broker from 0.7.1 to 0.9.0.

Updates github.com/carlos7ags/folio from 0.7.1 to 0.9.0

Release notes

Sourced from github.com/carlos7ags/folio's releases.

v0.9.0

What's Changed

Full Changelog: carlos7ags/folio@v0.8.0...v0.9.0

v0.8.0

What's Changed

... (truncated)

Changelog

Sourced from github.com/carlos7ags/folio's changelog.

[0.9.0] - 2026-05-31

Added

  • document.WriteOptions.Deterministic + document.Document.SetFileID([]byte) — opt-in byte-reproducible output. With Deterministic set, the trailer /ID is derived from an MD5 digest of the serialized object set (the content-based file-identifier scheme of ISO 32000-1 §14.4) instead of random bytes, and the XMP CreateDate/ModifyDate plus embedded-file timestamps fall back to the zero time rather than time.Now when Info.CreationDate is unset — so identical input documents produce byte-identical PDFs. Set Info.CreationDate/ModDate so the recorded dates are meaningful rather than the year-zero default. SetFileID pins the trailer /ID directly, overriding both the random PDF/A identifier and the derived digest; a non-PDF/A document that would otherwise carry no /ID gains one. Encrypted documents are excluded — the standard security handler mints a random file identifier and derives the encryption key from it (§7.6.3.3), so their output is never byte-stable
  • html.ParseError and html.AssetError error types — a typed taxonomy so callers (e.g. a service rendering untrusted templates) can map folio failures onto a response status with errors.As. *ParseError wraps a failure to parse the input HTML into a document — an input fault; folio's lenient parser makes it rare, but it is distinct from an internal fault. *AssetError is the typed form of the failures collected under StrictAssets: it carries Category ("image", "@font-face", "background-image", "stylesheet", "SVG image", "FallbackFontPath") and Ref (the offending src/href/url/path), and Unwraps to the underlying cause so errors.Is against fs.ErrNotExist, ErrURLPolicyDenied, network errors, etc. keeps working. The joined error returned by Convert/ConvertFull contains one *AssetError per failed reference. Any error that is neither type should be treated as an internal fault. AssetError.Error() is byte-identical to the previous untyped message, so existing log/grep expectations are unchanged
  • html.Options.MaxElements / html.Options.MaxDepth resource guards + html.LimitError — bound the HTML→layout conversion so untrusted input cannot exhaust memory or the goroutine stack. MaxElements caps the number of HTML nodes converted into layout elements; MaxDepth caps the element nesting depth. Both default to 0 (unlimited), preserving existing behavior. When a ceiling is crossed, Convert/ConvertFull stop walking the tree and return a *html.LimitError (with KindLimitElements or LimitDepth — and the configured Limit), failing closed instead of continuing to allocate. The guard sits at the single convertNode chokepoint every element node flows through (the <table>/grid/flex child loops included), so all conversion paths are bounded. LimitError joins the errors.As taxonomy alongside ParseError/AssetError as an input-side fault. Page-count and output-byte ceilings live at the layout and writer layers respectively and are tracked separately
  • context.Context on the render entry pointshtml.ConvertWithContext / html.ConvertFullWithContext, (*document.Document).AddHTMLWithContext, (*document.Document).WriteToWithContext, and (*layout.Renderer).RenderContext. Each is the context-aware variant of the existing call; the original (Convert, ConvertFull, AddHTML, WriteToWithOptions, Render) is preserved and now delegates with context.Background(), so this addition is non-breaking. The context is checked at element boundaries during the HTML tree walk (the convertNode chokepoint), at page boundaries during layout (the pagination and emission loops in renderWithPlans), and at object boundaries during PDF serialization (writeObjectBodies). When the context is done, conversion/layout/serialization stops and returns ctx.Err() (context.Canceled or context.DeadlineExceeded); partial output is discarded. This lets a caller bound a render with a real per-render deadline rather than abandoning a goroutine that keeps burning a core on a pathological document. The context is held on the short-lived per-conversion/per-render worker structs (never shared or persisted), avoiding a signature change across every internal recursive call
  • Root folio package façade — a new root-level package re-exports the common document-construction surface so callers can use a single stable import path: folio.NewDocument, folio.Document, folio.PageSize (and the PageSizeA0PageSizeExecutive presets), folio.Info, folio.WriteOptions, folio.PdfAConfig, folio.EncryptionConfig. The types are aliases and the constructor/presets are value re-exports, so they are fully interchangeable with the document package identifiers and carry the complete method set. Specialized APIs (HTML conversion, layout, fonts) remain in their own subpackages; the façade covers only document construction

[0.8.0] - 2026-05-30

Visual changes

  • GPOS cursive horizontal placementdrawShapedGIDsCursive previously applied the entry/exit X delta as a Td shift on top of the glyph's natural advance, landing each joined glyph one extra advance past its predecessor. Per OpenType §6.3, in horizontal text the X component of the cursive join is already encoded by hmtx; the feature only aligns the join in Y. Documents using fonts with cursive joining (Arabic, several Indic scripts) tighten in horizontal direction. Cursive remains LTR-only; the RTL pass is gated on the LookupFlag RIGHT_TO_LEFT bit which is parsed but not yet honoured by the draw path (#220)
  • CJK paragraphs across page breaks no longer corrupt with spurious spacescloneWithWords reconstructs the overflow paragraph during page-break splitting and previously joined every same-style word with a literal " " regardless of SpaceAfter. CJK ideographs (which breakCJKWords emits with SpaceAfter=0) crossing a page break became "中 文 文 本", and the corrupted text re-wrapped to MORE lines than the original because each inserted space became a real spaceW-wide gap on re-measure. Affects any documents with CJK content that paginated in v0.7.x (#246)
  • Unicode NFC normalization is applied at every layout entry pointNewRun/NewRunEmbedded/NewParagraph*/Heading.SetRuns/Row.AddCell*/TabbedLine.SetSegments. Documents that supplied canonically decomposed strings (e.g. e + combining acute U+0301 instead of é) now measure and render against the precomposed form. Most input is already NFC, so for the majority of documents output is byte-identical; affected documents see corrected widths and shaping (font cmap tables that only cover precomposed codepoints stop falling through to .notdef) (#217)
  • Numeric font-weight against standard PDF-14 fonts now rounds at 600 — pre-fix, parseFontWeight collapsed every numeric value to the binary string "normal"/"bold" with the boundary at 700, so font-weight: 600 against Helvetica picked Helvetica (Regular). Post-fix, weights ≥ 600 select the Bold variant per CSS Fonts L4 §5.2's synthetic-bolding guidance for missing weights. So font-weight: 600 against Helvetica now picks Helvetica-Bold; font-weight: 800 continues to pick Helvetica-Bold. Documents that wrote font-weight: 600 against the standard families and expected Regular weight will see headings tighten visually. The fix also unblocks proper SemiBold/Medium rendering when the family has matching @font-face declarations — see Added (#286, #287)
  • <th> honours explicit text-align: left / start instead of silently re-centering — pre-fix, the table-cell default-center heuristic gated on cellStyle.TextAlign == AlignLeft, so an author who wrote th { text-align: left } got their explicit choice overridden because the resolved alignment matched the re-center sentinel. Post-fix, the gate is !cellStyle.TextAlignSet && resolveTextAlign(cellStyle) == AlignLeft, which preserves explicit author intent (left, or start/end resolving to left under direction). Default <th> still centers when no author choice is set. The new semantic is more spec-correct (UA stylesheet center is a default, not an override) and matches every browser. Documents that wrote th { text-align: left } and expected the silent override will see headers shift from center to left (#288)

Changed (breaking)

  • html.Options.BasePath removed; BaseFS is the single way to resolve local assets — the v0.7.x compromise that kept both fields is gone. Callers pass any fs.FS (embed.FS, os.DirFS(dir), (*os.Root).FS(), fstest.MapFS) and every local reference — <img src>, <link href>, @font-face url(), background-image: url(), and Options.FallbackFontPath — flows through it. Paths are normalised to fs.FS conventions before the read: forward slashes, no leading /, no .. traversal. A leading / in document src/href is treated as web-style root-of-BaseFS (matching how <base href="/"> works in browsers) instead of an absolute filesystem path. With BaseFS nil, every local-asset reference fails — the document is expected to inline its assets via data: URIs. The C ABI signature is unchanged: folio_document_add_html_with_options still takes a basePath C string and wraps it as os.DirFS(basePath) internally (#85)
  • @font-face URLs resolve relative to their containing stylesheet — a linked <link rel="stylesheet" href="css/site.css"> containing @font-face { src: url(../fonts/Inter.ttf); } now resolves to fonts/Inter.ttf from the BaseFS root, not from the document root. HTTP-origin stylesheets resolve relative URLs as HTTP, FS-origin stylesheets resolve them through BaseFS. Inline <style> blocks continue to resolve relative URLs from BaseFS root. Documents that previously relied on the root-anchored behavior need to use root-relative /fonts/Inter.ttf or move the @font-face rule into an inline <style>
  • layout.UnitValue is no longer comparable with == — the struct now holds a func field for the new UnitCalc variant, so equality comparisons no longer compile. No in-tree consumer compared UnitValue for equality; out-of-tree consumers that did will see a compile error and need to switch to comparing the variant tag and resolved value separately (#236)
  • layout.BackgroundImage.Position is now [2]layout.ResolvableLength — pre-change the field was [2]float64, eagerly resolved at parse time, which dropped plain lengths and mixed-unit calc on background-position to 0 because the background box dimensions are only known at draw time. Post-change the field carries a ResolvableLength per axis whose Resolve(container, fontSize float64) float64 method evaluates at draw time. A new sibling FontSize float64 field on the struct feeds em / rem resolution. Out-of-tree code that constructs BackgroundImage directly must implement the one-method ResolvableLength interface for each axis (see MIGRATING) (#266, #319)

Added

  • html.Options.Logger (*slog.Logger) — receives warn-level events when a local or remote asset fails to load: missing fonts in @font-face, unreadable linked stylesheets, image fetch errors that fall back to alt text. Defaults to nil (silent). Pair with slog.NewTextHandler(os.Stderr, nil) during development to surface what would otherwise be swallowed (#85)
  • html.Options.Client (*http.Client) — HTTP client used for remote fetches (<img>, linked stylesheets, @font-face url(http://...)). Lets callers configure timeouts, transport, and proxies; mock the network in tests via httptest.NewServer; or share connection pools with surrounding code. Defaults to http.DefaultClient (#85)
  • tmpl.RenderFile / tmpl.RenderFileTo auto-populate BaseFS — when the caller's Options.BaseFS is nil, the helpers default it to os.DirFS(filepath.Dir(templatePath)) so that a template referencing <img src="logo.png"> next to itself resolves without extra wiring
  • html.Options.StrictAssets (bool) — promotes asset-load failures from warn-and-continue to returned errors. When true, Convert and ConvertFull collect every failed @font-face url(), <img>, background-image: url(), linked stylesheet, SVG load, and FallbackFontPath, then return them joined via errors.Join at the end of the conversion. The partial result (the elements that did render) is returned alongside the error so callers can inspect both. Errors are returned in document order — linked stylesheets, @font-face rules, then asset references in tree-walk order — and are byte-stable across runs given byte-identical input. Defaults to false — production keeps the warn-and-continue behavior. Use it in development and CI to surface broken asset paths in the local feedback loop instead of letting them silently degrade the output (#232)
  • font.ParseFontForLanguage(data, lang string) (Face, error) — TTC face selection by BCP-47 language tag. Pan-CJK font collections (NotoSansCJK, Source Han Sans, Hiragino, PingFang, msgothic.ttc) ship with separate faces for Japanese, Korean, Simplified Chinese, and Traditional Chinese variants encoded in each face's NameID 1 FontFamily ("Noto Sans CJK JP", "Noto Sans CJK SC", etc.). The new entry point picks the face whose family name best matches the requested language: "zh-CN" / "zh-Hans" → SC, "zh-TW" / "zh-Hant" → TC, "ja" → JP, "ko" → KR. Empty lang (or any unrecognised hint) falls back to face 0, so ParseFont is now a thin wrapper around ParseFontForLanguage(data, "") and back-compat is preserved. Pinned by tests against synthetic 4-face TTCs and a real-system round-trip. examples/cjk updated to prefer SC-specific standalone fonts (NotoSansSC-Regular.otf, simsun.ttc) ahead of the pan-CJK TTC bundles whose default face is JP
  • html.ErrURLPolicyDenied — sentinel returned when a URLPolicy callback rejects a fetch. The denial wraps it with fmt.Errorf("%w: %w", ErrURLPolicyDenied, policyErr) so callers can branch on errors.Is(err, html.ErrURLPolicyDenied) to distinguish "I told it to block" from "the asset broke." Under StrictAssets, ErrURLPolicyDenied is logged through Options.Logger but excluded from the joined return error — the caller already received the signal they wired the policy to produce (#232)
  • font.Fallback and layout.NewParagraphFallback — Phase 1 of #192. font.Fallback wraps an ordered list of *EmbeddedFont and dispatches per script run via PickFace(firstBaseRune). NewParagraphFallback(text, fb, size) walks SegmentByScript, picks one face per script run, coalesces same-face neighbours, and emits N TextRuns. Lets a single string mixing Latin / Hebrew / Arabic / CJK render without the caller pre-splitting into per-font runs. Within-script coverage gaps still render as .notdef; per-cluster intra-script dispatch is Phase 2. Pointer identity is preserved through the fallback chain so subsetting and the page-level font-resource map keep deduping by pointer — one Type0 dict per face per document regardless of how many paragraphs share the fallback (#225)
  • layout.Paragraph.MeasureLines(maxWidth) int and MeasureHeight(maxWidth) float64 — wrapped line count and rendered height (sum of line heights, excluding SpaceBefore/SpaceAfter so callers compose with their own pagination math) at a given width. Both are thin wrappers over the existing Layout() path, so the values always agree with what the renderer will produce. Unblocks clamp/truncate decisions before render (#238)
  • layout.Paragraph.SplitAfterLine(n int, maxWidth float64) (head, tail *Paragraph) — splits a paragraph after the first n rendered lines at a given width. Both returned paragraphs are clones; the receiver is unchanged. n <= 0 returns (nil, full), n >= total lines returns (full, nil). Spacing ownership: the half that owns the original boundary keeps that spacing; FirstLineIndent is dropped from both halves so re-laying re-applies it correctly. Designed for first-N-lines-plus-appendix flows. The cloneWithWords audit chain (#238/#241/#246/#250) shipped first so the resulting clones reproduce correctly across all script families, inline elements, links, and forced line breaks (#253)
  • layout.Anchor element + auto-registered PDF named destinations<a href="#anchor"> now emits a real PDF link annotation with an internal /Dest rather than a /URI action containing the literal "#anchor". The HTML walker prepends a zero-height layout.Anchor for any element with an id attribute; the renderer surfaces these onto PageResult.Anchors, and the document layer registers them as PDF named destinations automatically — no caller doc.AddNamedDest() calls required. TextRun/Word link plumbing splits into LinkURI vs LinkDestName so a single line can carry both kinds of links (#223)
  • layout.UnitCalc variant + layout.CalcUnit(fn) constructor — a UnitValue whose value is computed lazily at layout time via a Calc func(available float64) float64 closure. Introduced so CSS lengths that depend on a percentage in a calc expression (e.g. flex: 0 0 calc(50% - 8px)) can resolve against the actual layout area at render time rather than against the pre-margin container width. Pure absolute lengths still resolve eagerly via Pt — the new variant only kicks in when the parser detects percentage participation through cssLength.dependsOnPercent() / calcExpr.dependsOnPercent() (#236)
  • document.Info.Language (BCP-47 / RFC 3066) — writes catalog /Lang per ISO 32000-2 §14.9.2 and dc:language in XMP. Required for any PDF/A Level A variant per ISO 19005-2/3 §6.7.2 (#214)
  • PDF/A-3a and PDF/A-4 familyPdfA3a (ISO 19005-3:2012, Level A) for accessibility-conformance with attachments; PdfA4 (base, PDF 2.0), PdfA4F (embedded files, Factur-X successor), PdfA4E (engineering, replaces PDF/E-1) for ISO 19005-4:2020. pdfaid:rev = "2020" emitted for part 4; pdfaid:conformance omitted for plain A-4 and present (F / E) for A-4f / A-4e. Embedded files now permitted in A-3 (a/b) and A-4 (f/e); the pdfaf extension schema is declared for every level allowing associated files (#214)
  • C ABI: folio_document_set_language(doc, lang) + FOLIO_PDFA_3A / FOLIO_PDFA_4 / FOLIO_PDFA_4F / FOLIO_PDFA_4E — companions to the new Go-side PDF/A surface. Existing FOLIO_PDFA_* numeric values are preserved (#214)
  • C ABI: folio_paragraph_measure_lines / folio_paragraph_measure_height / folio_paragraph_split_after_line — surface the new Paragraph measurement and split helpers (#238, #253) to non-Go callers. measure_lines returns int32_t (-1 on bad handle); measure_height returns double (-1.0 on bad handle); split_after_line returns two paragraph handles via out-pointers, either of which may be 0 for the no-op halves (n <= 0(0, full), n >= total(full, 0)). Receiver unchanged; caller frees non-zero halves (#283)
  • C ABI: folio_font_parse_for_language(data, length, lang) — wraps font.ParseFontForLanguage so C consumers can pick the right TTC face by BCP-47 tag ("zh-CN", "ja", etc.) for pan-CJK font collections. NULL lang falls back to face 0, matching folio_font_parse_ttf semantics. The font.Fallback / layout.NewParagraphFallback surface (#225) is intentionally NOT exposed in v0.8.0 — per its PR description, C ABI exposure is Phase 2 work tied to promoting *EmbeddedFont to an interface (#283)
  • C ABI exports grow from 388 (v0.7.1) to 393 (+5)scripts/audit-cabi.sh reports Go //export directives, export/folio.h declarations, and built dylib symbols all in sync at 393. The header is updated in lockstep with each addition
  • WASM CLI exposes pdfa3a / pdfa4 / pdfa4f / pdfa4e — and fills in profile keys the Go API already supported but the playground did not (pdfa1a, pdfa2u, pdfa2a, pdfa3b) (#214)
  • CSS :empty pseudo-class (Selectors L3 §9) — matches an element with no element children and no non-empty text children. Comments do not count as children, per spec (#215)
  • CSS ::placeholder pseudo-element (Pseudo-Elements L4) — applies to <input> and <textarea> carrying a placeholder attribute, only when the field has no value (input) or body text (textarea). Supported sub-properties: color, font-style, font-weight, font-size. Numeric font-weight values route through parseFontWeight so font-weight: 700 / bolder resolve to the bold font variant (#215)
  • Indic shaping for eight Brahmic scripts — Bengali, Gujarati, Gurmukhi, Kannada, Malayalam, Oriya, Tamil, Telugu. Generalises the previously Devanagari-only five-phase shaper around a per-script indicScriptConfig. Existing Devanagari behaviour and tests are preserved. ScriptOf / Script is extended to recognise the six new scripts (Bengali and Tamil were already mapped). Paragraph layout dispatches via indicConfigFor(Script). Gurmukhi and Tamil use rephPosNone so a leading Ra + virama + consonant in those scripts is left as a plain halant-joined cluster (#216)

... (truncated)

Commits
  • 9efa456 Merge pull request #324 from carlos7ags/feat/root-facade
  • a1977b8 folio: add root package façade re-exporting the document surface
  • bc084bf Merge pull request #323 from carlos7ags/feat/render-context
  • e50c3e2 document: check fmt.Fprintf return in deterministicFileID (errcheck)
  • b268269 render: thread context.Context through the render entry points
  • 7d1ef7f Merge pull request #322 from carlos7ags/feat/html-resource-guards
  • 08530c6 html: resource guards — Options.MaxElements / MaxDepth + html.LimitError
  • b50abf8 Merge pull request #321 from carlos7ags/feat/html-error-taxonomy
  • 8bc2469 html: typed error taxonomy — html.ParseError + html.AssetError
  • af3861a Merge pull request #320 from carlos7ags/feat/deterministic-output
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore <dependency name> major version will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)
  • @dependabot ignore <dependency name> minor version will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)
  • @dependabot ignore <dependency name> will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)
  • @dependabot unignore <dependency name> will remove all of the ignore conditions of the specified dependency
  • @dependabot unignore <dependency name> <ignore condition> will remove the ignore condition of the specified dependency and ignore conditions

Bumps [github.com/carlos7ags/folio](https://github.com/carlos7ags/folio) in `/broker` from 0.7.1 to 0.9.0.


Updates `github.com/carlos7ags/folio` from 0.7.1 to 0.9.0
- [Release notes](https://github.com/carlos7ags/folio/releases)
- [Changelog](https://github.com/carlos7ags/folio/blob/main/CHANGELOG.md)
- [Commits](carlos7ags/folio@v0.7.1...v0.9.0)

---
updated-dependencies:
- dependency-name: github.com/carlos7ags/folio
  dependency-version: 0.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go_modules
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added the deps Dependency update label Jun 3, 2026
@dependabot dependabot Bot added the deps Dependency update label Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deps Dependency update

Development

Successfully merging this pull request may close these issues.

0 participants