paperlint 5.0.0 → 6.1.0

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.
Files changed (177) hide show
  1. package/CLAUDE.md +13 -0
  2. package/CONTRIBUTING.md +3 -0
  3. package/README.md +8 -8
  4. package/bin/paperlint.mjs +5 -1
  5. package/dist/adapters/latex/index.d.ts +2 -1
  6. package/dist/adapters/latex/index.d.ts.map +1 -1
  7. package/dist/adapters/latex/index.js +6 -2
  8. package/dist/adapters/latex/index.js.map +1 -1
  9. package/dist/adapters/latex/layout.d.ts +27 -0
  10. package/dist/adapters/latex/layout.d.ts.map +1 -0
  11. package/dist/adapters/latex/layout.js +62 -0
  12. package/dist/adapters/latex/layout.js.map +1 -0
  13. package/dist/adapters/latex/nodes.d.ts.map +1 -1
  14. package/dist/adapters/latex/nodes.js +11 -1
  15. package/dist/adapters/latex/nodes.js.map +1 -1
  16. package/dist/adapters/latex/parse.d.ts.map +1 -1
  17. package/dist/adapters/latex/parse.js +5 -1
  18. package/dist/adapters/latex/parse.js.map +1 -1
  19. package/dist/adapters/latex/prose.d.ts +6 -1
  20. package/dist/adapters/latex/prose.d.ts.map +1 -1
  21. package/dist/adapters/latex/prose.js +142 -31
  22. package/dist/adapters/latex/prose.js.map +1 -1
  23. package/dist/cli.d.ts.map +1 -1
  24. package/dist/cli.js +35 -18
  25. package/dist/cli.js.map +1 -1
  26. package/dist/domain/anonymity.d.ts +68 -0
  27. package/dist/domain/anonymity.d.ts.map +1 -0
  28. package/dist/domain/anonymity.js +94 -0
  29. package/dist/domain/anonymity.js.map +1 -0
  30. package/dist/domain/body-pages.d.ts +69 -0
  31. package/dist/domain/body-pages.d.ts.map +1 -0
  32. package/dist/domain/body-pages.js +141 -0
  33. package/dist/domain/body-pages.js.map +1 -0
  34. package/dist/domain/register.d.ts +96 -0
  35. package/dist/domain/register.d.ts.map +1 -0
  36. package/dist/domain/register.js +136 -0
  37. package/dist/domain/register.js.map +1 -0
  38. package/dist/domain/tex-document.d.ts +28 -0
  39. package/dist/domain/tex-document.d.ts.map +1 -1
  40. package/dist/domain/tex-document.js +8 -3
  41. package/dist/domain/tex-document.js.map +1 -1
  42. package/dist/eslint-rules/pdf-last-page-balance.d.ts +1 -1
  43. package/dist/eslint-rules/pdf-last-page-balance.js +2 -2
  44. package/dist/facts-file.d.ts +28 -2
  45. package/dist/facts-file.d.ts.map +1 -1
  46. package/dist/facts-file.js +54 -9
  47. package/dist/facts-file.js.map +1 -1
  48. package/dist/lib/paper-config.d.ts.map +1 -1
  49. package/dist/lib/paper-config.js +2 -1
  50. package/dist/lib/paper-config.js.map +1 -1
  51. package/dist/paper-settings.d.ts +11 -0
  52. package/dist/paper-settings.d.ts.map +1 -1
  53. package/dist/paper-settings.js +38 -4
  54. package/dist/paper-settings.js.map +1 -1
  55. package/dist/pdf-content.d.ts +40 -0
  56. package/dist/pdf-content.d.ts.map +1 -0
  57. package/dist/pdf-content.js +97 -0
  58. package/dist/pdf-content.js.map +1 -0
  59. package/dist/pdf-facts.d.ts +30 -0
  60. package/dist/pdf-facts.d.ts.map +1 -1
  61. package/dist/pdf-facts.js +37 -1
  62. package/dist/pdf-facts.js.map +1 -1
  63. package/dist/ports/latex.d.ts +8 -1
  64. package/dist/ports/latex.d.ts.map +1 -1
  65. package/dist/presets.d.ts +5 -0
  66. package/dist/presets.d.ts.map +1 -1
  67. package/dist/presets.js +8 -1
  68. package/dist/presets.js.map +1 -1
  69. package/dist/register-bands.d.ts +37 -0
  70. package/dist/register-bands.d.ts.map +1 -0
  71. package/dist/register-bands.js +196 -0
  72. package/dist/register-bands.js.map +1 -0
  73. package/dist/register.d.ts +4 -2
  74. package/dist/register.d.ts.map +1 -1
  75. package/dist/register.js +6 -45
  76. package/dist/register.js.map +1 -1
  77. package/dist/tex-requirements.d.ts +10 -0
  78. package/dist/tex-requirements.d.ts.map +1 -1
  79. package/dist/tex-requirements.js +29 -6
  80. package/dist/tex-requirements.js.map +1 -1
  81. package/dist/tex-venue-rules.d.ts +8 -2
  82. package/dist/tex-venue-rules.d.ts.map +1 -1
  83. package/dist/tex-venue-rules.js +40 -0
  84. package/dist/tex-venue-rules.js.map +1 -1
  85. package/dist/types.d.ts +2 -0
  86. package/dist/types.d.ts.map +1 -1
  87. package/dist/venue-rules.d.ts +38 -8
  88. package/dist/venue-rules.d.ts.map +1 -1
  89. package/dist/venue-rules.js +179 -41
  90. package/dist/venue-rules.js.map +1 -1
  91. package/docs/configuration.md +18 -16
  92. package/docs/e2e.md +32 -11
  93. package/docs/rules/anonymity/identity.md +111 -0
  94. package/docs/rules/format/layout-override.md +61 -0
  95. package/docs/rules/format/page-limit.md +108 -0
  96. package/docs/rules/pdf/body-size.md +87 -0
  97. package/docs/rules/tex/claim-emphasis.md +71 -0
  98. package/docs/rules/tex/contrast-frames.md +100 -0
  99. package/docs/rules/tex/relation-markers.md +72 -0
  100. package/docs/rules.md +59 -50
  101. package/eslint-rules/pdf-last-page-balance.harness.mjs +6 -1
  102. package/eslint-rules/pdf-last-page-balance.ts +2 -2
  103. package/fixtures/build-e2e/aidc/expect.json +1 -1
  104. package/fixtures/build-e2e/aidc/paperlint.json +1 -1
  105. package/fixtures/build-e2e/anon-ack/PIPELINE-STATUS.md +3 -0
  106. package/fixtures/build-e2e/anon-ack/expect.json +19 -0
  107. package/fixtures/build-e2e/anon-ack/paper.tex +31 -0
  108. package/fixtures/build-e2e/anon-ack/paperlint.json +1 -0
  109. package/fixtures/build-e2e/anon-author/PIPELINE-STATUS.md +3 -0
  110. package/fixtures/build-e2e/anon-author/expect.json +19 -0
  111. package/fixtures/build-e2e/anon-author/paper.tex +29 -0
  112. package/fixtures/build-e2e/anon-author/paperlint.json +1 -0
  113. package/fixtures/build-e2e/anon-bib/PIPELINE-STATUS.md +3 -0
  114. package/fixtures/build-e2e/anon-bib/expect.json +20 -0
  115. package/fixtures/build-e2e/anon-bib/paper.tex +35 -0
  116. package/fixtures/build-e2e/anon-bib/paperlint.json +1 -0
  117. package/fixtures/build-e2e/anon-href/PIPELINE-STATUS.md +3 -0
  118. package/fixtures/build-e2e/anon-href/expect.json +19 -0
  119. package/fixtures/build-e2e/anon-href/paper.tex +30 -0
  120. package/fixtures/build-e2e/anon-href/paperlint.json +1 -0
  121. package/fixtures/build-e2e/anon-macro/PIPELINE-STATUS.md +3 -0
  122. package/fixtures/build-e2e/anon-macro/expect.json +19 -0
  123. package/fixtures/build-e2e/anon-macro/paper.tex +30 -0
  124. package/fixtures/build-e2e/anon-macro/paperlint.json +1 -0
  125. package/fixtures/build-e2e/anon-pdfauthor/PIPELINE-STATUS.md +3 -0
  126. package/fixtures/build-e2e/anon-pdfauthor/expect.json +19 -0
  127. package/fixtures/build-e2e/anon-pdfauthor/paper.tex +31 -0
  128. package/fixtures/build-e2e/anon-pdfauthor/paperlint.json +1 -0
  129. package/fixtures/build-e2e/unbalanced/expect.json +2 -2
  130. package/lib/paper-config.ts +3 -1
  131. package/package.json +1 -1
  132. package/presets/acm-sigconf.jsonc +3 -1
  133. package/presets/aidc.jsonc +66 -17
  134. package/presets/ieee-conference.jsonc +8 -0
  135. package/presets/venue-profile.schema.json +57 -1
  136. package/skills/grade-paper-writing/SKILL.md +59 -27
  137. package/skills/grade-paper-writing/SKILL.md.spec.ts +58 -26
  138. package/skills/render-paper/extract-pdf-facts.harness.ts +3 -3
  139. package/src/adapters/latex/index.test.ts +91 -0
  140. package/src/adapters/latex/index.ts +6 -2
  141. package/src/adapters/latex/layout.ts +106 -0
  142. package/src/adapters/latex/nodes.ts +11 -3
  143. package/src/adapters/latex/parse.ts +5 -1
  144. package/src/adapters/latex/prose.ts +188 -58
  145. package/src/build.harness.mjs +2 -2
  146. package/src/build.test.ts +5 -0
  147. package/src/cli.test.ts +13 -0
  148. package/src/cli.ts +50 -17
  149. package/src/domain/anonymity.test.ts +163 -0
  150. package/src/domain/anonymity.ts +129 -0
  151. package/src/domain/body-pages.test.ts +300 -0
  152. package/src/domain/body-pages.ts +223 -0
  153. package/src/domain/register.test.ts +153 -0
  154. package/src/domain/register.ts +261 -0
  155. package/src/domain/tex-document.ts +47 -3
  156. package/src/facts-file.test.ts +100 -4
  157. package/src/facts-file.ts +91 -9
  158. package/src/new-paper.test.ts +7 -1
  159. package/src/paper-settings.test.ts +63 -6
  160. package/src/paper-settings.ts +53 -5
  161. package/src/pdf-content.test.ts +71 -0
  162. package/src/pdf-content.ts +125 -0
  163. package/src/pdf-facts.test.ts +110 -2
  164. package/src/pdf-facts.ts +106 -8
  165. package/src/ports/latex.ts +9 -0
  166. package/src/presets.ts +15 -9
  167. package/src/register-bands.test.ts +327 -0
  168. package/src/register-bands.ts +291 -0
  169. package/src/register.ts +7 -37
  170. package/src/rule-cases.test.ts +96 -20
  171. package/src/rule-docs.test.ts +0 -2
  172. package/src/tex-requirements.ts +56 -8
  173. package/src/tex-venue-rules.test.ts +110 -5
  174. package/src/tex-venue-rules.ts +64 -3
  175. package/src/types.ts +2 -0
  176. package/src/venue-rules.test.ts +351 -39
  177. package/src/venue-rules.ts +247 -47
