paperlint 6.0.0 → 6.2.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/dist/adapters/latex/index.d.ts +1 -1
- package/dist/adapters/latex/index.d.ts.map +1 -1
- package/dist/adapters/latex/index.js +3 -2
- package/dist/adapters/latex/index.js.map +1 -1
- package/dist/adapters/latex/prose.d.ts +6 -1
- package/dist/adapters/latex/prose.d.ts.map +1 -1
- package/dist/adapters/latex/prose.js +142 -31
- package/dist/adapters/latex/prose.js.map +1 -1
- package/dist/adapters/mp4box/index.d.ts +4 -0
- package/dist/adapters/mp4box/index.d.ts.map +1 -0
- package/dist/adapters/mp4box/index.js +46 -0
- package/dist/adapters/mp4box/index.js.map +1 -0
- package/dist/adapters/node/index.d.ts +1 -0
- package/dist/adapters/node/index.d.ts.map +1 -1
- package/dist/adapters/node/index.js +1 -0
- package/dist/adapters/node/index.js.map +1 -1
- package/dist/adapters/node/list-dir.io.d.ts +3 -0
- package/dist/adapters/node/list-dir.io.d.ts.map +1 -0
- package/dist/adapters/node/list-dir.io.js +15 -0
- package/dist/adapters/node/list-dir.io.js.map +1 -0
- package/dist/adapters/png/index.d.ts +11 -0
- package/dist/adapters/png/index.d.ts.map +1 -0
- package/dist/adapters/png/index.js +21 -0
- package/dist/adapters/png/index.js.map +1 -0
- package/dist/adapters/srt/index.d.ts +4 -0
- package/dist/adapters/srt/index.d.ts.map +1 -0
- package/dist/adapters/srt/index.js +12 -0
- package/dist/adapters/srt/index.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +40 -22
- package/dist/cli.js.map +1 -1
- package/dist/domain/register.d.ts +96 -0
- package/dist/domain/register.d.ts.map +1 -0
- package/dist/domain/register.js +136 -0
- package/dist/domain/register.js.map +1 -0
- package/dist/domain/talk.d.ts +121 -0
- package/dist/domain/talk.d.ts.map +1 -0
- package/dist/domain/talk.js +121 -0
- package/dist/domain/talk.js.map +1 -0
- package/dist/domain/tex-document.d.ts +19 -0
- package/dist/domain/tex-document.d.ts.map +1 -1
- package/dist/domain/tex-document.js +8 -3
- package/dist/domain/tex-document.js.map +1 -1
- package/dist/lib/paper-config.d.ts +2 -0
- package/dist/lib/paper-config.d.ts.map +1 -1
- package/dist/lib/paper-config.js +3 -0
- package/dist/lib/paper-config.js.map +1 -1
- package/dist/paper-settings.d.ts +3 -0
- package/dist/paper-settings.d.ts.map +1 -1
- package/dist/paper-settings.js +15 -9
- package/dist/paper-settings.js.map +1 -1
- package/dist/ports/latex.d.ts +6 -1
- package/dist/ports/latex.d.ts.map +1 -1
- package/dist/ports/talk-media.d.ts +18 -0
- package/dist/ports/talk-media.d.ts.map +1 -0
- package/dist/ports/talk-media.js +2 -0
- package/dist/ports/talk-media.js.map +1 -0
- package/dist/presets.d.ts +6 -0
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js +8 -9
- package/dist/presets.js.map +1 -1
- package/dist/register-bands.d.ts +37 -0
- package/dist/register-bands.d.ts.map +1 -0
- package/dist/register-bands.js +196 -0
- package/dist/register-bands.js.map +1 -0
- package/dist/register.d.ts +4 -2
- package/dist/register.d.ts.map +1 -1
- package/dist/register.js +6 -45
- package/dist/register.js.map +1 -1
- package/dist/talk-rules.d.ts +65 -0
- package/dist/talk-rules.d.ts.map +1 -0
- package/dist/talk-rules.js +451 -0
- package/dist/talk-rules.js.map +1 -0
- package/dist/tex-requirements.d.ts +9 -0
- package/dist/tex-requirements.d.ts.map +1 -1
- package/dist/tex-requirements.js +28 -6
- package/dist/tex-requirements.js.map +1 -1
- package/dist/tex-venue-rules.d.ts +1 -1
- package/dist/tex-venue-rules.d.ts.map +1 -1
- package/dist/tex-venue-rules.js.map +1 -1
- package/docs/configuration.md +2 -1
- package/docs/rules/talk/captions-cover.md +47 -0
- package/docs/rules/talk/duration-floor.md +38 -0
- package/docs/rules/talk/duration.md +43 -0
- package/docs/rules/talk/one-slide-size.md +38 -0
- package/docs/rules/talk/profile.md +64 -0
- package/docs/rules/talk/required-files.md +39 -0
- package/docs/rules/talk/undeclared.md +35 -0
- package/docs/rules/talk/video-format.md +43 -0
- package/docs/rules/tex/claim-emphasis.md +71 -0
- package/docs/rules/tex/contrast-frames.md +100 -0
- package/docs/rules/tex/relation-markers.md +72 -0
- package/docs/rules.md +57 -42
- package/docs/talk.md +94 -0
- package/fixtures/talk/audio-only.mp4 +0 -0
- package/fixtures/talk/one-slide.png +0 -0
- package/fixtures/talk/short-audio.mp4 +0 -0
- package/fixtures/talk/talk.mov +0 -0
- package/fixtures/talk/talk.mp4 +0 -0
- package/fixtures/talk/talk.srt +7 -0
- package/lib/paper-config.harness.mjs +5 -2
- package/lib/paper-config.ts +4 -0
- package/package.json +3 -1
- package/presets/agenticdev.jsonc +29 -0
- package/presets/aidc.jsonc +50 -0
- package/presets/venue-profile.schema.json +180 -1
- package/skills/grade-paper-writing/SKILL.md +59 -27
- package/skills/grade-paper-writing/SKILL.md.spec.ts +58 -26
- package/src/adapters/latex/index.test.ts +91 -0
- package/src/adapters/latex/index.ts +3 -2
- package/src/adapters/latex/prose.ts +188 -58
- package/src/adapters/mp4box/index.test.ts +63 -0
- package/src/adapters/mp4box/index.ts +50 -0
- package/src/adapters/node/index.ts +1 -0
- package/src/adapters/node/list-dir.io.ts +15 -0
- package/src/adapters/node/list-dir.test.ts +30 -0
- package/src/adapters/png/index.test.ts +43 -0
- package/src/adapters/png/index.ts +29 -0
- package/src/adapters/srt/index.test.ts +24 -0
- package/src/adapters/srt/index.ts +13 -0
- package/src/cli.test.ts +12 -0
- package/src/cli.ts +50 -21
- package/src/domain/register.test.ts +153 -0
- package/src/domain/register.ts +261 -0
- package/src/domain/talk.test.ts +125 -0
- package/src/domain/talk.ts +274 -0
- package/src/domain/tex-document.ts +37 -3
- package/src/new-paper.test.ts +1 -0
- package/src/paper-settings.test.ts +18 -1
- package/src/paper-settings.ts +21 -11
- package/src/ports/latex.ts +6 -0
- package/src/ports/talk-media.ts +19 -0
- package/src/presets.ts +14 -9
- package/src/register-bands.test.ts +327 -0
- package/src/register-bands.ts +291 -0
- package/src/register.ts +7 -37
- package/src/rule-cases.test.ts +177 -20
- package/src/talk-rules.test.ts +459 -0
- package/src/talk-rules.ts +672 -0
- package/src/tex-requirements.ts +56 -8
- package/src/tex-venue-rules.ts +7 -1
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# tex/relation-markers
|
|
2
|
+
|
|
3
|
+
**Level:** warn · **Reads:** `paper.tex` and the files it includes → `paperlint.json`
|
|
4
|
+
|
|
5
|
+
## What it catches
|
|
6
|
+
|
|
7
|
+
A body that names how its sentences relate less often — or far more often — than the accepted papers
|
|
8
|
+
of its venue. A relation marker is one of: _therefore_, _thus_, _hence_, _consequently_, _as a
|
|
9
|
+
result_, _because_, _since_, _this means_, _this implies_, _which explains_, _in turn_, _that is,_,
|
|
10
|
+
_i.e._, _in contrast_, _by contrast_, _however_, _nevertheless_, _nonetheless_, _whereas_, _in other
|
|
11
|
+
words_, _for this reason_, _it follows_, _accordingly_, _specifically,_, _in particular,_, _for
|
|
12
|
+
example_, _for instance_, _e.g._ — as whole words, anywhere in a sentence. Counted per 10,000 words of
|
|
13
|
+
the body.
|
|
14
|
+
|
|
15
|
+
Outside the band it reports once, at the start of the body, with the count, the rate, the band and
|
|
16
|
+
the anchors' range. A body under 2 000 words, or a paper whose preset records no anchors, is not
|
|
17
|
+
judged.
|
|
18
|
+
|
|
19
|
+
This is the FLOOR among the register checks: [`tex/contrast-frames`](contrast-frames.md) and
|
|
20
|
+
[`tex/claim-emphasis`](claim-emphasis.md) catch a device used too often; this one catches the
|
|
21
|
+
relation left for the reader to infer, which is what a rewrite that only deletes devices leaves
|
|
22
|
+
behind.
|
|
23
|
+
|
|
24
|
+
## Why
|
|
25
|
+
|
|
26
|
+
A reviewer wrote: _"Readers are often required to infer the intended relationships between claims."_
|
|
27
|
+
Measured on the LaTeX source, per 10,000 words:
|
|
28
|
+
|
|
29
|
+
| paper | words | markers | per 10,000 |
|
|
30
|
+
| ------------------------------------------------------- | ----: | ------: | ---------: |
|
|
31
|
+
| `rr-dataset-quality-acsac24` (ACSAC 2024) | 8130 | 32 | 39.4 |
|
|
32
|
+
| `barovox-acsac24` (ACSAC 2024) | 7670 | 31 | 40.4 |
|
|
33
|
+
| `secure-acsac24` (ACSAC 2024) | 7519 | 38 | 50.5 |
|
|
34
|
+
| `llm-splained-acsac25` (ACSAC 2025) | 9529 | 84 | 88.2 |
|
|
35
|
+
| `leaking-queries-acsac25` (ACSAC 2025) | 9133 | 103 | 112.8 |
|
|
36
|
+
| the paper reviewers called a blog post, current version | 10476 | 20 | 19.1 |
|
|
37
|
+
| the same paper, before its rewrite | 6128 | 9 | 14.7 |
|
|
38
|
+
| `agenticdev-acm26` (ours, "too informal", ACM) | 4374 | 13 | 29.7 |
|
|
39
|
+
|
|
40
|
+
_However_ alone stands 6–11 times in every accepted paper and never in the current version of ours. The
|
|
41
|
+
separation survives dropping any one marker from the list: with each of the 24 that occur removed in
|
|
42
|
+
turn, the lowest accepted paper stays at least 1.38 times the highest version of ours (the worst case
|
|
43
|
+
is dropping _however_). The list was fixed before this
|
|
44
|
+
corpus was measured (it is the one a register diagnosis of the same papers used, on text extracted
|
|
45
|
+
from PDFs, where the gap was narrow); on the parse tree the gap is twofold.
|
|
46
|
+
|
|
47
|
+
## Examples
|
|
48
|
+
|
|
49
|
+
```latex
|
|
50
|
+
Most guards match words. 24 of 46 block a harmless echo. % the relation is left to infer
|
|
51
|
+
Because most guards match words, 24 of 46 block a harmless echo. % named
|
|
52
|
+
Most guards match words; as a result, 24 of 46 block a harmless echo. % named
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Options / preset fields
|
|
56
|
+
|
|
57
|
+
No rule options. The band is the venue preset's `register.anchors`, exactly as for
|
|
58
|
+
[`tex/contrast-frames`](contrast-frames.md), which explains how it is derived. For `paperlint:aidc` it
|
|
59
|
+
is **25.4–135.0**.
|
|
60
|
+
|
|
61
|
+
## What it does not check
|
|
62
|
+
|
|
63
|
+
Whether a marker names the right relation, or a relation named another way (_this is why_, _so that_,
|
|
64
|
+
a colon). The list counts only words whose meaning does not depend on context; _since_ is on it and
|
|
65
|
+
is sometimes temporal.
|
|
66
|
+
|
|
67
|
+
## How to fix
|
|
68
|
+
|
|
69
|
+
Where two sentences stand side by side, say whether the second is the cause, the consequence, an
|
|
70
|
+
example or a limit of the first — with the word, not with a dash, a colon or a short sentence left to
|
|
71
|
+
land the point. The fix adds words; pay for them by moving detail to a table or the appendix, not by
|
|
72
|
+
cutting the connectives from another paragraph.
|
package/docs/rules.md
CHANGED
|
@@ -3,36 +3,47 @@
|
|
|
3
3
|
The README lists what each check catches in one line. This page says exactly which file each one
|
|
4
4
|
reads and when it fails. Errors fail `paperlint lint`; warnings print and do not.
|
|
5
5
|
|
|
6
|
-
| Rule | Level | Reads
|
|
7
|
-
| ----------------------------------------------------------- | ----- |
|
|
8
|
-
| `paper/stages` | error | `PIPELINE-STATUS.md`
|
|
9
|
-
| `paper/source` | error | `PIPELINE-STATUS.md`
|
|
10
|
-
| `paper/author-list` | error | `paper.tex` → `_build/references.json`
|
|
11
|
-
| `paper/section-word` | warn | `paper.tex` and its body files, `paper.md`
|
|
12
|
-
| `paper/leading-zero` | warn | `paper.tex` and its body files, `paper.md`
|
|
13
|
-
| `paper/figure-ref-style` | warn | `paper.tex` and its body files
|
|
14
|
-
| `bib/reachable-entry` | warn | `paper.tex` (its `filecontents` bibliography)
|
|
15
|
-
| `paper/cite-exists` | error | `paper.tex` → `_build/references.json`
|
|
16
|
-
| `paper/refs-fresh` | error | `paper.tex` → `_build/references.json`
|
|
17
|
-
| `paper/refs-checked` | warn | `paper.tex` → `_build/references.json`
|
|
18
|
-
| `tex/future-promise` | warn | `paper.tex` and its body files
|
|
19
|
-
| `tex/acm-frontmatter-override` | error | `paper.tex`
|
|
20
|
-
| [`tex/template`](rules/tex/template.md) | error | `paper.tex` → `paperlint.json`
|
|
21
|
-
| [`tex/required-section`](rules/tex/required-section.md) | error | `paper.tex` → `paperlint.json`
|
|
22
|
-
| [`format/layout-override`](rules/format/layout-override.md) | error | `paper.tex` → `paperlint.json`
|
|
23
|
-
| [`anonymity/identity`](rules/anonymity/identity.md) | error | `paper.tex` → `_build/paper.facts.json`
|
|
24
|
-
| [`tex/venue-leftover`](rules/tex/venue-leftover.md) | warn | `paper.tex` → `paperlint.json`
|
|
25
|
-
| [`tex/claim-provenance`](rules/tex/claim-provenance.md) | warn | `paper.tex`
|
|
26
|
-
| [`tex/register`](rules/tex/register.md) | warn | `paper.tex` and the files it includes
|
|
27
|
-
| `
|
|
28
|
-
| `
|
|
29
|
-
| `
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
32
|
-
| `pdf/
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
| `pdf/
|
|
6
|
+
| Rule | Level | Reads | Fails when |
|
|
7
|
+
| ----------------------------------------------------------- | ----- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
8
|
+
| `paper/stages` | error | `PIPELINE-STATUS.md` | a declared stage's PDF is missing, or the `bytes:` it names does not match the file's real size, or a frozen PDF exists that no stage declares |
|
|
9
|
+
| `paper/source` | error | `PIPELINE-STATUS.md` | a declared stage has no frozen `.tex` beside its PDF (a commit hash does not count — squash and gc destroy it) |
|
|
10
|
+
| `paper/author-list` | error | `paper.tex` → `_build/references.json` | an entry's authors are not those of the version it cites — typically the arXiv preprint's list under a published venue. Checked online by `paperlint build` (DBLP), reported on the entry's own line |
|
|
11
|
+
| `paper/section-word` | warn | `paper.tex` and its body files, `paper.md` | `§` or `\S\ref` instead of the word Section. **Fixable:** `--fix` writes `Section~\ref{…}` / `Section 5` |
|
|
12
|
+
| `paper/leading-zero` | warn | `paper.tex` and its body files, `paper.md` | a decimal below 1 without its leading zero (`.05` instead of `0.05`, IEEE / ISO 80000-1 style), counted only where the reader sees it — prose, math and table cells, not macro options, column specs, comments, code or tikz. A number right after `¶` or `§` (`¶¶.42`) is a paragraph designator and is not reported; in a paragraph that cites numbers that way, another bare decimal is reported without a fix, with the zero as a suggestion. **Fixable** |
|
|
13
|
+
| `paper/figure-ref-style` | warn | `paper.tex` and its body files | `Fig.~\ref` and `Figure~\ref` mixed in one document; each minority occurrence is reported. **Fixable:** `--fix` writes the majority form |
|
|
14
|
+
| `bib/reachable-entry` | warn | `paper.tex` (its `filecontents` bibliography) | an entry has no doi, url or arXiv id — a reader has nothing to follow. Reported on the entry; no fix, the link has to be looked up |
|
|
15
|
+
| `paper/cite-exists` | error | `paper.tex` → `_build/references.json` | an entry's doi or arXiv id resolves to nothing, or to a different work. Checked online by `paperlint build`; a work that was merely not found is not a finding |
|
|
16
|
+
| `paper/refs-fresh` | error | `paper.tex` → `_build/references.json` | the bibliography changed since the build checked it (its SHA-256 differs) — run `npx paperlint build` |
|
|
17
|
+
| `paper/refs-checked` | warn | `paper.tex` → `_build/references.json` | the paper has a bibliography and no build has checked it, or the last build could not (no network) — so the two rules above did not run |
|
|
18
|
+
| `tex/future-promise` | warn | `paper.tex` and its body files | a camera-ready build still says "will be released" about something already handed over |
|
|
19
|
+
| `tex/acm-frontmatter-override` | error | `paper.tex` | an `acmart` build overrides ACM's front-matter commands and drops template elements from page 1 |
|
|
20
|
+
| [`tex/template`](rules/tex/template.md) | error | `paper.tex` → `paperlint.json` | the `\documentclass` is not the preset's `template` class, or lacks an option it names — [page](rules/tex/template.md) |
|
|
21
|
+
| [`tex/required-section`](rules/tex/required-section.md) | error | `paper.tex` → `paperlint.json` | a section the preset requires (AIDC: «LLM Usage Statement», last) is missing or not where it must be — [page](rules/tex/required-section.md) |
|
|
22
|
+
| [`format/layout-override`](rules/format/layout-override.md) | error | `paper.tex` → `paperlint.json` | the source changes the page layout the venue's template sets for the whole document — `geometry`, a layout `\setlength`, `\linespread`, `\baselinestretch` — [page](rules/format/layout-override.md) |
|
|
23
|
+
| [`anonymity/identity`](rules/anonymity/identity.md) | error | `paper.tex` → `_build/paper.facts.json` | a double-blind venue (`"blind": true`) and no `identity` declared, or a declared name, handle, email or project in the PDF's text, metadata or link targets — [page](rules/anonymity/identity.md) |
|
|
24
|
+
| [`tex/venue-leftover`](rules/tex/venue-leftover.md) | warn | `paper.tex` → `paperlint.json` | the text names another shipped venue than the one the paper extends («Submission to VenueA 2026» in a paper now set for VenueB) — [page](rules/tex/venue-leftover.md) |
|
|
25
|
+
| [`tex/claim-provenance`](rules/tex/claim-provenance.md) | warn | `paper.tex` | a sentence of the body states a number and does not say whose it is — no citation or link, no _we_/_our_, no `\ref` or "Table 2", no sample ("n = 134", "48 runs") — [page](rules/tex/claim-provenance.md) |
|
|
26
|
+
| [`tex/register`](rules/tex/register.md) | warn | `paper.tex` and the files it includes | the body runs to a post's register: more than 0.8 sentences per 1000 words open with _And_, _So_, _But_, _Nor_, _Or_ or _Yet_ — the limit is an option — [page](rules/tex/register.md) |
|
|
27
|
+
| [`tex/contrast-frames`](rules/tex/contrast-frames.md) | warn | `paper.tex` and the files it includes → `paperlint.json` | contrast frames (_X, not Y_, _not X but Y_, _rather than_, _instead of_, _as opposed to_) per 10,000 words fall outside the band the venue preset's anchors set (AIDC: 0–10.4, from five accepted ACSAC papers); above it, each frame is reported too — [page](rules/tex/contrast-frames.md) |
|
|
28
|
+
| [`tex/claim-emphasis`](rules/tex/claim-emphasis.md) | warn | `paper.tex` and the files it includes → `paperlint.json` | claims set in bold inside a sentence (six words or more, or holding a number; not a term, not a label opening a paragraph) per 10,000 words fall outside the preset's band (AIDC: 0–17.8); above it, each is reported too — [page](rules/tex/claim-emphasis.md) |
|
|
29
|
+
| [`tex/relation-markers`](rules/tex/relation-markers.md) | warn | `paper.tex` and the files it includes → `paperlint.json` | words that name how a sentence relates to the one before (_because_, _therefore_, _however_, _for example_ …) per 10,000 words fall outside the preset's band (AIDC: 25.4–135.0) — the floor that catches relations left to infer — [page](rules/tex/relation-markers.md) |
|
|
30
|
+
| `review/frontmatter` | error | `reviews/*.md` | the review's frontmatter fails paperlint's JSON Schema — a `findings` record without `id`/`status`, an unknown field, or an **open** finding with no `cause` (`skill-defect` · `missing-skill` · `hook` · `rule`). A review with no `findings` key is not checked for findings |
|
|
31
|
+
| `sibling/frontmatter` | warn | `siblings/*.md` (not `README.md`) | a sibling card's frontmatter has no `read:` saying how much of the competing paper was read (`full` · `abstract` · `none`) |
|
|
32
|
+
| `pdf/fresh` | error | `paper.tex` → `_build/paper.facts.json` | the paper names a venue and the facts cannot be judged: not JSON, a schema other than 3, or they describe a PDF that is gone or differs from the one on disk (its SHA-256) |
|
|
33
|
+
| `pdf/profile` | error | `paper.tex` → `paperlint.json` | `paperlint.json` is not JSON or has an unknown key, its `extends` does not resolve (not found, a cycle, a chain longer than four, a preset that fails the schema, an npm name), it names no `kind` while the preset has kinds, or names a kind the preset does not have |
|
|
34
|
+
| `pdf/fonts` | error | `paper.tex` → `_build/paper.facts.json` | a font the pages draw is Type 3 or not embedded, or no font starts with the family the venue preset names for body text (`fonts_text`) or headings (`fonts_title`) |
|
|
35
|
+
| `pdf/geometry` | error | `paper.tex` → `_build/paper.facts.json` | the page width or height is more than `dimTol` (default 0.05 in) off the preset's, or the column count differs |
|
|
36
|
+
| [`format/page-limit`](rules/format/page-limit.md) | error | `paper.tex` → `_build/paper.facts.json` | body or reference pages exceed the limits of the paper's kind. With `body_ends_at: "references"` (AIDC) the body ends at the references or the appendix, whichever comes first — found by hyperref's anchors, then the heading line — and the page it ends on counts when body text stands above the heading; an end it cannot find, or signals that disagree, are reported — [page](rules/format/page-limit.md) |
|
|
37
|
+
| [`pdf/body-size`](rules/pdf/body-size.md) | error | `paper.tex` → `_build/paper.facts.json` | the body font size is more than `body_pt_tol` off the preset's, or the reference font size is outside the preset's range widened by `body_pt_tol`. banal reads 0.3 pt above the size the glyphs are set in; checked on five built accepted papers (none reported) and three variants one size off (each reported) — [page](rules/pdf/body-size.md) |
|
|
38
|
+
| `pdf/measured` | warn | `paper.tex` → `_build/paper.facts.json` | the paper's `paperlint.json` names no venue preset yet; or it names one and there are no facts (it was not built), or the facts carry no page geometry (banal was not found) — so the checks above did not run |
|
|
39
|
+
| [`talk/profile`](rules/talk/profile.md) | error | `paper.tex` → `paperlint.json` | the paper declares `talk` and names no preset, the preset has no `talk` block, the mode is not one the venue allows, or the venue sets no talk slot for the paper's kind — [page](rules/talk/profile.md) |
|
|
40
|
+
| [`talk/required-files`](rules/talk/required-files.md) | error | `paper.tex` → `paperlint.json`, the talk folder | a file the venue requires for the paper's talk mode (video, one-slide, captions…) is not in the talk folder — [page](rules/talk/required-files.md) |
|
|
41
|
+
| [`talk/undeclared`](rules/talk/undeclared.md) | warn | `paper.tex` → the paper's `talk/` folder | an `.mp4` sits in `talk/` and the paper declares no `talk`, so nothing checks it — [page](rules/talk/undeclared.md) |
|
|
42
|
+
| [`talk/duration`](rules/talk/duration.md) | error | `paper.tex` → the talk video | the video runs longer than the slot's `talk_s_max`, or its audio track is more than 1 s off the video's length — [page](rules/talk/duration.md) |
|
|
43
|
+
| [`talk/duration-floor`](rules/talk/duration-floor.md) | warn | `paper.tex` → the talk video | the video runs shorter than the slot's `talk_s_min` — [page](rules/talk/duration-floor.md) |
|
|
44
|
+
| [`talk/video-format`](rules/talk/video-format.md) | error | `paper.tex` → the talk video | the video is not ISO media, is QuickTime where the venue asks for MP4, is under `min_height_px`, or over `max_bytes` — [page](rules/talk/video-format.md) |
|
|
45
|
+
| [`talk/one-slide-size`](rules/talk/one-slide-size.md) | error | `paper.tex` → the one-slide PNG | the one-slide image is not the size the paper or the preset states, or not a PNG — [page](rules/talk/one-slide-size.md) |
|
|
46
|
+
| [`talk/captions-cover`](rules/talk/captions-cover.md) | warn | `paper.tex` → the captions and the video | the captions start late, end early or leave a long gap (uncalibrated thresholds) — [page](rules/talk/captions-cover.md) |
|
|
36
47
|
|
|
37
48
|
**Body files** are the files `paper.tex` includes from its document body (`\input`, `\include`,
|
|
38
49
|
`\subfile`, nested ones too), found in the paper's directory — not a preamble include, not a file
|
|
@@ -45,6 +56,9 @@ that names no file is printed as a note: lint did not read it, and the build wil
|
|
|
45
56
|
LLMs are used», which no rule can know; an author who used none says so in the section
|
|
46
57
|
([page](rules/tex/required-section.md)).
|
|
47
58
|
|
|
59
|
+
The `talk/*` rules judge a talk's finished files and are silent for a paper that declares no
|
|
60
|
+
`talk` (but `talk/undeclared`): [`talk.md`](talk.md).
|
|
61
|
+
|
|
48
62
|
Optional rules — off unless you turn them on in the `rules` setting, because only some venues need
|
|
49
63
|
them — are on their own page: [`optional-rules.md`](optional-rules.md). Today there is one,
|
|
50
64
|
`pdf/last-page-balance`.
|
|
@@ -202,21 +216,22 @@ papers/
|
|
|
202
216
|
|
|
203
217
|
The numbers and packages above illustrate the shape; take yours from the venue's own call for papers and template.
|
|
204
218
|
|
|
205
|
-
| key | what it is
|
|
206
|
-
| ------------------- |
|
|
207
|
-
| `extends` | the preset this one builds on: `paperlint:<name>` or `./path` / `../path`, relative to this file
|
|
208
|
-
| `name` | how messages name the venue; the file name otherwise
|
|
209
|
-
| `template` | the `\documentclass` the venue's template uses — a whole line (`\documentclass[conference,compsoc]{IEEEtran}`) or a bare class name; `tex/template` requires the paper's class and every option named here
|
|
210
|
-
| `aliases` | other names the venue goes by in a paper's text — its acronym, its parent conference: `["AISec", "ACM CCS"]`. Collected along `extends`, with `name`. Read by `tex/venue-leftover`
|
|
211
|
-
| `blind` | the venue reviews double-blind — set only where its call says so, with the quote. Turns on `anonymity/identity`; a child's value replaces its parent's
|
|
212
|
-
| `required_sections` | sections the venue requires, `[{ "title": "LLM Usage Statement", "position": "last" }]`: the exact title, and `last` when it must close the paper. Read by `tex/required-section`; a child's list replaces its parent's
|
|
213
|
-
| `format` | page size, columns, fonts, font sizes, and `kinds` (page limits per kind of paper)
|
|
214
|
-
| `tex` | TeX Live packages, each with the files that prove it is installed. Required unless `extends` is set
|
|
215
|
-
| `rules` | rules the venue implies, rule id → severity or `[severity, options]`
|
|
219
|
+
| key | what it is |
|
|
220
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
221
|
+
| `extends` | the preset this one builds on: `paperlint:<name>` or `./path` / `../path`, relative to this file |
|
|
222
|
+
| `name` | how messages name the venue; the file name otherwise |
|
|
223
|
+
| `template` | the `\documentclass` the venue's template uses — a whole line (`\documentclass[conference,compsoc]{IEEEtran}`) or a bare class name; `tex/template` requires the paper's class and every option named here |
|
|
224
|
+
| `aliases` | other names the venue goes by in a paper's text — its acronym, its parent conference: `["AISec", "ACM CCS"]`. Collected along `extends`, with `name`. Read by `tex/venue-leftover` |
|
|
225
|
+
| `blind` | the venue reviews double-blind — set only where its call says so, with the quote. Turns on `anonymity/identity`; a child's value replaces its parent's |
|
|
226
|
+
| `required_sections` | sections the venue requires, `[{ "title": "LLM Usage Statement", "position": "last" }]`: the exact title, and `last` when it must close the paper. Read by `tex/required-section`; a child's list replaces its parent's |
|
|
227
|
+
| `format` | page size, columns, fonts, font sizes, and `kinds` (page limits per kind of paper) |
|
|
228
|
+
| `tex` | TeX Live packages, each with the files that prove it is installed. Required unless `extends` is set |
|
|
229
|
+
| `rules` | rules the venue implies, rule id → severity or `[severity, options]` |
|
|
230
|
+
| `register` | `{ "anchors": [{ "paper", "words", "contrast_frames", "claim_emphasis", "relation_markers" }] }`: accepted papers of the venue (or its parent conference) as the register rules count them. Each measure's band is the anchors' range widened by two Poisson standard deviations — [page](rules/tex/contrast-frames.md#options--preset-fields). Read by `tex/contrast-frames`, `tex/claim-emphasis`, `tex/relation-markers`; a child's block replaces its parent's |
|
|
216
231
|
|
|
217
232
|
How a chain merges, from the root preset to the paper: `tex` is the union — a child never removes a
|
|
218
233
|
package; `format` keys are replaced one by one, and a child's kind replaces that kind whole;
|
|
219
|
-
`rules` are replaced rule by rule, and the paper's own `rules` come last. A chain is at most four
|
|
234
|
+
`rules` are replaced rule by rule, and the paper's own `rules` come last; `register` is replaced whole. A chain is at most four
|
|
220
235
|
presets long, and a cycle is refused by name. `paperlint toolchain` installs the packages of every
|
|
221
236
|
shipped preset and of every preset your papers extend.
|
|
222
237
|
|
package/docs/talk.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# The talk
|
|
2
|
+
|
|
3
|
+
A venue that accepts a paper usually asks for a talk too: a video for a remote presenter, a
|
|
4
|
+
one-slide image, sometimes captions. paperlint does not make the talk. It **judges the finished
|
|
5
|
+
files** against what the venue asks, so the same check works whether the video came from Keynote,
|
|
6
|
+
OBS, Zoom, a script, or by hand.
|
|
7
|
+
|
|
8
|
+
## Declaring a talk
|
|
9
|
+
|
|
10
|
+
The paper's own `paperlint.json` says how it is presented:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"extends": "paperlint:agenticdev",
|
|
15
|
+
"kind": "short",
|
|
16
|
+
"talk": { "mode": "remote-video" }
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
| key | meaning | default |
|
|
21
|
+
| ----------- | -------------------------------------------------------------------------------------------- | --------- |
|
|
22
|
+
| `mode` | `remote-video`, `remote-live` or `in-person` — must be one the venue allows | required |
|
|
23
|
+
| `dir` | the talk folder, relative to the paper | `talk` |
|
|
24
|
+
| `files` | the file name of each artifact in that folder, when it is not the default (no slashes) | see below |
|
|
25
|
+
| `one_slide` | `{ "width_px": 1920, "height_px": 1080 }` — the one-slide's size, when the venue states none | none |
|
|
26
|
+
|
|
27
|
+
`talk` is a paper's setting: the root `paperlint.json` refuses it.
|
|
28
|
+
|
|
29
|
+
**File names.** Each artifact is looked for under one name in the talk folder:
|
|
30
|
+
|
|
31
|
+
| artifact | default name |
|
|
32
|
+
| ------------ | --------------- |
|
|
33
|
+
| `video` | `talk.mp4` |
|
|
34
|
+
| `one-slide` | `one-slide.png` |
|
|
35
|
+
| `captions` | `talk.srt` |
|
|
36
|
+
| `slides-pdf` | `slides.pdf` |
|
|
37
|
+
| `poster` | `poster.pdf` |
|
|
38
|
+
|
|
39
|
+
A video named after the paper is declared once:
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
"talk": {
|
|
43
|
+
"mode": "remote-video",
|
|
44
|
+
"files": { "video": "agenticdev-2026-talk.mp4", "captions": "agenticdev-2026-talk.srt" }
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## What the venue says — the preset's `talk` block
|
|
49
|
+
|
|
50
|
+
```jsonc
|
|
51
|
+
"talk": {
|
|
52
|
+
"modes": ["remote-video"],
|
|
53
|
+
"artifacts": { "remote-video": { "required": ["video", "one-slide"], "optional": ["poster"] } },
|
|
54
|
+
"kinds": { "short": { "slot_s": 600, "talk_s_min": 360, "talk_s_max": 420, "qa_s": 210 } },
|
|
55
|
+
"video": { "container": "mp4", "min_height_px": 720, "max_bytes": 500000000, "captions": "optional" },
|
|
56
|
+
"one_slide": { "width_px": 1920, "height_px": 1080 }
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Every key is optional. Durations are seconds. `kinds` uses the names of `format.kinds`, and the
|
|
61
|
+
paper's `kind` picks one. `video.captions: "required"` adds the captions to the files the video's
|
|
62
|
+
mode owes. A child preset's `talk` block replaces its parent's whole. The shipped `agenticdev`
|
|
63
|
+
preset carries the organizers' numbers, each quoted beside it; it states no one-slide size, because
|
|
64
|
+
the venue did not.
|
|
65
|
+
|
|
66
|
+
## What is checked
|
|
67
|
+
|
|
68
|
+
All rules run on the paper's `paper.tex` and are silent for a paper that declares no `talk`, except
|
|
69
|
+
`talk/undeclared`.
|
|
70
|
+
|
|
71
|
+
| rule | level | fails when |
|
|
72
|
+
| ----------------------------------------------------- | ----- | ----------------------------------------------------------------------------------------------- |
|
|
73
|
+
| [`talk/profile`](rules/talk/profile.md) | error | no preset, a preset with no `talk` block, a mode the venue does not allow, no slot for the kind |
|
|
74
|
+
| [`talk/required-files`](rules/talk/required-files.md) | error | a file the venue requires for the mode is not in the talk folder |
|
|
75
|
+
| [`talk/undeclared`](rules/talk/undeclared.md) | warn | an `.mp4` sits in `talk/` and the paper declares no `talk` |
|
|
76
|
+
| [`talk/duration`](rules/talk/duration.md) | error | the video runs longer than `talk_s_max`, or its audio track is more than 1 s off its length |
|
|
77
|
+
| [`talk/duration-floor`](rules/talk/duration-floor.md) | warn | the video runs shorter than `talk_s_min` |
|
|
78
|
+
| [`talk/video-format`](rules/talk/video-format.md) | error | not an MP4 (QuickTime inside, or not ISO media at all), under `min_height_px`, over `max_bytes` |
|
|
79
|
+
| [`talk/one-slide-size`](rules/talk/one-slide-size.md) | error | the one-slide PNG is not the declared size |
|
|
80
|
+
| [`talk/captions-cover`](rules/talk/captions-cover.md) | warn | the captions start late, end early, or leave a long gap (thresholds uncalibrated) |
|
|
81
|
+
|
|
82
|
+
The video is read with [MP4Box.js](https://github.com/gpac/mp4box.js) — the container's own
|
|
83
|
+
headers, in JavaScript, in milliseconds. There is no ffmpeg anywhere in paperlint and no build step
|
|
84
|
+
for the talk.
|
|
85
|
+
|
|
86
|
+
## What is not checked
|
|
87
|
+
|
|
88
|
+
- **What the talk says.** Whether the video matches the paper, its tone, its claims, the QR code on
|
|
89
|
+
a slide — those need a reader, not a count.
|
|
90
|
+
- **How it was made.** A script, slides, a voice recording, cut points: paperlint never sees them,
|
|
91
|
+
and nothing here requires them to exist.
|
|
92
|
+
- **Deadlines and upload channels.** A deadline is a clock condition; it belongs in a calendar.
|
|
93
|
+
- **Whether the file was sent.** Freezing what was sent is not part of the talk rules yet.
|
|
94
|
+
- **Codecs, frame rate, bitrate, loudness.** Only the container, the height and the byte size.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -200,11 +200,14 @@ const loaded = await Promise.all(
|
|
|
200
200
|
// refuses any key not in SETTINGS_KEYS. So the list must hold every key some reader reads — or a
|
|
201
201
|
// consumer's valid key is refused — and nothing no one reads. The readers are FOUND, by the AST:
|
|
202
202
|
// every `settingsOf(root)?.<key>` (and the older `[CONFIG_KEY]?.<key>` shape), plus every field of
|
|
203
|
-
// `PaperlintConfig`, the
|
|
203
|
+
// `PaperlintConfig` and `PaperSettings`, the typed views of the root's and a paper's object.
|
|
204
204
|
{
|
|
205
205
|
const { SETTINGS_KEYS } = await import(join(HERE, "paper-config.ts"));
|
|
206
206
|
const ts = (await import("typescript")).default;
|
|
207
207
|
const readKeys = new Set();
|
|
208
|
+
// The two typed views of the object: the root file's (`PaperlintConfig`, cli.ts) and a paper's
|
|
209
|
+
// (`PaperSettings`, src/paper-settings.ts). A key only a paper may hold (`talk`) is read there.
|
|
210
|
+
const TYPED_VIEWS = ["PaperlintConfig", "PaperSettings"];
|
|
208
211
|
const isConfigKey = (e) =>
|
|
209
212
|
(ts.isIdentifier(e) && e.text === "CONFIG_KEY") ||
|
|
210
213
|
(ts.isStringLiteral(e) && e.text === "paperlint");
|
|
@@ -217,7 +220,7 @@ const loaded = await Promise.all(
|
|
|
217
220
|
const visit = (node) => {
|
|
218
221
|
if (ts.isPropertyAccessExpression(node) && isSettings(node.expression))
|
|
219
222
|
readKeys.add(node.name.text);
|
|
220
|
-
if (ts.isInterfaceDeclaration(node) && node.name.text
|
|
223
|
+
if (ts.isInterfaceDeclaration(node) && TYPED_VIEWS.includes(node.name.text))
|
|
221
224
|
for (const m of node.members)
|
|
222
225
|
if (m.name && ts.isIdentifier(m.name)) readKeys.add(m.name.text);
|
|
223
226
|
ts.forEachChild(node, visit);
|
package/lib/paper-config.ts
CHANGED
|
@@ -140,6 +140,7 @@ export const SETTINGS_KEYS: Readonly<Record<string, string>> = Object.freeze({
|
|
|
140
140
|
pdf: "where the built PDF is, relative to the paper, when it is not paper.pdf — the facts",
|
|
141
141
|
identity:
|
|
142
142
|
"what identifies the authors — names, handles, emails, affiliations, own project names; a blind venue's PDF must not say any of them — anonymity/identity. The root's list and a paper's are joined",
|
|
143
|
+
talk: 'how this paper is presented: { "mode": "remote-video", "dir"?, "files"?, "one_slide"? } — the talk/ rules. A paper\'s own; refused in the root file',
|
|
143
144
|
scripts: "how skill prose names the scripts — consumer.mjs",
|
|
144
145
|
timezone: "the zone deadline anchors are written in — consumer.mjs",
|
|
145
146
|
contactEmail: "the polite-pool address for citation lookups — consumer.mjs",
|
|
@@ -148,6 +149,9 @@ export const SETTINGS_KEYS: Readonly<Record<string, string>> = Object.freeze({
|
|
|
148
149
|
$comment: "a note for humans (JSON Schema's own comment keyword); ignored",
|
|
149
150
|
});
|
|
150
151
|
|
|
152
|
+
/** The keys that only mean something for one paper: refused in the root `paperlint.json`. */
|
|
153
|
+
export const PAPER_ONLY_KEYS: readonly string[] = Object.freeze(["talk"]);
|
|
154
|
+
|
|
151
155
|
/** The keys that only mean something for the whole project: refused in a paper's `paperlint.json`. */
|
|
152
156
|
export const ROOT_ONLY_KEYS: readonly string[] = Object.freeze([
|
|
153
157
|
"papersDir",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "paperlint",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"description": "A linter for scientific papers written in LaTeX: catches mistakes before you submit to a conference or journal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,7 +27,9 @@
|
|
|
27
27
|
"eslint": "^10.9.1",
|
|
28
28
|
"js-yaml": "^4.1.0",
|
|
29
29
|
"markdown-it": "^14.3.0",
|
|
30
|
+
"mp4box": "^2.4.1",
|
|
30
31
|
"remeda": "^2.50.0",
|
|
32
|
+
"srt-parser-2": "^1.2.3",
|
|
31
33
|
"ts-essentials": "^10.2.1",
|
|
32
34
|
"typescript": "^6.0.3",
|
|
33
35
|
"unpdf": "^1.8.1",
|
package/presets/agenticdev.jsonc
CHANGED
|
@@ -31,6 +31,35 @@
|
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
33
|
|
|
34
|
+
// The talk (talk/* rules), for a paper whose paperlint.json declares `talk`. The numbers are the
|
|
35
|
+
// organizers', each with its source; one_slide is left out on purpose — the venue never stated a
|
|
36
|
+
// size, so a paper that wants its own checked declares it in its own `talk` key.
|
|
37
|
+
"talk": {
|
|
38
|
+
// AgenticDev adopted ASE's «not in person presentation» policy (co-chairs, 2026-08-27).
|
|
39
|
+
"modes": ["remote-video"],
|
|
40
|
+
"artifacts": {
|
|
41
|
+
// «a presentation video … a one-slide presentation … and optionally a poster»
|
|
42
|
+
"remote-video": {
|
|
43
|
+
"required": ["video", "one-slide"],
|
|
44
|
+
"optional": ["poster"],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
"kinds": {
|
|
48
|
+
// «short paper = 10 min: 6–7 min talk + 3–4 min questions» (co-chairs, 2026-09-29).
|
|
49
|
+
// qa_s is the middle of 3–4 min; it is informational and not judged. The full-paper slot
|
|
50
|
+
// was not in the email, so `full` and `demo` have no entry and talk/profile says so.
|
|
51
|
+
"short": {
|
|
52
|
+
"slot_s": 600,
|
|
53
|
+
"talk_s_min": 360,
|
|
54
|
+
"talk_s_max": 420,
|
|
55
|
+
"qa_s": 210,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
// ASE 2026's not-in-person page: «recommendation: 10 min duration, mp4 file format, HD
|
|
59
|
+
// resolution» — the parent conference's recommendation; the workshop's own slot is above.
|
|
60
|
+
"video": { "container": "mp4", "min_height_px": 720 },
|
|
61
|
+
},
|
|
62
|
+
|
|
34
63
|
// The proceedings are produced by Conference Publishing Consulting — agenticdev.md takes its
|
|
35
64
|
// numbers from their author instructions — which require "balanced columns on the last page, if
|
|
36
65
|
// the page is not filled" and sent an accepted camera-ready back for it on 2026-08-29, the day
|
package/presets/aidc.jsonc
CHANGED
|
@@ -43,6 +43,56 @@
|
|
|
43
43
|
// for) is not a section with this title and does not count.
|
|
44
44
|
"required_sections": [{ "title": "LLM Usage Statement", "position": "last" }],
|
|
45
45
|
|
|
46
|
+
// THE REGISTER OF THE BODY IS JUDGED AGAINST ACSAC, AIDC'S PARENT CONFERENCE: AIDC 2026 is the
|
|
47
|
+
// workshop's first edition, so it has no accepted papers yet, and it uses ACSAC's template. The
|
|
48
|
+
// anchors are the five accepted ACSAC papers in fixtures/accepted-papers/, measured by paperlint's
|
|
49
|
+
// own counters on their LaTeX source (tex/contrast-frames, tex/claim-emphasis, tex/relation-markers).
|
|
50
|
+
// src/register-bands.test.ts re-measures every anchor that has a fixture and requires these exact
|
|
51
|
+
// numbers, so a change to a counter changes this list in the same commit. The bands they set, per
|
|
52
|
+
// 10,000 words (the anchors' range, widened by two Poisson standard deviations at each end):
|
|
53
|
+
// contrast frames anchors 1.3–5.5 band 0–10.4
|
|
54
|
+
// claims in bold anchors 0.0–10.4 band 0–17.8
|
|
55
|
+
// relation markers anchors 39.4–112.8 band 25.4–135.0
|
|
56
|
+
"register": {
|
|
57
|
+
"anchors": [
|
|
58
|
+
{
|
|
59
|
+
"paper": "barovox-acsac24",
|
|
60
|
+
"words": 7670,
|
|
61
|
+
"contrast_frames": 1,
|
|
62
|
+
"claim_emphasis": 8,
|
|
63
|
+
"relation_markers": 31,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"paper": "leaking-queries-acsac25",
|
|
67
|
+
"words": 9133,
|
|
68
|
+
"contrast_frames": 5,
|
|
69
|
+
"claim_emphasis": 0,
|
|
70
|
+
"relation_markers": 103,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"paper": "llm-splained-acsac25",
|
|
74
|
+
"words": 9529,
|
|
75
|
+
"contrast_frames": 4,
|
|
76
|
+
"claim_emphasis": 1,
|
|
77
|
+
"relation_markers": 84,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"paper": "rr-dataset-quality-acsac24",
|
|
81
|
+
"words": 8130,
|
|
82
|
+
"contrast_frames": 3,
|
|
83
|
+
"claim_emphasis": 0,
|
|
84
|
+
"relation_markers": 32,
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"paper": "secure-acsac24",
|
|
88
|
+
"words": 7519,
|
|
89
|
+
"contrast_frames": 3,
|
|
90
|
+
"claim_emphasis": 0,
|
|
91
|
+
"relation_markers": 38,
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
|
|
46
96
|
"format": {
|
|
47
97
|
// \textwidth and \textheight of [conference,compsoc], measured (ieee-conference.jsonc).
|
|
48
98
|
"textblock_w_in": 7.0,
|