arrolio 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CLAUDE.md +17 -20
- data/TODO.complete/96-pagination-drift-parity.md +22 -0
- data/TODO.complete/README.md +6 -4
- data/lib/arrolio/flowable.rb +14 -0
- data/lib/arrolio/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 057f22d28911ebd5fb250d0a3ee3aae065a493c2c8aee0a5ff329a138da38674
|
|
4
|
+
data.tar.gz: 8477b14736601c87ee24c690aa867ef175de94568ef866b48d260948c3d98116
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2aef88dd6df44e8aef2be218f34f53de0e332ecfb94bc2ef5aa8a87f0221fab634ac05ad0a900997fc1ebb870529626a464eeaa302c7f3e19d1b05664bfd7e90
|
|
7
|
+
data.tar.gz: b984b3dae46396305d96e5c6977a24992c4ddae317be8a4682fafed9de46a35a7e2442dbc418147c77afb943ba7981c6b8be28b562b85723fe5624b3242b6c7c
|
data/CLAUDE.md
CHANGED
|
@@ -53,16 +53,17 @@ PDF bytes (via Pdfrb)
|
|
|
53
53
|
|
|
54
54
|
Each layer is independently testable. Keep layer boundaries airtight: Content knows nothing about pages or PDF; Engine knows nothing about PDF bytes; Renderer knows nothing about layout algorithms.
|
|
55
55
|
|
|
56
|
-
## Project state (as of 2026-
|
|
56
|
+
## Project state (as of 2026-09-01)
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
The generic config-driven pipeline renders the OIML r060/1 fixture to a 28-page A4 PDF matching the mn2pdf v2.55 reference at **68.92% text parity, 28/28 pages** (`bundle exec rake parity:check`). 452 specs, 0 rubocop offenses, 214 files.
|
|
59
59
|
|
|
60
60
|
What's in the gem (core, flavor-agnostic):
|
|
61
61
|
- `lib/arrolio/{content,style,layout_spec,font,font_metrics,glyph_measurer,inline_run,text_layout,flowable,flowables,frame,flow_context,engine,output,renderer,harness,flavor}/`
|
|
62
|
-
- `lib/
|
|
63
|
-
- `lib/
|
|
64
|
-
- `lib/
|
|
65
|
-
- `lib/
|
|
62
|
+
- `lib/arroolio/generic_adapter.rb` — dispatch + document glue; per-concern conversion lives in included seams under `lib/arroolio/generic_adapter/` (FootnoteExtraction, TableConversion, InlineRunCollection, HeadingExtraction, ListConversion, MetadataExtraction, DocumentExtraction). Adding an element family = a module + one include.
|
|
63
|
+
- `lib/arroolio/generic_flow_builder.rb` — `build()` + dispatch; per-family emission seams under `lib/arroolio/generic_flow_builder/` (Sequences, Terms, Notes, Figures, Lists, Bibliography, Tables).
|
|
64
|
+
- `lib/arroolio/config_driven_pipeline.rb` — orchestrates adapter + flow builder + engine + renderer + ToC; resolves fonts via fontist (`FontScanner`).
|
|
65
|
+
- `lib/arroolio/renderer/pdf.rb` — page emission; Pdfrb coupling points in `lib/arroolio/renderer/pdf/` (FontEmbedding, Assets, Metadata). The renderer never measures glyph widths — `Line::PlacedRun` carries `chunk_widths` from the breakers.
|
|
66
|
+
- `lib/arroolio/asset_resolver.rb`, `lib/arroolio/toc_builder.rb` — generic helpers (both with direct specs).
|
|
66
67
|
- `exe/arrolio2pdf` — generic CLI taking a flavor directory argument.
|
|
67
68
|
- `scripts/xsl_to_config.rb` — generates all three flavor YAML files from an XSL stylesheet.
|
|
68
69
|
- `data/arrolio/` — AFM metrics + glyphlist for the 14 PDF standard fonts (core data, not flavor data).
|
|
@@ -71,18 +72,13 @@ What's outside the gem (flavor artifacts):
|
|
|
71
72
|
- `flavors/oiml/{layout_spec,adapter_rules,flow_rules}.yml` — generated by `xsl_to_config.rb` from the authoritative XSL at `~/src/mn/metanorma-taste/data/oiml/oiml.xsl`.
|
|
72
73
|
- `spec/fixtures/flavors/sample/` — synthetic flavor-neutral fixture for the gem's tests.
|
|
73
74
|
|
|
74
|
-
What's
|
|
75
|
-
- TODO
|
|
76
|
-
- TODO
|
|
77
|
-
- TODO
|
|
78
|
-
- TODO
|
|
79
|
-
- TODO
|
|
80
|
-
-
|
|
81
|
-
- TODO 59: XSL converter profiles (metanorma, dita, docbook).
|
|
82
|
-
- TODO 60: footnote / note-hanging-indent / example-body-margin fidelity.
|
|
83
|
-
- TODO 61: typed error model + strict mode.
|
|
84
|
-
- TODO 62: font resolution via fontist (currently absolute paths in YAML).
|
|
85
|
-
- Plus the older TODO.implementation items (Knuth-Plass, PageSequenceMaster, table layout, etc.).
|
|
75
|
+
What's open (intentionally — see `TODO.complete/`, frontmatter `status:` is authoritative):
|
|
76
|
+
- TODO 87: odd/even page templates beyond header parity (headers mirror; templates don't).
|
|
77
|
+
- TODO 88: hyphenation support.
|
|
78
|
+
- TODO 90: MathML mfrac true stacking (the open piece).
|
|
79
|
+
- TODO 93: figure text searchability (figures render as images; the reference's figure text extracts).
|
|
80
|
+
- TODO 96: pagination drift parity — the master ledger: remaining region deficits, keep-rules negative results (the reference does NOT enforce widows; term entries are NOT atomic), the heading-gap coupled-landing recipe, and the C2 margin-unification decode (a dedicated re-tuning session, not a release-day change).
|
|
81
|
+
- TODOs 53-62 are DONE (second flavor spike, manifest contract, header/footer config, adapter MECE, strict typing, packaging docs, XSL profiles, footnote fidelity, typed errors, fontist).
|
|
86
82
|
|
|
87
83
|
The TODO files in `TODO.complete/` and `TODO.implementation/` are the roadmap. `TODO.complete/README.md` covers the parity roadmap; `TODO.implementation/README.md` covers the foundation phase plan.
|
|
88
84
|
|
|
@@ -137,8 +133,9 @@ When extending any layer, apply OCP/DRY/MECE strictly:
|
|
|
137
133
|
## Renderer/Pdfrb coupling notes
|
|
138
134
|
|
|
139
135
|
- `Renderer::Pdf#render_page` deliberately points each pdfrb page's `Resources` Hash at the catalog's. Pdfrb's `Fonts#add` attaches fonts to the *catalog* Resources, but each Page shadows with its own empty Hash — without this workaround, fonts are invisible to readers.
|
|
140
|
-
- `
|
|
141
|
-
-
|
|
136
|
+
- Margin contract (see `Flowable`'s doc): TextFlowable (and HeadingFlowable) count `space_before/after` inside height/emit; List/Image/Table-based flowables do not — spacing around them travels as explicit Spacers. The engine collapses via `Engine::MarginCollapse`; do NOT unify without a dedicated re-tuning session (decoded in TODO 96).
|
|
137
|
+
- Header/footer styling comes from `layout_spec.yml` (`header_footer:` block); font resolution goes through fontist (`FontScanner`) with AFM fallback for the 14 standard fonts.
|
|
138
|
+
- Parity workflow: `bundle exec rake parity:check` / `parity:diff PAGE=N`; drift-map tooling and diagnostic cautions live in TODO 96.
|
|
142
139
|
|
|
143
140
|
## Key files to read first
|
|
144
141
|
|
|
@@ -512,6 +512,28 @@ or the layout differs from the pipeline.
|
|
|
512
512
|
gaps reproduce (p8 69 vs 76) but nets -6pp; still blocked by the
|
|
513
513
|
p9-p15 fill mismatch.
|
|
514
514
|
|
|
515
|
+
## C2 margin unification — attempt executed and reverted (2026-08-31)
|
|
516
|
+
|
|
517
|
+
Round-5 attempt with the prepared MarginCollapse seam. The
|
|
518
|
+
implementation (margins inside every List/Image/Note/Table
|
|
519
|
+
flowable, CSS inset = max(pa,b) - pa + b, page-top exception,
|
|
520
|
+
Spacer workarounds deleted, block-style neutralization for the
|
|
521
|
+
dead note/list margins) measured 31.7% / 30pp vs the committed
|
|
522
|
+
68.92% / 28-28 - outside the correction budget, reverted clean.
|
|
523
|
+
|
|
524
|
+
ROOT CAUSE DECODED (the load-bearing finding): the OLD model
|
|
525
|
+
under-charges every counting flowable's space_before - ink is
|
|
526
|
+
drawn ABOVE the cursor, inside the previous flowable's consumed
|
|
527
|
+
space_after zone. The reference's calibrated constants ride that
|
|
528
|
+
under-charging; a geometrically correct model shifts every b>0
|
|
529
|
+
charge. Page-top behavior also differs from paper analysis
|
|
530
|
+
(heading ink at landings implies the old fresh-page path consumes
|
|
531
|
+
mt INSIDE the page - re-derive from HeadingFlowable's emit before
|
|
532
|
+
the next attempt, and note TableFlowable still needs the
|
|
533
|
+
convention added). Unification = dedicated re-tuning session, not
|
|
534
|
+
a release-day change. Full convention map now on Flowable's
|
|
535
|
+
contract doc.
|
|
536
|
+
|
|
515
537
|
## Measurement
|
|
516
538
|
|
|
517
539
|
`bundle exec rake parity:check` — 64.07% (2026-08-17).
|
data/TODO.complete/README.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# TODO.complete — Path to 100% mn2pdf parity
|
|
2
2
|
|
|
3
|
-
## Current baseline (2026-
|
|
3
|
+
## Current baseline (2026-09-01)
|
|
4
4
|
|
|
5
|
-
`bundle exec rake parity:check` reports **
|
|
6
|
-
on the OIML r060/1 fixture, **28 pages vs 28 reference
|
|
5
|
+
`bundle exec rake parity:check` reports **68.92%** overall similarity
|
|
6
|
+
on the OIML r060/1 fixture, **28 pages vs 28 reference**.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
452 specs pass, 0 failures, 0 rubocop offenses across 214 files.
|
|
9
|
+
TODO 96 is the live ledger (region deficits, keep-rule negative
|
|
10
|
+
results, the C2 margin decode).
|
|
9
11
|
|
|
10
12
|
## Status snapshot
|
|
11
13
|
|
data/lib/arrolio/flowable.rb
CHANGED
|
@@ -16,6 +16,20 @@
|
|
|
16
16
|
#
|
|
17
17
|
# A flowable's height() and emit() must agree on whether margins
|
|
18
18
|
# are included, or fit checks and drawing diverge.
|
|
19
|
+
#
|
|
20
|
+
# Convention map: TextFlowable (and HeadingFlowable, its
|
|
21
|
+
# subclass) count margins. ListFlowable + its subclasses (lists,
|
|
22
|
+
# notes), ImageFlowable, and TableFlowable do not — spacing
|
|
23
|
+
# around them travels as explicit Spacers.
|
|
24
|
+
#
|
|
25
|
+
# UNIFICATION DECODED (2026-08-31 attempt, reverted): the old
|
|
26
|
+
# model UNDER-CHARGES every counting flowable's space_before —
|
|
27
|
+
# its ink is drawn ABOVE the cursor, inside the previous
|
|
28
|
+
# flowable's already-consumed space_after zone. The reference's
|
|
29
|
+
# calibrated constants ride that under-charging. A correct CSS
|
|
30
|
+
# model (inset = max(pa,b) - pa + b, margins inside every
|
|
31
|
+
# flowable) measures 31.7% / 30pp: every b>0 charge shifts
|
|
32
|
+
# geometry. Unify only with a full re-tuning session.
|
|
19
33
|
module Arrolio
|
|
20
34
|
class Flowable
|
|
21
35
|
attr_reader :style
|
data/lib/arrolio/version.rb
CHANGED