paperlint 7.2.0 → 9.0.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 (474) hide show
  1. package/CLAUDE.md +9 -25
  2. package/CONTRIBUTING.md +5 -4
  3. package/README.md +4 -3
  4. package/dist/adapters/bibtex/index.d.ts +3 -0
  5. package/dist/adapters/bibtex/index.d.ts.map +1 -0
  6. package/dist/adapters/bibtex/index.js +103 -0
  7. package/dist/adapters/bibtex/index.js.map +1 -0
  8. package/dist/adapters/latex/filecontents.d.ts +33 -0
  9. package/dist/adapters/latex/filecontents.d.ts.map +1 -0
  10. package/dist/adapters/latex/filecontents.js +65 -0
  11. package/dist/adapters/latex/filecontents.js.map +1 -0
  12. package/dist/adapters/latex/includes.d.ts +3 -3
  13. package/dist/adapters/latex/includes.d.ts.map +1 -1
  14. package/dist/adapters/latex/includes.js +18 -10
  15. package/dist/adapters/latex/includes.js.map +1 -1
  16. package/dist/adapters/latex/index.d.ts.map +1 -1
  17. package/dist/adapters/latex/index.js +2 -0
  18. package/dist/adapters/latex/index.js.map +1 -1
  19. package/dist/adapters/latex/nodes.d.ts +12 -0
  20. package/dist/adapters/latex/nodes.d.ts.map +1 -1
  21. package/dist/adapters/latex/nodes.js +39 -0
  22. package/dist/adapters/latex/nodes.js.map +1 -1
  23. package/dist/adapters/latex/parse.d.ts +7 -1
  24. package/dist/adapters/latex/parse.d.ts.map +1 -1
  25. package/dist/adapters/latex/parse.js +55 -6
  26. package/dist/adapters/latex/parse.js.map +1 -1
  27. package/dist/adapters/memory/index.d.ts +3 -0
  28. package/dist/adapters/memory/index.d.ts.map +1 -1
  29. package/dist/adapters/memory/index.js +9 -0
  30. package/dist/adapters/memory/index.js.map +1 -1
  31. package/dist/adapters/references/index.d.ts.map +1 -1
  32. package/dist/adapters/references/index.js +27 -24
  33. package/dist/adapters/references/index.js.map +1 -1
  34. package/dist/adapters/sources-record/index.d.ts +9 -0
  35. package/dist/adapters/sources-record/index.d.ts.map +1 -0
  36. package/dist/adapters/sources-record/index.js +68 -0
  37. package/dist/adapters/sources-record/index.js.map +1 -0
  38. package/dist/adapters/tex-output/blg.d.ts +9 -0
  39. package/dist/adapters/tex-output/blg.d.ts.map +1 -0
  40. package/dist/adapters/tex-output/blg.js +20 -0
  41. package/dist/adapters/tex-output/blg.js.map +1 -0
  42. package/dist/adapters/tex-output/fls.d.ts +8 -0
  43. package/dist/adapters/tex-output/fls.d.ts.map +1 -0
  44. package/dist/adapters/tex-output/fls.js +16 -0
  45. package/dist/adapters/tex-output/fls.js.map +1 -0
  46. package/dist/adapters/tex-output/index.d.ts +7 -0
  47. package/dist/adapters/tex-output/index.d.ts.map +1 -0
  48. package/dist/adapters/tex-output/index.js +7 -0
  49. package/dist/adapters/tex-output/index.js.map +1 -0
  50. package/dist/bib-rules.d.ts +47 -0
  51. package/dist/bib-rules.d.ts.map +1 -0
  52. package/dist/bib-rules.js +127 -0
  53. package/dist/bib-rules.js.map +1 -0
  54. package/dist/build.d.ts +29 -1
  55. package/dist/build.d.ts.map +1 -1
  56. package/dist/build.js +41 -30
  57. package/dist/build.js.map +1 -1
  58. package/dist/claim-provenance.d.ts +2 -2
  59. package/dist/cli.d.ts +9 -5
  60. package/dist/cli.d.ts.map +1 -1
  61. package/dist/cli.js +43 -68
  62. package/dist/cli.js.map +1 -1
  63. package/dist/domain/paper-source.d.ts +1 -10
  64. package/dist/domain/paper-source.d.ts.map +1 -1
  65. package/dist/domain/paper-source.js +34 -24
  66. package/dist/domain/paper-source.js.map +1 -1
  67. package/dist/domain/paper-sources.d.ts +72 -0
  68. package/dist/domain/paper-sources.d.ts.map +1 -0
  69. package/dist/domain/paper-sources.js +18 -0
  70. package/dist/domain/paper-sources.js.map +1 -0
  71. package/dist/domain/sources-record.d.ts +102 -0
  72. package/dist/domain/sources-record.d.ts.map +1 -0
  73. package/dist/domain/sources-record.js +38 -0
  74. package/dist/domain/sources-record.js.map +1 -0
  75. package/dist/domain/tex-run.d.ts +25 -0
  76. package/dist/domain/tex-run.d.ts.map +1 -0
  77. package/dist/domain/tex-run.js +79 -0
  78. package/dist/domain/tex-run.js.map +1 -0
  79. package/dist/eslint-rules/latex-language.d.ts.map +1 -1
  80. package/dist/eslint-rules/latex-language.js +10 -13
  81. package/dist/eslint-rules/latex-language.js.map +1 -1
  82. package/dist/eslint-rules/paper-context.d.ts.map +1 -1
  83. package/dist/eslint-rules/paper-context.js +6 -5
  84. package/dist/eslint-rules/paper-context.js.map +1 -1
  85. package/dist/eslint-rules/paper-typography.d.ts +0 -9
  86. package/dist/eslint-rules/paper-typography.d.ts.map +1 -1
  87. package/dist/eslint-rules/paper-typography.js +34 -96
  88. package/dist/eslint-rules/paper-typography.js.map +1 -1
  89. package/dist/eslint-rules/papers.d.ts +1 -3
  90. package/dist/eslint-rules/papers.d.ts.map +1 -1
  91. package/dist/eslint-rules/papers.js +2 -4
  92. package/dist/eslint-rules/papers.js.map +1 -1
  93. package/dist/eslint-rules/tex-build.d.ts.map +1 -1
  94. package/dist/eslint-rules/tex-build.js +8 -25
  95. package/dist/eslint-rules/tex-build.js.map +1 -1
  96. package/dist/init.d.ts +1 -4
  97. package/dist/init.d.ts.map +1 -1
  98. package/dist/init.js +3 -9
  99. package/dist/init.js.map +1 -1
  100. package/dist/latex-log.d.ts +10 -0
  101. package/dist/latex-log.d.ts.map +1 -1
  102. package/dist/latex-log.js +10 -0
  103. package/dist/latex-log.js.map +1 -1
  104. package/dist/latex-loop.d.ts +2 -0
  105. package/dist/latex-loop.d.ts.map +1 -1
  106. package/dist/latex-loop.js.map +1 -1
  107. package/dist/lib/markdown.d.ts +5 -81
  108. package/dist/lib/markdown.d.ts.map +1 -1
  109. package/dist/lib/markdown.js +5 -116
  110. package/dist/lib/markdown.js.map +1 -1
  111. package/dist/lib/paper-config.d.ts.map +1 -1
  112. package/dist/lib/paper-config.js +0 -2
  113. package/dist/lib/paper-config.js.map +1 -1
  114. package/dist/lib/skill-eval-fixture.d.ts +6 -4
  115. package/dist/lib/skill-eval-fixture.d.ts.map +1 -1
  116. package/dist/lib/skill-eval-fixture.js +25 -18
  117. package/dist/lib/skill-eval-fixture.js.map +1 -1
  118. package/dist/new-paper.d.ts +5 -11
  119. package/dist/new-paper.d.ts.map +1 -1
  120. package/dist/new-paper.js +12 -23
  121. package/dist/new-paper.js.map +1 -1
  122. package/dist/package-dirs.d.ts.map +1 -1
  123. package/dist/package-dirs.js +3 -2
  124. package/dist/package-dirs.js.map +1 -1
  125. package/dist/paper-files.d.ts +4 -4
  126. package/dist/paper-includes.d.ts +4 -7
  127. package/dist/paper-includes.d.ts.map +1 -1
  128. package/dist/paper-includes.js +29 -21
  129. package/dist/paper-includes.js.map +1 -1
  130. package/dist/paper-prose.d.ts +17 -0
  131. package/dist/paper-prose.d.ts.map +1 -0
  132. package/dist/paper-prose.js +46 -0
  133. package/dist/paper-prose.js.map +1 -0
  134. package/dist/paper-record.d.ts +25 -0
  135. package/dist/paper-record.d.ts.map +1 -0
  136. package/dist/paper-record.js +39 -0
  137. package/dist/paper-record.js.map +1 -0
  138. package/dist/paper-sources.d.ts +66 -0
  139. package/dist/paper-sources.d.ts.map +1 -0
  140. package/dist/paper-sources.js +92 -0
  141. package/dist/paper-sources.js.map +1 -0
  142. package/dist/ports/bib-reader.d.ts +18 -0
  143. package/dist/ports/bib-reader.d.ts.map +1 -0
  144. package/dist/ports/bib-reader.js +2 -0
  145. package/dist/ports/bib-reader.js.map +1 -0
  146. package/dist/ports/check-references.d.ts +9 -4
  147. package/dist/ports/check-references.d.ts.map +1 -1
  148. package/dist/ports/latex.d.ts +15 -0
  149. package/dist/ports/latex.d.ts.map +1 -1
  150. package/dist/ports/sources-codec.d.ts +11 -0
  151. package/dist/ports/sources-codec.d.ts.map +1 -0
  152. package/dist/ports/sources-codec.js +2 -0
  153. package/dist/ports/sources-codec.js.map +1 -0
  154. package/dist/ports/tex-output.d.ts +17 -0
  155. package/dist/ports/tex-output.d.ts.map +1 -0
  156. package/dist/ports/tex-output.js +2 -0
  157. package/dist/ports/tex-output.js.map +1 -0
  158. package/dist/recorded-bibliography.d.ts +89 -0
  159. package/dist/recorded-bibliography.d.ts.map +1 -0
  160. package/dist/recorded-bibliography.js +136 -0
  161. package/dist/recorded-bibliography.js.map +1 -0
  162. package/dist/reference-rules.d.ts +5 -5
  163. package/dist/reference-rules.d.ts.map +1 -1
  164. package/dist/reference-rules.js +150 -77
  165. package/dist/reference-rules.js.map +1 -1
  166. package/dist/references.d.ts +71 -16
  167. package/dist/references.d.ts.map +1 -1
  168. package/dist/references.js +110 -26
  169. package/dist/references.js.map +1 -1
  170. package/dist/register-bands.d.ts +3 -3
  171. package/dist/register-bands.d.ts.map +1 -1
  172. package/dist/register-bands.js.map +1 -1
  173. package/dist/register.d.ts +2 -2
  174. package/dist/sources-record.d.ts +38 -0
  175. package/dist/sources-record.d.ts.map +1 -0
  176. package/dist/sources-record.js +123 -0
  177. package/dist/sources-record.js.map +1 -0
  178. package/dist/sources-rules.d.ts +44 -0
  179. package/dist/sources-rules.d.ts.map +1 -0
  180. package/dist/sources-rules.js +76 -0
  181. package/dist/sources-rules.js.map +1 -0
  182. package/dist/structure.d.ts.map +1 -1
  183. package/dist/structure.js +4 -3
  184. package/dist/structure.js.map +1 -1
  185. package/dist/tex-paper.d.ts +10 -15
  186. package/dist/tex-paper.d.ts.map +1 -1
  187. package/dist/tex-paper.js +24 -40
  188. package/dist/tex-paper.js.map +1 -1
  189. package/dist/tex-venue-rules.d.ts +3 -3
  190. package/dist/tex-venue-rules.d.ts.map +1 -1
  191. package/dist/tex-venue-rules.js.map +1 -1
  192. package/dist/types.d.ts +0 -2
  193. package/dist/types.d.ts.map +1 -1
  194. package/docs/configuration.md +18 -12
  195. package/docs/design/paper-sources.md +197 -0
  196. package/docs/e2e.md +4 -6
  197. package/docs/package-shape-options.md +1 -1
  198. package/docs/prior-art/paper-folder-scaffolding.md +24 -29
  199. package/docs/references.md +34 -8
  200. package/docs/rules/bib/reachable-entry.md +64 -0
  201. package/docs/rules/paper/sources-fresh.md +81 -0
  202. package/docs/rules/tex/claim-provenance.md +0 -1
  203. package/docs/rules.md +62 -61
  204. package/eslint-rules/latex-language.harness.mjs +3 -3
  205. package/eslint-rules/latex-language.ts +10 -13
  206. package/eslint-rules/paper-context.ts +6 -5
  207. package/eslint-rules/paper-typography.test.mjs +29 -157
  208. package/eslint-rules/paper-typography.ts +35 -104
  209. package/eslint-rules/papers.harness.mjs +1 -1
  210. package/eslint-rules/papers.ts +2 -4
  211. package/eslint-rules/tex-build.harness.mjs +2 -2
  212. package/eslint-rules/tex-build.ts +8 -25
  213. package/eslint.config.mjs +22 -1
  214. package/fixtures/build-e2e/aidc/paper.tex +1 -1
  215. package/fixtures/build-e2e/anon-ack/paper.tex +1 -1
  216. package/fixtures/build-e2e/anon-author/paper.tex +1 -1
  217. package/fixtures/build-e2e/anon-bib/paper.tex +1 -1
  218. package/fixtures/build-e2e/anon-href/paper.tex +1 -1
  219. package/fixtures/build-e2e/anon-macro/paper.tex +1 -1
  220. package/fixtures/build-e2e/anon-pdfauthor/paper.tex +1 -1
  221. package/fixtures/paper-sources/p1/paper.tex +30 -0
  222. package/fixtures/paper-sources/p1/refs.bib +6 -0
  223. package/fixtures/paper-sources/p1/sections/dead.tex +6 -0
  224. package/fixtures/paper-sources/p1/sections/intro.tex +7 -0
  225. package/fixtures/paper-sources/p1/sections/parked.tex +6 -0
  226. package/fixtures/paper-sources/p1/tex-truth.json +37 -0
  227. package/fixtures/paper-sources/p1/versions/2026-01-01-review.tex +4 -0
  228. package/fixtures/paper-sources/v1-stale/paper.tex +14 -0
  229. package/fixtures/paper-sources/v1-stale/refs.bib +6 -0
  230. package/fixtures/paper-sources/v1-stale/tex-truth.json +32 -0
  231. package/fixtures/paper-sources/v10-ifthenelse/anon.bib +1 -0
  232. package/fixtures/paper-sources/v10-ifthenelse/paper.tex +9 -0
  233. package/fixtures/paper-sources/v10-ifthenelse/real.bib +1 -0
  234. package/fixtures/paper-sources/v10-ifthenelse/tex-truth.json +28 -0
  235. package/fixtures/paper-sources/v11-two-blocks/paper.tex +12 -0
  236. package/fixtures/paper-sources/v11-two-blocks/tex-truth.json +30 -0
  237. package/fixtures/paper-sources/v13-percent-text/paper.tex +6 -0
  238. package/fixtures/paper-sources/v13-percent-text/refs.bib +3 -0
  239. package/fixtures/paper-sources/v13-percent-text/tex-truth.json +30 -0
  240. package/fixtures/paper-sources/v15-after-end/paper.tex +6 -0
  241. package/fixtures/paper-sources/v15-after-end/refs.bib +1 -0
  242. package/fixtures/paper-sources/v15-after-end/tex-truth.json +17 -0
  243. package/fixtures/paper-sources/v16-included-block/bibblock.tex +3 -0
  244. package/fixtures/paper-sources/v16-included-block/paper.tex +7 -0
  245. package/fixtures/paper-sources/v16-included-block/refs.bib +1 -0
  246. package/fixtures/paper-sources/v16-included-block/tex-truth.json +35 -0
  247. package/fixtures/paper-sources/v17-include-order/bibsetup.tex +1 -0
  248. package/fixtures/paper-sources/v17-include-order/first.bib +1 -0
  249. package/fixtures/paper-sources/v17-include-order/later.bib +1 -0
  250. package/fixtures/paper-sources/v17-include-order/paper.tex +7 -0
  251. package/fixtures/paper-sources/v17-include-order/tex-truth.json +40 -0
  252. package/fixtures/paper-sources/v2-overwrite/paper.tex +14 -0
  253. package/fixtures/paper-sources/v2-overwrite/refs.bib +6 -0
  254. package/fixtures/paper-sources/v2-overwrite/tex-truth.json +30 -0
  255. package/fixtures/paper-sources/v22-parked-thebibliography/paper.tex +7 -0
  256. package/fixtures/paper-sources/v22-parked-thebibliography/tex-truth.json +17 -0
  257. package/fixtures/paper-sources/v23-parked-include/old.bib +1 -0
  258. package/fixtures/paper-sources/v23-parked-include/paper.tex +7 -0
  259. package/fixtures/paper-sources/v23-parked-include/parked.tex +1 -0
  260. package/fixtures/paper-sources/v23-parked-include/refs.bib +1 -0
  261. package/fixtures/paper-sources/v23-parked-include/tex-truth.json +28 -0
  262. package/fixtures/paper-sources/v24-quoted-fields/paper.tex +6 -0
  263. package/fixtures/paper-sources/v24-quoted-fields/refs.bib +5 -0
  264. package/fixtures/paper-sources/v24-quoted-fields/tex-truth.json +32 -0
  265. package/fixtures/paper-sources/v25-string-differs/paper.tex +10 -0
  266. package/fixtures/paper-sources/v25-string-differs/refs.bib +2 -0
  267. package/fixtures/paper-sources/v25-string-differs/tex-truth.json +32 -0
  268. package/fixtures/paper-sources/v26-comment-in-names/one.bib +1 -0
  269. package/fixtures/paper-sources/v26-comment-in-names/paper.tex +7 -0
  270. package/fixtures/paper-sources/v26-comment-in-names/tex-truth.json +32 -0
  271. package/fixtures/paper-sources/v26-comment-in-names/two.bib +1 -0
  272. package/fixtures/paper-sources/v27-shared-string/abbreviations.bib +2 -0
  273. package/fixtures/paper-sources/v27-shared-string/paper.tex +6 -0
  274. package/fixtures/paper-sources/v27-shared-string/references.bib +6 -0
  275. package/fixtures/paper-sources/v27-shared-string/tex-truth.json +31 -0
  276. package/fixtures/paper-sources/v28-shared-string-block/abbreviations.bib +2 -0
  277. package/fixtures/paper-sources/v28-shared-string-block/paper.tex +14 -0
  278. package/fixtures/paper-sources/v28-shared-string-block/tex-truth.json +33 -0
  279. package/fixtures/paper-sources/v29-generated-input/paper.tex +9 -0
  280. package/fixtures/paper-sources/v29-generated-input/tex-truth.json +24 -0
  281. package/fixtures/paper-sources/v3-declared/paper.bib +6 -0
  282. package/fixtures/paper-sources/v3-declared/paper.tex +6 -0
  283. package/fixtures/paper-sources/v3-declared/tex-truth.json +28 -0
  284. package/fixtures/paper-sources/v30-name-next-line/paper.tex +14 -0
  285. package/fixtures/paper-sources/v30-name-next-line/tex-truth.json +30 -0
  286. package/fixtures/paper-sources/v4-commented/paper.tex +14 -0
  287. package/fixtures/paper-sources/v4-commented/refs.bib +6 -0
  288. package/fixtures/paper-sources/v4-commented/tex-truth.json +28 -0
  289. package/fixtures/paper-sources/v5-percent-entry/paper.tex +20 -0
  290. package/fixtures/paper-sources/v5-percent-entry/tex-truth.json +37 -0
  291. package/fixtures/paper-sources/v6-unclosed/paper.tex +6 -0
  292. package/fixtures/paper-sources/v6-unclosed/refs.bib +5 -0
  293. package/fixtures/paper-sources/v6-unclosed/tex-truth.json +37 -0
  294. package/fixtures/paper-sources/v8-jobname/paper.tex +9 -0
  295. package/fixtures/paper-sources/v8-jobname/tex-truth.json +30 -0
  296. package/fixtures/paper-sources/v9-two-bibliographies/one.bib +1 -0
  297. package/fixtures/paper-sources/v9-two-bibliographies/paper.tex +7 -0
  298. package/fixtures/paper-sources/v9-two-bibliographies/tex-truth.json +35 -0
  299. package/fixtures/paper-sources/v9-two-bibliographies/two.bib +1 -0
  300. package/fixtures/paper-typography/clean-paper/paper.tex +1 -1
  301. package/fixtures/paper-typography/messy-paper/paper.tex +1 -1
  302. package/hooks/hooks.harness.ts +15 -15
  303. package/hooks/paper-edit-guard.hook.mjs +5 -8
  304. package/hooks/paper-edit-guard.test.ts +12 -3
  305. package/hooks/paper-skills-nudge.hook.mjs +2 -3
  306. package/hooks/paper-skills-nudge.test.ts +13 -3
  307. package/hooks/paper-status-gates.hook.mjs +2 -2
  308. package/hooks/paper-status-gates.test.ts +14 -2
  309. package/lib/markdown.test.mjs +5 -60
  310. package/lib/markdown.ts +9 -136
  311. package/lib/paper-config.ts +0 -2
  312. package/lib/skill-checks.test.mjs +4 -1
  313. package/lib/skill-eval-fixture.ts +25 -18
  314. package/package.json +2 -12
  315. package/presets/realm.jsonc +1 -1
  316. package/scripts/check.test.ts +23 -1
  317. package/scripts/check.ts +7 -3
  318. package/scripts/coverage-config.test.ts +19 -10
  319. package/scripts/harness-api.frozen.json +0 -5
  320. package/scripts/layer-legacy-frozen.test.ts +41 -2
  321. package/scripts/layer-legacy-frozen.ts +31 -2
  322. package/skills/cold-read-diff/SKILL.md +3 -3
  323. package/skills/cold-read-diff/SKILL.md.spec.ts +2 -2
  324. package/skills/grade-paper-writing/SKILL.md +15 -22
  325. package/skills/grade-paper-writing/SKILL.md.spec.ts +14 -21
  326. package/skills/grade-paper-writing/__snapshots__/prose-lint.test.ts.snap +40 -26
  327. package/skills/grade-paper-writing/prose-lint.mjs +117 -278
  328. package/skills/grade-paper-writing/prose-lint.test.ts +230 -79
  329. package/skills/paper-adversarial-review/SKILL.md +2 -2
  330. package/skills/paper-adversarial-review/SKILL.md.spec.ts +1 -1
  331. package/skills/paper-pipeline/SKILL.md +9 -12
  332. package/skills/paper-pipeline/SKILL.md.spec.ts +8 -11
  333. package/skills/paper-pipeline/description-language.eval.mjs +25 -15
  334. package/skills/paper-pipeline/framing-vs-vocabulary.eval.mjs +25 -15
  335. package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +25 -15
  336. package/skills/paper-pipeline/pipeline-firing.eval.mjs +27 -16
  337. package/skills/paper-pipeline/pipeline-language.eval.mjs +25 -15
  338. package/skills/paper-pipeline/references/acceptance-gate.md +16 -20
  339. package/skills/paper-pipeline/references/artifact-checklist.md +4 -5
  340. package/skills/paper-pipeline/references/pipeline-status-template.md +1 -1
  341. package/skills/paper-pipeline/scripts/README.md +0 -4
  342. package/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs +91 -105
  343. package/skills/paper-pipeline/scripts/extract-ref-facts.mjs +85 -241
  344. package/skills/paper-pipeline/scripts/extract-ref-facts.test.mjs +166 -153
  345. package/skills/paper-pipeline/scripts/generated-code.harness.mjs +3 -3
  346. package/skills/paper-status/SKILL.md +2 -2
  347. package/skills/paper-status/SKILL.md.spec.ts +1 -1
  348. package/skills/render-paper/SKILL.md +2 -2
  349. package/skills/render-paper/SKILL.md.spec.ts +1 -1
  350. package/skills/render-paper/extract-pdf-facts.mjs +2 -2
  351. package/skills/tighten-paper/SKILL.md +29 -42
  352. package/skills/tighten-paper/SKILL.md.spec.ts +28 -41
  353. package/skills/verify-citations/SKILL.md +7 -4
  354. package/skills/verify-citations/SKILL.md.spec.ts +6 -3
  355. package/skills/verify-citations/scripts/bib-authors.check.test.mjs +17 -32
  356. package/skills/verify-citations/scripts/bib-authors.cli.test.ts +138 -43
  357. package/skills/verify-citations/scripts/bib-authors.d.mts +22 -2
  358. package/skills/verify-citations/scripts/bib-authors.mjs +54 -193
  359. package/skills/verify-citations/scripts/bib-authors.test.mjs +1 -44
  360. package/skills/verify-citations/scripts/verify-cites.cli.test.ts +16 -0
  361. package/skills/verify-citations/scripts/verify-cites.d.mts +19 -3
  362. package/skills/verify-citations/scripts/verify-cites.mjs +42 -108
  363. package/skills/verify-citations/scripts/verify-cites.test.mjs +23 -36
  364. package/src/adapters/bibtex/index.test.ts +163 -0
  365. package/src/adapters/bibtex/index.ts +155 -0
  366. package/src/adapters/latex/filecontents.ts +114 -0
  367. package/src/adapters/latex/includes.ts +18 -10
  368. package/src/adapters/latex/index.test.ts +73 -0
  369. package/src/adapters/latex/index.ts +2 -0
  370. package/src/adapters/latex/nodes.ts +64 -0
  371. package/src/adapters/latex/parse.test.ts +38 -0
  372. package/src/adapters/latex/parse.ts +67 -6
  373. package/src/adapters/memory/index.ts +17 -0
  374. package/src/adapters/references/index.test.ts +75 -21
  375. package/src/adapters/references/index.ts +37 -32
  376. package/src/adapters/sources-record/index.test.ts +87 -0
  377. package/src/adapters/sources-record/index.ts +82 -0
  378. package/src/adapters/tex-output/blg.ts +27 -0
  379. package/src/adapters/tex-output/fls.ts +24 -0
  380. package/src/adapters/tex-output/index.test.ts +171 -0
  381. package/src/adapters/tex-output/index.ts +12 -0
  382. package/src/bib-rules.test.ts +356 -0
  383. package/src/bib-rules.ts +228 -0
  384. package/src/bibliography-at.test.ts +286 -0
  385. package/src/build.harness.mjs +2 -2
  386. package/src/build.test.ts +211 -1
  387. package/src/build.ts +101 -41
  388. package/src/claim-provenance.test.ts +33 -7
  389. package/src/claim-provenance.ts +2 -2
  390. package/src/cli.harness.mjs +46 -56
  391. package/src/cli.test.ts +44 -48
  392. package/src/cli.ts +51 -82
  393. package/src/domain/paper-source.test.ts +58 -20
  394. package/src/domain/paper-source.ts +38 -42
  395. package/src/domain/paper-sources.ts +94 -0
  396. package/src/domain/sources-record.test.ts +71 -0
  397. package/src/domain/sources-record.ts +136 -0
  398. package/src/domain/tex-run.test.ts +228 -0
  399. package/src/domain/tex-run.ts +139 -0
  400. package/src/folder-venue-rule.test.ts +1 -1
  401. package/src/heading-case.test.ts +24 -10
  402. package/src/init.test.ts +6 -7
  403. package/src/init.ts +3 -22
  404. package/src/latex-log.ts +20 -0
  405. package/src/latex-loop.harness.ts +1 -0
  406. package/src/latex-loop.ts +2 -0
  407. package/src/lint-fix.test.ts +10 -4
  408. package/src/linted-set.test.ts +9 -1
  409. package/src/new-paper.harness.mjs +12 -30
  410. package/src/new-paper.test.ts +15 -11
  411. package/src/new-paper.ts +11 -30
  412. package/src/package-dirs.ts +3 -2
  413. package/src/paper-files.test.ts +5 -4
  414. package/src/paper-files.ts +4 -4
  415. package/src/paper-includes.test.ts +157 -38
  416. package/src/paper-includes.ts +39 -35
  417. package/src/paper-prose.test.ts +78 -0
  418. package/src/paper-prose.ts +67 -0
  419. package/src/paper-record.test.ts +173 -0
  420. package/src/paper-record.ts +66 -0
  421. package/src/paper-settings-commands.test.ts +5 -2
  422. package/src/paper-sources.ts +151 -0
  423. package/src/parse-args.test.ts +0 -1
  424. package/src/ports/bib-reader.ts +27 -0
  425. package/src/ports/check-references.ts +7 -3
  426. package/src/ports/latex.ts +19 -0
  427. package/src/ports/sources-codec.ts +11 -0
  428. package/src/ports/tex-output.ts +17 -0
  429. package/src/recorded-bibliography.ts +297 -0
  430. package/src/reference-rules.ts +217 -104
  431. package/src/references.test.ts +520 -177
  432. package/src/references.ts +185 -37
  433. package/src/register-bands.test.ts +5 -1
  434. package/src/register-bands.ts +3 -5
  435. package/src/register.test.ts +6 -1
  436. package/src/register.ts +2 -2
  437. package/src/rule-cases.test.ts +68 -12
  438. package/src/rule-docs.test.ts +0 -1
  439. package/src/sources-record.test.ts +308 -0
  440. package/src/sources-record.ts +231 -0
  441. package/src/sources-rules.test.ts +152 -0
  442. package/src/sources-rules.ts +117 -0
  443. package/src/structure.harness.ts +5 -11
  444. package/src/structure.ts +4 -3
  445. package/src/tex-paper.test.ts +148 -78
  446. package/src/tex-paper.ts +31 -61
  447. package/src/tex-venue-rules.test.ts +36 -8
  448. package/src/tex-venue-rules.ts +3 -5
  449. package/src/types.ts +0 -2
  450. package/dist/eslint-rules/bib-reachable-entry.d.ts +0 -22
  451. package/dist/eslint-rules/bib-reachable-entry.d.ts.map +0 -1
  452. package/dist/eslint-rules/bib-reachable-entry.js +0 -75
  453. package/dist/eslint-rules/bib-reachable-entry.js.map +0 -1
  454. package/eslint-rules/bib-reachable-entry.ts +0 -76
  455. package/fixtures/real-markdown-paper/baseline.json +0 -22
  456. package/fixtures/real-markdown-paper/baseline.ts +0 -70
  457. package/skills/paper-pipeline/PIPELINE-MAP.md +0 -381
  458. package/skills/paper-pipeline/pipeline-firing.baseline.json +0 -270
  459. package/skills/paper-pipeline/references/sweep-2026-08-09-ideal-pipeline.md +0 -585
  460. package/skills/paper-pipeline/scripts/artifact-coverage.harness.mjs +0 -492
  461. package/skills/paper-pipeline/scripts/artifact-coverage.mjs +0 -397
  462. package/skills/paper-pipeline/scripts/artifact-coverage.test.ts +0 -86
  463. package/skills/paper-pipeline/scripts/check-provenance.mjs +0 -184
  464. package/skills/paper-pipeline/scripts/population-map.harness.mjs +0 -135
  465. package/skills/paper-pipeline/scripts/population-map.mjs +0 -188
  466. package/skills/paper-pipeline/scripts/population-map.test.mjs +0 -154
  467. package/skills/paper-pipeline/scripts/provenance.harness.mjs +0 -266
  468. package/skills/paper-pipeline/scripts/round-diff.harness.ts +0 -907
  469. package/skills/paper-pipeline/scripts/round-diff.mjs +0 -583
  470. package/skills/paper-pipeline/scripts/round-diff.test.mjs +0 -159
  471. package/skills/tighten-paper/__snapshots__/structure.test.ts.snap +0 -133
  472. package/skills/tighten-paper/structure.mjs +0 -364
  473. package/skills/tighten-paper/structure.test.ts +0 -117
  474. package/templates/paper/paper.md +0 -4
