Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_austenite/tests/oracle/fixtures/claim_index_fixture.typ

7.3 KiB, 2 runs

created by r1870400018:58314, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1// The oracle harness's reverse-claim-index fixture -- the corpus's root for the D2 reverse claim-reference
2// index. It exercises three things at once: `#claim-label(<code>)` sets a compressed code in the outside
3// margin (the A1 marginalia primitive, as `marginalia_fixture.typ` does); `#claim-refs(<code>..)` registers
4// a metadata-only reference, setting nothing visible; and a line-leading `#context { ... collect-claim-refs()
5// ... }` appendix builds the reverse index -- for each claim code, in byte order, the pages it was referenced
6// on. Self-contained -- no `#import` of any shared template -- so it compiles under typst 0.15.1 with no
7// symbol-modifier patch, and austenite reads `#claim-label`/`#claim-refs` as builtins and recognises the
8// `collect-claim-refs(` signature in the `#context` block without evaluating the block (it is hard-stratified
9// and runs no `query`), building the same reverse index from the references it gathered walking the body.
10//
11// The page geometry is austenite's own `PageGeometry::a4()` (A4, uniform 56.9 pt margins) at the default
12// 11 pt Libertinus Serif, so a referenced code lands on the same leaf in both engines. The body references a
13// small set of codes spread across two pages, so the reverse index is non-vacuous: at least one code is
14// referenced on more than one page, and the codes sort into byte order. The `claim-refs`/`claim-label`/
15// `collect-claim-refs` definitions reproduce the book's `claims.typ` metadata-and-query machinery so Typst
16// renders the same index austenite builds from the ledger.
17
18#set page(width: 595.276pt, height: 841.89pt, margin: 56.9pt)
19#set text(size: 11pt, font: "Libertinus Serif")
20#set par(justify: true)
21
22#let claim-ref-tag = "claim-ref"
23
24// Register one or more claim codes at the current location. No visible output.
25#let claim-refs(..codes) = {
26 let code-strs = codes.pos().map(c => if type(c) == label { str(c) } else { str(c) })
27 [#metadata((tag: claim-ref-tag, codes: code-strs))<claim-ref>]
28}
29
30// Query helper -- returns the metadata elements registered by claim-refs/claim-label.
31#let collect-claim-refs() = {
32 query(<claim-ref>)
33}
34
35// Place a compressed claim code in the outside margin AND register its metadata for the reverse index.
36#let claim-label(..codes) = {
37 let strs = codes.pos().map(c => if type(c) == label { str(c) } else { str(c) })
38 let display = strs.join(" ")
39 [#metadata((tag: claim-ref-tag, codes: strs))<claim-ref>]
40 box(width: 0pt, clip: false, context {
41 let pos = here().position()
42 let page-w = 595.276pt
43 let outside-m = 56.9pt
44 let content = text(size: 6.5pt, fill: luma(90), hyphenate: false, display)
45 let m = measure(content)
46 let sized = box(width: m.width, content)
47 if calc.odd(counter(page).get().first()) {
48 place(dx: page-w - outside-m - pos.x, sized)
49 } else {
50 place(dx: outside-m - m.width - pos.x, sized)
51 }
52 })
53}
54
55= Reverse Claim Index
56
57The opening paragraph invokes a foundational claim#claim-refs(<A1>) whose code is registered as a metadata-
58only reference, setting nothing in the body column and nothing in the margin, while the reverse index records
59the page it fell on. A second proposition#claim-refs(<B2>) is registered on the same leaf, so two distinct
60codes share this first page and the index must list each against it.
61
62A claim reference cannot resolve its own page inline, because the page a mark lands on is a forward layout
63fact the paragraph has not yet fixed. The stratified answer is to weave a zero-width anchor at the point of
64the reference, record where it lands, and read the page back from the converged ledger when the reverse index
65is set as back matter. Nothing about the anchor occupies horizontal space, so the words flow as if it were
66absent, and the same code#claim-refs(<A2>) referenced here joins the index under its own entry.
67
68The compression the visible label applies collapses a run of three or more consecutive codes into a range,
69and a single code sets as written. A visible label#claim-label(<C3>) both draws its code in the outside margin
70and registers the same metadata for the reverse index, so a label and a bare reference contribute alike to the
71page list, the label leaving ink in the margin and the reference leaving none.
72
73Reproduction is the instrument. Every downstream document that leans on a reverse index is an opportunity to
74harden the machinery, to break it against a real page and mend it upstream rather than papering over the gap
75in the document that surfaced it. The reverse index is one such exercise, long missing from the reproduction
76because a hard-stratified engine could not run the query the appendix is written with, and had to recognise
77its shape instead and build the same index from the anchors it recorded walking the body.
78
79The apparatus of a scholarly page is mostly its cross references, and mostly invisible until it is missing. A
80claim referenced in the body and gathered into an appendix is a small thing on any one line and a substantial
81thing across a book, the thread that ties a proposition to every place it is invoked. Reproducing it end to
82end, from the reference mark to the sorted page list, is the difference between a document that looks right
83and one that is right.
84
85Enough prose now stands above this point to carry the column past the foot of the first page and onto the
86second, so that a reference set below falls on a different leaf and the reverse index lists a code against two
87distinct pages rather than one. The overlay draws each entry's pages from the same converged ledger the running
88head reads, so neither can reopen the fixed point the composition settled on.
89
90This second-page paragraph invokes the foundational claim#claim-refs(<A1>) once more, on a later leaf than its
91first mention, so the index lists that code against two pages and proves the deduplicated, sorted page list is
92built from real resolved folios rather than a single occurrence. A further reference#claim-refs(<B1>) registers
93a fourth code, so the sorted index carries A1, A2, B1, B2 and C3 in byte order, each followed by the pages it
94was referenced on.
95
96== Index of Body References
97
98Foundational claims are cited through invisible metadata. The reverse index records the pages where each claim
99is invoked.
100
101#context {
102 let refs = collect-claim-refs()
103 if refs.len() == 0 [
104 _No body references registered._
105 ] else {
106 let by-code = (:)
107 for r in refs {
108 for code in r.value.codes {
109 if code in by-code {
110 by-code.insert(code, by-code.at(code) + (r.location(),))
111 } else {
112 by-code.insert(code, (r.location(),))
113 }
114 }
115 }
116 let codes = by-code.keys().sorted()
117 for code in codes {
118 let locs = by-code.at(code)
119 let pages = locs.map(loc => str(counter(page).at(loc).first()))
120 [#strong(code): #pages.join(", ").]
121 linebreak()
122 }
123 }
124}
125
126== Sources
127
128A section set after the reverse index, so its placement pins the listing above. In Typst the
129`#context { ... collect-claim-refs() ... }` block sets in flow at its heading, so this section opens directly
130beneath the last claim entry. A listing appended as back matter instead -- after every later section -- would
131strand these entries below this heading rather than above it, leaving the "Index of Body References" heading
132and its intro paragraph orphaned pages ahead of a headless run of codes. The section is here so the reverse
133index's in-flow placement is a fact the oracle can see, not an assertion the comment alone carries.