package/CLAUDE.md CHANGED
@@ -77,6 +77,19 @@ and stay QUIET on a clean fixture. A check that has only been seen quiet is
77
77
  indistinguishable from a dead one — silence is its success state. Prove the fire half by
78
78
  seeing the test go RED before the fix lands ([`docs/testing.md`](docs/testing.md)).
79
79
 
80
+ **One rule, one requirement.** A rule checks one thing a user would want to switch off, or set a
81
+ severity for, on its own; two checks with different reasons to disable them are two rules. Several
82
+ messageIds for facets of one requirement are fine. Example: `pdf/limits` checked body pages,
83
+ reference pages and the reference font size — the first two are one page budget and became
84
+ `format/page-limit`; the font size is a different requirement and moved to `pdf/body-size`.
85
+
86
+ **A rule that judges a venue requirement is validated on real accepted papers of that venue** (or
87
+ of its parent venue, with the same template), built to PDF, with the ground truth established
88
+ independently of the rule — rendered and looked at — plus variant fixtures derived from those real
89
+ sources, one change each. Synthetic minimal fixtures alone are not enough: they are written by the
90
+ same hand as the rule, and share its blind spots. Example: `format/page-limit`'s body count, on the
91
+ built ACSAC papers in `fixtures/accepted-papers/` (`test/e2e/tex/page-count.e2e.ts`).
92
+
80
93
  **A new rule ships with its page**, `docs/rules/<group>/<rule>.md`, in these sections: What it
