ucode 0.1.0 → 0.1.1
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/CHANGELOG.md +72 -0
- data/Gemfile.lock +2 -2
- data/TODO.full/00-README.md +116 -0
- data/TODO.full/01-panglyph-vision.md +112 -0
- data/TODO.full/02-panglyph-repo-bootstrap.md +184 -0
- data/TODO.full/03-panglyph-font-builder.md +201 -0
- data/TODO.full/04-panglyph-publish-pipeline.md +126 -0
- data/TODO.full/05-ucode-0-1-1-release.md +139 -0
- data/TODO.full/06-fontisan-remove-audit.md +142 -0
- data/TODO.full/07-fontisan-remove-ucd.md +125 -0
- data/TODO.full/08-archive-private-bin-build.md +143 -0
- data/TODO.full/09-archive-public-structure.md +164 -0
- data/TODO.full/10-fontist-org-woff-glyphs.md +131 -0
- data/TODO.full/11-fontist-org-audit-coverage.md +140 -0
- data/TODO.full/12-implementation-order.md +216 -0
- data/TODO.full/13-fontisan-font-writer-api.md +189 -0
- data/TODO.full/14-fontisan-table-writers.md +66 -0
- data/TODO.full/15-panglyph-builder-real.md +82 -0
- data/TODO.full/16-archive-public-sync-workflows.md +167 -0
- data/TODO.full/17-fontist-org-font-picker.md +73 -0
- data/TODO.full/18-comprehensive-spec-coverage.md +64 -0
- data/TODO.full/19-ucode-0-1-2-patch.md +32 -0
- data/TODO.full/20-fontisan-0-2-23-release.md +52 -0
- data/TODO.new/00-README.md +30 -0
- data/TODO.new/23-universal-glyph-set-source-map.md +312 -0
- data/TODO.new/24-universal-glyph-set-build.md +189 -0
- data/TODO.new/25-font-audit-against-universal-set.md +195 -0
- data/TODO.new/26-missing-glyph-reporter.md +189 -0
- data/TODO.new/27-fontist-org-consumer-integration.md +200 -0
- data/TODO.new/28-implementation-order-update.md +187 -0
- data/TODO.new/29-universal-set-curation-uc17.md +312 -0
- data/TODO.new/30-tier1-font-acquisition.md +241 -0
- data/TODO.new/31-universal-set-production-build.md +205 -0
- data/TODO.new/32-uc17-coverage-matrix.md +165 -0
- data/TODO.new/33-specialist-font-acquisition-refresh.md +138 -0
- data/TODO.new/34-pillar2-content-stream-correlator.md +147 -0
- data/TODO.new/35-universal-set-production-run.md +160 -0
- data/TODO.new/36-per-font-coverage-audit.md +145 -0
- data/TODO.new/37-coverage-highlight-reporter.md +125 -0
- data/TODO.new/38-fontist-org-glyph-consumer.md +141 -0
- data/TODO.new/39-implementation-order-update-32-38.md +258 -0
- data/TODO.new/40-archive-private-uses-ucode-audit.md +124 -0
- data/TODO.new/41-ucode-unicode-archive-bridge.md +160 -0
- data/config/specialist_fonts.yml +102 -0
- data/config/unicode17_tier1_fonts.yml +42 -0
- data/config/unicode17_universal_glyph_set.yml +293 -0
- data/lib/ucode/audit/block_aggregator.rb +57 -29
- data/lib/ucode/audit/browser/face_page.rb +128 -0
- data/lib/ucode/audit/browser/glyph_panel.rb +124 -0
- data/lib/ucode/audit/browser/library_page.rb +74 -0
- data/lib/ucode/audit/browser/missing_glyph_page.rb +87 -0
- data/lib/ucode/audit/browser/template.rb +47 -0
- data/lib/ucode/audit/browser/templates/face.css +200 -0
- data/lib/ucode/audit/browser/templates/face.html.erb +41 -0
- data/lib/ucode/audit/browser/templates/face.js +298 -0
- data/lib/ucode/audit/browser/templates/library.css +119 -0
- data/lib/ucode/audit/browser/templates/library.html.erb +42 -0
- data/lib/ucode/audit/browser/templates/library.js +99 -0
- data/lib/ucode/audit/browser/templates/missing_glyph_page.css +119 -0
- data/lib/ucode/audit/browser/templates/missing_glyph_page.html.erb +58 -0
- data/lib/ucode/audit/browser/templates/missing_glyph_page.js +2 -0
- data/lib/ucode/audit/browser.rb +32 -0
- data/lib/ucode/audit/context.rb +27 -1
- data/lib/ucode/audit/coverage_reference.rb +103 -0
- data/lib/ucode/audit/differ.rb +121 -0
- data/lib/ucode/audit/emitter/block_emitter.rb +52 -0
- data/lib/ucode/audit/emitter/codepoint_emitter.rb +87 -0
- data/lib/ucode/audit/emitter/collection_emitter.rb +80 -0
- data/lib/ucode/audit/emitter/face_directory.rb +212 -0
- data/lib/ucode/audit/emitter/glyph_emitter.rb +48 -0
- data/lib/ucode/audit/emitter/index_emitter.rb +149 -0
- data/lib/ucode/audit/emitter/library_emitter.rb +96 -0
- data/lib/ucode/audit/emitter/paths.rb +312 -0
- data/lib/ucode/audit/emitter/plane_emitter.rb +29 -0
- data/lib/ucode/audit/emitter/script_emitter.rb +29 -0
- data/lib/ucode/audit/emitter.rb +29 -0
- data/lib/ucode/audit/extractors/aggregations.rb +31 -2
- data/lib/ucode/audit/face_auditor.rb +86 -0
- data/lib/ucode/audit/formatters/audit_diff_text.rb +112 -0
- data/lib/ucode/audit/formatters/audit_text.rb +411 -0
- data/lib/ucode/audit/formatters/color.rb +48 -0
- data/lib/ucode/audit/formatters/library_summary_text.rb +98 -0
- data/lib/ucode/audit/formatters/text_formatter.rb +83 -0
- data/lib/ucode/audit/formatters.rb +23 -0
- data/lib/ucode/audit/library_aggregator.rb +86 -0
- data/lib/ucode/audit/library_auditor.rb +105 -0
- data/lib/ucode/audit/release/emitter.rb +152 -0
- data/lib/ucode/audit/release/face_card.rb +93 -0
- data/lib/ucode/audit/release/formula_audits.rb +50 -0
- data/lib/ucode/audit/release/library_index_builder.rb +78 -0
- data/lib/ucode/audit/release/manifest_builder.rb +127 -0
- data/lib/ucode/audit/release.rb +42 -0
- data/lib/ucode/audit/ucd_only_reference.rb +81 -0
- data/lib/ucode/audit/universal_set_reference.rb +136 -0
- data/lib/ucode/audit.rb +31 -0
- data/lib/ucode/cli.rb +339 -33
- data/lib/ucode/commands/audit/browser_command.rb +82 -0
- data/lib/ucode/commands/audit/collection_command.rb +103 -0
- data/lib/ucode/commands/audit/compare_command.rb +188 -0
- data/lib/ucode/commands/audit/font_command.rb +140 -0
- data/lib/ucode/commands/audit/library_command.rb +87 -0
- data/lib/ucode/commands/audit/reference_builder.rb +64 -0
- data/lib/ucode/commands/audit.rb +20 -0
- data/lib/ucode/commands/block_feed.rb +73 -0
- data/lib/ucode/commands/canonical_build.rb +138 -0
- data/lib/ucode/commands/fetch.rb +37 -1
- data/lib/ucode/commands/release.rb +115 -0
- data/lib/ucode/commands/universal_set.rb +211 -0
- data/lib/ucode/commands.rb +5 -0
- data/lib/ucode/coordinator/indices.rb +11 -0
- data/lib/ucode/coordinator.rb +138 -5
- data/lib/ucode/error.rb +30 -2
- data/lib/ucode/fetch/font_fetcher/result.rb +39 -0
- data/lib/ucode/fetch/font_fetcher.rb +16 -0
- data/lib/ucode/fetch/specialist_font_fetcher.rb +280 -0
- data/lib/ucode/fetch.rb +7 -3
- data/lib/ucode/glyphs/real_fonts/cmap_cache.rb +74 -0
- data/lib/ucode/glyphs/real_fonts.rb +1 -0
- data/lib/ucode/glyphs/resolver.rb +62 -0
- data/lib/ucode/glyphs/source.rb +48 -0
- data/lib/ucode/glyphs/source_builder.rb +61 -0
- data/lib/ucode/glyphs/source_config/coverage_assertion.rb +79 -0
- data/lib/ucode/glyphs/source_config/gap_report.rb +54 -0
- data/lib/ucode/glyphs/source_config.rb +104 -0
- data/lib/ucode/glyphs/sources/pillar1_embedded_tounicode.rb +63 -0
- data/lib/ucode/glyphs/sources/pillar3_last_resort.rb +51 -0
- data/lib/ucode/glyphs/sources/tier1_real_font.rb +104 -0
- data/lib/ucode/glyphs/sources.rb +20 -0
- data/lib/ucode/glyphs/universal_set/builder.rb +161 -0
- data/lib/ucode/glyphs/universal_set/coverage_report.rb +139 -0
- data/lib/ucode/glyphs/universal_set/idempotency.rb +86 -0
- data/lib/ucode/glyphs/universal_set/manifest_accumulator.rb +195 -0
- data/lib/ucode/glyphs/universal_set/manifest_writer.rb +61 -0
- data/lib/ucode/glyphs/universal_set/pre_build_check.rb +197 -0
- data/lib/ucode/glyphs/universal_set/validator.rb +204 -0
- data/lib/ucode/glyphs/universal_set.rb +45 -0
- data/lib/ucode/glyphs.rb +6 -0
- data/lib/ucode/models/audit/baseline.rb +6 -0
- data/lib/ucode/models/audit/block_summary.rb +7 -0
- data/lib/ucode/models/audit/codepoint_provenance.rb +39 -0
- data/lib/ucode/models/audit/release_face.rb +42 -0
- data/lib/ucode/models/audit/release_formula.rb +33 -0
- data/lib/ucode/models/audit/release_manifest.rb +43 -0
- data/lib/ucode/models/audit/release_universal_set.rb +37 -0
- data/lib/ucode/models/audit.rb +9 -0
- data/lib/ucode/models/block.rb +2 -0
- data/lib/ucode/models/build_report.rb +109 -0
- data/lib/ucode/models/codepoint/glyph.rb +42 -0
- data/lib/ucode/models/codepoint.rb +3 -0
- data/lib/ucode/models/glyph_source.rb +86 -0
- data/lib/ucode/models/glyph_source_map.rb +138 -0
- data/lib/ucode/models/specialist_font.rb +70 -0
- data/lib/ucode/models/specialist_font_manifest.rb +48 -0
- data/lib/ucode/models/unihan_entry.rb +81 -9
- data/lib/ucode/models/unihan_field.rb +21 -0
- data/lib/ucode/models/universal_set_entry.rb +47 -0
- data/lib/ucode/models/universal_set_manifest.rb +78 -0
- data/lib/ucode/models/validation_report.rb +99 -0
- data/lib/ucode/models.rb +9 -0
- data/lib/ucode/parsers/named_sequences.rb +5 -5
- data/lib/ucode/parsers/unihan.rb +50 -19
- data/lib/ucode/repo/aggregate_writer.rb +34 -2
- data/lib/ucode/repo/block_feed_emitter.rb +153 -0
- data/lib/ucode/repo/build_report_accumulator.rb +138 -0
- data/lib/ucode/repo/build_report_writer.rb +46 -0
- data/lib/ucode/repo/build_validator.rb +229 -0
- data/lib/ucode/repo/codepoint_writer.rb +50 -1
- data/lib/ucode/repo/paths.rb +8 -0
- data/lib/ucode/repo.rb +4 -0
- data/lib/ucode/version.rb +1 -1
- data/schema/block-feed.output.schema.yml +134 -0
- metadata +143 -2
- data/ucode.gemspec +0 -56
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# 26 — Missing glyph reporter (drill-down view)
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Per-font drill-down view that renders the universal-set glyph SVG next
|
|
6
|
+
to every missing codepoint. Turns "this font is missing U+10980" into
|
|
7
|
+
"this font is missing U+10980, here's what it looks like."
|
|
8
|
+
|
|
9
|
+
This is Part 3 of the user's three-part directive. Without it, the
|
|
10
|
+
audit report (TODO 25) is a list of integers; with it, the user sees
|
|
11
|
+
the actual glyph shape they're missing.
|
|
12
|
+
|
|
13
|
+
## Why a separate TODO
|
|
14
|
+
|
|
15
|
+
TODO 14 (HTML face browser) shows missing codepoints as chips. TODO 26
|
|
16
|
+
adds a glyph rendering mode: each chip loads the universal-set SVG for
|
|
17
|
+
that codepoint and shows it inline.
|
|
18
|
+
|
|
19
|
+
Two different concerns:
|
|
20
|
+
|
|
21
|
+
- TODO 14: the browser shell, navigation, sortable tables, plane band.
|
|
22
|
+
- TODO 26: the glyph-rendering drill-down that the browser shell calls
|
|
23
|
+
into when the user clicks a chip.
|
|
24
|
+
|
|
25
|
+
Building TODO 26 on top of TODO 14 keeps the glyph rendering isolated
|
|
26
|
+
and reviewable.
|
|
27
|
+
|
|
28
|
+
## Files to create / change
|
|
29
|
+
|
|
30
|
+
- `lib/ucode/audit/browser/glyph_panel.rb` — new component: given a
|
|
31
|
+
codepoint + universal-set manifest path, returns the inline SVG
|
|
32
|
+
markup for the panel.
|
|
33
|
+
- `lib/ucode/audit/browser/templates/glyph_panel.html.erb` — the panel
|
|
34
|
+
template (used both for inline expansion and standalone mode below).
|
|
35
|
+
- `lib/ucode/audit/browser/missing_glyph_page.rb` — optional standalone
|
|
36
|
+
per-block "missing glyphs gallery" page: emits
|
|
37
|
+
`output/font_audit/<label>/missing/<BLOCK>.html` per touched block.
|
|
38
|
+
- `lib/ucode/audit/browser/templates/missing_glyph_page.html.erb`.
|
|
39
|
+
- `lib/ucode/audit/browser/face_page.rb` — update to accept a
|
|
40
|
+
`universal_set_root:` kwarg; when present, JS hooks become
|
|
41
|
+
glyph-aware.
|
|
42
|
+
- `lib/ucode/audit/browser/templates/face.js` — add glyph-panel logic.
|
|
43
|
+
- Specs:
|
|
44
|
+
- `spec/ucode/audit/browser/glyph_panel_spec.rb`
|
|
45
|
+
- `spec/ucode/audit/browser/missing_glyph_page_spec.rb`
|
|
46
|
+
- update `face_page_spec.rb` to cover the glyph-aware mode.
|
|
47
|
+
|
|
48
|
+
## Glyph panel shape
|
|
49
|
+
|
|
50
|
+
When the user clicks a codepoint chip (e.g. U+037D in Greek and Coptic
|
|
51
|
+
block, marked missing), the panel expands inline:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
┌──────────────────────────────────────────────────────┐
|
|
55
|
+
│ U+037D GREEK SMALL LETTER PAMPHYLIAN DIGAMMA │
|
|
56
|
+
│ │
|
|
57
|
+
│ [SVG: ] │
|
|
58
|
+
│ [ SVG ] ← universal-set glyph rendered inline │
|
|
59
|
+
│ [ ] │
|
|
60
|
+
│ │
|
|
61
|
+
│ Source: tier-1:noto-sans │
|
|
62
|
+
│ Unicode block: Greek and Coptic │
|
|
63
|
+
│ Age: Unicode 5.1 (March 2008) │
|
|
64
|
+
│ General category: Ll (Lowercase Letter) │
|
|
65
|
+
│ │
|
|
66
|
+
│ This font is missing this codepoint. │
|
|
67
|
+
│ Universal glyph shown for reference. │
|
|
68
|
+
└──────────────────────────────────────────────────────┘
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The SVG comes from the universal-set directory
|
|
72
|
+
(`output/universal_glyph_set/glyphs/U+037D.svg`), resolved via the
|
|
73
|
+
manifest's per-codepoint entry.
|
|
74
|
+
|
|
75
|
+
## Standalone missing-glyph gallery
|
|
76
|
+
|
|
77
|
+
The standalone page (`missing_glyph_page.html.erb`) emits one HTML
|
|
78
|
+
file per touched block, listing every missing codepoint in that block
|
|
79
|
+
as a grid of glyph thumbnails:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
output/font_audit/<label>/missing/
|
|
83
|
+
├── Greek_and_Coptic.html # ~55 missing glyphs as a grid
|
|
84
|
+
├── Sidetic.html # ~26 missing glyphs
|
|
85
|
+
└── CJK_Unified_Ideographs.html # potentially thousands
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The gallery is a static page — no JS needed. Each thumbnail links to
|
|
89
|
+
the chip in the main `index.html` (so users can jump back to context).
|
|
90
|
+
|
|
91
|
+
This page is what fontist.org can iframe or screenshot for the "what's
|
|
92
|
+
missing" widget.
|
|
93
|
+
|
|
94
|
+
## JS behavior (face.js additions)
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
// when a codepoint chip is clicked:
|
|
98
|
+
async function expandCodepoint(chip, codepoint) {
|
|
99
|
+
const panel = await renderPanel(codepoint);
|
|
100
|
+
chip.insertAdjacentElement('afterend', panel);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function renderPanel(codepoint) {
|
|
104
|
+
// 1. fetch codepoints/<BLOCK>.json → get name, gc, age, etc.
|
|
105
|
+
// 2. fetch ../../../universal_glyph_set/glyphs/<U+XXXX>.svg
|
|
106
|
+
// (path resolved from manifest field)
|
|
107
|
+
// 3. fetch ../../../universal_glyph_set/manifest.json → get source
|
|
108
|
+
// 4. build panel DOM, return
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
If the universal set is not co-located with the audit output (e.g. the
|
|
113
|
+
audit was generated on a different machine), the page shows a "glyph
|
|
114
|
+
preview not available" message instead of the SVG. The page itself
|
|
115
|
+
remains functional.
|
|
116
|
+
|
|
117
|
+
## Universal-set path resolution
|
|
118
|
+
|
|
119
|
+
`face_page.rb` records the universal-set path in the inlined JSON
|
|
120
|
+
overview:
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
...
|
|
125
|
+
"universal_set": {
|
|
126
|
+
"available": true,
|
|
127
|
+
"manifest_path": "../../../universal_glyph_set/manifest.json",
|
|
128
|
+
"glyphs_dir": "../../../universal_glyph_set/glyphs/"
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The JS uses these paths at runtime. When `available: false`, the JS
|
|
134
|
+
skips the SVG fetch and shows the text-only panel.
|
|
135
|
+
|
|
136
|
+
## Standalone page generation
|
|
137
|
+
|
|
138
|
+
The standalone missing-glyph page is opt-in:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
bin/ucode audit font <path> --with-missing-glyph-pages
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
This flag implies `--with-glyphs` (TODO 14's verbose flag) and
|
|
145
|
+
requires a universal-set manifest to be present. Output goes under
|
|
146
|
+
`output/font_audit/<label>/missing/<BLOCK>.html` per touched block.
|
|
147
|
+
|
|
148
|
+
## Performance considerations
|
|
149
|
+
|
|
150
|
+
- A CJK font can be missing thousands of codepoints. The grid is
|
|
151
|
+
paginated client-side (50 per page); the static HTML emits only the
|
|
152
|
+
first page; subsequent pages are loaded via fetch from a parallel
|
|
153
|
+
JSON file (`missing/<BLOCK>.json`).
|
|
154
|
+
- The SVG fetch is cached per session (Map); clicking the same
|
|
155
|
+
codepoint twice doesn't re-fetch.
|
|
156
|
+
- For very large blocks (CJK), the standalone page emits at most 500
|
|
157
|
+
thumbnails; the rest are available via the JSON file.
|
|
158
|
+
|
|
159
|
+
## Acceptance
|
|
160
|
+
|
|
161
|
+
- Clicking a missing-codepoint chip on the face page opens a panel
|
|
162
|
+
that renders the universal-set glyph SVG inline.
|
|
163
|
+
- The panel shows: codepoint id, name, age, gc, block, universal-set
|
|
164
|
+
source provenance, "this font is missing this codepoint" notice.
|
|
165
|
+
- `--with-missing-glyph-pages` produces per-block standalone HTML
|
|
166
|
+
files at `output/font_audit/<label>/missing/<BLOCK>.html`.
|
|
167
|
+
- When the universal set is not co-located, the panel shows a
|
|
168
|
+
text-only fallback without errors.
|
|
169
|
+
- The standalone gallery page is self-contained (inlined CSS/JS);
|
|
170
|
+
works via `file://`.
|
|
171
|
+
- Specs cover: panel rendering with SVG, panel rendering without SVG,
|
|
172
|
+
standalone gallery generation, pagination.
|
|
173
|
+
- Rubocop clean.
|
|
174
|
+
|
|
175
|
+
## Out of scope
|
|
176
|
+
|
|
177
|
+
- The face browser shell itself — TODO 14.
|
|
178
|
+
- The library browser (cross-font view) — TODO 15.
|
|
179
|
+
- fontist.org consumer side — TODO 27.
|
|
180
|
+
- The universal-set build — TODO 24.
|
|
181
|
+
|
|
182
|
+
## References
|
|
183
|
+
|
|
184
|
+
- Universal set build: `TODO.new/24-universal-glyph-set-build.md`
|
|
185
|
+
- Font audit against universal set: `TODO.new/25-font-audit-against-universal-set.md`
|
|
186
|
+
- HTML face browser: `TODO.new/14-html-face-browser.md`
|
|
187
|
+
- fontist.org contract: `TODO.new/04-fontist-org-contract.md`
|
|
188
|
+
- Existing face browser: `lib/ucode/audit/browser/face_page.rb`
|
|
189
|
+
(post-TODO 14)
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# 27 — fontist.org consumer integration
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Wire fontist.org (the consumer side) to ingest ucode's per-font audit
|
|
6
|
+
JSON + universal-set glyph references. Replaces the current
|
|
7
|
+
fontisan-YAML consumer with the new ucode-JSON consumer defined in
|
|
8
|
+
TODO 04.
|
|
9
|
+
|
|
10
|
+
This is the "fully integrate with fontist.org" directive. Two repos
|
|
11
|
+
are touched:
|
|
12
|
+
|
|
13
|
+
- `fontist/ucode` (this repo) — produces the artifacts.
|
|
14
|
+
- `fontist/fontist.org` (consumer) — fetches and renders them.
|
|
15
|
+
|
|
16
|
+
The contract is locked in TODO 04; this TODO implements the consumer
|
|
17
|
+
side and any producer-side emitter gaps the consumer surfaces.
|
|
18
|
+
|
|
19
|
+
## What exists today (consumer side)
|
|
20
|
+
|
|
21
|
+
fontist.org currently consumes (per
|
|
22
|
+
`fontist.org/CLAUDE.md` and `fontist.org/coverage-architecture.md`):
|
|
23
|
+
|
|
24
|
+
- `coverage/{formula_slug}/{PostScriptName}.yaml` — fontisan audit YAML.
|
|
25
|
+
- `woff/{formula_slug}/{PostScriptName}.woff` — WOFF specimens.
|
|
26
|
+
- `fonts.json`, `font-metadata.json` — fonts registry.
|
|
27
|
+
- `unicode/blocks/*.json` — Unicode block reference data.
|
|
28
|
+
- `unicode/indexes/*` — Unicode property indexes.
|
|
29
|
+
|
|
30
|
+
The audit YAML is the fontisan AuditCommand output (legacy). The
|
|
31
|
+
shape is documented in `fontist.org/coverage-architecture.md` §"Audit
|
|
32
|
+
YAML Schema."
|
|
33
|
+
|
|
34
|
+
## What changes
|
|
35
|
+
|
|
36
|
+
fontist.org gains a parallel data feed for ucode audits:
|
|
37
|
+
|
|
38
|
+
- `audit/{formula_slug}/{PostScriptName}/index.json` — ucode per-face
|
|
39
|
+
AuditReport (TODO 04 contract).
|
|
40
|
+
- `audit/{formula_slug}/{PostScriptName}/blocks/<NAME>.json` — per-block
|
|
41
|
+
chunk.
|
|
42
|
+
- `audit/{formula_slug}/{PostScriptName}/missing/<BLOCK>.html` —
|
|
43
|
+
optional, missing-glyph gallery (TODO 26).
|
|
44
|
+
- `universal_glyph_set/manifest.json` — the universal-set manifest
|
|
45
|
+
(TODO 24), single global file.
|
|
46
|
+
- `universal_glyph_set/glyphs/<U+XXXX>.svg` — universal-set glyphs.
|
|
47
|
+
|
|
48
|
+
The legacy `coverage/` feed stays (fontisan still produces it during
|
|
49
|
+
the migration window). fontist.org's renderer switches to `audit/`
|
|
50
|
+
when present; falls back to `coverage/` when not.
|
|
51
|
+
|
|
52
|
+
## fontist.org consumer work
|
|
53
|
+
|
|
54
|
+
### Files to change in `fontist/fontist.org`
|
|
55
|
+
|
|
56
|
+
- `scripts/fetch-data.sh` — add fetch of `audit/` from the archive;
|
|
57
|
+
add fetch of `universal_glyph_set/` (single zip, ~50 MB).
|
|
58
|
+
- `src/lib/fonts/loader.ts` — load the new audit JSON shape; keep
|
|
59
|
+
legacy YAML loader as fallback.
|
|
60
|
+
- `src/lib/unicode/data/loader.ts` — load the universal-set manifest;
|
|
61
|
+
expose `getUniversalGlyph(codepoint)` API.
|
|
62
|
+
- `src/composables/useCoverage.ts` — switch from legacy YAML parsing
|
|
63
|
+
to the new JSON shape; preserve the existing API for component
|
|
64
|
+
compatibility.
|
|
65
|
+
- `src/pages/FontBlockPage.vue` — render missing codepoints using the
|
|
66
|
+
universal-set glyphs (replace the current text-only chips with SVG
|
|
67
|
+
thumbnails when universal set is loaded).
|
|
68
|
+
- `src/pages/FontDetailPage.vue` — use the new `index.json` shape;
|
|
69
|
+
surface tier breakdown ("X glyphs from Tier 1, Y from Pillar 3") in
|
|
70
|
+
the audit footer.
|
|
71
|
+
- `src/components/UnicodeBrowser/` — add a `MissingGlyphGrid.vue`
|
|
72
|
+
component for the drill-down view.
|
|
73
|
+
- `tests/audit-json-shape.test.ts` — independent contract test for
|
|
74
|
+
the new JSON shape (mirrors `spec/fixtures/audit/` in ucode).
|
|
75
|
+
|
|
76
|
+
### Migration strategy
|
|
77
|
+
|
|
78
|
+
1. **Phase A — parallel feed.** fontist.org fetches both `coverage/`
|
|
79
|
+
and `audit/`. Renderer uses `audit/` when present (a per-formula
|
|
80
|
+
flag controls rollout). This de-risks the migration.
|
|
81
|
+
2. **Phase B — audit default.** Once all formulas have audit JSON,
|
|
82
|
+
flip the default. Legacy `coverage/` becomes backup-only.
|
|
83
|
+
3. **Phase C — coverage decommission.** Stop fetching `coverage/`
|
|
84
|
+
when fontisan audit subsystem is removed (TODO 17-19).
|
|
85
|
+
|
|
86
|
+
### SSG route additions
|
|
87
|
+
|
|
88
|
+
fontist.org generates static HTML at build time. Per TODO 04, the
|
|
89
|
+
audit is fetched per-font on the client (no per-codepoint static
|
|
90
|
+
HTML). SSG routes:
|
|
91
|
+
|
|
92
|
+
- `/fonts/<slug>/coverage/` — uses `audit/<slug>/<ps>/index.json`
|
|
93
|
+
- `/fonts/<slug>/coverage/<ps>/` — per-face detail
|
|
94
|
+
- `/fonts/<slug>/coverage/<ps>/<block-slug>/` — per-block drill-down
|
|
95
|
+
with missing-glyph grid
|
|
96
|
+
|
|
97
|
+
~13,200 existing routes grow by ~3,000 audit routes. SSG build time
|
|
98
|
+
budget: under 30 minutes (current: ~25 minutes).
|
|
99
|
+
|
|
100
|
+
### Universal-set global artifact
|
|
101
|
+
|
|
102
|
+
The universal-set directory is fetched once and shared across all
|
|
103
|
+
font pages. It's served from `/universal-glyph/<U+XXXX>.svg` (no
|
|
104
|
+
formula slug in the URL — it's not per-font).
|
|
105
|
+
|
|
106
|
+
For SSG: don't pre-render every glyph; let the browser fetch on
|
|
107
|
+
demand. The manifest is committed to fontist.org as
|
|
108
|
+
`public/universal-glyph-manifest.json` (~5 MB).
|
|
109
|
+
|
|
110
|
+
## ucode producer work
|
|
111
|
+
|
|
112
|
+
The producer side is mostly TODO 04 + TODO 13 + TODO 24. What's left:
|
|
113
|
+
|
|
114
|
+
### Audit JSON emitter gap
|
|
115
|
+
|
|
116
|
+
TODO 13's emitter writes the per-face directory tree. We need a
|
|
117
|
+
top-level emitter that walks a library and produces:
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
output/font_audit_release/
|
|
121
|
+
├── audit/<formula_slug>/<ps>/... # one face directory per TODO 03 layout
|
|
122
|
+
├── universal_glyph_set/... # the universal set (TODO 24)
|
|
123
|
+
├── library.json # all formulas + faces index
|
|
124
|
+
└── manifest.json # release manifest (versions, sha256s)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
This is the artifact `fontist.org/scripts/fetch-data.sh` consumes.
|
|
128
|
+
|
|
129
|
+
### Files to create in ucode
|
|
130
|
+
|
|
131
|
+
- `lib/ucode/audit/release_emitter.rb` — walks a library audit, emits
|
|
132
|
+
the release tree.
|
|
133
|
+
- `lib/ucode/commands/release.rb` — CLI: `bin/ucode release` produces
|
|
134
|
+
the release tree.
|
|
135
|
+
- `spec/ucode/audit/release_emitter_spec.rb`
|
|
136
|
+
|
|
137
|
+
### CI / publishing
|
|
138
|
+
|
|
139
|
+
A new GHA workflow in `fontist-archive-private`:
|
|
140
|
+
|
|
141
|
+
1. Matrix-audit every formula (existing pipeline).
|
|
142
|
+
2. After all matrix jobs complete, a collector job:
|
|
143
|
+
- Downloads all per-formula audit outputs.
|
|
144
|
+
- Runs `bin/ucode release` to assemble the release tree.
|
|
145
|
+
- Uploads as a GitHub release artifact tagged
|
|
146
|
+
`audit-<unicode-version>-<date>`.
|
|
147
|
+
3. `fontist.org/scripts/fetch-data.sh` fetches the latest such tag.
|
|
148
|
+
|
|
149
|
+
## Acceptance
|
|
150
|
+
|
|
151
|
+
### Producer (ucode)
|
|
152
|
+
|
|
153
|
+
- `bin/ucode release` produces the release tree at
|
|
154
|
+
`output/font_audit_release/`.
|
|
155
|
+
- The release tree contains all per-face audits + the universal-set +
|
|
156
|
+
a library.json + manifest.json.
|
|
157
|
+
- manifest.json records: ucode version, unicode version, source-config
|
|
158
|
+
sha256, per-face count, per-block glyph count from universal set.
|
|
159
|
+
- One smoke spec runs `release` against a small fixture library.
|
|
160
|
+
|
|
161
|
+
### Consumer (fontist.org)
|
|
162
|
+
|
|
163
|
+
- `scripts/fetch-data.sh` fetches `audit/` and `universal_glyph_set/`
|
|
164
|
+
without errors.
|
|
165
|
+
- A test font page (e.g. `/fonts/manual/inter/coverage/Inter-Regular/`)
|
|
166
|
+
renders using the new JSON shape.
|
|
167
|
+
- The block drill-down view shows missing glyphs as universal-set SVG
|
|
168
|
+
thumbnails.
|
|
169
|
+
- The footer shows tier breakdown ("X glyphs via Tier 1, Y via Pillar
|
|
170
|
+
3") from the audit baseline.
|
|
171
|
+
- Legacy `coverage/` fallback works when `audit/` is absent.
|
|
172
|
+
- SSG build time stays under 30 minutes.
|
|
173
|
+
- Contract test (`tests/audit-json-shape.test.ts`) passes against the
|
|
174
|
+
fixture from `ucode/spec/fixtures/audit/`.
|
|
175
|
+
|
|
176
|
+
### Cross-repo
|
|
177
|
+
|
|
178
|
+
- ucode's `spec/fixtures/audit/index.json` matches what fontist.org's
|
|
179
|
+
contract test expects.
|
|
180
|
+
- fontist.org's coverage map renders correctly with both shape
|
|
181
|
+
versions for the migration window.
|
|
182
|
+
|
|
183
|
+
## Out of scope
|
|
184
|
+
|
|
185
|
+
- The producer-side audit subsystem itself — TODOs 06-16.
|
|
186
|
+
- The universal-set build — TODO 24.
|
|
187
|
+
- fontisan decommission — TODOs 17-19.
|
|
188
|
+
- fontist.org's existing Unicode browser (per-codepoint detail) —
|
|
189
|
+
unchanged; it uses the legacy `unicode/blocks/*.json` data.
|
|
190
|
+
|
|
191
|
+
## References
|
|
192
|
+
|
|
193
|
+
- fontist.org contract: `TODO.new/04-fontist-org-contract.md`
|
|
194
|
+
- Directory emitter: `TODO.new/13-directory-emitter.md`
|
|
195
|
+
- HTML face browser: `TODO.new/14-html-face-browser.md`
|
|
196
|
+
- Missing glyph reporter: `TODO.new/26-missing-glyph-reporter.md`
|
|
197
|
+
- Universal-set build: `TODO.new/24-universal-glyph-set-build.md`
|
|
198
|
+
- fontist.org consumer repo: `/Users/mulgogi/src/fontist/fontist.org`
|
|
199
|
+
- fontist.org architecture: `fontist.org/CLAUDE.md`
|
|
200
|
+
- Coverage architecture: `fontist.org/coverage-architecture.md`
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# 28 — Implementation order (universal set + audit + fontist.org)
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Update the canonical implementation order to include TODOs 23-31
|
|
6
|
+
(universal glyph set, font audit against universal set, missing glyph
|
|
7
|
+
reporter, fontist.org consumer integration, full Unicode 17 curation,
|
|
8
|
+
specialist font acquisition, production build + validation). This
|
|
9
|
+
file replaces TODO.new/22 as the authoritative sequencing reference
|
|
10
|
+
for the new work; TODO 22 continues to govern TODOs 01-21.
|
|
11
|
+
|
|
12
|
+
## Sequencing principles (carried from TODO 22)
|
|
13
|
+
|
|
14
|
+
- **Schema and contract first.** Lock data shapes before porting code.
|
|
15
|
+
- **Measure before optimizing.** Baseline audit (TODO 05) informs the
|
|
16
|
+
source config (TODO 23).
|
|
17
|
+
- **One PR per TODO** unless tightly coupled.
|
|
18
|
+
- **Migration order: port → wire → cleanup.**
|
|
19
|
+
|
|
20
|
+
## Dependency graph (additions in bold)
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
01 pillar-terminology-alignment
|
|
24
|
+
02 audit-schema-design
|
|
25
|
+
03 directory-output-spec
|
|
26
|
+
04 fontist-org-contract
|
|
27
|
+
05 baseline-unicode17-coverage-audit ───┐
|
|
28
|
+
│
|
|
29
|
+
06-16 audit migration track │
|
|
30
|
+
│
|
|
31
|
+
17-19 fontisan cleanup │
|
|
32
|
+
│
|
|
33
|
+
20 canonical-resolver-4-tier ────────────┤
|
|
34
|
+
│
|
|
35
|
+
21 canonical-unicode17-build │
|
|
36
|
+
│
|
|
37
|
+
**23 universal-glyph-set-source-map** ───┤
|
|
38
|
+
│
|
|
39
|
+
**24 universal-glyph-set-build** ────────┤
|
|
40
|
+
│
|
|
41
|
+
**25 font-audit-against-universal-set** ─┤ (shipped — PR #34)
|
|
42
|
+
│
|
|
43
|
+
**29 universal-set-curation-uc17** ──────┤ (fills TODO 23's YAML)
|
|
44
|
+
│
|
|
45
|
+
**30 tier1-font-acquisition** ───────────┤ (downloads specialist fonts)
|
|
46
|
+
│
|
|
47
|
+
**31 universal-set-production-build** ───┤ (executes TODO 24 end-to-end)
|
|
48
|
+
│
|
|
49
|
+
**26 missing-glyph-reporter** ───────────┤
|
|
50
|
+
│
|
|
51
|
+
**27 fontist-org-consumer-integration** ─┘
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Phased rollout
|
|
55
|
+
|
|
56
|
+
### Phase 1 — Audit migration (TODOs 01-16)
|
|
57
|
+
|
|
58
|
+
Build the audit subsystem in ucode. Mode 2 (per-font audit) lands.
|
|
59
|
+
fontist.org continues consuming legacy `coverage/` YAML during this
|
|
60
|
+
phase.
|
|
61
|
+
|
|
62
|
+
Status (as of this writing): PRs through TODO 12 merged; TODOs 13-16
|
|
63
|
+
in flight.
|
|
64
|
+
|
|
65
|
+
### Phase 2 — Canonical dataset (TODOs 20-21)
|
|
66
|
+
|
|
67
|
+
Build the resolver (TODO 20) and run the canonical Unicode 17 build
|
|
68
|
+
(TODO 21). Mode 1 (per-codepoint UCD dataset) lands. This work is
|
|
69
|
+
independent of Phase 1; can run in parallel.
|
|
70
|
+
|
|
71
|
+
### Phase 3 — Universal glyph set (TODOs 23-24) **new**
|
|
72
|
+
|
|
73
|
+
Curate the per-block Tier 1 source map (TODO 23) from the baseline
|
|
74
|
+
audit (TODO 05). Build the universal set as a standalone artifact
|
|
75
|
+
(TODO 24).
|
|
76
|
+
|
|
77
|
+
Dependencies:
|
|
78
|
+
- TODO 05 must be complete (cmap-verified font recommendations).
|
|
79
|
+
- TODO 20 must be merged (resolver mechanics).
|
|
80
|
+
- TODO 21 must have produced a baseline run (validates the resolver).
|
|
81
|
+
|
|
82
|
+
Output: `output/universal_glyph_set/` artifact.
|
|
83
|
+
|
|
84
|
+
### Phase 4 — Universal-set-driven audit (TODOs 25-26) **new**
|
|
85
|
+
|
|
86
|
+
Replace the cmap-vs-UCD audit (current) with cmap-vs-universal-set
|
|
87
|
+
(TODO 25). Add the missing-glyph drill-down view (TODO 26).
|
|
88
|
+
|
|
89
|
+
Dependencies:
|
|
90
|
+
- TODO 24 must be complete (universal-set manifest exists).
|
|
91
|
+
- TODO 13 must be merged (directory emitter, the wire format).
|
|
92
|
+
- TODO 14 must be merged (face browser, the host of TODO 26 panels).
|
|
93
|
+
|
|
94
|
+
Output: per-font audits carry provenance; missing-glyph galleries
|
|
95
|
+
ship alongside.
|
|
96
|
+
|
|
97
|
+
Status: TODO 25 shipped as PR #34.
|
|
98
|
+
|
|
99
|
+
### Phase 4b — UC17 curation + production build (TODOs 29-31) **new**
|
|
100
|
+
|
|
101
|
+
Fill the source config with concrete Tier 1 font recommendations for
|
|
102
|
+
all ~340 Unicode 17 blocks (TODO 29). Acquire specialist fonts not in
|
|
103
|
+
fontist's index (TODO 30). Execute the universal-set build end-to-end
|
|
104
|
+
and validate coverage (TODO 31).
|
|
105
|
+
|
|
106
|
+
Dependencies:
|
|
107
|
+
- TODO 23 must be merged (source map mechanism — already shipped).
|
|
108
|
+
- TODO 24 must be merged (build pipeline — already shipped).
|
|
109
|
+
- TODO 05 baseline audit (font investigation analysis, encoded into
|
|
110
|
+
TODO 29).
|
|
111
|
+
|
|
112
|
+
Output: populated `config/unicode17_universal_glyph_set.yml`,
|
|
113
|
+
`data/fonts/<specialist>.ttf`, complete
|
|
114
|
+
`output/universal_glyph_set/` artifact with 100% Tier 1 coverage
|
|
115
|
+
outside documented residual gaps.
|
|
116
|
+
|
|
117
|
+
### Phase 5 — fontist.org consumer (TODO 27) **new**
|
|
118
|
+
|
|
119
|
+
Wire fontist.org to consume the new audit JSON + universal-set
|
|
120
|
+
glyphs. Parallel-feed alongside legacy `coverage/` during migration.
|
|
121
|
+
|
|
122
|
+
Dependencies:
|
|
123
|
+
- TODO 04 contract locked (already done).
|
|
124
|
+
- TODO 24 universal-set shipped.
|
|
125
|
+
- TODO 25 audit JSON shape stable.
|
|
126
|
+
- TODO 26 missing-glyph galleries available.
|
|
127
|
+
- TODO 31 production build validates (universal-set is complete and
|
|
128
|
+
auditable).
|
|
129
|
+
|
|
130
|
+
Output: fontist.org renders new audit data; legacy feed becomes
|
|
131
|
+
backup-only.
|
|
132
|
+
|
|
133
|
+
### Phase 6 — fontisan decommission (TODOs 17-19)
|
|
134
|
+
|
|
135
|
+
Once fontist.org has fully migrated to the new feed, remove the
|
|
136
|
+
audit subsystem from fontisan. Out of scope for this doc; tracked in
|
|
137
|
+
TODO 22.
|
|
138
|
+
|
|
139
|
+
## Cross-cutting concerns
|
|
140
|
+
|
|
141
|
+
### Source-config stability
|
|
142
|
+
|
|
143
|
+
TODO 23's YAML is the canonical Tier 1 font map. Any change there
|
|
144
|
+
triggers:
|
|
145
|
+
- TODO 24 rebuild (universal-set manifest delta).
|
|
146
|
+
- TODO 25 re-audit (per-block coverage may shift).
|
|
147
|
+
- TODO 27 re-release (fontist.org fetches new manifest).
|
|
148
|
+
|
|
149
|
+
Recommendation: bump `ucode_version` field on every config edit;
|
|
150
|
+
consumers detect drift via that field.
|
|
151
|
+
|
|
152
|
+
### Performance
|
|
153
|
+
|
|
154
|
+
- TODO 24 build: target under 4 hours for full Unicode 17.
|
|
155
|
+
- TODO 25 re-audit: per-font is independent; can parallelize across CI
|
|
156
|
+
matrix (one job per formula).
|
|
157
|
+
- TODO 27 SSG build: target under 30 minutes (current ~25).
|
|
158
|
+
|
|
159
|
+
### Backwards compatibility
|
|
160
|
+
|
|
161
|
+
- TODO 25 audit JSON: additive field (`missing_codepoint_provenance`).
|
|
162
|
+
Old consumers ignore the new field.
|
|
163
|
+
- TODO 27 consumer: parallel-feed during migration; legacy fallback
|
|
164
|
+
when audit JSON is absent.
|
|
165
|
+
|
|
166
|
+
## Acceptance
|
|
167
|
+
|
|
168
|
+
- All Phase 3-5 TODOs ship as one PR each.
|
|
169
|
+
- The sequencing above is reflected in the actual PR stack on GitHub.
|
|
170
|
+
- TODO 22 is updated to cross-reference this file.
|
|
171
|
+
|
|
172
|
+
## Out of scope
|
|
173
|
+
|
|
174
|
+
- Anything already covered by TODO 22 (TODOs 01-21).
|
|
175
|
+
- fontisan decommission (Phase 6, TODO 22).
|
|
176
|
+
|
|
177
|
+
## References
|
|
178
|
+
|
|
179
|
+
- Predecessor: `TODO.new/22-implementation-order.md`
|
|
180
|
+
- Universal-set source map: `TODO.new/23-universal-glyph-set-source-map.md`
|
|
181
|
+
- Universal-set build: `TODO.new/24-universal-glyph-set-build.md`
|
|
182
|
+
- Font audit against universal set: `TODO.new/25-font-audit-against-universal-set.md`
|
|
183
|
+
- Missing glyph reporter: `TODO.new/26-missing-glyph-reporter.md`
|
|
184
|
+
- fontist.org consumer integration: `TODO.new/27-fontist-org-consumer-integration.md`
|
|
185
|
+
- UC17 curation (Part 1): `TODO.new/29-universal-set-curation-uc17.md`
|
|
186
|
+
- Tier 1 font acquisition: `TODO.new/30-tier1-font-acquisition.md`
|
|
187
|
+
- Production build + validation: `TODO.new/31-universal-set-production-build.md`
|