paperlint 2.0.1 → 3.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 +6 -1
- package/CONTRIBUTING.md +21 -0
- package/README.md +231 -180
- package/action.yml +4 -6
- package/dist/adapters/references/index.d.ts +13 -0
- package/dist/adapters/references/index.d.ts.map +1 -0
- package/dist/adapters/references/index.js +55 -0
- package/dist/adapters/references/index.js.map +1 -0
- package/dist/adapters/references/reach.io.d.ts +3 -0
- package/dist/adapters/references/reach.io.d.ts.map +1 -0
- package/dist/adapters/references/reach.io.js +14 -0
- package/dist/adapters/references/reach.io.js.map +1 -0
- package/dist/build-engine.d.ts.map +1 -1
- package/dist/build-engine.js +5 -2
- package/dist/build-engine.js.map +1 -1
- package/dist/build.d.ts +16 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +40 -5
- package/dist/build.js.map +1 -1
- package/dist/cli.d.ts +37 -20
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +377 -251
- package/dist/cli.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +37 -52
- package/dist/doctor.js.map +1 -1
- package/dist/facts-file.d.ts +33 -9
- package/dist/facts-file.d.ts.map +1 -1
- package/dist/facts-file.js +117 -17
- package/dist/facts-file.js.map +1 -1
- package/dist/hooks-settings.d.ts +0 -21
- package/dist/hooks-settings.d.ts.map +1 -1
- package/dist/hooks-settings.js +17 -135
- package/dist/hooks-settings.js.map +1 -1
- package/dist/init.d.ts +40 -19
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +144 -109
- package/dist/init.js.map +1 -1
- package/dist/link-skills.d.ts +1 -1
- package/dist/link-skills.d.ts.map +1 -1
- package/dist/link-skills.js +11 -29
- package/dist/link-skills.js.map +1 -1
- package/dist/new-paper.d.ts +2 -2
- package/dist/new-paper.d.ts.map +1 -1
- package/dist/new-paper.js +6 -2
- package/dist/new-paper.js.map +1 -1
- package/dist/paper-files.d.ts +63 -0
- package/dist/paper-files.d.ts.map +1 -0
- package/dist/paper-files.js +69 -0
- package/dist/paper-files.js.map +1 -0
- package/dist/paper-settings.d.ts +40 -0
- package/dist/paper-settings.d.ts.map +1 -0
- package/dist/paper-settings.js +144 -0
- package/dist/paper-settings.js.map +1 -0
- package/dist/ports/check-references.d.ts +31 -0
- package/dist/ports/check-references.d.ts.map +1 -0
- package/dist/ports/check-references.js +7 -0
- package/dist/ports/check-references.js.map +1 -0
- package/dist/presets.d.ts +84 -0
- package/dist/presets.d.ts.map +1 -0
- package/dist/presets.js +184 -0
- package/dist/presets.js.map +1 -0
- package/dist/reference-rules.d.ts +47 -0
- package/dist/reference-rules.d.ts.map +1 -0
- package/dist/reference-rules.js +156 -0
- package/dist/reference-rules.js.map +1 -0
- package/dist/references.d.ts +36 -0
- package/dist/references.d.ts.map +1 -0
- package/dist/references.js +91 -0
- package/dist/references.js.map +1 -0
- package/dist/rules-config.d.ts +11 -2
- package/dist/rules-config.d.ts.map +1 -1
- package/dist/rules-config.js +25 -11
- package/dist/rules-config.js.map +1 -1
- package/dist/structure.d.ts.map +1 -1
- package/dist/structure.js +3 -2
- package/dist/structure.js.map +1 -1
- package/dist/tex-requirements.d.ts +63 -7
- package/dist/tex-requirements.d.ts.map +1 -1
- package/dist/tex-requirements.js +91 -24
- package/dist/tex-requirements.js.map +1 -1
- package/dist/types.d.ts +20 -18
- package/dist/types.d.ts.map +1 -1
- package/dist/venue-rules.d.ts +109 -0
- package/dist/venue-rules.d.ts.map +1 -0
- package/dist/venue-rules.js +389 -0
- package/dist/venue-rules.js.map +1 -0
- package/docs/configuration.md +152 -77
- package/docs/e2e.md +1 -1
- package/docs/install.md +25 -40
- package/docs/optional-rules.md +26 -24
- package/docs/rules.md +181 -15
- package/eslint-rules/bib-reachable-entry.mjs +75 -0
- package/eslint-rules/latex-language.mjs +29 -1
- package/eslint-rules/paper-stages.harness.mjs +1 -117
- package/eslint-rules/paper-stages.mjs +0 -120
- package/eslint-rules/paper-stages.mutations.mjs +0 -76
- package/eslint-rules/paper-typography.mjs +267 -192
- package/eslint-rules/paper-typography.test.mjs +297 -0
- package/eslint-rules/papers.harness.mjs +8 -12
- package/eslint-rules/papers.mjs +17 -27
- package/eslint-rules/pdf-last-page-balance.mjs +23 -5
- package/eslint-rules/review-frontmatter.mjs +118 -0
- package/eslint-rules/review-frontmatter.schema.json +36 -0
- package/eslint-rules/review-frontmatter.test.mjs +118 -0
- package/eslint-rules/sibling-frontmatter.mjs +19 -0
- package/eslint-rules/sibling-frontmatter.schema.json +14 -0
- package/eslint.config.mjs +0 -15
- package/fixtures/build-e2e/acmart/paperlint.json +1 -0
- package/fixtures/real-markdown-paper/baseline.json +6 -7
- package/hooks/hooks.harness.mjs +39 -98
- package/hooks/hooks.mutations.mjs +6 -6
- package/hooks/paper-edit-guard.hook.d.mts +2 -3
- package/hooks/paper-edit-guard.hook.mjs +31 -42
- package/hooks/paper-skills-nudge.hook.mjs +21 -19
- package/hooks/paper-status-gates.hook.mjs +21 -19
- package/hooks/paper-status-gates.sh +8 -13
- package/lib/paper-config.d.mts +15 -18
- package/lib/paper-config.harness.mjs +18 -35
- package/lib/paper-config.mjs +90 -81
- package/lib/paper-config.mutations.mjs +2 -2
- package/lib/skill-checks.mjs +1 -1
- package/lib/skill-trigger-cases.harness.mjs +9 -8
- package/lib/skill-trigger-cases.mjs +7 -15
- package/package.json +1 -1
- package/scripts/eslint-report-guard.mjs +1 -1
- package/scripts/harness-api.frozen.json +0 -3
- package/scripts/mutation-batteries.frozen.json +4 -13
- package/skills/analyze-sibling-paper/SKILL.md +16 -12
- package/skills/analyze-sibling-paper/SKILL.md.spec.ts +15 -11
- package/skills/cold-read-diff/SKILL.md +20 -1
- package/skills/cold-read-diff/SKILL.md.spec.ts +19 -0
- package/skills/find-venue/SKILL.md +5 -1
- package/skills/find-venue/SKILL.md.spec.ts +4 -0
- package/skills/grade-paper-writing/SKILL.md +20 -1
- package/skills/grade-paper-writing/SKILL.md.spec.ts +19 -0
- package/skills/paper-pipeline/PIPELINE-MAP.md +14 -4
- package/skills/paper-pipeline/SKILL.md +4 -3
- package/skills/paper-pipeline/SKILL.md.spec.ts +3 -2
- package/skills/paper-pipeline/scripts/consumer.d.mts +0 -1
- package/skills/paper-pipeline/scripts/consumer.harness.mjs +8 -12
- package/skills/paper-pipeline/scripts/consumer.mjs +19 -33
- package/skills/paper-pipeline/scripts/extract-ref-facts.harness.mjs +6 -4
- package/skills/paper-pipeline/scripts/run-mechanical.mjs +2 -11
- package/skills/plan-paper-timeline/SKILL.md +2 -2
- package/skills/plan-paper-timeline/SKILL.md.spec.ts +1 -1
- package/skills/plan-paper-timeline/plan-paper-timeline.effects.harness.mjs +1 -1
- package/skills/plan-paper-timeline/plan-paper-timeline.effects.mutations.mjs +2 -2
- package/skills/render-paper/check-render.sh +2 -3
- package/skills/render-paper/extract-pdf-facts.harness.mjs +5 -5
- package/skills/render-paper/extract-pdf-facts.mjs +4 -4
- package/skills/render-paper/render-paper.harness.mjs +2 -2
- package/skills/study-accepted-papers/SKILL.md +2 -1
- package/skills/study-accepted-papers/SKILL.md.spec.ts +1 -0
- package/skills/submit-paper/SKILL.md +9 -1
- package/skills/submit-paper/SKILL.md.spec.ts +8 -0
- package/skills/submit-paper/references/venues/acm-sigconf.jsonc +86 -0
- package/skills/submit-paper/references/venues/agenticdev.jsonc +34 -102
- package/skills/submit-paper/references/venues/aisec.jsonc +21 -82
- package/skills/submit-paper/references/venues/realm.jsonc +45 -43
- package/skills/submit-paper/references/venues/tex-base.jsonc +1 -1
- package/skills/submit-paper/references/venues/venue-profile.schema.json +119 -29
- package/skills/verify-citations/SKILL.md +10 -1
- package/skills/verify-citations/SKILL.md.spec.ts +9 -0
- package/skills/verify-citations/scripts/bib-authors.mjs +48 -26
- package/src/adapters/references/index.ts +102 -0
- package/src/adapters/references/reach.io.ts +12 -0
- package/src/build-engine.ts +10 -2
- package/src/build.harness.mjs +31 -22
- package/src/build.ts +65 -8
- package/src/cli.harness.mjs +151 -294
- package/src/cli.mutations.mjs +35 -44
- package/src/cli.ts +457 -288
- package/src/doctor.harness.mjs +41 -84
- package/src/doctor.mutations.mjs +9 -9
- package/src/doctor.ts +41 -61
- package/src/facts-file.test.ts +47 -7
- package/src/facts-file.ts +145 -24
- package/src/hooks-settings.harness.mjs +7 -92
- package/src/hooks-settings.mutations.mjs +2 -17
- package/src/hooks-settings.ts +18 -162
- package/src/init.test.ts +206 -0
- package/src/init.ts +193 -159
- package/src/link-skills.harness.mjs +1 -38
- package/src/link-skills.mutations.mjs +9 -5
- package/src/link-skills.ts +10 -34
- package/src/lint-fix.test.ts +120 -0
- package/src/new-paper.harness.mjs +9 -6
- package/src/new-paper.test.ts +133 -0
- package/src/new-paper.ts +7 -2
- package/src/paper-files.test.ts +290 -0
- package/src/paper-files.ts +144 -0
- package/src/paper-settings-commands.test.ts +274 -0
- package/src/paper-settings.test.ts +249 -0
- package/src/paper-settings.ts +208 -0
- package/src/ports/check-references.ts +28 -0
- package/src/presets.test.ts +236 -0
- package/src/presets.ts +297 -0
- package/src/reference-rules.ts +229 -0
- package/src/references.test.ts +209 -0
- package/src/references.ts +138 -0
- package/src/rules-config.harness.mjs +24 -8
- package/src/rules-config.ts +30 -13
- package/src/structure.harness.mjs +6 -4
- package/src/structure.ts +3 -2
- package/src/tex-requirements.harness.mjs +11 -17
- package/src/tex-requirements.ts +179 -29
- package/src/types.ts +30 -18
- package/src/venue-rules.test.ts +554 -0
- package/src/venue-rules.ts +571 -0
- package/templates/paper/paperlint.json +4 -0
- package/eslint-rules/doc-fields.harness.mjs +0 -336
- package/eslint-rules/doc-fields.mjs +0 -186
- package/eslint-rules/doc-fields.mutations.mjs +0 -96
- package/eslint-rules/paper-typography.harness.mjs +0 -291
- package/eslint-rules/paper-typography.mutations.mjs +0 -131
- package/eslint-rules/review-findings-cause.harness.mjs +0 -228
- package/eslint-rules/review-findings-cause.mjs +0 -135
- package/eslint-rules/review-findings-cause.mutations.mjs +0 -72
- package/fixtures/build-e2e/acmart/venue.json +0 -1
- package/fixtures/paper-stages/authors-ran/PIPELINE-STATUS.md +0 -16
- package/fixtures/paper-stages/marker-in-prose/PIPELINE-STATUS.md +0 -17
- package/fixtures/review-findings-cause/clean.md +0 -17
- package/fixtures/review-findings-cause/defect.md +0 -14
- package/fixtures/review-findings-cause/old-debt.md +0 -14
- package/fixtures/review-findings-cause/quiet-in-fence.md +0 -16
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// ACM `acmart` sigconf — the TEMPLATE FAMILY: everything the ACM template decides, whatever the
|
|
2
|
+
// venue. A venue preset extends it ("extends": "paperlint:acm-sigconf") and adds what its call for
|
|
3
|
+
// papers sets: the page limit of each kind of paper, and the rules its producer implies.
|
|
4
|
+
//
|
|
5
|
+
// The numbers were measured on acmart sigconf builds (banal + pdf.js, 2026-08-26) and quoted from
|
|
6
|
+
// the Conference Publishing author instructions for ACM (2026-08-25), which state ACM's own
|
|
7
|
+
// requirements. A paper may extend this family directly for an ACM venue nobody has profiled:
|
|
8
|
+
// page size, columns and fonts are checked; with no kinds, the page limit is not.
|
|
9
|
+
{
|
|
10
|
+
"template": "acmart",
|
|
11
|
+
|
|
12
|
+
// TeX Live packages the acmart template needs ON TOP OF tex-base.jsonc, each with the files that
|
|
13
|
+
// prove it is present (checked with kpsewhich after every install). Read by `paperlint toolchain` and
|
|
14
|
+
// `paperlint build`; the shape is venue-profile.schema.json.
|
|
15
|
+
// libertine · inconsolata (zi4) · newtx — acmart.cls checks ALL THREE and, if ANY is missing,
|
|
16
|
+
// silently falls back to Computer Modern: the PDF compiles, looks normal, is set in the wrong
|
|
17
|
+
// font, and the other metric gives another pagination. A submitted paper went out that way.
|
|
18
|
+
// kastrup (binhex.tex) — pulled in by newtx. Missing it is a HARD stop, so adding the fonts
|
|
19
|
+
// without it breaks a build that worked.
|
|
20
|
+
// fancyhdr — required by acmart itself; present on most images by accident, absent on a
|
|
21
|
+
// minimal one ("File `fancyhdr.sty' not found", measured on TinyTeX, issue #37).
|
|
22
|
+
// the rest — pulled in by acmart ITSELF, not by the paper, so reading \usepackage never finds
|
|
23
|
+
// them. Found 2026-09-01 by the loop build → missing file → tlmgr search --file → install.
|
|
24
|
+
"tex": {
|
|
25
|
+
"packages": {
|
|
26
|
+
"acmart": ["acmart.cls"],
|
|
27
|
+
"amscls": ["amsart.cls"],
|
|
28
|
+
"libertine": ["libertine.sty"],
|
|
29
|
+
"inconsolata": ["zi4.sty"],
|
|
30
|
+
"newtx": ["newtxmath.sty"],
|
|
31
|
+
"kastrup": ["binhex.tex"],
|
|
32
|
+
"fancyhdr": ["fancyhdr.sty"],
|
|
33
|
+
"totpages": ["totpages.sty"],
|
|
34
|
+
"environ": ["environ.sty"],
|
|
35
|
+
"preprint": ["balance.sty"],
|
|
36
|
+
// acmart's `pbalance` option (the vendor's first fix for an unbalanced last page, which the
|
|
37
|
+
// optional rule `pdf/last-page-balance` recommends) loads pbalance, which needs filehook and
|
|
38
|
+
// zref. Measured 2026-09-25 on an acmart sigconf camera-ready: without them the option stops
|
|
39
|
+
// the build; with them the last page went from 639.6 / 224.1 to 424.4 / 439.2 pt, same page count.
|
|
40
|
+
"pbalance": ["pbalance.sty"],
|
|
41
|
+
"filehook": ["filehook.sty"],
|
|
42
|
+
"zref": ["zref-abspage.sty"],
|
|
43
|
+
"xstring": ["xstring.sty"],
|
|
44
|
+
"everyshi": ["everyshi.sty"],
|
|
45
|
+
"hyperxmp": ["hyperxmp.sty"],
|
|
46
|
+
"ncctools": ["manyfoot.sty"],
|
|
47
|
+
"cmap": ["cmap.sty"],
|
|
48
|
+
"float": ["float.sty"],
|
|
49
|
+
"comment": ["comment.sty"],
|
|
50
|
+
"upquote": ["upquote.sty"],
|
|
51
|
+
"doclicense": ["doclicense.sty"],
|
|
52
|
+
"textcase": ["textcase.sty"],
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
"format": {
|
|
57
|
+
// 8.5 x 11 in
|
|
58
|
+
"page_size": "letter",
|
|
59
|
+
"page_w_in": 8.5,
|
|
60
|
+
"page_h_in": 11.0,
|
|
61
|
+
|
|
62
|
+
// «text width must not exceed 18 cm»
|
|
63
|
+
"textblock_w_in": 7.087,
|
|
64
|
+
// «text height must not exceed 23.5 cm»
|
|
65
|
+
"textblock_h_in": 9.252,
|
|
66
|
+
// Last-page balance is NOT a format field: it is the optional rule pdf/last-page-balance, which
|
|
67
|
+
// a VENUE preset turns on in its `rules` when its producer asks (see agenticdev.jsonc).
|
|
68
|
+
|
|
69
|
+
"columns": 2,
|
|
70
|
+
|
|
71
|
+
// «font size is 9 pt for all body text»
|
|
72
|
+
"body_pt": 9,
|
|
73
|
+
// banal measures the MODE of the rendered text, not the declared size (measured 08-26: 9.30 at
|
|
74
|
+
// acmart's declared 9). Hence the tolerance — and hence why body size stays a nudge, not a gate.
|
|
75
|
+
"body_pt_tol": 0.5,
|
|
76
|
+
|
|
77
|
+
// «font size of the references can be from 7 pt to 9 pt»
|
|
78
|
+
"ref_pt_min": 7,
|
|
79
|
+
"ref_pt_max": 9,
|
|
80
|
+
|
|
81
|
+
// «text must be in serif font (Libertine)»
|
|
82
|
+
"fonts_text": "LinLibertine",
|
|
83
|
+
// «The title must be in sans-serif font (Biolinum)»
|
|
84
|
+
"fonts_title": "LinBiolinum",
|
|
85
|
+
},
|
|
86
|
+
}
|
|
@@ -1,108 +1,40 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// 🔴 Why JSONC and not YAML (decided 08-26). I had this in YAML, justifying it with "JSON has no
|
|
7
|
-
// comments, and every number here carries a quote from the instructions." That objection turned
|
|
8
|
-
// out to be false: @eslint/json ships three languages — json, jsonc, json5 — and jsonc is exactly
|
|
9
|
-
// JSON with comments. So the quotes stay in place, the file is read by a real parser
|
|
10
|
-
// (@humanwhocodes/momoa, already a transitive dependency), AND it's linted by the same engine as
|
|
11
|
-
// everything else. One extra dependency (js-yaml on this path) goes away.
|
|
1
|
+
// AgenticDev (an ASE workshop) — a VENUE preset over the ACM sigconf family. Prose about the venue
|
|
2
|
+
// is in agenticdev.md nearby. Everything the ACM template decides (page size, columns, fonts, font
|
|
3
|
+
// sizes, TeX packages) comes from acm-sigconf.jsonc; this file adds what AgenticDev's call for
|
|
4
|
+
// papers sets.
|
|
5
|
+
// Source for the numbers: the Conference Publishing author instructions 2026-08-25.
|
|
12
6
|
{
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"newtx": ["newtxmath.sty"],
|
|
34
|
-
"kastrup": ["binhex.tex"],
|
|
35
|
-
"fancyhdr": ["fancyhdr.sty"],
|
|
36
|
-
"totpages": ["totpages.sty"],
|
|
37
|
-
"environ": ["environ.sty"],
|
|
38
|
-
"preprint": ["balance.sty"],
|
|
39
|
-
// acmart's `pbalance` option (the vendor's first fix for an unbalanced last page, which the
|
|
40
|
-
// optional rule `pdf/last-page-balance` recommends) loads pbalance, which needs filehook and
|
|
41
|
-
// zref. Measured 2026-09-25 on an acmart sigconf camera-ready: without them the option stops
|
|
42
|
-
// the build; with them the last page went from 639.6 / 224.1 to 424.4 / 439.2 pt, same page count.
|
|
43
|
-
"pbalance": ["pbalance.sty"],
|
|
44
|
-
"filehook": ["filehook.sty"],
|
|
45
|
-
"zref": ["zref-abspage.sty"],
|
|
46
|
-
"xstring": ["xstring.sty"],
|
|
47
|
-
"everyshi": ["everyshi.sty"],
|
|
48
|
-
"hyperxmp": ["hyperxmp.sty"],
|
|
49
|
-
"ncctools": ["manyfoot.sty"],
|
|
50
|
-
"cmap": ["cmap.sty"],
|
|
51
|
-
"float": ["float.sty"],
|
|
52
|
-
"comment": ["comment.sty"],
|
|
53
|
-
"upquote": ["upquote.sty"],
|
|
54
|
-
"doclicense": ["doclicense.sty"],
|
|
55
|
-
"textcase": ["textcase.sty"],
|
|
7
|
+
"extends": "paperlint:acm-sigconf",
|
|
8
|
+
|
|
9
|
+
"format": {
|
|
10
|
+
// The limits are a property of the paper's TYPE at this venue, not of the venue itself.
|
|
11
|
+
// A given paper's type is stated in its <paper-dir>/paperlint.json (`kind`).
|
|
12
|
+
"kinds": {
|
|
13
|
+
"short": {
|
|
14
|
+
"body_pages_max": 5,
|
|
15
|
+
// «up to 2 extra pages of references»
|
|
16
|
+
"ref_pages_max": 2,
|
|
17
|
+
},
|
|
18
|
+
"full": {
|
|
19
|
+
// «Full ≤10pp (mature)»
|
|
20
|
+
"body_pages_max": 10,
|
|
21
|
+
"ref_pages_max": 2,
|
|
22
|
+
},
|
|
23
|
+
"demo": {
|
|
24
|
+
"body_pages_max": 5,
|
|
25
|
+
"ref_pages_max": 2,
|
|
26
|
+
},
|
|
56
27
|
},
|
|
57
28
|
},
|
|
58
29
|
|
|
59
|
-
//
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// Last-page balance is NOT a profile field. It is the optional lint rule pdf/last-page-balance,
|
|
69
|
-
// which a consumer turns on for the papers whose publisher asks (Conference Publishing bounced
|
|
70
|
-
// an accepted paper for it on 08-29: "Please correct the last page balancing") — see
|
|
71
|
-
// docs/optional-rules.md.
|
|
72
|
-
|
|
73
|
-
"columns": 2,
|
|
74
|
-
|
|
75
|
-
// «font size is 9 pt for all body text»
|
|
76
|
-
"body_pt": 9,
|
|
77
|
-
// banal measures the MODE of the rendered text, not the declared size (measured 08-26: 9.30 at
|
|
78
|
-
// acmart's declared 9). Hence the tolerance — and hence why body size stays a nudge, not a gate.
|
|
79
|
-
"body_pt_tol": 0.5,
|
|
80
|
-
|
|
81
|
-
// «font size of the references can be from 7 pt to 9 pt»
|
|
82
|
-
"ref_pt_min": 7,
|
|
83
|
-
"ref_pt_max": 9,
|
|
84
|
-
|
|
85
|
-
// «text must be in serif font (Libertine)»
|
|
86
|
-
"fonts_text": "LinLibertine",
|
|
87
|
-
// «The title must be in sans-serif font (Biolinum)»
|
|
88
|
-
"fonts_title": "LinBiolinum",
|
|
89
|
-
|
|
90
|
-
// The limits are a property of the paper's TYPE at this venue, not of the venue itself.
|
|
91
|
-
// A given paper's type is stated in its <paper-dir>/venue.json.
|
|
92
|
-
"kinds": {
|
|
93
|
-
"short": {
|
|
94
|
-
"body_pages_max": 5,
|
|
95
|
-
// «up to 2 extra pages of references»
|
|
96
|
-
"ref_pages_max": 2,
|
|
97
|
-
},
|
|
98
|
-
"full": {
|
|
99
|
-
// «Full ≤10pp (mature)»
|
|
100
|
-
"body_pages_max": 10,
|
|
101
|
-
"ref_pages_max": 2,
|
|
102
|
-
},
|
|
103
|
-
"demo": {
|
|
104
|
-
"body_pages_max": 5,
|
|
105
|
-
"ref_pages_max": 2,
|
|
106
|
-
},
|
|
30
|
+
// The proceedings are produced by Conference Publishing Consulting — agenticdev.md takes its
|
|
31
|
+
// numbers from their author instructions — which require "balanced columns on the last page, if
|
|
32
|
+
// the page is not filled" and sent an accepted camera-ready back for it on 2026-08-29, the day
|
|
33
|
+
// after AgenticDev's camera-ready deadline ("Please correct the last page balancing"). So every
|
|
34
|
+
// AgenticDev paper gets the optional rule; a paper can still turn it off in its own
|
|
35
|
+
// paperlint.json. 120 pt is the rule's default, measured: the balanced build ended 2.7 pt apart,
|
|
36
|
+
// the returned one 321.4 pt apart (docs/optional-rules.md).
|
|
37
|
+
"rules": {
|
|
38
|
+
"pdf/last-page-balance": ["error", { "tolerancePt": 120 }],
|
|
107
39
|
},
|
|
108
40
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
// AISec @ ACM CCS
|
|
1
|
+
// AISec @ ACM CCS — a VENUE preset over the ACM sigconf family. Data for the `pdf/*` rules over
|
|
2
|
+
// `_build/paper.facts.json`.
|
|
2
3
|
// Prose about the venue and tracks is in `aisec.md` nearby.
|
|
3
4
|
//
|
|
4
5
|
// PAGE LIMITS — verbatim from https://aisec.cc/ (verified 2026-08-26, not from memory):
|
|
@@ -14,88 +15,26 @@
|
|
|
14
15
|
// a 13th page. That's deliberate: the case is rare, and automation that knows "sometimes it's
|
|
15
16
|
// fine" is worse than a plain rejection a human clears by eye.
|
|
16
17
|
//
|
|
17
|
-
// GEOMETRY AND
|
|
18
|
-
//
|
|
19
|
-
//
|
|
18
|
+
// GEOMETRY, FONTS AND TeX PACKAGES come from acm-sigconf.jsonc: AISec points to the "main ACM
|
|
19
|
+
// CCS'26 formatting instructions" and does not publish its own numbers.
|
|
20
|
+
//
|
|
21
|
+
// NO `rules` HERE, on purpose: nothing in aisec.md says who produces the AISec proceedings or
|
|
22
|
+
// whether they require a balanced last page (Sheridan does for CCS itself — docs/optional-rules.md —
|
|
23
|
+
// but that is the main conference). Turn pdf/last-page-balance on in the paper's paperlint.json if
|
|
24
|
+
// the camera-ready instructions ask for it.
|
|
20
25
|
{
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// the rest — pulled in by acmart ITSELF, not by the paper, so reading \usepackage never finds
|
|
34
|
-
// them. Found 2026-09-01 by the loop build → missing file → tlmgr search --file → install.
|
|
35
|
-
"tex": {
|
|
36
|
-
"packages": {
|
|
37
|
-
"acmart": ["acmart.cls"],
|
|
38
|
-
"amscls": ["amsart.cls"],
|
|
39
|
-
"libertine": ["libertine.sty"],
|
|
40
|
-
"inconsolata": ["zi4.sty"],
|
|
41
|
-
"newtx": ["newtxmath.sty"],
|
|
42
|
-
"kastrup": ["binhex.tex"],
|
|
43
|
-
"fancyhdr": ["fancyhdr.sty"],
|
|
44
|
-
"totpages": ["totpages.sty"],
|
|
45
|
-
"environ": ["environ.sty"],
|
|
46
|
-
"preprint": ["balance.sty"],
|
|
47
|
-
// acmart's `pbalance` option (the vendor's first fix for an unbalanced last page, which the
|
|
48
|
-
// optional rule `pdf/last-page-balance` recommends) loads pbalance, which needs filehook and
|
|
49
|
-
// zref. Measured 2026-09-25 on an acmart sigconf camera-ready: without them the option stops
|
|
50
|
-
// the build; with them the last page went from 639.6 / 224.1 to 424.4 / 439.2 pt, same page count.
|
|
51
|
-
"pbalance": ["pbalance.sty"],
|
|
52
|
-
"filehook": ["filehook.sty"],
|
|
53
|
-
"zref": ["zref-abspage.sty"],
|
|
54
|
-
"xstring": ["xstring.sty"],
|
|
55
|
-
"everyshi": ["everyshi.sty"],
|
|
56
|
-
"hyperxmp": ["hyperxmp.sty"],
|
|
57
|
-
"ncctools": ["manyfoot.sty"],
|
|
58
|
-
"cmap": ["cmap.sty"],
|
|
59
|
-
"float": ["float.sty"],
|
|
60
|
-
"comment": ["comment.sty"],
|
|
61
|
-
"upquote": ["upquote.sty"],
|
|
62
|
-
"doclicense": ["doclicense.sty"],
|
|
63
|
-
"textcase": ["textcase.sty"],
|
|
26
|
+
"extends": "paperlint:acm-sigconf",
|
|
27
|
+
|
|
28
|
+
"format": {
|
|
29
|
+
// Four tracks (original research · position/open-problem · SoK · benchmark) — the limits are
|
|
30
|
+
// the SAME for all of them, the venue doesn't split them. The keys are kept separate so a
|
|
31
|
+
// paper's `paperlint.json` can name its own track: not for the numbers, but so it's visible which
|
|
32
|
+
// track it was submitted under.
|
|
33
|
+
"kinds": {
|
|
34
|
+
"research": { "body_pages_max": 10, "ref_pages_max": 2 },
|
|
35
|
+
"benchmark": { "body_pages_max": 10, "ref_pages_max": 2 },
|
|
36
|
+
"position": { "body_pages_max": 10, "ref_pages_max": 2 },
|
|
37
|
+
"sok": { "body_pages_max": 10, "ref_pages_max": 2 },
|
|
64
38
|
},
|
|
65
39
|
},
|
|
66
|
-
|
|
67
|
-
"page_size": "letter",
|
|
68
|
-
"page_w_in": 8.5,
|
|
69
|
-
"page_h_in": 11.0,
|
|
70
|
-
|
|
71
|
-
"textblock_w_in": 7.087,
|
|
72
|
-
"textblock_h_in": 9.252,
|
|
73
|
-
// Last-page balance is NOT a profile field. It is the optional lint rule pdf/last-page-balance,
|
|
74
|
-
// which a consumer turns on for the papers whose publisher asks (Conference Publishing bounced
|
|
75
|
-
// an accepted paper for it on 08-29: "Please correct the last page balancing") — see
|
|
76
|
-
// docs/optional-rules.md.
|
|
77
|
-
|
|
78
|
-
"columns": 2,
|
|
79
|
-
|
|
80
|
-
"body_pt": 9,
|
|
81
|
-
// banal measures the rendered text's mode, not the declared size (measured: 9.30 at a
|
|
82
|
-
// declared 9).
|
|
83
|
-
"body_pt_tol": 0.5,
|
|
84
|
-
|
|
85
|
-
"ref_pt_min": 7,
|
|
86
|
-
"ref_pt_max": 9,
|
|
87
|
-
|
|
88
|
-
"fonts_text": "LinLibertine",
|
|
89
|
-
"fonts_title": "LinBiolinum",
|
|
90
|
-
|
|
91
|
-
// Four tracks (original research · position/open-problem · SoK · benchmark) — the limits are
|
|
92
|
-
// the SAME for all of them, the venue doesn't split them. The keys are kept separate so a
|
|
93
|
-
// paper's `venue.json` can name its own track: not for the numbers, but so it's visible which
|
|
94
|
-
// track it was submitted under.
|
|
95
|
-
"kinds": {
|
|
96
|
-
"research": { "body_pages_max": 10, "ref_pages_max": 2 },
|
|
97
|
-
"benchmark": { "body_pages_max": 10, "ref_pages_max": 2 },
|
|
98
|
-
"position": { "body_pages_max": 10, "ref_pages_max": 2 },
|
|
99
|
-
"sok": { "body_pages_max": 10, "ref_pages_max": 2 },
|
|
100
|
-
},
|
|
101
40
|
}
|
|
@@ -28,54 +28,56 @@
|
|
|
28
28
|
},
|
|
29
29
|
},
|
|
30
30
|
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
"format": {
|
|
32
|
+
"page_size": "a4",
|
|
33
|
+
"page_w_in": 8.27,
|
|
34
|
+
"page_h_in": 11.69,
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
"columns": 2,
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
// ACL's stated body size is 11pt; banal measures the render's mode and gives 11.3.
|
|
39
|
+
"body_pt": 11,
|
|
40
|
+
"body_pt_tol": 0.5,
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
// ⚠️ The range is derived from a SINGLE measurement (10.3), not from ACL's spec — I could not
|
|
43
|
+
// find ACL's own numbers for the reference size. So it's set wide: for an `error`-level rule, a
|
|
44
|
+
// false positive is worse than a miss. Narrow it once a primary source turns up.
|
|
45
|
+
"ref_pt_min": 9,
|
|
46
|
+
"ref_pt_max": 11,
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
// The Times clone from the ACL template. Headings are NOT gated: the build also contains
|
|
49
|
+
// NimbusSanL-Bold, but a `pdffonts` measurement can't establish exactly what the heading is set
|
|
50
|
+
// in — it only says a typeface IS present in the file, not where it's applied.
|
|
51
|
+
"fonts_text": "NimbusRomNo9L",
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
53
|
+
// 🔴 PAGE LIMITS ARE NOT GATED HERE, AND THAT IS A MEASUREMENT, NOT LAZINESS.
|
|
54
|
+
//
|
|
55
|
+
// banal classifies pages by content and counts Limitations and Ethics as part of the BODY.
|
|
56
|
+
// ACL excludes them from the limit. Measured 08-26 on our own paper: banal said "body 13," the
|
|
57
|
+
// build's own counter said "body pages: 9," and both are right — they're just counting
|
|
58
|
+
// different things (the body ends at Conclusion on p.9; pp.10-13 are Limitations/Ethics; the
|
|
59
|
+
// bibliography starts at 14).
|
|
60
|
+
//
|
|
61
|
+
// A gate on banal's number would give 13 against a limit of 8 and would redden on a paper that
|
|
62
|
+
// is within the limit. For an `error`-level rule that is the worst outcome. The limit stays
|
|
63
|
+
// owned by the counter inside `build-submission.sh`: it reads the markdown source and therefore
|
|
64
|
+
// KNOWS where the body ends, which the PDF does not.
|
|
65
|
+
//
|
|
66
|
+
// The numbers below are DATA for that counter and for humans, not an input to the rule. Source:
|
|
67
|
+
// `realm.md`, verified by directly fetching the 2026-08-02/03 CFP.
|
|
68
|
+
"page_limits_not_gated": {
|
|
69
|
+
"_": "8 at submission, 9 at camera-ready (+1 page). Both numbers are CURRENTLY hardcoded in build-submission.sh — 8 in the header, 9 in the run — which reads like a mismatch even though these are different STAGES. The script should pull them from here instead.",
|
|
70
|
+
"long_submission": 8,
|
|
71
|
+
"long_camera_ready": 9,
|
|
72
|
+
"short_submission": 4,
|
|
73
|
+
"short_camera_ready": 5,
|
|
74
|
+
"refs_and_appendices": "unlimited",
|
|
75
|
+
"limitations_and_ethics": "not counted (ACL rule)",
|
|
76
|
+
},
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
"kinds": {
|
|
79
|
+
"long": {},
|
|
80
|
+
"short": {},
|
|
81
|
+
},
|
|
80
82
|
},
|
|
81
83
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// The TeX Live packages EVERY paper gets — and ALL a paper gets when its venue is unknown (no
|
|
2
|
-
//
|
|
2
|
+
// paperlint.json, or a paperlint.json naming a venue with no profile here). A venue's own `tex.packages`
|
|
3
3
|
// is added on top of this set, never instead of it.
|
|
4
4
|
//
|
|
5
5
|
// Read by `paperlint toolchain` (it installs this set plus every venue's) and by `paperlint build` (it checks
|
|
@@ -1,43 +1,121 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"$id": "https://github.com/zernie/paperlint/venue-profile.schema.json",
|
|
4
|
-
"title": "Venue
|
|
5
|
-
"description": "One venue
|
|
4
|
+
"title": "Venue preset",
|
|
5
|
+
"description": "One venue preset or template family (venues/<name>.jsonc), and the TeX base set (venues/tex-base.jsonc). A paper's paperlint.json names one with \"extends\"; a preset may extend another. `format` and `rules` are read by paperlint's pdf/* venue rules and its lint config (src/venue-rules.ts, src/presets.ts); `tex` by `paperlint toolchain` and `paperlint build`.",
|
|
6
6
|
"type": "object",
|
|
7
|
-
"required": ["tex"],
|
|
8
7
|
"additionalProperties": false,
|
|
9
8
|
"properties": {
|
|
10
|
-
"
|
|
9
|
+
"extends": {
|
|
10
|
+
"description": "The preset this one builds on: `paperlint:<name>` (shipped) or a path starting with ./ or ../, relative to this file.",
|
|
11
|
+
"type": "string",
|
|
12
|
+
"minLength": 1
|
|
13
|
+
},
|
|
14
|
+
"name": {
|
|
15
|
+
"description": "A display name for messages; the file name otherwise.",
|
|
16
|
+
"type": "string",
|
|
17
|
+
"minLength": 1
|
|
18
|
+
},
|
|
19
|
+
"tex": {
|
|
20
|
+
"$ref": "#/definitions/tex"
|
|
21
|
+
},
|
|
11
22
|
"template": {
|
|
12
23
|
"description": "The \\documentclass the venue's template uses.",
|
|
13
24
|
"type": "string",
|
|
14
25
|
"minLength": 1
|
|
15
26
|
},
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
"page_h_in": { "type": "number", "exclusiveMinimum": 0 },
|
|
19
|
-
"textblock_w_in": { "type": "number", "exclusiveMinimum": 0 },
|
|
20
|
-
"textblock_h_in": { "type": "number", "exclusiveMinimum": 0 },
|
|
21
|
-
"columns": { "type": "integer", "minimum": 1 },
|
|
22
|
-
"body_pt": { "type": "number", "exclusiveMinimum": 0 },
|
|
23
|
-
"body_pt_tol": { "type": "number", "minimum": 0 },
|
|
24
|
-
"ref_pt_min": { "type": "number", "exclusiveMinimum": 0 },
|
|
25
|
-
"ref_pt_max": { "type": "number", "exclusiveMinimum": 0 },
|
|
26
|
-
"fonts_text": { "type": "string", "minLength": 1 },
|
|
27
|
-
"fonts_title": { "type": "string", "minLength": 1 },
|
|
28
|
-
"page_limits_not_gated": { "type": "object" },
|
|
29
|
-
"kinds": {
|
|
27
|
+
"format": {
|
|
28
|
+
"description": "What the venue's call for papers sets. Every key is optional; a child preset's key replaces its parent's, and a child's kind replaces that kind.",
|
|
30
29
|
"type": "object",
|
|
31
|
-
"additionalProperties":
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
|
|
30
|
+
"additionalProperties": false,
|
|
31
|
+
"properties": {
|
|
32
|
+
"page_size": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"enum": ["letter", "a4"]
|
|
35
|
+
},
|
|
36
|
+
"page_w_in": {
|
|
37
|
+
"type": "number",
|
|
38
|
+
"exclusiveMinimum": 0
|
|
39
|
+
},
|
|
40
|
+
"page_h_in": {
|
|
41
|
+
"type": "number",
|
|
42
|
+
"exclusiveMinimum": 0
|
|
43
|
+
},
|
|
44
|
+
"textblock_w_in": {
|
|
45
|
+
"type": "number",
|
|
46
|
+
"exclusiveMinimum": 0
|
|
47
|
+
},
|
|
48
|
+
"textblock_h_in": {
|
|
49
|
+
"type": "number",
|
|
50
|
+
"exclusiveMinimum": 0
|
|
51
|
+
},
|
|
52
|
+
"columns": {
|
|
53
|
+
"type": "integer",
|
|
54
|
+
"minimum": 1
|
|
55
|
+
},
|
|
56
|
+
"body_pt": {
|
|
57
|
+
"type": "number",
|
|
58
|
+
"exclusiveMinimum": 0
|
|
59
|
+
},
|
|
60
|
+
"body_pt_tol": {
|
|
61
|
+
"type": "number",
|
|
62
|
+
"minimum": 0
|
|
63
|
+
},
|
|
64
|
+
"ref_pt_min": {
|
|
65
|
+
"type": "number",
|
|
66
|
+
"exclusiveMinimum": 0
|
|
67
|
+
},
|
|
68
|
+
"ref_pt_max": {
|
|
69
|
+
"type": "number",
|
|
70
|
+
"exclusiveMinimum": 0
|
|
71
|
+
},
|
|
72
|
+
"fonts_text": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"minLength": 1
|
|
75
|
+
},
|
|
76
|
+
"fonts_title": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"minLength": 1
|
|
79
|
+
},
|
|
80
|
+
"page_limits_not_gated": {
|
|
81
|
+
"type": "object"
|
|
82
|
+
},
|
|
83
|
+
"kinds": {
|
|
84
|
+
"type": "object",
|
|
85
|
+
"additionalProperties": {
|
|
86
|
+
"type": "object",
|
|
87
|
+
"additionalProperties": false,
|
|
88
|
+
"properties": {
|
|
89
|
+
"body_pages_max": {
|
|
90
|
+
"type": "integer",
|
|
91
|
+
"minimum": 1
|
|
92
|
+
},
|
|
93
|
+
"ref_pages_max": {
|
|
94
|
+
"type": "integer",
|
|
95
|
+
"minimum": 0
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
37
99
|
}
|
|
38
100
|
}
|
|
101
|
+
},
|
|
102
|
+
"rules": {
|
|
103
|
+
"description": "Rules the venue implies, rule id \u2192 ESLint entry (a severity, or [severity, options]). Applied to every paper that extends this preset, before the paper's own rules.",
|
|
104
|
+
"type": "object"
|
|
39
105
|
}
|
|
40
106
|
},
|
|
107
|
+
"allOf": [
|
|
108
|
+
{
|
|
109
|
+
"if": {
|
|
110
|
+
"not": {
|
|
111
|
+
"required": ["extends"]
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"then": {
|
|
115
|
+
"required": ["tex"]
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
],
|
|
41
119
|
"definitions": {
|
|
42
120
|
"ctanName": {
|
|
43
121
|
"description": "A package name as tlmgr knows it (CTAN / TeX Live), not a distribution package name.",
|
|
@@ -48,7 +126,11 @@
|
|
|
48
126
|
"type": "array",
|
|
49
127
|
"minItems": 1,
|
|
50
128
|
"uniqueItems": true,
|
|
51
|
-
"items": {
|
|
129
|
+
"items": {
|
|
130
|
+
"type": "string",
|
|
131
|
+
"minLength": 1,
|
|
132
|
+
"pattern": "^[^/\\s]+$"
|
|
133
|
+
}
|
|
52
134
|
},
|
|
53
135
|
"tex": {
|
|
54
136
|
"description": "The TeX Live packages this template needs. Each package maps to the files that PROVE it is present: `kpsewhich` must find every one after an install, or the install failed and says which package.",
|
|
@@ -59,14 +141,22 @@
|
|
|
59
141
|
"packages": {
|
|
60
142
|
"type": "object",
|
|
61
143
|
"minProperties": 1,
|
|
62
|
-
"propertyNames": {
|
|
63
|
-
|
|
144
|
+
"propertyNames": {
|
|
145
|
+
"$ref": "#/definitions/ctanName"
|
|
146
|
+
},
|
|
147
|
+
"additionalProperties": {
|
|
148
|
+
"$ref": "#/definitions/proofs"
|
|
149
|
+
}
|
|
64
150
|
},
|
|
65
151
|
"tools": {
|
|
66
152
|
"description": "Packages that ship a PROGRAM rather than a file LaTeX loads. Proved by an executable of that name in TeX Live's bin directory, not by kpsewhich.",
|
|
67
153
|
"type": "object",
|
|
68
|
-
"propertyNames": {
|
|
69
|
-
|
|
154
|
+
"propertyNames": {
|
|
155
|
+
"$ref": "#/definitions/ctanName"
|
|
156
|
+
},
|
|
157
|
+
"additionalProperties": {
|
|
158
|
+
"$ref": "#/definitions/proofs"
|
|
159
|
+
}
|
|
70
160
|
}
|
|
71
161
|
}
|
|
72
162
|
}
|