@@ -0,0 +1,39 @@
1
+ /**
2
+ * `paperRecord(dir)` — what every consumer of the build's record asks first: is there a record of
3
+ * this paper, and is it still about the files on disk? The answer is one of three states, and the
4
+ * rules that depend on the record are silent in two of them (docs/design/paper-sources.md §1):
5
+ *
6
+ * none no `_build/sources.json`, or one this paperlint cannot read — the paper was not built
7
+ * stale a file the build read has other bytes now (`changed` names them)
8
+ * fresh every file is as the build hashed it; the record is TeX's answer for this paper
9
+ *
10
+ * Reads through the `Files` port alone; the one paperlint-specific question — which files make a
11
+ * record stale — is `changesSince` (`src/domain/sources-record.ts`).
12
+ */
13
+ import { resolve } from "node:path";
14
+ import { callerPath } from "./caller-path.js";
15
+ import { sha256Hex } from "./domain/sha256.js";
16
+ import { changesSince, } from "./domain/sources-record.js";
17
+ import { sourcesPath } from "./sources-record.js";
18
+ /** The digest of the file at `path` in the paper directory now, or null when there is none. */
19
+ const digestOf = (dir, files) => (path) => {
20
+ const b = files.readBytes(callerPath(resolve(dir, path)));
21
+ return b === null ? null : sha256Hex(b);
22
+ };
23
+ export function paperRecord(dir, deps) {
24
+ const raw = deps.files.readBytes(callerPath(sourcesPath(dir)));
25
+ if (raw === null)
26
+ return { kind: "none", unreadable: null };
27
+ const parsed = deps.codec.parse(new TextDecoder().decode(raw));
28
+ if (!parsed.ok)
29
+ return { kind: "none", unreadable: parsed.why };
30
+ const changed = changesSince(parsed.record, digestOf(dir, deps.files));
31
+ return changed.length === 0
32
+ ? { kind: "fresh", record: parsed.record }
33
+ : { kind: "stale", changed };
34
+ }
35
+ /** The files of `role` the record lists, as absolute paths, in the order TeX first read them. */
36
+ export const recordedFiles = (dir, record, role) => record.inputs
37
+ .filter((i) => i.role === role)
38
+ .map((i) => callerPath(resolve(dir, i.path)));
39
+ //# sourceMappingURL=paper-record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paper-record.js","sourceRoot":"","sources":["../src/paper-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAe,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EACL,YAAY,GAIb,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAQlD,+FAA+F;AAC/F,MAAM,QAAQ,GACZ,CAAC,GAAW,EAAE,KAAY,EAAE,EAAE,CAC9B,CAAC,IAAY,EAAiB,EAAE;IAC9B,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC,CAAC;AAQJ,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,IAAoB;IAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC/D,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;IAChE,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACvE,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC;QACzB,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QAC1C,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AACjC,CAAC;AAED,iGAAiG;AACjG,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,GAAW,EACX,MAAqB,EACrB,IAAe,EACU,EAAE,CAC3B,MAAM,CAAC,MAAM;KACV,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;KAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,66 @@
1
+ import { type BibText } from "./domain/paper-sources.ts";
2
+ import type { AbsolutePath } from "./domain/paths.ts";
3
+ import { type Result } from "./domain/result.ts";
4
+ import type { PaperRecord } from "./paper-record.ts";
5
+ import { type RecordedDeps } from "./recorded-bibliography.ts";
6
+ /** What a path a person gave comes to: where the paper is, and the texts to read. */
7
+ export interface PathBibliography {
8
+ /** The `.bib`'s directory, the `.tex`'s, or the directory named. */
9
+ readonly paperDir: AbsolutePath;
10
+ readonly texts: readonly [BibText, ...BibText[]];
11
+ }
12
+ /** Why a path a person gave has no bibliography to read. One vocabulary for every caller. */
13
+ export type BibliographyUnread =
14
+ /** A `.bib` or `.tex` named that is not there. */
15
+ {
16
+ readonly kind: "missing";
17
+ readonly path: AbsolutePath;
18
+ }
19
+ /** A file that is neither a `.bib` nor a `.tex`. */
20
+ | {
21
+ readonly kind: "not-bib-or-tex";
22
+ readonly path: AbsolutePath;
23
+ }
24
+ /** Not a file, and no `paper.tex` in it. */
25
+ | {
26
+ readonly kind: "no-paper";
27
+ readonly path: AbsolutePath;
28
+ }
29
+ /** A paper with no current record of a build: what bibtex read is not known (`state` says why). */
30
+ | {
31
+ readonly kind: "not-built";
32
+ readonly dir: AbsolutePath;
33
+ readonly state: Exclude<PaperRecord, {
34
+ readonly kind: "fresh";
35
+ }>;
36
+ }
37
+ /** A paper whose last build's bibtex read no database, or whose databases are not on disk now. */
38
+ | {
39
+ readonly kind: "no-database";
40
+ readonly dir: AbsolutePath;
41
+ /** The databases bibtex opened: none when it ran none. */
42
+ readonly opened: readonly string[];
43
+ }
44
+ /**
45
+ * A paper whose last build's bibtex also opened databases the paper directory does not hold — found
46
+ * on its search path (BIBINPUTS). Reading the others alone would leave every entry of these out.
47
+ */
48
+ | {
49
+ readonly kind: "outside-paper";
50
+ readonly dir: AbsolutePath;
51
+ /** As bibtex names them. */
52
+ readonly unread: readonly [string, ...string[]];
53
+ };
54
+ /**
55
+ * THE answer to "a path a person gave → the bibliography to read", for every script that takes one: a
56
+ * `.bib` is read alone, as named; a `.tex`, or a directory holding `paper.tex`, is the bibliography the
57
+ * last build's bibtex opened for that paper (`_build/sources.json`) — never a guess by file name, and
58
+ * never read out of TeX source. A paper with no current record is refused: run `npx paperlint build`
59
+ * first, and so is one whose bibtex also opened a database outside the paper directory — a part of the
60
+ * bibliography is not given as the whole. Anything else is refused in the words `bibliographyUnreadWhy`
61
+ * gives.
62
+ */
63
+ export declare function bibliographyAt(path: AbsolutePath, deps: RecordedDeps): Result<PathBibliography, BibliographyUnread>;
64
+ /** One sentence: why `bibliographyAt` refused, naming the path and what to give instead. */
65
+ export declare function bibliographyUnreadWhy(e: BibliographyUnread): string;
66
+ //# sourceMappingURL=paper-sources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paper-sources.d.ts","sourceRoot":"","sources":["../src/paper-sources.ts"],"names":[],"mappings":"AASA,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,4BAA4B,CAAC;AAMpC,qFAAqF;AACrF,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;CAClD;AAED,6FAA6F;AAC7F,MAAM,MAAM,kBAAkB;AAC5B,kDAAkD;AAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE;AAC3D,oDAAoD;GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE;AAClE,4CAA4C;GAC1C;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE;AAC5D,mGAAmG;GACjG;IACE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAClE;AACH,kGAAkG;GAChG;IACE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AACH;;;GAGG;GACD;IACE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC;IAC3B,4BAA4B;IAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;CACjD,CAAC;AAwBN;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,YAAY,GACjB,MAAM,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAgB9C;AAmBD,4FAA4F;AAC5F,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAiBnE"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * `bibliographyAt(path)` — the one answer to "a path a person gave → the bibliography to read", for
3
+ * every script that takes one (`extract-ref-facts`, `bib-authors`, `verify-cites`). A `.bib` is read
4
+ * alone, as named; a `.tex`, or a directory holding `paper.tex`, is the bibliography the last build's
5
+ * bibtex opened for that paper — TeX's answer, from `_build/sources.json` (docs/design/paper-sources.md
6
+ * §1), never read out of TeX source.
7
+ */
8
+ import { dirname, extname, join } from "node:path";
9
+ import { callerPath } from "./caller-path.js";
10
+ import { MAIN_FILE } from "./domain/paper-sources.js";
11
+ import { err, ok } from "./domain/result.js";
12
+ import { describeChanges } from "./domain/sources-record.js";
13
+ import { authoredTexts, recordedBibliography, } from "./recorded-bibliography.js";
14
+ const decoded = (b) => new TextDecoder().decode(b);
15
+ /** The texts of the paper in `dir` the last build's bibtex read, or why there are none. */
16
+ function ofPaper(dir, deps) {
17
+ const r = recordedBibliography(dir, deps);
18
+ if (r.kind === "unrecorded")
19
+ return err({ kind: "not-built", dir, state: r.record });
20
+ const [first, ...rest] = authoredTexts(dir, r, deps);
21
+ if (first === undefined)
22
+ return err({
23
+ kind: "no-database",
24
+ dir,
25
+ opened: r.record.bibtex.ran ? r.record.bibtex.databases : [],
26
+ });
27
+ // Some databases read and some not is no bibliography: a script would report on part of it as on all.
28
+ const [outside, ...more] = r.unread;
29
+ return outside === undefined
30
+ ? ok({ paperDir: dir, texts: [first, ...rest] })
31
+ : err({ kind: "outside-paper", dir, unread: [outside, ...more] });
32
+ }
33
+ /**
34
+ * THE answer to "a path a person gave → the bibliography to read", for every script that takes one: a
35
+ * `.bib` is read alone, as named; a `.tex`, or a directory holding `paper.tex`, is the bibliography the
36
+ * last build's bibtex opened for that paper (`_build/sources.json`) — never a guess by file name, and
37
+ * never read out of TeX source. A paper with no current record is refused: run `npx paperlint build`
38
+ * first, and so is one whose bibtex also opened a database outside the paper directory — a part of the
39
+ * bibliography is not given as the whole. Anything else is refused in the words `bibliographyUnreadWhy`
40
+ * gives.
41
+ */
42
+ export function bibliographyAt(path, deps) {
43
+ const ext = extname(path).toLowerCase();
44
+ if (ext === ".bib" || ext === ".tex") {
45
+ const bytes = deps.files.readBytes(path);
46
+ if (bytes === null)
47
+ return err({ kind: "missing", path });
48
+ return ext === ".bib"
49
+ ? ok({
50
+ paperDir: callerPath(dirname(path)),
51
+ texts: [deps.bib.readFile(path, decoded(bytes))],
52
+ })
53
+ : ofPaper(callerPath(dirname(path)), deps);
54
+ }
55
+ if (deps.files.isFile(path))
56
+ return err({ kind: "not-bib-or-tex", path });
57
+ return deps.files.readBytes(callerPath(join(path, MAIN_FILE))) === null
58
+ ? err({ kind: "no-paper", path })
59
+ : ofPaper(path, deps);
60
+ }
61
+ const BUILD = "run `npx paperlint build` first";
62
+ /** Why a paper has no current record, in words a person can act on. */
63
+ function notBuiltWhy(dir, s) {
64
+ switch (s.kind) {
65
+ case "none":
66
+ return s.unreadable === null
67
+ ? `${dir} has not been built — ${BUILD}, which records the databases bibtex reads`
68
+ : `the last build's record of ${dir} cannot be used (${s.unreadable}) — ${BUILD}`;
69
+ case "stale":
70
+ return `${dir} changed since the last build (${describeChanges(s.changed)}) — ${BUILD}`;
71
+ }
72
+ }
73
+ /** One sentence: why `bibliographyAt` refused, naming the path and what to give instead. */
74
+ export function bibliographyUnreadWhy(e) {
75
+ switch (e.kind) {
76
+ case "missing":
77
+ return `${e.path} does not exist — nowhere to take a bibliography from`;
78
+ case "not-bib-or-tex":
79
+ return `${e.path} is neither a .bib nor a .tex — name the paper's directory, its .tex, or a .bib`;
80
+ case "no-paper":
81
+ return `no paper.tex in ${e.path} — name the paper's .tex, or a .bib to read it alone`;
82
+ case "not-built":
83
+ return notBuiltWhy(e.dir, e.state);
84
+ case "no-database":
85
+ return e.opened.length === 0
86
+ ? `bibtex read no database in the last build of ${e.dir} — there is nothing to read`
87
+ : `bibtex opened ${e.opened.join(", ")} in the last build of ${e.dir}, and none of them is on disk now`;
88
+ case "outside-paper":
89
+ return `bibtex opened ${e.unread.join(", ")} in the last build of ${e.dir} from outside it (its search path, BIBINPUTS), and paperlint reads only the paper's own databases — copy it into ${e.dir}, or name each .bib to read it alone`;
90
+ }
91
+ }
92
+ //# sourceMappingURL=paper-sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paper-sources.js","sourceRoot":"","sources":["../src/paper-sources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * THE BIBTEX READER — the one way paperlint reads a `.bib` database. Every consumer (`recordedBibliography`,
3
+ * `bib/reachable-entry`, the build's reference check, `extract-ref-facts`, `bib-authors`) reads
4
+ * through it; the adapter is `src/adapters/bibtex/`.
5
+ *
6
+ * A database is read as bibtex reads it in its place among the paper's: `inherited` is the `@string`s
7
+ * the databases before it left in force (the previous one's `strings`), none for a database read alone.
8
+ */
9
+ import type { BibStrings, BibText } from "../domain/paper-sources.ts";
10
+ import type { AbsolutePath } from "../domain/paths.ts";
11
+ import type { Span } from "../domain/tex-document.ts";
12
+ export interface BibReader {
13
+ /** The database in `body` of `text`, the text of the file at `path`: a block in a `.tex`. */
14
+ readonly read: (path: AbsolutePath, text: string, body: Span, inherited?: BibStrings) => BibText;
15
+ /** A whole `.bib` file. */
16
+ readonly readFile: (path: AbsolutePath, text: string, inherited?: BibStrings) => BibText;
17
+ }
18
+ //# sourceMappingURL=bib-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bib-reader.d.ts","sourceRoot":"","sources":["../../src/ports/bib-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAEtD,MAAM,WAAW,SAAS;IACxB,6FAA6F;IAC7F,QAAQ,CAAC,IAAI,EAAE,CACb,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,EACV,SAAS,CAAC,EAAE,UAAU,KACnB,OAAO,CAAC;IACb,2BAA2B;IAC3B,QAAQ,CAAC,QAAQ,EAAE,CACjB,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,UAAU,KACnB,OAAO,CAAC;CACd"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bib-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bib-reader.js","sourceRoot":"","sources":["../../src/ports/bib-reader.ts"],"names":[],"mappings":""}
@@ -4,8 +4,10 @@
4
4
  * passes a function.
5
5
  */
6
6
  import type { LookupCache } from "../domain/lookup-cache.ts";
7
+ import type { BibEntry } from "../domain/paper-sources.ts";
7
8
  /** What one bibliography entry came to. */
8
9
  export interface EntryVerdict {
10
+ /** The entry's key: a name for people, not its identity — two entries may share it. */
9
11
  readonly key: string;
10
12
  /**
11
13
  * Does the cited work exist, and does its title match? `false` only on a positive disproof (an
@@ -18,7 +20,9 @@ export interface EntryVerdict {
18
20
  /** Why, in one line, when either is not a plain pass. */
19
21
  readonly why?: string;
20
22
  }
21
- export type ReferencesCheck = {
23
+ export type ReferencesCheck =
24
+ /** One verdict per entry given, in the order given: verdict `i` is about entry `i`. */
25
+ {
22
26
  readonly kind: "checked";
23
27
  readonly entries: readonly EntryVerdict[];
24
28
  }
@@ -34,8 +38,9 @@ export interface ReferencesRun {
34
38
  readonly cache: LookupCache;
35
39
  }
36
40
  /**
37
- * The bibliography's text (BibTeX) and the paper's lookup cache → the verdicts, derived afresh from
38
- * cached and newly fetched answers. Never throws: a failure is `not-checked`.
41
+ * The bibliography's entries (as the bibtex reader read them) and the paper's lookup cache → the
42
+ * verdicts, one per entry in its order, derived afresh from cached and newly fetched answers. Never
43
+ * throws: a failure is `not-checked`.
39
44
  */
40
- export type CheckReferences = (bib: string, cache: LookupCache) => Promise<ReferencesRun>;
45
+ export type CheckReferences = (entries: readonly BibEntry[], cache: LookupCache) => Promise<ReferencesRun>;
41
46
  //# sourceMappingURL=check-references.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"check-references.d.ts","sourceRoot":"","sources":["../../src/ports/check-references.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,cAAc,CAAC;IACnD,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC;IACjE,yDAAyD;IACzD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAA;CAAE;AACzE,6EAA6E;GAC3E;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3D,kFAAkF;AAClF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,uGAAuG;IACvG,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,WAAW,KACf,OAAO,CAAC,aAAa,CAAC,CAAC"}
1
+ {"version":3,"file":"check-references.d.ts","sourceRoot":"","sources":["../../src/ports/check-references.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAE3D,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,uFAAuF;IACvF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,cAAc,CAAC;IACnD,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC;IACjE,yDAAyD;IACzD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,eAAe;AACzB,uFAAuF;AACrF;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAA;CAAE;AACzE,6EAA6E;GAC3E;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3D,kFAAkF;AAClF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,uGAAuG;IACvG,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;CAC7B;AAED;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,OAAO,EAAE,SAAS,QAAQ,EAAE,EAC5B,KAAK,EAAE,WAAW,KACf,OAAO,CAAC,aAAa,CAAC,CAAC"}
@@ -4,6 +4,15 @@
4
4
  */
5
5
  import type { Include } from "../domain/paper-source.ts";
6
6
  import type { ClassLine, DocumentClass, Emphasis, LayoutOverride, Outline, Passage, Span, TextRun, TitledHeading } from "../domain/tex-document.ts";
7
+ /** A `filecontents` block of a source: the file it writes, `[overwrite]`/`[force]` or not, where it is. */
8
+ export interface Filecontents {
9
+ readonly writes: string;
10
+ readonly overwrite: boolean;
11
+ /** The whole environment, `\begin` to `\end`. */
12
+ readonly span: Span;
13
+ /** What it writes: from the line after `\begin{…}{…}` to `\end`. */
14
+ readonly body: Span;
15
+ }
7
16
  export interface LatexReader {
8
17
  /** The source's `\documentclass`, as one of its states. */
9
18
  readonly documentClass: (src: string) => ClassLine;
@@ -44,5 +53,11 @@ export interface LatexReader {
44
53
  readonly withDocumentClass: (src: string, want: DocumentClass) => string;
45
54
  /** Every command that changes the page layout the class sets: margins, text block, line spacing. */
46
55
  readonly layoutOverrides: (src: string) => readonly LayoutOverride[];
56
+ /**
57
+ * Every live `filecontents` block of `src`, in source order, where each stands: a lookup of the text
58
+ * that wrote a `.bib`, never a decision of what TeX wrote (that is `_build/sources.json`). `jobname`
59
+ * is what `\jobname` names in a block's file name.
60
+ */
61
+ readonly filecontents: (src: string, jobname: string) => readonly Filecontents[];
47
62
  }
48
63
  //# sourceMappingURL=latex.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"latex.d.ts","sourceRoot":"","sources":["../../src/ports/latex.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,QAAQ,EACR,cAAc,EACd,OAAO,EACP,OAAO,EACP,IAAI,EACJ,OAAO,EACP,aAAa,EACd,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;IACnD,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,aAAa,EAAE,CAAC;IAC7D,mGAAmG;IACnG,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,OAAO,EAAE,CAAC;IAC3D;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,OAAO,EAAE,CAAC;IACxD;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,QAAQ,EAAE,CAAC;IAC5D,wGAAwG;IACxG,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,OAAO,EAAE,CAAC;IACvD,uFAAuF;IACvF,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IACpD;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,aAAa,GAAG,IAAI,CAAC;IAC1D;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,KAAK,MAAM,CAAC;IACzE,oGAAoG;IACpG,QAAQ,CAAC,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,cAAc,EAAE,CAAC;CACtE"}
1
+ {"version":3,"file":"latex.d.ts","sourceRoot":"","sources":["../../src/ports/latex.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,QAAQ,EACR,cAAc,EACd,OAAO,EACP,OAAO,EACP,IAAI,EACJ,OAAO,EACP,aAAa,EACd,MAAM,2BAA2B,CAAC;AAEnC,2GAA2G;AAC3G,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,oEAAoE;IACpE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,2DAA2D;IAC3D,QAAQ,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;IACnD,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,aAAa,EAAE,CAAC;IAC7D,mGAAmG;IACnG,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,OAAO,EAAE,CAAC;IAC3D;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,OAAO,EAAE,CAAC;IACxD;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,QAAQ,EAAE,CAAC;IAC5D,wGAAwG;IACxG,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,OAAO,EAAE,CAAC;IACvD,uFAAuF;IACvF,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IACpD;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,aAAa,GAAG,IAAI,CAAC;IAC1D;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,KAAK,MAAM,CAAC;IACzE,oGAAoG;IACpG,QAAQ,CAAC,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,cAAc,EAAE,CAAC;IACrE;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,CACrB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,KACZ,SAAS,YAAY,EAAE,CAAC;CAC9B"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * How a `sources.json` becomes a value: its text parsed once, where it enters, against the schema of
3
+ * `SourcesRecord` (`src/domain/sources-record.ts`). The one implementation is
4
+ * `src/adapters/sources-record/` (zod); `src/cli.ts` wires it.
5
+ */
6
+ import type { ParsedRecord } from "../domain/sources-record.ts";
7
+ export interface SourcesCodec {
8
+ /** A `sources.json`'s text: the record, or the one reason it is not one of this schema. */
9
+ readonly parse: (text: string) => ParsedRecord;
10
+ }
11
+ //# sourceMappingURL=sources-codec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources-codec.d.ts","sourceRoot":"","sources":["../../src/ports/sources-codec.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE,MAAM,WAAW,YAAY;IAC3B,2FAA2F;IAC3F,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,YAAY,CAAC;CAChD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sources-codec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources-codec.js","sourceRoot":"","sources":["../../src/ports/sources-codec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * What paperlint reads from the files TeX writes beside a paper, shaped by what the record of a build
3
+ * needs (`src/domain/sources-record.ts`) — not by the formats. The one implementation is
4
+ * `src/adapters/tex-output/`; `src/cli.ts` wires it.
5
+ *
6
+ * What the build's `.aux`, `.blg` and `.bbl` hold about the bibliography is read by `src/latex-log.ts`,
7
+ * which the build loop already reads them with.
8
+ */
9
+ import type { BibtexError } from "../domain/sources-record.ts";
10
+ import type { Fls } from "../domain/tex-run.ts";
11
+ export interface TexOutput {
12
+ /** An `.fls`'s text. */
13
+ readonly fls: (text: string) => Fls;
14
+ /** The errors a bibtex `.blg` reports, in order; warnings are not errors. */
15
+ readonly blgErrors: (blg: string) => readonly BibtexError[];
16
+ }
17
+ //# sourceMappingURL=tex-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tex-output.d.ts","sourceRoot":"","sources":["../../src/ports/tex-output.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,WAAW,SAAS;IACxB,wBAAwB;IACxB,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,GAAG,CAAC;IACpC,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,WAAW,EAAE,CAAC;CAC7D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tex-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tex-output.js","sourceRoot":"","sources":["../../src/ports/tex-output.ts"],"names":[],"mappings":""}
@@ -0,0 +1,89 @@
1
+ import { type BibEntry, type BibText } from "./domain/paper-sources.ts";
2
+ import type { AbsolutePath } from "./domain/paths.ts";
3
+ import type { Span } from "./domain/tex-document.ts";
4
+ import { type SourcesRecord } from "./domain/sources-record.ts";
5
+ import { type PaperRecord, type RecordReadDeps } from "./paper-record.ts";
6
+ import type { BibReader } from "./ports/bib-reader.ts";
7
+ import type { LatexReader } from "./ports/latex.ts";
8
+ /** What reading the recorded bibliography needs: the disk, the record's schema, the bibtex reader. */
9
+ export interface RecordedReadDeps extends RecordReadDeps {
10
+ readonly bib: BibReader;
11
+ }
12
+ /** And what finding where a `.bib` TeX wrote stands needs besides: the reader of `filecontents` blocks. */
13
+ export interface RecordedDeps extends RecordedReadDeps {
14
+ readonly latex: Pick<LatexReader, "filecontents">;
15
+ }
16
+ /** A database bibtex opened that is on disk now, as the bibtex reader reads it. */
17
+ export interface ReadDatabase {
18
+ /** As bibtex names it: `refs.bib`, `bibs/x.bib`. */
19
+ readonly name: string;
20
+ /** A `.bib` TeX wrote (a `filecontents` block), not one the author keeps. */
21
+ readonly written: boolean;
22
+ readonly bib: BibText;
23
+ }
24
+ export type RecordedBibliography = {
25
+ readonly kind: "unrecorded";
26
+ readonly record: Exclude<PaperRecord, {
27
+ readonly kind: "fresh";
28
+ }>;
29
+ } | {
30
+ readonly kind: "recorded";
31
+ readonly record: SourcesRecord;
32
+ /** In the order bibtex opened them, each once. */
33
+ readonly databases: readonly ReadDatabase[];
34
+ /**
35
+ * As bibtex names them: the databases it opened that the paper directory does not hold — found on
36
+ * its search path (BIBINPUTS). One that was there when the build recorded it and is gone now made
37
+ * the record stale instead: every database bibtex opened is hashed.
38
+ */
39
+ readonly unread: readonly string[];
40
+ };
41
+ /** The bibliography the last build of the paper in `dir` read. */
42
+ export declare function recordedBibliography(dir: string, deps: RecordedReadDeps): RecordedBibliography;
43
+ /** An entry of a database bibtex opened, and where it stands in that database. */
44
+ export interface RecordedEntry {
45
+ readonly database: ReadDatabase;
46
+ readonly entry: BibEntry;
47
+ /** Its place among the database's entries: what pairs it with the same entry of a block. */
48
+ readonly index: number;
49
+ }
50
+ /** Every entry of the databases, in the order bibtex opened them and the entries stand. */
51
+ export declare const entriesOfDatabases: (databases: readonly ReadDatabase[]) => readonly RecordedEntry[];
52
+ /** Where a finding about an entry is reported in paper.tex. */
53
+ export type EntryReport = {
54
+ readonly kind: "here";
55
+ readonly span: Span;
56
+ }
57
+ /** At the top of paper.tex; `where` names the entry (`refs.bib:12:1`). */
58
+ | {
59
+ readonly kind: "elsewhere";
60
+ readonly span: Span;
61
+ readonly where: string;
62
+ };
63
+ /** A text of the paper that may hold a block: a file of the record, the main file as the editor has it. */
64
+ interface Holder {
65
+ readonly path: AbsolutePath;
66
+ readonly text: string;
67
+ }
68
+ /** The paper being linted: where it is, the record of its build, and its main file as the editor holds it. */
69
+ export interface LintedPaper {
70
+ readonly dir: string;
71
+ readonly record: SourcesRecord;
72
+ readonly main: Holder;
73
+ }
74
+ /**
75
+ * Where each finding about `found` is reported, in the same order. The main file is read as the editor
76
+ * holds it; the record's other `.tex` files are read from disk.
77
+ */
78
+ export declare function entryReports(paper: LintedPaper, found: readonly RecordedEntry[], deps: RecordedDeps): readonly EntryReport[];
79
+ /**
80
+ * The text the author edits for each database bibtex opened, in the order it opened them: for a `.bib`
81
+ * TeX wrote, the block of `paper.tex` or of an included file that holds what bibtex read; for any other
82
+ * database, and for a written one no block holds, the file itself. What a script reads, so its entries
83
+ * stand where the author finds them.
84
+ */
85
+ export declare function authoredTexts(dir: string, recorded: Extract<RecordedBibliography, {
86
+ readonly kind: "recorded";
87
+ }>, deps: RecordedDeps): readonly BibText[];
88
+ export {};
89
+ //# sourceMappingURL=recorded-bibliography.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recorded-bibliography.d.ts","sourceRoot":"","sources":["../src/recorded-bibliography.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * THE BIBLIOGRAPHY THE LAST BUILD READ — the entries of the databases bibtex opened, from the build's
3
+ * record (`_build/sources.json`, docs/design/paper-sources.md §1), through the one bibtex reader. Nothing
4
+ * here reads TeX source to decide which bibliography a paper has: TeX answered, the build wrote it
5
+ * down, and `paperRecord` says whether the paper is still the one it was written for.
6
+ *
7
+ * unrecorded no record, or a stale one — the rules that need it are silent (`paper/sources-fresh`
8
+ * speaks), the scripts refuse ("run `npx paperlint build` first")
9
+ * recorded a current record, and the databases bibtex opened that are on disk now (none when
10
+ * bibtex ran none), and the names of those that are not
11
+ *
12
+ * The databases are read in the order bibtex opened them, each with the `@string`s the ones before it
13
+ * left in force — bibtex keeps one table of them across its databases, so `\\bibliography{abbrev,refs}`
14
+ * expands an entry of `refs.bib` with a `@string` of `abbrev.bib`. A database that is not on disk adds
15
+ * none: its `@string`s are bibtex's alone.
16
+ *
17
+ * WHERE A FINDING ABOUT AN ENTRY GOES (`entryReports`). ESLint lints `paper.tex` only, so every finding
18
+ * is a place in it. An entry of a `.bib` TeX wrote (a `filecontents` block) is reported on its own line
19
+ * in the block of `paper.tex` whose body bibtex takes as the same database (`sameDatabase`) — a lookup
20
+ * of where the text stands, which decides nothing: the record said what TeX read. When no block of
21
+ * `paper.tex` is that database — the block is in an included file, or `paper.tex` was edited after the
22
+ * build — and for the entry of every other `.bib`, the finding is at the top of `paper.tex`, the file,
23
+ * line and column of the entry at the front of the message (`refs.bib:12:1:`).
24
+ */
25
+ import { extname, posix, relative, resolve } from "node:path";
26
+ import { callerPath } from "./caller-path.js";
27
+ import { sameDatabase, } from "./domain/paper-sources.js";
28
+ import { JOBNAME, spelledIn, } from "./domain/sources-record.js";
29
+ import { paperRecord, } from "./paper-record.js";
30
+ import { decoded, lineColumn } from "./tex-paper.js";
31
+ /**
32
+ * The databases `names`, in this order, each read with the `@string`s the ones before it left in force,
33
+ * as bibtex reads them. One that is not on disk adds none.
34
+ */
35
+ const readInSequence = (dir, names, deps) => names.reduce((acc, name) => {
36
+ const path = callerPath(resolve(dir, name));
37
+ const text = decoded(deps.files.readBytes(path));
38
+ const bib = text === null ? null : deps.bib.readFile(path, text, acc.inForce);
39
+ return {
40
+ inForce: bib?.strings ?? acc.inForce,
41
+ read: [...acc.read, { name, bib }],
42
+ };
43
+ }, { inForce: {}, read: [] }).read;
44
+ /** The bibliography the last build of the paper in `dir` read. */
45
+ export function recordedBibliography(dir, deps) {
46
+ const r = paperRecord(dir, deps);
47
+ if (r.kind !== "fresh")
48
+ return { kind: "unrecorded", record: r };
49
+ const { bibtex, written } = r.record;
50
+ const opened = readInSequence(dir, (bibtex.ran ? bibtex.databases : []).filter((d, i, all) => all.findIndex((o) => resolve(dir, o) === resolve(dir, d)) === i), deps);
51
+ return {
52
+ kind: "recorded",
53
+ record: r.record,
54
+ databases: opened.flatMap(({ name, bib }) => bib === null ? [] : [{ name, written: written.includes(name), bib }]),
55
+ unread: opened.filter((d) => d.bib === null).map((d) => d.name),
56
+ };
57
+ }
58
+ /** Every entry of the databases, in the order bibtex opened them and the entries stand. */
59
+ export const entriesOfDatabases = (databases) => databases.flatMap((database) => database.bib.entries.map((entry, index) => ({ database, entry, index })));
60
+ /** The first line of an entry: `@misc{key,` — what a finding underlines. */
61
+ const headOf = (bib, e) => {
62
+ const first = bib.text
63
+ .slice(e.span.start, e.span.end)
64
+ .split("\n", 1)
65
+ .join("");
66
+ return { start: e.span.start, end: e.span.start + first.length };
67
+ };
68
+ const TOP = { start: 0, end: 0 };
69
+ /**
70
+ * The text of every `.tex` the record lists, in the order TeX first read them: from disk, except
71
+ * `override` (the main file as the editor holds it), which stands for its own path. A record is only
72
+ * current while every file it lists is on disk, so none is skipped for being absent.
73
+ */
74
+ function holders(dir, record, override, deps) {
75
+ return record.inputs
76
+ .map((i) => callerPath(resolve(dir, i.path)))
77
+ .filter((p) => extname(p) === ".tex")
78
+ .map((path) => override !== null && override.path === path
79
+ ? override
80
+ : { path, text: decoded(deps.files.readBytes(path)) })
81
+ .filter((h) => h.text !== null);
82
+ }
83
+ /** The block, in some text of the paper, that holds what bibtex read of `db`. */
84
+ const blockHolding = (db, texts, deps) => texts
85
+ .flatMap((holder) => deps.latex
86
+ .filecontents(holder.text, JOBNAME)
87
+ // The block that wrote this database: its file, then its text.
88
+ .filter((b) => spelledIn([posix.normalize(b.writes)], db.name) !== null)
89
+ // Read as bibtex read the database: with the `@string`s in force before it.
90
+ .map((b) => ({
91
+ holder,
92
+ bib: deps.bib.read(holder.path, holder.text, b.body, db.bib.inherited),
93
+ })))
94
+ .find((b) => sameDatabase(b.bib, db.bib)) ?? null;
95
+ /** Where a finding about `f` is reported, given the block of a text of the paper that holds its database (or none). */
96
+ function reportOf(paper, block, f) {
97
+ const there = block?.bib.entries[f.index];
98
+ if (block === null || there?.key !== f.entry.key)
99
+ return {
100
+ kind: "elsewhere",
101
+ span: TOP,
102
+ where: `${f.database.name}:${lineColumn(f.database.bib.text, headOf(f.database.bib, f.entry).start)}`,
103
+ };
104
+ const span = headOf(block.bib, there);
105
+ return block.holder.path === paper.main.path
106
+ ? { kind: "here", span }
107
+ : {
108
+ kind: "elsewhere",
109
+ span: TOP,
110
+ where: `${relative(paper.dir, block.holder.path)}:${lineColumn(block.holder.text, span.start)}`,
111
+ };
112
+ }
113
+ /**
114
+ * Where each finding about `found` is reported, in the same order. The main file is read as the editor
115
+ * holds it; the record's other `.tex` files are read from disk.
116
+ */
117
+ export function entryReports(paper, found, deps) {
118
+ const texts = holders(paper.dir, paper.record, paper.main, deps);
119
+ // Only the written databases that have a finding are searched for their block.
120
+ const blocks = new Map(found
121
+ .map((f) => f.database)
122
+ .filter((d, i, all) => d.written && all.indexOf(d) === i)
123
+ .map((d) => [d, blockHolding(d, texts, deps)]));
124
+ return found.map((f) => reportOf(paper, blocks.get(f.database) ?? null, f));
125
+ }
126
+ /**
127
+ * The text the author edits for each database bibtex opened, in the order it opened them: for a `.bib`
128
+ * TeX wrote, the block of `paper.tex` or of an included file that holds what bibtex read; for any other
129
+ * database, and for a written one no block holds, the file itself. What a script reads, so its entries
130
+ * stand where the author finds them.
131
+ */
132
+ export function authoredTexts(dir, recorded, deps) {
133
+ const texts = holders(dir, recorded.record, null, deps);
134
+ return recorded.databases.map((d) => (d.written ? blockHolding(d, texts, deps)?.bib : undefined) ?? d.bib);
135
+ }
136
+ //# sourceMappingURL=recorded-bibliography.js.map