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.
- package/CLAUDE.md +9 -25
- package/CONTRIBUTING.md +5 -4
- package/README.md +4 -3
- package/dist/adapters/bibtex/index.d.ts +3 -0
- package/dist/adapters/bibtex/index.d.ts.map +1 -0
- package/dist/adapters/bibtex/index.js +103 -0
- package/dist/adapters/bibtex/index.js.map +1 -0
- package/dist/adapters/latex/filecontents.d.ts +33 -0
- package/dist/adapters/latex/filecontents.d.ts.map +1 -0
- package/dist/adapters/latex/filecontents.js +65 -0
- package/dist/adapters/latex/filecontents.js.map +1 -0
- package/dist/adapters/latex/includes.d.ts +3 -3
- package/dist/adapters/latex/includes.d.ts.map +1 -1
- package/dist/adapters/latex/includes.js +18 -10
- package/dist/adapters/latex/includes.js.map +1 -1
- package/dist/adapters/latex/index.d.ts.map +1 -1
- package/dist/adapters/latex/index.js +2 -0
- package/dist/adapters/latex/index.js.map +1 -1
- package/dist/adapters/latex/nodes.d.ts +12 -0
- package/dist/adapters/latex/nodes.d.ts.map +1 -1
- package/dist/adapters/latex/nodes.js +39 -0
- package/dist/adapters/latex/nodes.js.map +1 -1
- package/dist/adapters/latex/parse.d.ts +7 -1
- package/dist/adapters/latex/parse.d.ts.map +1 -1
- package/dist/adapters/latex/parse.js +55 -6
- package/dist/adapters/latex/parse.js.map +1 -1
- package/dist/adapters/memory/index.d.ts +3 -0
- package/dist/adapters/memory/index.d.ts.map +1 -1
- package/dist/adapters/memory/index.js +9 -0
- package/dist/adapters/memory/index.js.map +1 -1
- package/dist/adapters/references/index.d.ts.map +1 -1
- package/dist/adapters/references/index.js +27 -24
- package/dist/adapters/references/index.js.map +1 -1
- package/dist/adapters/sources-record/index.d.ts +9 -0
- package/dist/adapters/sources-record/index.d.ts.map +1 -0
- package/dist/adapters/sources-record/index.js +68 -0
- package/dist/adapters/sources-record/index.js.map +1 -0
- package/dist/adapters/tex-output/blg.d.ts +9 -0
- package/dist/adapters/tex-output/blg.d.ts.map +1 -0
- package/dist/adapters/tex-output/blg.js +20 -0
- package/dist/adapters/tex-output/blg.js.map +1 -0
- package/dist/adapters/tex-output/fls.d.ts +8 -0
- package/dist/adapters/tex-output/fls.d.ts.map +1 -0
- package/dist/adapters/tex-output/fls.js +16 -0
- package/dist/adapters/tex-output/fls.js.map +1 -0
- package/dist/adapters/tex-output/index.d.ts +7 -0
- package/dist/adapters/tex-output/index.d.ts.map +1 -0
- package/dist/adapters/tex-output/index.js +7 -0
- package/dist/adapters/tex-output/index.js.map +1 -0
- package/dist/bib-rules.d.ts +47 -0
- package/dist/bib-rules.d.ts.map +1 -0
- package/dist/bib-rules.js +127 -0
- package/dist/bib-rules.js.map +1 -0
- package/dist/build.d.ts +29 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +41 -30
- package/dist/build.js.map +1 -1
- package/dist/claim-provenance.d.ts +2 -2
- package/dist/cli.d.ts +9 -5
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +43 -68
- package/dist/cli.js.map +1 -1
- package/dist/domain/paper-source.d.ts +1 -10
- package/dist/domain/paper-source.d.ts.map +1 -1
- package/dist/domain/paper-source.js +34 -24
- package/dist/domain/paper-source.js.map +1 -1
- package/dist/domain/paper-sources.d.ts +72 -0
- package/dist/domain/paper-sources.d.ts.map +1 -0
- package/dist/domain/paper-sources.js +18 -0
- package/dist/domain/paper-sources.js.map +1 -0
- package/dist/domain/sources-record.d.ts +102 -0
- package/dist/domain/sources-record.d.ts.map +1 -0
- package/dist/domain/sources-record.js +38 -0
- package/dist/domain/sources-record.js.map +1 -0
- package/dist/domain/tex-run.d.ts +25 -0
- package/dist/domain/tex-run.d.ts.map +1 -0
- package/dist/domain/tex-run.js +79 -0
- package/dist/domain/tex-run.js.map +1 -0
- package/dist/eslint-rules/latex-language.d.ts.map +1 -1
- package/dist/eslint-rules/latex-language.js +10 -13
- package/dist/eslint-rules/latex-language.js.map +1 -1
- package/dist/eslint-rules/paper-context.d.ts.map +1 -1
- package/dist/eslint-rules/paper-context.js +6 -5
- package/dist/eslint-rules/paper-context.js.map +1 -1
- package/dist/eslint-rules/paper-typography.d.ts +0 -9
- package/dist/eslint-rules/paper-typography.d.ts.map +1 -1
- package/dist/eslint-rules/paper-typography.js +34 -96
- package/dist/eslint-rules/paper-typography.js.map +1 -1
- package/dist/eslint-rules/papers.d.ts +1 -3
- package/dist/eslint-rules/papers.d.ts.map +1 -1
- package/dist/eslint-rules/papers.js +2 -4
- package/dist/eslint-rules/papers.js.map +1 -1
- package/dist/eslint-rules/tex-build.d.ts.map +1 -1
- package/dist/eslint-rules/tex-build.js +8 -25
- package/dist/eslint-rules/tex-build.js.map +1 -1
- package/dist/init.d.ts +1 -4
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +3 -9
- package/dist/init.js.map +1 -1
- package/dist/latex-log.d.ts +10 -0
- package/dist/latex-log.d.ts.map +1 -1
- package/dist/latex-log.js +10 -0
- package/dist/latex-log.js.map +1 -1
- package/dist/latex-loop.d.ts +2 -0
- package/dist/latex-loop.d.ts.map +1 -1
- package/dist/latex-loop.js.map +1 -1
- package/dist/lib/markdown.d.ts +5 -81
- package/dist/lib/markdown.d.ts.map +1 -1
- package/dist/lib/markdown.js +5 -116
- package/dist/lib/markdown.js.map +1 -1
- package/dist/lib/paper-config.d.ts.map +1 -1
- package/dist/lib/paper-config.js +0 -2
- package/dist/lib/paper-config.js.map +1 -1
- package/dist/lib/skill-eval-fixture.d.ts +6 -4
- package/dist/lib/skill-eval-fixture.d.ts.map +1 -1
- package/dist/lib/skill-eval-fixture.js +25 -18
- package/dist/lib/skill-eval-fixture.js.map +1 -1
- package/dist/new-paper.d.ts +5 -11
- package/dist/new-paper.d.ts.map +1 -1
- package/dist/new-paper.js +12 -23
- package/dist/new-paper.js.map +1 -1
- package/dist/package-dirs.d.ts.map +1 -1
- package/dist/package-dirs.js +3 -2
- package/dist/package-dirs.js.map +1 -1
- package/dist/paper-files.d.ts +4 -4
- package/dist/paper-includes.d.ts +4 -7
- package/dist/paper-includes.d.ts.map +1 -1
- package/dist/paper-includes.js +29 -21
- package/dist/paper-includes.js.map +1 -1
- package/dist/paper-prose.d.ts +17 -0
- package/dist/paper-prose.d.ts.map +1 -0
- package/dist/paper-prose.js +46 -0
- package/dist/paper-prose.js.map +1 -0
- package/dist/paper-record.d.ts +25 -0
- package/dist/paper-record.d.ts.map +1 -0
- package/dist/paper-record.js +39 -0
- package/dist/paper-record.js.map +1 -0
- package/dist/paper-sources.d.ts +66 -0
- package/dist/paper-sources.d.ts.map +1 -0
- package/dist/paper-sources.js +92 -0
- package/dist/paper-sources.js.map +1 -0
- package/dist/ports/bib-reader.d.ts +18 -0
- package/dist/ports/bib-reader.d.ts.map +1 -0
- package/dist/ports/bib-reader.js +2 -0
- package/dist/ports/bib-reader.js.map +1 -0
- package/dist/ports/check-references.d.ts +9 -4
- package/dist/ports/check-references.d.ts.map +1 -1
- package/dist/ports/latex.d.ts +15 -0
- package/dist/ports/latex.d.ts.map +1 -1
- package/dist/ports/sources-codec.d.ts +11 -0
- package/dist/ports/sources-codec.d.ts.map +1 -0
- package/dist/ports/sources-codec.js +2 -0
- package/dist/ports/sources-codec.js.map +1 -0
- package/dist/ports/tex-output.d.ts +17 -0
- package/dist/ports/tex-output.d.ts.map +1 -0
- package/dist/ports/tex-output.js +2 -0
- package/dist/ports/tex-output.js.map +1 -0
- package/dist/recorded-bibliography.d.ts +89 -0
- package/dist/recorded-bibliography.d.ts.map +1 -0
- package/dist/recorded-bibliography.js +136 -0
- package/dist/recorded-bibliography.js.map +1 -0
- package/dist/reference-rules.d.ts +5 -5
- package/dist/reference-rules.d.ts.map +1 -1
- package/dist/reference-rules.js +150 -77
- package/dist/reference-rules.js.map +1 -1
- package/dist/references.d.ts +71 -16
- package/dist/references.d.ts.map +1 -1
- package/dist/references.js +110 -26
- package/dist/references.js.map +1 -1
- package/dist/register-bands.d.ts +3 -3
- package/dist/register-bands.d.ts.map +1 -1
- package/dist/register-bands.js.map +1 -1
- package/dist/register.d.ts +2 -2
- package/dist/sources-record.d.ts +38 -0
- package/dist/sources-record.d.ts.map +1 -0
- package/dist/sources-record.js +123 -0
- package/dist/sources-record.js.map +1 -0
- package/dist/sources-rules.d.ts +44 -0
- package/dist/sources-rules.d.ts.map +1 -0
- package/dist/sources-rules.js +76 -0
- package/dist/sources-rules.js.map +1 -0
- package/dist/structure.d.ts.map +1 -1
- package/dist/structure.js +4 -3
- package/dist/structure.js.map +1 -1
- package/dist/tex-paper.d.ts +10 -15
- package/dist/tex-paper.d.ts.map +1 -1
- package/dist/tex-paper.js +24 -40
- package/dist/tex-paper.js.map +1 -1
- package/dist/tex-venue-rules.d.ts +3 -3
- package/dist/tex-venue-rules.d.ts.map +1 -1
- package/dist/tex-venue-rules.js.map +1 -1
- package/dist/types.d.ts +0 -2
- package/dist/types.d.ts.map +1 -1
- package/docs/configuration.md +18 -12
- package/docs/design/paper-sources.md +197 -0
- package/docs/e2e.md +4 -6
- package/docs/package-shape-options.md +1 -1
- package/docs/prior-art/paper-folder-scaffolding.md +24 -29
- package/docs/references.md +34 -8
- package/docs/rules/bib/reachable-entry.md +64 -0
- package/docs/rules/paper/sources-fresh.md +81 -0
- package/docs/rules/tex/claim-provenance.md +0 -1
- package/docs/rules.md +62 -61
- package/eslint-rules/latex-language.harness.mjs +3 -3
- package/eslint-rules/latex-language.ts +10 -13
- package/eslint-rules/paper-context.ts +6 -5
- package/eslint-rules/paper-typography.test.mjs +29 -157
- package/eslint-rules/paper-typography.ts +35 -104
- package/eslint-rules/papers.harness.mjs +1 -1
- package/eslint-rules/papers.ts +2 -4
- package/eslint-rules/tex-build.harness.mjs +2 -2
- package/eslint-rules/tex-build.ts +8 -25
- package/eslint.config.mjs +22 -1
- package/fixtures/build-e2e/aidc/paper.tex +1 -1
- package/fixtures/build-e2e/anon-ack/paper.tex +1 -1
- package/fixtures/build-e2e/anon-author/paper.tex +1 -1
- package/fixtures/build-e2e/anon-bib/paper.tex +1 -1
- package/fixtures/build-e2e/anon-href/paper.tex +1 -1
- package/fixtures/build-e2e/anon-macro/paper.tex +1 -1
- package/fixtures/build-e2e/anon-pdfauthor/paper.tex +1 -1
- package/fixtures/paper-sources/p1/paper.tex +30 -0
- package/fixtures/paper-sources/p1/refs.bib +6 -0
- package/fixtures/paper-sources/p1/sections/dead.tex +6 -0
- package/fixtures/paper-sources/p1/sections/intro.tex +7 -0
- package/fixtures/paper-sources/p1/sections/parked.tex +6 -0
- package/fixtures/paper-sources/p1/tex-truth.json +37 -0
- package/fixtures/paper-sources/p1/versions/2026-01-01-review.tex +4 -0
- package/fixtures/paper-sources/v1-stale/paper.tex +14 -0
- package/fixtures/paper-sources/v1-stale/refs.bib +6 -0
- package/fixtures/paper-sources/v1-stale/tex-truth.json +32 -0
- package/fixtures/paper-sources/v10-ifthenelse/anon.bib +1 -0
- package/fixtures/paper-sources/v10-ifthenelse/paper.tex +9 -0
- package/fixtures/paper-sources/v10-ifthenelse/real.bib +1 -0
- package/fixtures/paper-sources/v10-ifthenelse/tex-truth.json +28 -0
- package/fixtures/paper-sources/v11-two-blocks/paper.tex +12 -0
- package/fixtures/paper-sources/v11-two-blocks/tex-truth.json +30 -0
- package/fixtures/paper-sources/v13-percent-text/paper.tex +6 -0
- package/fixtures/paper-sources/v13-percent-text/refs.bib +3 -0
- package/fixtures/paper-sources/v13-percent-text/tex-truth.json +30 -0
- package/fixtures/paper-sources/v15-after-end/paper.tex +6 -0
- package/fixtures/paper-sources/v15-after-end/refs.bib +1 -0
- package/fixtures/paper-sources/v15-after-end/tex-truth.json +17 -0
- package/fixtures/paper-sources/v16-included-block/bibblock.tex +3 -0
- package/fixtures/paper-sources/v16-included-block/paper.tex +7 -0
- package/fixtures/paper-sources/v16-included-block/refs.bib +1 -0
- package/fixtures/paper-sources/v16-included-block/tex-truth.json +35 -0
- package/fixtures/paper-sources/v17-include-order/bibsetup.tex +1 -0
- package/fixtures/paper-sources/v17-include-order/first.bib +1 -0
- package/fixtures/paper-sources/v17-include-order/later.bib +1 -0
- package/fixtures/paper-sources/v17-include-order/paper.tex +7 -0
- package/fixtures/paper-sources/v17-include-order/tex-truth.json +40 -0
- package/fixtures/paper-sources/v2-overwrite/paper.tex +14 -0
- package/fixtures/paper-sources/v2-overwrite/refs.bib +6 -0
- package/fixtures/paper-sources/v2-overwrite/tex-truth.json +30 -0
- package/fixtures/paper-sources/v22-parked-thebibliography/paper.tex +7 -0
- package/fixtures/paper-sources/v22-parked-thebibliography/tex-truth.json +17 -0
- package/fixtures/paper-sources/v23-parked-include/old.bib +1 -0
- package/fixtures/paper-sources/v23-parked-include/paper.tex +7 -0
- package/fixtures/paper-sources/v23-parked-include/parked.tex +1 -0
- package/fixtures/paper-sources/v23-parked-include/refs.bib +1 -0
- package/fixtures/paper-sources/v23-parked-include/tex-truth.json +28 -0
- package/fixtures/paper-sources/v24-quoted-fields/paper.tex +6 -0
- package/fixtures/paper-sources/v24-quoted-fields/refs.bib +5 -0
- package/fixtures/paper-sources/v24-quoted-fields/tex-truth.json +32 -0
- package/fixtures/paper-sources/v25-string-differs/paper.tex +10 -0
- package/fixtures/paper-sources/v25-string-differs/refs.bib +2 -0
- package/fixtures/paper-sources/v25-string-differs/tex-truth.json +32 -0
- package/fixtures/paper-sources/v26-comment-in-names/one.bib +1 -0
- package/fixtures/paper-sources/v26-comment-in-names/paper.tex +7 -0
- package/fixtures/paper-sources/v26-comment-in-names/tex-truth.json +32 -0
- package/fixtures/paper-sources/v26-comment-in-names/two.bib +1 -0
- package/fixtures/paper-sources/v27-shared-string/abbreviations.bib +2 -0
- package/fixtures/paper-sources/v27-shared-string/paper.tex +6 -0
- package/fixtures/paper-sources/v27-shared-string/references.bib +6 -0
- package/fixtures/paper-sources/v27-shared-string/tex-truth.json +31 -0
- package/fixtures/paper-sources/v28-shared-string-block/abbreviations.bib +2 -0
- package/fixtures/paper-sources/v28-shared-string-block/paper.tex +14 -0
- package/fixtures/paper-sources/v28-shared-string-block/tex-truth.json +33 -0
- package/fixtures/paper-sources/v29-generated-input/paper.tex +9 -0
- package/fixtures/paper-sources/v29-generated-input/tex-truth.json +24 -0
- package/fixtures/paper-sources/v3-declared/paper.bib +6 -0
- package/fixtures/paper-sources/v3-declared/paper.tex +6 -0
- package/fixtures/paper-sources/v3-declared/tex-truth.json +28 -0
- package/fixtures/paper-sources/v30-name-next-line/paper.tex +14 -0
- package/fixtures/paper-sources/v30-name-next-line/tex-truth.json +30 -0
- package/fixtures/paper-sources/v4-commented/paper.tex +14 -0
- package/fixtures/paper-sources/v4-commented/refs.bib +6 -0
- package/fixtures/paper-sources/v4-commented/tex-truth.json +28 -0
- package/fixtures/paper-sources/v5-percent-entry/paper.tex +20 -0
- package/fixtures/paper-sources/v5-percent-entry/tex-truth.json +37 -0
- package/fixtures/paper-sources/v6-unclosed/paper.tex +6 -0
- package/fixtures/paper-sources/v6-unclosed/refs.bib +5 -0
- package/fixtures/paper-sources/v6-unclosed/tex-truth.json +37 -0
- package/fixtures/paper-sources/v8-jobname/paper.tex +9 -0
- package/fixtures/paper-sources/v8-jobname/tex-truth.json +30 -0
- package/fixtures/paper-sources/v9-two-bibliographies/one.bib +1 -0
- package/fixtures/paper-sources/v9-two-bibliographies/paper.tex +7 -0
- package/fixtures/paper-sources/v9-two-bibliographies/tex-truth.json +35 -0
- package/fixtures/paper-sources/v9-two-bibliographies/two.bib +1 -0
- package/fixtures/paper-typography/clean-paper/paper.tex +1 -1
- package/fixtures/paper-typography/messy-paper/paper.tex +1 -1
- package/hooks/hooks.harness.ts +15 -15
- package/hooks/paper-edit-guard.hook.mjs +5 -8
- package/hooks/paper-edit-guard.test.ts +12 -3
- package/hooks/paper-skills-nudge.hook.mjs +2 -3
- package/hooks/paper-skills-nudge.test.ts +13 -3
- package/hooks/paper-status-gates.hook.mjs +2 -2
- package/hooks/paper-status-gates.test.ts +14 -2
- package/lib/markdown.test.mjs +5 -60
- package/lib/markdown.ts +9 -136
- package/lib/paper-config.ts +0 -2
- package/lib/skill-checks.test.mjs +4 -1
- package/lib/skill-eval-fixture.ts +25 -18
- package/package.json +2 -12
- package/presets/realm.jsonc +1 -1
- package/scripts/check.test.ts +23 -1
- package/scripts/check.ts +7 -3
- package/scripts/coverage-config.test.ts +19 -10
- package/scripts/harness-api.frozen.json +0 -5
- package/scripts/layer-legacy-frozen.test.ts +41 -2
- package/scripts/layer-legacy-frozen.ts +31 -2
- package/skills/cold-read-diff/SKILL.md +3 -3
- package/skills/cold-read-diff/SKILL.md.spec.ts +2 -2
- package/skills/grade-paper-writing/SKILL.md +15 -22
- package/skills/grade-paper-writing/SKILL.md.spec.ts +14 -21
- package/skills/grade-paper-writing/__snapshots__/prose-lint.test.ts.snap +40 -26
- package/skills/grade-paper-writing/prose-lint.mjs +117 -278
- package/skills/grade-paper-writing/prose-lint.test.ts +230 -79
- package/skills/paper-adversarial-review/SKILL.md +2 -2
- package/skills/paper-adversarial-review/SKILL.md.spec.ts +1 -1
- package/skills/paper-pipeline/SKILL.md +9 -12
- package/skills/paper-pipeline/SKILL.md.spec.ts +8 -11
- package/skills/paper-pipeline/description-language.eval.mjs +25 -15
- package/skills/paper-pipeline/framing-vs-vocabulary.eval.mjs +25 -15
- package/skills/paper-pipeline/grade-paper-writing-ablation.eval.mjs +25 -15
- package/skills/paper-pipeline/pipeline-firing.eval.mjs +27 -16
- package/skills/paper-pipeline/pipeline-language.eval.mjs +25 -15
- package/skills/paper-pipeline/references/acceptance-gate.md +16 -20
- package/skills/paper-pipeline/references/artifact-checklist.md +4 -5
- package/skills/paper-pipeline/references/pipeline-status-template.md +1 -1
- package/skills/paper-pipeline/scripts/README.md +0 -4
- package/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs +91 -105
- package/skills/paper-pipeline/scripts/extract-ref-facts.mjs +85 -241
- package/skills/paper-pipeline/scripts/extract-ref-facts.test.mjs +166 -153
- package/skills/paper-pipeline/scripts/generated-code.harness.mjs +3 -3
- package/skills/paper-status/SKILL.md +2 -2
- package/skills/paper-status/SKILL.md.spec.ts +1 -1
- package/skills/render-paper/SKILL.md +2 -2
- package/skills/render-paper/SKILL.md.spec.ts +1 -1
- package/skills/render-paper/extract-pdf-facts.mjs +2 -2
- package/skills/tighten-paper/SKILL.md +29 -42
- package/skills/tighten-paper/SKILL.md.spec.ts +28 -41
- package/skills/verify-citations/SKILL.md +7 -4
- package/skills/verify-citations/SKILL.md.spec.ts +6 -3
- package/skills/verify-citations/scripts/bib-authors.check.test.mjs +17 -32
- package/skills/verify-citations/scripts/bib-authors.cli.test.ts +138 -43
- package/skills/verify-citations/scripts/bib-authors.d.mts +22 -2
- package/skills/verify-citations/scripts/bib-authors.mjs +54 -193
- package/skills/verify-citations/scripts/bib-authors.test.mjs +1 -44
- package/skills/verify-citations/scripts/verify-cites.cli.test.ts +16 -0
- package/skills/verify-citations/scripts/verify-cites.d.mts +19 -3
- package/skills/verify-citations/scripts/verify-cites.mjs +42 -108
- package/skills/verify-citations/scripts/verify-cites.test.mjs +23 -36
- package/src/adapters/bibtex/index.test.ts +163 -0
- package/src/adapters/bibtex/index.ts +155 -0
- package/src/adapters/latex/filecontents.ts +114 -0
- package/src/adapters/latex/includes.ts +18 -10
- package/src/adapters/latex/index.test.ts +73 -0
- package/src/adapters/latex/index.ts +2 -0
- package/src/adapters/latex/nodes.ts +64 -0
- package/src/adapters/latex/parse.test.ts +38 -0
- package/src/adapters/latex/parse.ts +67 -6
- package/src/adapters/memory/index.ts +17 -0
- package/src/adapters/references/index.test.ts +75 -21
- package/src/adapters/references/index.ts +37 -32
- package/src/adapters/sources-record/index.test.ts +87 -0
- package/src/adapters/sources-record/index.ts +82 -0
- package/src/adapters/tex-output/blg.ts +27 -0
- package/src/adapters/tex-output/fls.ts +24 -0
- package/src/adapters/tex-output/index.test.ts +171 -0
- package/src/adapters/tex-output/index.ts +12 -0
- package/src/bib-rules.test.ts +356 -0
- package/src/bib-rules.ts +228 -0
- package/src/bibliography-at.test.ts +286 -0
- package/src/build.harness.mjs +2 -2
- package/src/build.test.ts +211 -1
- package/src/build.ts +101 -41
- package/src/claim-provenance.test.ts +33 -7
- package/src/claim-provenance.ts +2 -2
- package/src/cli.harness.mjs +46 -56
- package/src/cli.test.ts +44 -48
- package/src/cli.ts +51 -82
- package/src/domain/paper-source.test.ts +58 -20
- package/src/domain/paper-source.ts +38 -42
- package/src/domain/paper-sources.ts +94 -0
- package/src/domain/sources-record.test.ts +71 -0
- package/src/domain/sources-record.ts +136 -0
- package/src/domain/tex-run.test.ts +228 -0
- package/src/domain/tex-run.ts +139 -0
- package/src/folder-venue-rule.test.ts +1 -1
- package/src/heading-case.test.ts +24 -10
- package/src/init.test.ts +6 -7
- package/src/init.ts +3 -22
- package/src/latex-log.ts +20 -0
- package/src/latex-loop.harness.ts +1 -0
- package/src/latex-loop.ts +2 -0
- package/src/lint-fix.test.ts +10 -4
- package/src/linted-set.test.ts +9 -1
- package/src/new-paper.harness.mjs +12 -30
- package/src/new-paper.test.ts +15 -11
- package/src/new-paper.ts +11 -30
- package/src/package-dirs.ts +3 -2
- package/src/paper-files.test.ts +5 -4
- package/src/paper-files.ts +4 -4
- package/src/paper-includes.test.ts +157 -38
- package/src/paper-includes.ts +39 -35
- package/src/paper-prose.test.ts +78 -0
- package/src/paper-prose.ts +67 -0
- package/src/paper-record.test.ts +173 -0
- package/src/paper-record.ts +66 -0
- package/src/paper-settings-commands.test.ts +5 -2
- package/src/paper-sources.ts +151 -0
- package/src/parse-args.test.ts +0 -1
- package/src/ports/bib-reader.ts +27 -0
- package/src/ports/check-references.ts +7 -3
- package/src/ports/latex.ts +19 -0
- package/src/ports/sources-codec.ts +11 -0
- package/src/ports/tex-output.ts +17 -0
- package/src/recorded-bibliography.ts +297 -0
- package/src/reference-rules.ts +217 -104
- package/src/references.test.ts +520 -177
- package/src/references.ts +185 -37
- package/src/register-bands.test.ts +5 -1
- package/src/register-bands.ts +3 -5
- package/src/register.test.ts +6 -1
- package/src/register.ts +2 -2
- package/src/rule-cases.test.ts +68 -12
- package/src/rule-docs.test.ts +0 -1
- package/src/sources-record.test.ts +308 -0
- package/src/sources-record.ts +231 -0
- package/src/sources-rules.test.ts +152 -0
- package/src/sources-rules.ts +117 -0
- package/src/structure.harness.ts +5 -11
- package/src/structure.ts +4 -3
- package/src/tex-paper.test.ts +148 -78
- package/src/tex-paper.ts +31 -61
- package/src/tex-venue-rules.test.ts +36 -8
- package/src/tex-venue-rules.ts +3 -5
- package/src/types.ts +0 -2
- package/dist/eslint-rules/bib-reachable-entry.d.ts +0 -22
- package/dist/eslint-rules/bib-reachable-entry.d.ts.map +0 -1
- package/dist/eslint-rules/bib-reachable-entry.js +0 -75
- package/dist/eslint-rules/bib-reachable-entry.js.map +0 -1
- package/eslint-rules/bib-reachable-entry.ts +0 -76
- package/fixtures/real-markdown-paper/baseline.json +0 -22
- package/fixtures/real-markdown-paper/baseline.ts +0 -70
- package/skills/paper-pipeline/PIPELINE-MAP.md +0 -381
- package/skills/paper-pipeline/pipeline-firing.baseline.json +0 -270
- package/skills/paper-pipeline/references/sweep-2026-08-09-ideal-pipeline.md +0 -585
- package/skills/paper-pipeline/scripts/artifact-coverage.harness.mjs +0 -492
- package/skills/paper-pipeline/scripts/artifact-coverage.mjs +0 -397
- package/skills/paper-pipeline/scripts/artifact-coverage.test.ts +0 -86
- package/skills/paper-pipeline/scripts/check-provenance.mjs +0 -184
- package/skills/paper-pipeline/scripts/population-map.harness.mjs +0 -135
- package/skills/paper-pipeline/scripts/population-map.mjs +0 -188
- package/skills/paper-pipeline/scripts/population-map.test.mjs +0 -154
- package/skills/paper-pipeline/scripts/provenance.harness.mjs +0 -266
- package/skills/paper-pipeline/scripts/round-diff.harness.ts +0 -907
- package/skills/paper-pipeline/scripts/round-diff.mjs +0 -583
- package/skills/paper-pipeline/scripts/round-diff.test.mjs +0 -159
- package/skills/tighten-paper/__snapshots__/structure.test.ts.snap +0 -133
- package/skills/tighten-paper/structure.mjs +0 -364
- package/skills/tighten-paper/structure.test.ts +0 -117
- package/templates/paper/paper.md +0 -4
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The schema of `_build/sources.json`: the one text it is parsed from, and every way a file can fail to
|
|
3
|
+
* be a record of this schema — refused by name, never read as a record.
|
|
4
|
+
*/
|
|
5
|
+
import { describe, expect, it } from "vitest";
|
|
6
|
+
import {
|
|
7
|
+
serializeSourcesRecord,
|
|
8
|
+
type SourcesRecord,
|
|
9
|
+
} from "../../domain/sources-record.ts";
|
|
10
|
+
import { sourcesCodec } from "./index.ts";
|
|
11
|
+
|
|
12
|
+
const parseSourcesRecord = sourcesCodec.parse;
|
|
13
|
+
const A = "a".repeat(64);
|
|
14
|
+
|
|
15
|
+
const RECORD: SourcesRecord = {
|
|
16
|
+
schema: 1,
|
|
17
|
+
inputs: [
|
|
18
|
+
{ path: "paper.tex", role: "body" },
|
|
19
|
+
{ path: "macros.tex", role: "preamble" },
|
|
20
|
+
],
|
|
21
|
+
written: ["refs.bib"],
|
|
22
|
+
bibdata: ["refs"],
|
|
23
|
+
bibtex: {
|
|
24
|
+
ran: true,
|
|
25
|
+
databases: ["refs.bib"],
|
|
26
|
+
keys: ["k1"],
|
|
27
|
+
exit: 2,
|
|
28
|
+
errors: [{ message: "bad", file: "refs.bib", line: 4 }],
|
|
29
|
+
},
|
|
30
|
+
sha256: { "paper.tex": A, "macros.tex": null },
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
describe("parsing a sources.json", () => {
|
|
34
|
+
it("what serialize wrote parses back to the same record, and the text ends with a newline", () => {
|
|
35
|
+
const text = serializeSourcesRecord(RECORD);
|
|
36
|
+
expect(text.endsWith("}\n")).toBe(true);
|
|
37
|
+
expect(parseSourcesRecord(text)).toEqual({ ok: true, record: RECORD });
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("a build that ran no bibtex parses too", () => {
|
|
41
|
+
const record: SourcesRecord = { ...RECORD, bibtex: { ran: false } };
|
|
42
|
+
expect(parseSourcesRecord(serializeSourcesRecord(record))).toEqual({
|
|
43
|
+
ok: true,
|
|
44
|
+
record,
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("text that is not JSON is refused by name", () => {
|
|
49
|
+
expect(parseSourcesRecord("{")).toEqual({
|
|
50
|
+
ok: false,
|
|
51
|
+
why: "sources.json is not JSON",
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("another schema number is refused by name, not read as this one", () => {
|
|
56
|
+
expect(parseSourcesRecord('{"schema":2}')).toEqual({
|
|
57
|
+
ok: false,
|
|
58
|
+
why: "sources.json is schema 2, this paperlint reads schema 1",
|
|
59
|
+
});
|
|
60
|
+
expect(parseSourcesRecord("[]")).toEqual({
|
|
61
|
+
ok: false,
|
|
62
|
+
why: "sources.json is schema unknown, this paperlint reads schema 1",
|
|
63
|
+
});
|
|
64
|
+
expect(parseSourcesRecord('{"schema":"1"}')).toEqual({
|
|
65
|
+
ok: false,
|
|
66
|
+
why: "sources.json is schema unknown, this paperlint reads schema 1",
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("a record of this schema that is not shaped like one names where", () => {
|
|
71
|
+
const bad = (patch: object): string => {
|
|
72
|
+
const r = parseSourcesRecord(JSON.stringify({ ...RECORD, ...patch }));
|
|
73
|
+
return r.ok ? "accepted" : r.why;
|
|
74
|
+
};
|
|
75
|
+
expect(bad({ inputs: "paper.tex" })).toContain("inputs");
|
|
76
|
+
expect(bad({ sha256: { "paper.tex": "not a digest" } })).toContain(
|
|
77
|
+
"sha256.paper.tex",
|
|
78
|
+
);
|
|
79
|
+
expect(bad({ bibtex: { ran: "yes" } })).toContain("bibtex");
|
|
80
|
+
expect(bad({ inputs: [{ path: "a.tex", role: "main" }] })).toContain(
|
|
81
|
+
"inputs.0.role",
|
|
82
|
+
);
|
|
83
|
+
expect(parseSourcesRecord(JSON.stringify({ schema: 1 }))).toMatchObject({
|
|
84
|
+
ok: false,
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The schema of `_build/sources.json` — the one place its shape is checked (docs/design/paper-sources.md
|
|
3
|
+
* §1). The text is parsed once, here, into the domain's `SourcesRecord`; whatever reads a record after
|
|
4
|
+
* it never re-validates. A record of another schema number is refused by name, not read as this one.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import {
|
|
8
|
+
SOURCES_FILE,
|
|
9
|
+
SOURCES_SCHEMA,
|
|
10
|
+
type ParsedRecord,
|
|
11
|
+
} from "../../domain/sources-record.ts";
|
|
12
|
+
import type { SourcesCodec } from "../../ports/sources-codec.ts";
|
|
13
|
+
|
|
14
|
+
const SHA256 = /^[0-9a-f]{64}$/;
|
|
15
|
+
|
|
16
|
+
const bibtexError = z.object({
|
|
17
|
+
message: z.string(),
|
|
18
|
+
file: z.string(),
|
|
19
|
+
line: z.number().int().nullable(),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const recordSchema = z.object({
|
|
23
|
+
schema: z.literal(SOURCES_SCHEMA),
|
|
24
|
+
inputs: z.array(
|
|
25
|
+
z.object({ path: z.string(), role: z.enum(["preamble", "body"]) }),
|
|
26
|
+
),
|
|
27
|
+
written: z.array(z.string()),
|
|
28
|
+
bibdata: z.array(z.string()),
|
|
29
|
+
bibtex: z.discriminatedUnion("ran", [
|
|
30
|
+
z.object({ ran: z.literal(false) }),
|
|
31
|
+
z.object({
|
|
32
|
+
ran: z.literal(true),
|
|
33
|
+
databases: z.array(z.string()),
|
|
34
|
+
keys: z.array(z.string()),
|
|
35
|
+
exit: z.number().int(),
|
|
36
|
+
errors: z.array(bibtexError),
|
|
37
|
+
}),
|
|
38
|
+
]),
|
|
39
|
+
sha256: z.record(z.string(), z.string().regex(SHA256).nullable()),
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
/** The JSON `text` holds, or undefined when it is not JSON. */
|
|
43
|
+
function jsonOf(text: string): unknown {
|
|
44
|
+
try {
|
|
45
|
+
return JSON.parse(text);
|
|
46
|
+
} catch {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** The `schema` field of a parsed file, whatever it holds, or undefined when there is none. */
|
|
52
|
+
const schemaOf = (json: unknown): unknown =>
|
|
53
|
+
typeof json === "object" && json !== null && "schema" in json
|
|
54
|
+
? json.schema
|
|
55
|
+
: undefined;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* A `sources.json`'s text, parsed once at the boundary: the record, or the one reason it is not one.
|
|
59
|
+
* A record of another schema number is refused by name, not read as this one.
|
|
60
|
+
*/
|
|
61
|
+
export function parseSourcesRecord(text: string): ParsedRecord {
|
|
62
|
+
const json = jsonOf(text);
|
|
63
|
+
if (json === undefined)
|
|
64
|
+
return { ok: false, why: `${SOURCES_FILE} is not JSON` };
|
|
65
|
+
const schema = schemaOf(json);
|
|
66
|
+
if (schema !== SOURCES_SCHEMA)
|
|
67
|
+
return {
|
|
68
|
+
ok: false,
|
|
69
|
+
why: `${SOURCES_FILE} is schema ${typeof schema === "number" ? String(schema) : "unknown"}, this paperlint reads schema ${String(SOURCES_SCHEMA)}`,
|
|
70
|
+
};
|
|
71
|
+
const parsed = recordSchema.safeParse(json);
|
|
72
|
+
if (parsed.success) return { ok: true, record: parsed.data };
|
|
73
|
+
const issues = parsed.error.issues.map(
|
|
74
|
+
(i) => `${i.path.join(".")} ${i.message}`,
|
|
75
|
+
);
|
|
76
|
+
return {
|
|
77
|
+
ok: false,
|
|
78
|
+
why: `${SOURCES_FILE} does not match schema ${String(SOURCES_SCHEMA)}: ${issues.join("; ")}`,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export const sourcesCodec: SourcesCodec = { parse: parseSourcesRecord };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The errors in bibtex's log (`paper.blg`). bibtex ends an error with the place it was reading —
|
|
3
|
+
* `---line 4 of file refs.bib`, or `---while reading file paper.aux` when it names no line — and a
|
|
4
|
+
* warning with a single dash (`--line 1 of file x.bib`), so the three dashes are the whole grammar.
|
|
5
|
+
* The message is what stands before them on the line, or, when they start the line, the line before.
|
|
6
|
+
*/
|
|
7
|
+
import type { BibtexError } from "../../domain/sources-record.ts";
|
|
8
|
+
|
|
9
|
+
const PLACE = /^(.*?)---(?:line (\d+) of file|while reading file) (.+)$/;
|
|
10
|
+
const LINE_NUMBER = /---line (\d+) of file/;
|
|
11
|
+
|
|
12
|
+
export function parseBlgErrors(blg: string): readonly BibtexError[] {
|
|
13
|
+
const rows = blg.split(/\r?\n/);
|
|
14
|
+
return rows.flatMap((row, i): readonly BibtexError[] => {
|
|
15
|
+
const m = PLACE.exec(row);
|
|
16
|
+
if (m === null) return [];
|
|
17
|
+
const [, before = "", , file = ""] = m;
|
|
18
|
+
const line = LINE_NUMBER.exec(row)?.[1];
|
|
19
|
+
return [
|
|
20
|
+
{
|
|
21
|
+
message: (before === "" ? (rows[i - 1] ?? "") : before).trim(),
|
|
22
|
+
file: file.trim(),
|
|
23
|
+
line: line === undefined ? null : Number(line),
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
});
|
|
27
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pdflatex's `-recorder` file (`paper.fls`): one line per file TeX opened — `INPUT <path>` to read
|
|
3
|
+
* it, `OUTPUT <path>` to write it — in the order TeX opened them, and a `PWD <dir>` line first. The
|
|
4
|
+
* format has no quoting: a path is the rest of its line.
|
|
5
|
+
*/
|
|
6
|
+
import type { Fls, FlsLine } from "../../domain/tex-run.ts";
|
|
7
|
+
|
|
8
|
+
const OPS = ["INPUT", "OUTPUT"] as const;
|
|
9
|
+
|
|
10
|
+
/** `INPUT a.tex` → the line; anything else (`PWD …`, a blank, a word with no path) → none. */
|
|
11
|
+
function lineOf(raw: string): readonly FlsLine[] {
|
|
12
|
+
const op = OPS.find((o) => raw.startsWith(`${o} `));
|
|
13
|
+
const path = op === undefined ? "" : raw.slice(op.length + 1).trimEnd();
|
|
14
|
+
return op === undefined || path === "" ? [] : [{ op, path }];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function parseFls(text: string): Fls {
|
|
18
|
+
const rows = text.split(/\r?\n/);
|
|
19
|
+
const pwd = rows.find((r) => r.startsWith("PWD "));
|
|
20
|
+
return {
|
|
21
|
+
pwd: pwd === undefined ? null : pwd.slice("PWD ".length).trimEnd(),
|
|
22
|
+
lines: rows.flatMap(lineOf),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The readers of what TeX writes beside a paper — `.fls` (pdflatex `-recorder`) and the errors in
|
|
3
|
+
* bibtex's `.blg` — on files captured whole from real runs of the planted papers in
|
|
4
|
+
* `fixtures/paper-sources/` (test/fixtures/tex-output/README.md), not on text written for the test.
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync } from "node:fs";
|
|
7
|
+
import { dirname, join } from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { describe, expect, it } from "vitest";
|
|
10
|
+
import { texOutput } from "./index.ts";
|
|
11
|
+
|
|
12
|
+
const CAPTURES = join(
|
|
13
|
+
dirname(dirname(dirname(dirname(fileURLToPath(import.meta.url))))),
|
|
14
|
+
"test",
|
|
15
|
+
"fixtures",
|
|
16
|
+
"tex-output",
|
|
17
|
+
);
|
|
18
|
+
const capture = (paper: string, file: string): string =>
|
|
19
|
+
readFileSync(join(CAPTURES, paper, file), "utf8");
|
|
20
|
+
|
|
21
|
+
/** The lines that name a file of the paper: not the TeX tree's (absolute) files. */
|
|
22
|
+
const ofPaper = (text: string) =>
|
|
23
|
+
texOutput.fls(text).lines.filter((l) => !l.path.startsWith("/"));
|
|
24
|
+
|
|
25
|
+
describe("the .fls reader", () => {
|
|
26
|
+
it("reads every INPUT and OUTPUT line in order, and the directory pdflatex ran in", () => {
|
|
27
|
+
const fls = texOutput.fls(capture("v8-jobname", "paper.fls"));
|
|
28
|
+
expect(fls.pwd).toBe("/work/paper");
|
|
29
|
+
expect(fls.lines.filter((l) => !l.path.startsWith("/"))).toEqual([
|
|
30
|
+
{ op: "INPUT", path: "paper.tex" },
|
|
31
|
+
{ op: "OUTPUT", path: "paper.log" },
|
|
32
|
+
{ op: "INPUT", path: "./paper.bib" },
|
|
33
|
+
{ op: "INPUT", path: "paper.bib" },
|
|
34
|
+
{ op: "OUTPUT", path: "paper.bib" },
|
|
35
|
+
{ op: "INPUT", path: "./paper.aux" },
|
|
36
|
+
{ op: "INPUT", path: "./paper.aux" },
|
|
37
|
+
{ op: "INPUT", path: "paper.aux" },
|
|
38
|
+
{ op: "OUTPUT", path: "paper.aux" },
|
|
39
|
+
{ op: "INPUT", path: "./paper.bbl" },
|
|
40
|
+
{ op: "INPUT", path: "./paper.bbl" },
|
|
41
|
+
{ op: "INPUT", path: "paper.bbl" },
|
|
42
|
+
{ op: "OUTPUT", path: "paper.pdf" },
|
|
43
|
+
{ op: "INPUT", path: "paper.aux" },
|
|
44
|
+
]);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("keeps the TeX tree's files too, as the absolute paths TeX opened", () => {
|
|
48
|
+
const fls = texOutput.fls(capture("v3-declared", "paper.fls"));
|
|
49
|
+
expect(fls.lines.slice(0, 4)).toEqual([
|
|
50
|
+
{ op: "INPUT", path: "/usr/share/texlive/texmf.cnf" },
|
|
51
|
+
{ op: "INPUT", path: "/usr/share/texlive/texmf-dist/web2c/texmf.cnf" },
|
|
52
|
+
{
|
|
53
|
+
op: "INPUT",
|
|
54
|
+
path: "/usr/share/texlive/texmf-var/web2c/pdftex/pdflatex.fmt",
|
|
55
|
+
},
|
|
56
|
+
{ op: "INPUT", path: "paper.tex" },
|
|
57
|
+
]);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe("the .fls reader, on the shapes of a real run", () => {
|
|
62
|
+
it("a file in a folder keeps its folder; a first pass has no .aux to read yet; a block over a .bib that is already there writes nothing", () => {
|
|
63
|
+
expect(ofPaper(capture("p1", "first-pass.fls"))).toEqual([
|
|
64
|
+
{ op: "INPUT", path: "paper.tex" },
|
|
65
|
+
{ op: "OUTPUT", path: "paper.log" },
|
|
66
|
+
{ op: "INPUT", path: "./refs.bib" },
|
|
67
|
+
{ op: "INPUT", path: "refs.bib" },
|
|
68
|
+
{ op: "OUTPUT", path: "paper.aux" },
|
|
69
|
+
{ op: "INPUT", path: "./sections/intro.tex" },
|
|
70
|
+
{ op: "INPUT", path: "./sections/intro.tex" },
|
|
71
|
+
{ op: "INPUT", path: "./sections/intro.tex" },
|
|
72
|
+
{ op: "INPUT", path: "./sections/intro.tex" },
|
|
73
|
+
{ op: "INPUT", path: "sections/intro.tex" },
|
|
74
|
+
{ op: "OUTPUT", path: "paper.pdf" },
|
|
75
|
+
{ op: "INPUT", path: "paper.aux" },
|
|
76
|
+
]);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("a path with a space is the whole rest of the line; text that is not a line of the format is skipped", () => {
|
|
80
|
+
expect(
|
|
81
|
+
texOutput.fls(
|
|
82
|
+
"PWD /a b/p\nINPUT my file.tex\nOUTPUT out dir/x.aux\nsomething else\nINPUT\n",
|
|
83
|
+
),
|
|
84
|
+
).toEqual({
|
|
85
|
+
pwd: "/a b/p",
|
|
86
|
+
lines: [
|
|
87
|
+
{ op: "INPUT", path: "my file.tex" },
|
|
88
|
+
{ op: "OUTPUT", path: "out dir/x.aux" },
|
|
89
|
+
],
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("an .fls with no PWD line has no directory", () => {
|
|
94
|
+
expect(texOutput.fls("INPUT paper.tex\n")).toEqual({
|
|
95
|
+
pwd: null,
|
|
96
|
+
lines: [{ op: "INPUT", path: "paper.tex" }],
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe("the .blg error reader", () => {
|
|
102
|
+
it("a run that ends well reports none, warnings included", () => {
|
|
103
|
+
expect(texOutput.blgErrors(capture("v3-declared", "paper.blg"))).toEqual(
|
|
104
|
+
[],
|
|
105
|
+
);
|
|
106
|
+
expect(
|
|
107
|
+
texOutput.blgErrors(
|
|
108
|
+
"Database file #1: x.bib\nWarning--I'm ignoring a's extra \"year\" field\n--line 1 of file x.bib\n",
|
|
109
|
+
),
|
|
110
|
+
).toEqual([]);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe("the .blg error reader, on what real runs reported", () => {
|
|
115
|
+
it("an entry never closed: the message before the dashes, the file and the line after", () => {
|
|
116
|
+
expect(texOutput.blgErrors(capture("v6-unclosed", "paper.blg"))).toEqual([
|
|
117
|
+
{
|
|
118
|
+
message: "I was expecting a `,' or a `}'",
|
|
119
|
+
file: "refs.bib",
|
|
120
|
+
line: 4,
|
|
121
|
+
},
|
|
122
|
+
]);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("a second \\bibdata command is an error in the .aux", () => {
|
|
126
|
+
expect(
|
|
127
|
+
texOutput.blgErrors(capture("v9-two-bibliographies", "paper.blg")),
|
|
128
|
+
).toEqual([
|
|
129
|
+
{
|
|
130
|
+
message: "Illegal, another \\bibdata command",
|
|
131
|
+
file: "paper.aux",
|
|
132
|
+
line: 5,
|
|
133
|
+
},
|
|
134
|
+
]);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it("dashes on the first line of the log have no message before them", () => {
|
|
138
|
+
expect(texOutput.blgErrors("---line 1 of file paper.aux\n")).toEqual([
|
|
139
|
+
{ message: "", file: "paper.aux", line: 1 },
|
|
140
|
+
]);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it("a message on the line before its dashes, and an error with no line", () => {
|
|
144
|
+
expect(
|
|
145
|
+
texOutput.blgErrors(
|
|
146
|
+
[
|
|
147
|
+
"The style file: plain.bst",
|
|
148
|
+
"I couldn't open database file paper.bib",
|
|
149
|
+
"---line 4 of file paper.aux",
|
|
150
|
+
" : \\bibdata{paper",
|
|
151
|
+
" : }",
|
|
152
|
+
"I'm skipping whatever remains of this command",
|
|
153
|
+
"I found no database files---while reading file paper.aux",
|
|
154
|
+
'Warning--I didn\'t find a database entry for "declared2023"',
|
|
155
|
+
"(There were 2 error messages)",
|
|
156
|
+
].join("\n"),
|
|
157
|
+
),
|
|
158
|
+
).toEqual([
|
|
159
|
+
{
|
|
160
|
+
message: "I couldn't open database file paper.bib",
|
|
161
|
+
file: "paper.aux",
|
|
162
|
+
line: 4,
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
message: "I found no database files",
|
|
166
|
+
file: "paper.aux",
|
|
167
|
+
line: null,
|
|
168
|
+
},
|
|
169
|
+
]);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The readers of what TeX writes beside a paper: pdflatex's `-recorder` file and bibtex's errors.
|
|
3
|
+
* One implementation of `TexOutput` (`src/ports/tex-output.ts`).
|
|
4
|
+
*/
|
|
5
|
+
import type { TexOutput } from "../../ports/tex-output.ts";
|
|
6
|
+
import { parseBlgErrors } from "./blg.ts";
|
|
7
|
+
import { parseFls } from "./fls.ts";
|
|
8
|
+
|
|
9
|
+
export const texOutput: TexOutput = {
|
|
10
|
+
fls: parseFls,
|
|
11
|
+
blgErrors: parseBlgErrors,
|
|
12
|
+
};
|