81
94
  catches · Why · Examples (failing / passing) · Options / preset fields · What it does not check ·
82
95
  How to fix. Its `meta.docs.url` points at that page, and its row in `docs/rules.md` is one line
package/CONTRIBUTING.md CHANGED
@@ -77,6 +77,9 @@ Most of the package's rules run on users' papers and are described for users in
77
77
  [`docs/rules.md`](docs/rules.md); the rest lint this package's own source and never see a user's
78
78
  files.
79
79
 
80
+ One rule checks one requirement, and a rule that judges a venue requirement is validated on real
81
+ accepted papers built to PDF — both in [`CLAUDE.md`](CLAUDE.md#the-ten-rules-that-decide-what-may-live-here--and-what-may-not-be-written), rule 3.
82
+
80
83
  A new rule ships with its page, `docs/rules/<group>/<rule>.md`, in these sections: What it
81
84
  catches · Why · Examples (failing / passing) · Options / preset fields · What it does not check ·
82
85
  How to fix. Its `meta.docs.url` points at that page, and its row in `docs/rules.md` is one line
package/README.md CHANGED
@@ -69,14 +69,14 @@ build: compiles and measures the PDF; lint then checks pages, fonts, references
69
69
  A **venue preset** holds a venue's format and page limits. A paper's **kind** picks which limit
70
70
  applies: at AgenticDev a `short` paper gets 5 pages and a `full` one 10. You choose it once per paper.
71
71
 
72
- | preset | venue | format | kinds and page limits |
73
- | --------------------------- | ------------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
74
- | `paperlint:acm-sigconf` | any ACM conference | ACM two-column | no kinds: the format only, no page limit |
75
- | `paperlint:agenticdev` | AgenticDev @ ASE | ACM two-column | `short` 5, `full` 10, `demo` 5 pages, + 2 pages of references |
76
- | `paperlint:aisec` | AISec @ ACM CCS | ACM two-column | `research`, `benchmark`, `position`, `sok`: 10 pages + 2 pages of references |
77
- | `paperlint:realm` | REALM @ EMNLP | ACL two-column, A4 | `long` 8, `short` 4 — recorded, not checked ([why](docs/rules.md#checks-against-the-venue)) |
78
- | `paperlint:ieee-conference` | any IEEE conference | IEEE two-column | no kinds: the format only, no page limit |
79
- | `paperlint:aidc` | AIDC @ IEEE ACSAC | IEEE two-column, `compsoc` | `regular` 12, `short` 6 — recorded, not checked ([why](docs/rules.md#checks-against-the-venue)); requires the «LLM Usage Statement» |
72
+ | preset | venue | format | kinds and page limits |
73
+ | --------------------------- | ------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
74
+ | `paperlint:acm-sigconf` | any ACM conference | ACM two-column | no kinds: the format only, no page limit |
75
+ | `paperlint:agenticdev` | AgenticDev @ ASE | ACM two-column | `short` 5, `full` 10, `demo` 5 pages, + 2 pages of references |
76
+ | `paperlint:aisec` | AISec @ ACM CCS | ACM two-column | `research`, `benchmark`, `position`, `sok`: 10 pages + 2 pages of references |
77
+ | `paperlint:realm` | REALM @ EMNLP | ACL two-column, A4 | `long` 8, `short` 4 — recorded, not checked ([why](docs/rules.md#checks-against-the-venue)) |
78
+ | `paperlint:ieee-conference` | any IEEE conference | IEEE two-column | no kinds: the format only, no page limit |
79
+ | `paperlint:aidc` | AIDC @ IEEE ACSAC | IEEE two-column, `compsoc` | `regular` 12, `short` 6, counted before the references ([why](docs/rules.md#checks-against-the-venue)); requires the «LLM Usage Statement»; double-blind |
80
80
 
81
81
  Not shipped yet: USENIX, NeurIPS, Springer, IEEE venues other than AIDC, and ACL venues other than
82
82
  REALM.
package/bin/paperlint.mjs CHANGED
@@ -40,4 +40,8 @@ const { run, isMain } = await import("../dist/cli.js");
40
40
  // The question is about THIS file, not `dist/cli.js`: `bin` is the target of a symlink from
41
41
  // `node_modules/.bin`, and `isMain` can compare it to the real path. For `cli.js` itself
42
42
  // the answer is now always "no" — it is imported, not invoked.
43
- if (isMain(import.meta.url)) process.exit(await run(process.argv.slice(2)));
43
+ // Not process.exit(): on macOS stdout into a pipe is written asynchronously, and exit() drops
44
+ // whatever has not drained yet, cutting `lint --json` at the 64 KiB pipe buffer. Setting exitCode
45
+ // lets Node exit once the output has drained — what the Node docs recommend over exit().
46
+ if (isMain(import.meta.url))
47
+ process.exitCode = await run(process.argv.slice(2));
@@ -26,8 +26,9 @@ export { collapse, inPlace, macroPlace, mandatory, optional, placeOf, textOf, }
26
26
  export { documentBodyOf, includesOf } from "./includes.ts";
27
27
  export { outlineOf } from "./outline.ts";
28
28
  export { parseLatex, type ParsedTex } from "./parse.ts";
29
- export { bodyProse } from "./prose.ts";
29
+ export { bodyEmphasis, bodyProse } from "./prose.ts";
30
30
  export { renderedRuns } from "./rendered.ts";
31
+ export { layoutOverridesOf } from "./layout.ts";
31
32
  /** The `LatexReader` port over unified-latex: each call parses its source once. */
32
33
  export declare const latexReader: LatexReader;
33
34
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/latex/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAYxD,OAAO,EACL,eAAe,EACf,aAAa,EACb,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,QAAQ,EACR,OAAO,EACP,UAAU,EACV,SAAS,EACT,QAAQ,EACR,OAAO,EACP,MAAM,GACP,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,mFAAmF;AACnF,eAAO,MAAM,WAAW,EAAE,WASzB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/latex/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAaxD,OAAO,EACL,eAAe,EACf,aAAa,EACb,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,QAAQ,EACR,OAAO,EACP,UAAU,EACV,SAAS,EACT,QAAQ,EACR,OAAO,EACP,MAAM,GACP,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,mFAAmF;AACnF,eAAO,MAAM,WAAW,EAAE,WAWzB,CAAC"}
@@ -2,24 +2,28 @@ import { documentClassOf, parseTemplate, replaceDocumentClass, } from "./documen
2
2
  import { documentBodyOf, includesOf } from "./includes.js";
3
3
  import { outlineOf } from "./outline.js";
4
4
  import { parseLatex } from "./parse.js";
5
- import { bodyProse } from "./prose.js";
5
+ import { bodyEmphasis, bodyProse } from "./prose.js";
6
6
  import { renderedRuns } from "./rendered.js";
7
+ import { layoutOverridesOf } from "./layout.js";
7
8
  export { documentClassOf, parseTemplate, replaceDocumentClass, } from "./document-class.js";
8
9
  export { collapse, inPlace, macroPlace, mandatory, optional, placeOf, textOf, } from "./nodes.js";
9
10
  export { documentBodyOf, includesOf } from "./includes.js";
10
11
  export { outlineOf } from "./outline.js";
11
12
  export { parseLatex } from "./parse.js";
12
- export { bodyProse } from "./prose.js";
13
+ export { bodyEmphasis, bodyProse } from "./prose.js";
13
14
  export { renderedRuns } from "./rendered.js";
15
+ export { layoutOverridesOf } from "./layout.js";
14
16
  /** The `LatexReader` port over unified-latex: each call parses its source once. */
15
17
  export const latexReader = {
16
18
  documentClass: (src) => documentClassOf(parseLatex(src)),
17
19
  outline: (src) => outlineOf(parseLatex(src)),
18
20
  renderedRuns: (src) => renderedRuns(parseLatex(src)),
19
21
  bodyProse: (src) => bodyProse(parseLatex(src)),
22
+ bodyEmphasis: (src) => bodyEmphasis(parseLatex(src)),
20
23
  includes: (src) => includesOf(parseLatex(src)),
21
24
  documentBody: (src) => documentBodyOf(parseLatex(src)),
22
25
  template: parseTemplate,
23
26
  withDocumentClass: (src, want) => replaceDocumentClass(parseLatex(src), want),
27
+ layoutOverrides: (src) => layoutOverridesOf(parseLatex(src)),
24
28
  };
25
29
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/latex/index.ts"],"names":[],"mappings":"AAuBA,OAAO,EACL,eAAe,EACf,aAAa,EACb,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,EACL,eAAe,EACf,aAAa,EACb,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,QAAQ,EACR,OAAO,EACP,UAAU,EACV,SAAS,EACT,QAAQ,EACR,OAAO,EACP,MAAM,GACP,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAkB,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,mFAAmF;AACnF,MAAM,CAAC,MAAM,WAAW,GAAgB;IACtC,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACxD,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC5C,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACpD,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC9C,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC9C,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACtD,QAAQ,EAAE,aAAa;IACvB,iBAAiB,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,oBAAoB,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;CAC9E,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/latex/index.ts"],"names":[],"mappings":"AAuBA,OAAO,EACL,eAAe,EACf,aAAa,EACb,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EACL,eAAe,EACf,aAAa,EACb,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,QAAQ,EACR,OAAO,EACP,UAAU,EACV,SAAS,EACT,QAAQ,EACR,OAAO,EACP,MAAM,GACP,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAkB,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,mFAAmF;AACnF,MAAM,CAAC,MAAM,WAAW,GAAgB;IACtC,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACxD,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC5C,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACpD,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC9C,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACpD,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC9C,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACtD,QAAQ,EAAE,aAAa;IACvB,iBAAiB,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,oBAAoB,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IAC7E,eAAe,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,iBAAiB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;CAC7D,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Where a source changes the page layout its class sets for the whole document — the input of
3
+ * `format/layout-override`. Read from the parse tree, never the text: a command in a comment is not
4
+ * a command.
5
+ *
6
+ * What counts, each by its node:
7
+ *
8
+ * \usepackage{geometry} · \RequirePackage{…,geometry} the package that re-sets the margins
9
+ * \geometry{…} · \newgeometry{…} its commands
10
+ * \setlength / \addtolength on a layout length \textheight \textwidth \topmargin …
11
+ * \linespread{…} · \renewcommand{\baselinestretch} the line spacing
12
+ *
13
+ * Local spacing — a negative `\vspace` or `\vskip` around one float — is not a layout the template
14
+ * sets, and no venue's call names it; it is not read.
15
+ *
16
+ * A comment and a `comment` environment are not read — the parser hands both back as text, not
17
+ * macros. Everything else is — the bibliography, math, floats — and a macro definition too: a
18
+ * `\newcommand` whose body sets a layout length does so wherever it is used. Conditionals are not
19
+ * evaluated.
20
+ */
21
+ import type { LayoutOverride } from "../../domain/tex-document.ts";
22
+ import type { ParsedTex } from "./parse.ts";
23
+ /** The lengths the class sets for the page and the line; changing one changes the venue's layout. */
24
+ export declare const LAYOUT_LENGTHS: ReadonlySet<string>;
25
+ /** Every layout override in the source, in document order. */
26
+ export declare function layoutOverridesOf(t: ParsedTex): readonly LayoutOverride[];
27
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../src/adapters/latex/layout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAUnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,qGAAqG;AACrG,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAW7C,CAAC;AAkDH,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,SAAS,GAAG,SAAS,cAAc,EAAE,CAUzE"}
@@ -0,0 +1,62 @@
1
+ import { collapse, isList, macroPlace, mandatory, textOf, visited, } from "./nodes.js";
2
+ /** The lengths the class sets for the page and the line; changing one changes the venue's layout. */
3
+ export const LAYOUT_LENGTHS = new Set([
4
+ "textheight",
5
+ "textwidth",
6
+ "topmargin",
7
+ "oddsidemargin",
8
+ "evensidemargin",
9
+ "columnsep",
10
+ "headsep",
11
+ "headheight",
12
+ "footskip",
13
+ "baselineskip",
14
+ ]);
15
+ /** The macro a mandatory argument holds first, or undefined: `{\textheight}` → `textheight`. */
16
+ function firstMacro(m, i) {
17
+ const first = mandatory(m)[i]?.content.find((n) => n.type !== "whitespace");
18
+ return first?.type === "macro" ? first.content : undefined;
19
+ }
20
+ const argText = (m, i) => collapse(textOf(mandatory(m)[i]?.content));
21
+ const usesGeometry = (m) => argText(m, 0)
22
+ .split(",")
23
+ .map((p) => p.trim())
24
+ .includes("geometry")
25
+ ? `\\${m.content}{geometry}`
26
+ : null;
27
+ const setsLayoutLength = (m) => {
28
+ const length = firstMacro(m, 0);
29
+ return length !== undefined && LAYOUT_LENGTHS.has(length)
30
+ ? `\\${m.content}{\\${length}}`
31
+ : null;
32
+ };
33
+ /** Each macro that may override the layout, and how to tell whether this use of it does. */
34
+ const OVERRIDES = new Map([
35
+ ["usepackage", usesGeometry],
36
+ ["RequirePackage", usesGeometry],
37
+ ["geometry", (m) => `\\${m.content}`],
38
+ ["newgeometry", (m) => `\\${m.content}`],
39
+ ["linespread", (m) => `\\linespread{${argText(m, 0)}}`],
40
+ ["setlength", setsLayoutLength],
41
+ ["addtolength", setsLayoutLength],
42
+ [
43
+ "renewcommand",
44
+ (m) => firstMacro(m, 0) === "baselinestretch"
45
+ ? "\\renewcommand{\\baselinestretch}"
46
+ : null,
47
+ ],
48
+ ]);
49
+ /** How a message names a macro that overrides the layout, or null when it does not. */
50
+ const overrideOf = (m) => OVERRIDES.get(m.content)?.(m) ?? null;
51
+ /** Every layout override in the source, in document order. */
52
+ export function layoutOverridesOf(t) {
53
+ // Nothing is pruned: a comment, and a `comment` environment, reach the tree as leaves of text.
54
+ const lists = visited(t.root, () => false).filter(isList);
55
+ return lists.flatMap((list) => list.flatMap((n) => {
56
+ if (n.type !== "macro")
57
+ return [];
58
+ const command = overrideOf(n);
59
+ return command === null ? [] : [{ command, place: macroPlace(n) }];
60
+ }));
61
+ }
62
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../../src/adapters/latex/layout.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../../../src/adapters/latex/nodes.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,OAAO,KAAK,KAAK,GAAG,MAAM,oCAAoC,CAAC;AAE/D,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAGhE,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAExD,4EAA4E;AAC5E,MAAM,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACtC,MAAM,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACxC,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAE9C,uGAAuG;AACvG,UAAU,UAAU;IAClB,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAClB,QAAQ,CAAC,KAAK,EAAE;YAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;QAC5C,QAAQ,CAAC,GAAG,EAAE;YAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;KAC3C,CAAC;CACH;AAED,uDAAuD;AACvD,eAAO,MAAM,OAAO,GAAI,GAAG,UAAU,KAAG,KAMjC,CAAC;AAER,2FAA2F;AAC3F,eAAO,MAAM,OAAO,GAAI,CAAC,EACvB,GAAG,KAAK,EACR,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,EAAE,KAC9B,SAAS,CAAC,EAAwC,CAAC;AAEtD,yEAAyE;AACzE,eAAO,MAAM,WAAW,GAAI,GAAG,KAAK,KAAG,SAAS,QAAQ,EAAkB,CAAC;AAE3E,0GAA0G;AAC1G,eAAO,MAAM,SAAS,GAAI,GAAG,KAAK,KAAG,SAAS,QAAQ,EACJ,CAAC;AACnD,eAAO,MAAM,QAAQ,GAAI,GAAG,KAAK,KAAG,QAAQ,GAAG,SACC,CAAC;AAEjD,iGAAiG;AACjG,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,KAAG,MACZ,CAAC;AA+BlC;;;;;GAKG;AACH,eAAO,MAAM,MAAM,GAAI,OAAO,SAAS,IAAI,EAAE,GAAG,SAAS,KAAG,MAU/C,CAAC;AAEd;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,CAS1C;AAED,mGAAmG;AACnG,MAAM,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC;AAEvE;;;;GAIG;AACH,wBAAgB,OAAO,CAErB,IAAI,EAAE,GAAG,CAAC,GAAG,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,KAAK,OAAO,GACzD,SAAS,OAAO,EAAE,CAapB;AAED,yFAAyF;AACzF,eAAO,MAAM,MAAM,GAAI,GAAG,OAAO,KAAG,CAAC,IAAI,SAAS,CAAC,IAAI,GAAG,QAAQ,CAAC,EACjD,CAAC;AAEnB,+CAA+C;AAC/C,eAAO,MAAM,UAAU,GAAI,GAAG,OAAO,KAAG,CAAC,IAAI,QACR,CAAC;AAEtC,mFAAmF;AACnF,eAAO,MAAM,MAAM,GAAI,GAAG,OAAO,KAAG,CAAC,IAAI,IACiB,CAAC"}
1
+ {"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../../../src/adapters/latex/nodes.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,OAAO,KAAK,KAAK,GAAG,MAAM,oCAAoC,CAAC;AAE/D,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAGhE,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAExD,4EAA4E;AAC5E,MAAM,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACtC,MAAM,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACxC,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAE9C,uGAAuG;AACvG,UAAU,UAAU;IAClB,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAClB,QAAQ,CAAC,KAAK,EAAE;YAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;QAC5C,QAAQ,CAAC,GAAG,EAAE;YAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;KAC3C,CAAC;CACH;AAED,uDAAuD;AACvD,eAAO,MAAM,OAAO,GAAI,GAAG,UAAU,KAAG,KAMjC,CAAC;AAER,2FAA2F;AAC3F,eAAO,MAAM,OAAO,GAAI,CAAC,EACvB,GAAG,KAAK,EACR,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,EAAE,KAC9B,SAAS,CAAC,EAAwC,CAAC;AAEtD,yEAAyE;AACzE,eAAO,MAAM,WAAW,GAAI,GAAG,KAAK,KAAG,SAAS,QAAQ,EAAkB,CAAC;AAE3E,0GAA0G;AAC1G,eAAO,MAAM,SAAS,GAAI,GAAG,KAAK,KAAG,SAAS,QAAQ,EACJ,CAAC;AACnD,eAAO,MAAM,QAAQ,GAAI,GAAG,KAAK,KAAG,QAAQ,GAAG,SACC,CAAC;AAEjD,iGAAiG;AACjG,eAAO,MAAM,UAAU,GAAI,SAAS,MAAM,KAAG,MACZ,CAAC;AAuClC;;;;;GAKG;AACH,eAAO,MAAM,MAAM,GAAI,OAAO,SAAS,IAAI,EAAE,GAAG,SAAS,KAAG,MAU/C,CAAC;AAEd;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,CAS1C;AAED,mGAAmG;AACnG,MAAM,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC;AAEvE;;;;GAIG;AACH,wBAAgB,OAAO,CAErB,IAAI,EAAE,GAAG,CAAC,GAAG,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,KAAK,OAAO,GACzD,SAAS,OAAO,EAAE,CAapB;AAED,yFAAyF;AACzF,eAAO,MAAM,MAAM,GAAI,GAAG,OAAO,KAAG,CAAC,IAAI,SAAS,CAAC,IAAI,GAAG,QAAQ,CAAC,EACjD,CAAC;AAEnB,+CAA+C;AAC/C,eAAO,MAAM,UAAU,GAAI,GAAG,OAAO,KAAG,CAAC,IAAI,QACR,CAAC;AAEtC,mFAAmF;AACnF,eAAO,MAAM,MAAM,GAAI,GAAG,OAAO,KAAG,CAAC,IAAI,IACiB,CAAC"}
@@ -27,7 +27,17 @@ const NONE = { kind: "none" };
27
27
  */
28
28
  const SHOWN_ARGUMENT = new Map([
29
29
  ["texorpdfstring", { kind: "argument", at: 0 }],
30
- ...["color", "fontsize", "vspace", "hspace", "setlength", "addtolength"].map((m) => [m, NONE]),
30
+ ...[
31
+ "color",
32
+ "fontsize",
33
+ "vspace",
34
+ "hspace",
35
+ "setlength",
36
+ "addtolength",
37
+ "linespread",
38
+ "geometry",
39
+ "newgeometry",
40
+ ].map((m) => [m, NONE]),
31
41
  ]);
32
42
  /** The text a (non-key) macro typesets: see `SHOWN_ARGUMENT`. */
33
43
  function shownText(m) {
@@ -1 +1 @@
1
- {"version":3,"file":"nodes.js","sourceRoot":"","sources":["../../../src/adapters/latex/nodes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nodes.js","sourceRoot":"","sources":["../../../src/adapters/latex/nodes.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../src/adapters/latex/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,KAAK,GAAG,MAAM,oCAAoC,CAAC;AAU/D,oGAAoG;AACpG,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAgB9C,CAAC;AAEH,yFAAyF;AACzF,eAAO,MAAM,cAAc,EAAE,QAAQ,CACnC,MAAM,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAwB9C,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAGnD,CAAC;AAUH;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAWhD,CAAC;AAOH,QAAA,MAAM,MAAM,eAAsB,CAAC;AAEnC,0GAA0G;AAC1G,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC;IACxB,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC;CACzB;AAcD,iCAAiC;AACjC,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,KAAG,SAIvC,CAAC"}
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../src/adapters/latex/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,KAAK,GAAG,MAAM,oCAAoC,CAAC;AAU/D,oGAAoG;AACpG,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAgB9C,CAAC;AAEH,yFAAyF;AACzF,eAAO,MAAM,cAAc,EAAE,QAAQ,CACnC,MAAM,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAwB9C,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAGnD,CAAC;AAcH;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAWhD,CAAC;AAOH,QAAA,MAAM,MAAM,eAAsB,CAAC;AAEnC,0GAA0G;AAC1G,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC;IACxB,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC;CACzB;AAcD,iCAAiC;AACjC,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,KAAG,SAIvC,CAAC"}
@@ -55,7 +55,11 @@ const LINK_SIGNATURES = Object.fromEntries(signed(["href"], "m m"));
55
55
  * Declarations unified-latex has no signature for: signed so their arguments (sizes, not text)
56
56
  * attach to them instead of standing beside them as groups a reader would seem to see.
57
57
  */
58
- const DECLARATION_SIGNATURES = Object.fromEntries(signed(["fontsize"], "m m"));
58
+ const DECLARATION_SIGNATURES = Object.fromEntries([
59
+ ...signed(["fontsize"], "m m"),
60
+ // The layout commands `format/layout-override` reads: a spacing factor, geometry's key list.
61
+ ...signed(["linespread", "geometry", "newgeometry"], "m"),
62
+ ]);
59
63
  /**
60
64
  * Macros that define other macros or environments. A heading in a body is no section where it is
61
65
  * written, so the outline skips these; the rendered text reads a body as written, since nothing here
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/adapters/latex/parse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/adapters/latex/parse.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,13 @@
1
- import type { Passage } from "../../domain/tex-document.ts";
1
+ import type { Emphasis, Passage } from "../../domain/tex-document.ts";
2
2
  import { type ParsedTex } from "./parse.ts";
3
3
  /**
4
4
  * The body's prose, in document order: the content of the `document` environment (the whole
5
5
  * source when there is none), up to the first back-matter node.
6
6
  */
7
7
  export declare function bodyProse(t: ParsedTex): readonly Passage[];
8
+ /**
9
+ * The phrases set in bold, italics or underline inside the body's prose, in document order: what
10
+ * `bodyProse` reads, so never a heading, a run-in heading, a caption, a float or a table.
11
+ */
12
+ export declare function bodyEmphasis(t: ParsedTex): readonly Emphasis[];
8
13
  //# sourceMappingURL=prose.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prose.d.ts","sourceRoot":"","sources":["../../../src/adapters/latex/prose.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAS,OAAO,EAAc,MAAM,8BAA8B,CAAC;AAW/E,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AA6bhF;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,SAAS,GAAG,SAAS,OAAO,EAAE,CAM1D"}
1
+ {"version":3,"file":"prose.d.ts","sourceRoot":"","sources":["../../../src/adapters/latex/prose.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,QAAQ,EAGR,OAAO,EAGR,MAAM,8BAA8B,CAAC;AAYtC,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AA+iBhF;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,SAAS,GAAG,SAAS,OAAO,EAAE,CAE1D;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,SAAS,GAAG,SAAS,QAAQ,EAAE,CAE9D"}
@@ -1,5 +1,5 @@
1
- import { hasAtLeast, sortBy } from "remeda";
2
- import { argumentsOf, inPlace, macroPlace, mandatory, placeOf, stringText, } from "./nodes.js";
1
+ import { hasAtLeast, mapWithFeedback, only, sortBy, zip } from "remeda";
2
+ import { argumentsOf, collapse, inPlace, macroPlace, mandatory, placeOf, stringText, } from "./nodes.js";
3
3
  import { CITATION_MACROS, DEFINITION_MACROS } from "./parse.js";
4
4
  const BREAK = { kind: "break" };
5
5
  const END = { kind: "end" };
@@ -186,6 +186,62 @@ const OWN_EVENTS = new Map([
186
186
  (t, m) => [BREAK, ...walkList(t, itemBody(m), true)],
187
187
  ],
188
188
  ]);
189
+ /** Formatting macros that set their argument apart from the running text, and how. */
190
+ const EMPHASIS_MACROS = new Map([
191
+ ["textbf", "bold"],
192
+ ["emph", "italic"],
193
+ ["textit", "italic"],
194
+ ["textsl", "italic"],
195
+ ["underline", "underline"],
196
+ ["uline", "underline"],
197
+ ]);
198
+ /**
199
+ * Declarations that set the rest of their group apart — `{\bfseries …}`, `{\em …}` — and how. The
200
+ * group is the phrase.
201
+ */
202
+ const EMPHASIS_DECLARATIONS = new Map([
203
+ ["bfseries", "bold"],
204
+ ["bf", "bold"],
205
+ ["em", "italic"],
206
+ ["itshape", "italic"],
207
+ ["it", "italic"],
208
+ ["slshape", "italic"],
209
+ ]);
210
+ /** An emphasised phrase over `place`, typesetting what `inner` typesets; nothing when it has no place or no text. */
211
+ const emphasisOf = (style, place, inner) => inPlace(place, (span) => {
212
+ const text = collapse(typeset(inner));
213
+ return text === ""
214
+ ? []
215
+ : [
216
+ {
217
+ kind: "emphasis",
218
+ emphasis: { style, place: "inline", text, span },
219
+ },
220
+ ];
221
+ });
222
+ /** A formatting macro's events: what it typesets, and — for an emphasising one — the phrase. */
223
+ function formattingEvents(t, m) {
224
+ const inner = walkList(t, lastArgument(m));
225
+ const style = EMPHASIS_MACROS.get(m.content);
226
+ return style === undefined
227
+ ? inner
228
+ : [...emphasisOf(style, macroPlace(m), inner), ...inner];
229
+ }
230
+ /** The style a group's opening declaration sets, when it opens with one (`{\bfseries …}`). */
231
+ function declaredStyle(list) {
232
+ const first = list.find((n) => n.type !== "whitespace" && n.type !== "comment");
233
+ return first?.type === "macro"
234
+ ? EMPHASIS_DECLARATIONS.get(first.content)
235
+ : undefined;
236
+ }
237
+ /** A group's events: what it typesets, and — when it opens with an emphasis declaration — the phrase. */
238
+ function groupEvents(t, g) {
239
+ const inner = walkList(t, g.content);
240
+ const style = declaredStyle(g.content);
241
+ return style === undefined
242
+ ? inner
243
+ : [...emphasisOf(style, placeOf(g), inner), ...inner];
244
+ }
189
245
  function macroEvents(t, m) {
190
246
  const name = m.content;
191
247
  if (DEFINITION_MACROS.has(name))
@@ -202,7 +258,7 @@ function macroEvents(t, m) {
202
258
  if (BREAK_MACROS.has(name))
203
259
  return [BREAK];
204
260
  if (INLINE_MACROS.has(name))
205
- return walkList(t, lastArgument(m));
261
+ return formattingEvents(t, m);
206
262
  const ch = CHARACTER_MACROS.get(name);
207
263
  return ch === undefined ? [] : characterAt(m, ch);
208
264
  }
@@ -235,7 +291,7 @@ function nodeEvents(t, n) {
235
291
  case "whitespace":
236
292
  return textAt(n, " ");
237
293
  case "group":
238
- return walkList(t, n.content);
294
+ return groupEvents(t, n);
239
295
  case "environment":
240
296
  case "mathenv":
241
297
  return environmentEvents(t, n);
@@ -266,13 +322,12 @@ function step(state, n) {
266
322
  * macro the parser gave no signature — `\institution{…}`, `\ccsdesc[500]{…}`, `\tool{}`,
267
323
  * `\if\conference1` — which are its arguments, not text. A formatting macro's group (`\enquote{…}` without csquotes' signature) stays prose.
268
324
  */
269
- const proseNodes = (list) => list.reduce((acc, n) => {
270
- const next = step(acc.state, n);
271
- return {
272
- kept: next.skip ? acc.kept : [...acc.kept, n],
273
- state: next.state,
274
- };
275
- }, { kept: [], state: "prose" }).kept;
325
+ const proseNodes = (list) => {
326
+ // Each node's step, fed the state the one before left: a scan, linear in the list.
327
+ const start = { skip: false, state: "prose" };
328
+ const steps = mapWithFeedback(list, (prev, n) => step(prev.state, n), start);
329
+ return zip(list, steps).flatMap(([n, st]) => (st.skip ? [] : [n]));
330
+ };
276
331
  /** Formatting macros a run-in heading is set in: `\textbf{Correctness gate.} Each task…`. */
277
332
  const RUN_IN_MACROS = new Set([
278
333
  "textbf",
@@ -285,10 +340,28 @@ const RUN_IN_MACROS = new Set([
285
340
  const typeset = (events) => events
286
341
  .map((e) => e.kind === "piece" && e.piece.kind === "text" ? e.piece.segment.text : "")
287
342
  .join("");
288
- /** A formatting macro whose phrase ends in `.` or `:` — a run-in heading, when it opens a paragraph. */
289
- const isRunInHeading = (t, n) => n.type === "macro" &&
290
- RUN_IN_MACROS.has(n.content) &&
291
- /[.:]$/u.test(typeset(walkList(t, lastArgument(n))).trim());
343
+ /** The one node a group holds besides spaces and comments — `{\textbf{…}}` → the `\textbf` — or null. */
344
+ const soleChild = (n) => {
345
+ if (n.type !== "group")
346
+ return null;
347
+ const kept = n.content.filter((c) => c.type !== "whitespace" && c.type !== "comment");
348
+ return only(kept) ?? null;
349
+ };
350
+ /** A node with the groups around it taken off: `{{\textbf{…}}}` → the `\textbf`. */
351
+ const unwrapped = (n) => {
352
+ const inner = soleChild(n);
353
+ return inner === null ? n : unwrapped(inner);
354
+ };
355
+ /**
356
+ * A formatting macro whose phrase ends in `.` or `:` — a run-in heading, when it opens a paragraph.
357
+ * Braces around it change nothing on the page, so `{\textbf{Threats:}}` is one too.
358
+ */
359
+ const isRunInHeading = (t, node) => {
360
+ const n = unwrapped(node);
361
+ return (n.type === "macro" &&
362
+ RUN_IN_MACROS.has(n.content) &&
363
+ /[.:]$/u.test(typeset(walkList(t, lastArgument(n))).trim()));
364
+ };
292
365
  /** Macros that typeset no text, and so leave a paragraph's opening where it was. */
293
366
  const SILENT_AT_OPENING = new Set([
294
367
  "noindent",
@@ -305,18 +378,38 @@ const keepsOpening = (n) => n.type === "whitespace" ||
305
378
  (n.type === "macro" && SILENT_AT_OPENING.has(n.content));
306
379
  /** Nodes after which a paragraph opens: a paragraph break, and a macro that ends a passage (a heading). */
307
380
  const opensAfter = (n) => n.type === "parbreak" || (n.type === "macro" && BREAK_MACROS.has(n.content));
381
+ /**
382
+ * An emphasising node's events when it opens a paragraph: its own phrase — the first event — is a
383
+ * label, not inline; braces around it change nothing on the page (`{\textbf{…}}.`). Any other node
384
+ * (an environment, a footnote) is left as it is: what it holds opens nothing here.
385
+ */
386
+ const asOpening = (node, events) => {
387
+ const [own, ...rest] = events;
388
+ const n = unwrapped(node);
389
+ const emphasises = (n.type === "macro" && EMPHASIS_MACROS.has(n.content)) ||
390
+ (n.type === "group" && declaredStyle(n.content) !== undefined);
391
+ return emphasises && own?.kind === "emphasis"
392
+ ? [
393
+ { kind: "emphasis", emphasis: { ...own.emphasis, place: "opening" } },
394
+ ...rest,
395
+ ]
396
+ : events;
397
+ };
308
398
  /**
309
399
  * A list's events. `opens` says the list starts a paragraph (the body, an environment's content);
310
- * a run-in heading that opens a paragraph ends the passage before it and is left out, like a heading.
400
+ * a run-in heading that opens a paragraph ends the passage before it and is left out, like a heading,
401
+ * and a phrase emphasised there is a label (`opening`).
311
402
  */
312
403
  function walkList(t, list, opens = false) {
313
- return proseNodes(list).reduce((acc, n) => ({
314
- events: [
315
- ...acc.events,
316
- ...(acc.opening && isRunInHeading(t, n) ? [BREAK] : nodeEvents(t, n)),
317
- ],
318
- opening: opensAfter(n) || (acc.opening && keepsOpening(n)),
319
- }), { events: [], opening: opens }).events;
404
+ const nodes = proseNodes(list);
405
+ // Whether a paragraph is open AFTER each node: a scan, so the walk stays linear in the list.
406
+ const after = mapWithFeedback(nodes, (opening, n) => opensAfter(n) || (opening && keepsOpening(n)), opens);
407
+ return nodes.flatMap((n, i) => {
408
+ const opening = i === 0 ? opens : after[i - 1] === true;
409
+ if (!opening)
410
+ return nodeEvents(t, n);
411
+ return isRunInHeading(t, n) ? [BREAK] : asOpening(n, nodeEvents(t, n));
412
+ });
320
413
  }
321
414
  /** The events before the back matter starts. */
322
415
  const untilEnd = (events) => {
@@ -325,15 +418,25 @@ const untilEnd = (events) => {
325
418
  };
326
419
  /** Events → passages: pieces between breaks, each footnote a passage of its own. */
327
420
  function passagesOf(events) {
328
- const { done, current } = events.reduce((acc, e) => e.kind === "piece"
329
- ? { done: acc.done, current: [...acc.current, e.piece] }
330
- : e.kind === "break"
331
- ? { done: [...acc.done, acc.current], current: [] }
332
- : acc, { done: [], current: [] });
421
+ // Where each passage starts and ends: between breaks. Slicing between them keeps this linear in
422
+ // the events — a paragraph of thousands of words is one slice, not a copy per word.
423
+ const breaks = events.flatMap((e, i) => (e.kind === "break" ? [i] : []));
424
+ const bounds = zip([0, ...breaks.map((b) => b + 1)], [...breaks, events.length]);
425
+ const own = bounds.flatMap(([from, to]) => {
426
+ const pieces = events
427
+ .slice(from, to)
428
+ .flatMap((e) => (e.kind === "piece" ? [e.piece] : []));
429
+ return hasAtLeast(pieces, 1) ? [{ pieces }] : [];
430
+ });
333
431
  const asides = events.flatMap((e) => e.kind === "aside" ? passagesOf(untilEnd(e.events)) : []);
334
- const own = [...done, current].flatMap((pieces) => hasAtLeast(pieces, 1) ? [{ pieces }] : []);
335
432
  return [...own, ...asides];
336
433
  }
434
+ /** Every emphasised phrase among events, a footnote's included, up to the back matter. */
435
+ const emphasesOf = (events) => untilEnd(events).flatMap((e) => e.kind === "emphasis"
436
+ ? [e.emphasis]
437
+ : e.kind === "aside"
438
+ ? emphasesOf(e.events)
439
+ : []);
337
440
  const isDocument = (n) => n.type === "environment" && n.env === "document";
338
441
  /** A passage with something in it besides spaces. */
339
442
  const hasProse = (p) => p.pieces.some((x) => x.kind !== "text" || x.segment.text.trim() !== "");
@@ -347,7 +450,15 @@ const startOf = (p) => {
347
450
  * source when there is none), up to the first back-matter node.
348
451
  */
349
452
  export function bodyProse(t) {
350
- const body = t.root.content.find(isDocument)?.content ?? t.root.content;
351
- return sortBy(passagesOf(untilEnd(walkList(t, body, true))).filter(hasProse), startOf);
453
+ return sortBy(passagesOf(untilEnd(bodyEvents(t))).filter(hasProse), startOf);
454
+ }
455
+ /** The walk of the body: the content of the `document` environment, or the whole source when there is none. */
456
+ const bodyEvents = (t) => walkList(t, t.root.content.find(isDocument)?.content ?? t.root.content, true);
457
+ /**
458
+ * The phrases set in bold, italics or underline inside the body's prose, in document order: what
459
+ * `bodyProse` reads, so never a heading, a run-in heading, a caption, a float or a table.
460
+ */
461
+ export function bodyEmphasis(t) {
462
+ return sortBy(emphasesOf(bodyEvents(t)), (e) => e.span.start);
352
463
  }
353
464
  //# sourceMappingURL=prose.js.map