diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..7b076de
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,6 @@
+.git
+.venv
+__pycache__
+*.pyc
+out
+out/checkpoints
diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml
index 115af0c..bb5d072 100644
--- a/.forgejo/workflows/ci.yml
+++ b/.forgejo/workflows/ci.yml
@@ -14,7 +14,7 @@ jobs:
- name: Setup Python
uses: actions/setup-python@v5
with:
- python-version: "3.11"
+ python-version: "3.12"
- name: Install deps
run: |
diff --git a/.forgejo/workflows/docker-ci.yml b/.forgejo/workflows/docker-ci.yml
new file mode 100644
index 0000000..4e412ab
--- /dev/null
+++ b/.forgejo/workflows/docker-ci.yml
@@ -0,0 +1,17 @@
+name: docker-ci
+
+on:
+ workflow_dispatch:
+
+jobs:
+ docker:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Build image
+ run: docker build -t iftypeset-ci .
+
+ - name: Run CI inside container
+ run: docker run --rm iftypeset-ci bash scripts/ci.sh
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..a433b7a
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,56 @@
+# AGENTS.md — `iftypeset` working rules
+
+These instructions apply to the entire `iftypeset/` tree.
+
+## Non‑negotiables (copyright + scope)
+
+- Do **not** OCR/transcribe Chicago/Bringhurst into the repo. Rules are **paraphrases only** with **pointer refs** (e.g., `CMOS18 §6.2 p377 (scan p10)`).
+- OCR is allowed only **ephemerally** (stdout or temp files deleted) to locate pointers.
+- Prefer deterministic, measurable rules. If it can’t be automated, mark it as manual via `tags: ["manual_checklist=true"]` and ensure it lands in the checklist output.
+
+## “Don’t lose work” operating practice
+
+- Trust the filesystem, not the chat transcript.
+- Use `./scripts/audit.sh` to capture current state.
+- Use `./scripts/ci.sh` as the fastest sanity check.
+- After meaningful changes, create a restore point: `./scripts/checkpoint.sh "short note"`.
+- Checkpoints are recorded in `docs/CHECKPOINTS.md`.
+
+## Session ID hygiene (required)
+
+Codex CLI shows a `session_id` via `/status` (look for the `Session:` line). To prevent two terminals from sharing/overwriting one session state:
+
+- Run `/status` at session start and copy the `Session:` value.
+- When claiming a task in `docs/13-task-board.md`, include it in `owner` (example: `codex-cli (gpt-5.2) [sid: 019b…]`).
+- Also include it in your row in `/root/docs/SESSION_STATE.md` (either in `who` or `notes`).
+- If you ever see two live terminals with the same `session_id`, stop one and start a fresh session (new `session_id`).
+
+Fallback (if `/status` is unavailable):
+
+```bash
+day_dir=/root/.codex/sessions/$(date -u +%Y/%m/%d)
+latest=$(ls -1t "$day_dir"/rollout-*.jsonl | head -n 1)
+python3 - <<'PY' "$latest"
+import json,sys
+print(json.loads(open(sys.argv[1]).readline())["payload"]["id"])
+PY
+```
+
+If multiple sessions are active, run this immediately after starting your session so “latest” corresponds to your own launch.
+
+## When adding rules
+
+- Follow `spec/schema/rule.schema.json` strictly; run `PYTHONPATH=src python3 -m iftypeset.cli validate-spec --spec spec --build-indexes`.
+- Keep `rule_text` short and paraphrased; never paste long passages.
+- Prefer adding new batches (e.g., `v1_links_004.ndjson`) over editing old IDs; deprecate instead of mutating IDs.
+
+## When changing code
+
+- Keep dependencies minimal (currently `requirements.txt` is intentionally small).
+- Update `app/CLI_SPEC.md` and `STATUS.md` when behavior or counts change.
+- Ensure `./scripts/ci.sh` passes before handing off.
+
+## Typography baseline (house default)
+
+- Default body font size is `12pt` for reader-facing PDFs; do not go below `12pt` unless the profile description explicitly justifies it (e.g., slide decks, constrained one-page CVs).
+- Prefer fixing density with margins/spacing/layout before shrinking type.
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..1446518
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,34 @@
+FROM python:3.12.12-slim-bookworm
+
+ENV PYTHONUNBUFFERED=1 \
+ PIP_NO_CACHE_DIR=1 \
+ PIP_DISABLE_PIP_VERSION_CHECK=1
+
+RUN apt-get update \
+ && apt-get install -y --no-install-recommends \
+ ca-certificates \
+ fontconfig \
+ fonts-dejavu-core \
+ fonts-liberation \
+ fonts-noto-core \
+ poppler-utils \
+ && rm -rf /var/lib/apt/lists/*
+
+WORKDIR /workspace
+
+COPY requirements.txt ./
+RUN python -m pip install --upgrade pip \
+ && python -m pip install -r requirements.txt \
+ && python -m playwright install --with-deps
+
+COPY pyproject.toml README.md STATUS.md AGENTS.md ./
+COPY src ./src
+COPY spec ./spec
+COPY app ./app
+COPY scripts ./scripts
+COPY docs ./docs
+COPY fixtures ./fixtures
+
+RUN python -m pip install -e .
+
+ENTRYPOINT ["iftypeset"]
diff --git a/README.md b/README.md
index f48158e..4cb9cfe 100644
--- a/README.md
+++ b/README.md
@@ -15,27 +15,100 @@ It is designed to be embedded into constrained workers (e.g. Forgejo PDF export
- **No bulk OCR/transcription** of Chicago/Bringhurst into this repo (copyright).
- Rule records are **paraphrases only**, backed by **pointers** (e.g. `CMOS18 §X.Y pNNN (scan pMMM)`).
- Chicago OCR (when needed) must be **ephemeral** (extract just enough to locate pointers; do not store page text).
+- Optional profile `webtypography_nc` is **CC BY-NC 4.0** (non-commercial only). See `docs/18-webtypography-nc.md`.
## Quickstart (current)
From `ai-workspace/iftypeset/`:
- (Optional) Install deps into a venv: `python3 -m venv .venv && . .venv/bin/activate && python -m pip install -r requirements.txt`
-- Validate spec + rebuild indexes: `PYTHONPATH=src python3 -m iftypeset.cli validate-spec --spec spec --build-indexes`
-- Lint Markdown: `PYTHONPATH=src python3 -m iftypeset.cli lint --input fixtures/sample.md --out out --profile web_pdf`
-- Render HTML + CSS: `PYTHONPATH=src python3 -m iftypeset.cli render-html --input fixtures/sample.md --out out --profile web_pdf`
-- Render PDF (if an engine is installed): `PYTHONPATH=src python3 -m iftypeset.cli render-pdf --input fixtures/sample.md --out out --profile web_pdf`
-- Run QA gates (HTML fallback if no PDF): `PYTHONPATH=src python3 -m iftypeset.cli qa --out out --profile web_pdf`
-- Coverage report: `PYTHONPATH=src python3 -m iftypeset.cli report --spec spec --out out`
+- Install the console entrypoint: `python3 -m pip install -e .`
+- Validate spec + rebuild indexes: `iftypeset validate-spec --spec spec --build-indexes`
+- One-shot CI pipeline (recommended): `iftypeset run --input fixtures/sample.md --out out --profile web_pdf --degraded-ok`
+- Multi-doc run (directory or glob): `iftypeset run --input fixtures --out out --profile web_pdf --degraded-ok`
+- Lint Markdown (emits `out/lint-report.json` + `out/manual-checklist.md`): `iftypeset lint --input fixtures/sample.md --out out --profile web_pdf`
+- Lint with auto-fix + post-fix diagnostics: `iftypeset lint --input fixtures/sample.md --out out --profile web_pdf --fix --fix-mode rewrite --lint-fixed`
+- Render HTML + CSS: `iftypeset render-html --input fixtures/sample.md --out out --profile web_pdf`
+- Run QA gates (HTML fallback if no PDF): `iftypeset qa --out out --profile web_pdf`
+- Render PDF (if an engine is installed): `iftypeset render-pdf --input fixtures/sample.md --out out --profile web_pdf`
+- Coverage + trust contract + HTML index: `iftypeset report --spec spec --out out` (writes `out/report/index.html`)
+- Environment/determinism report: `iftypeset doctor --spec spec --out out`
+- Portable review bundle: `iftypeset bundle --out out` (writes `out/iftypeset-bundle.tar.gz`)
- Run self-check tests: `python3 -m unittest discover -s tests -p 'test_*.py'`
+- Inspect profiles/gates/rules:
+ - `iftypeset profiles list`
+ - `iftypeset gates show --profile web_pdf`
+ - `iftypeset rules list --category links`
+ - `iftypeset rules show HOUSE.LINKS.URLS.PREFER_HTTPS`
+
+If you do not want to install the console entrypoint, you can still run:
+
+- `PYTHONPATH=src python3 -m iftypeset.cli ...`
+
+## Config file (`iftypeset.yaml`)
+
+You can set repo defaults in `./iftypeset.yaml`. CLI flags always win.
+
+Example:
+
+```yaml
+defaults:
+ spec: spec
+ out: out
+ profile: web_pdf
+lint:
+ fail_on: must
+ degraded_ok: true
+run:
+ skip_pdf: false
+ require_pdf: false
+ engine: playwright
+```
+
+To use a different config path: `iftypeset --config /path/to/iftypeset.yaml ...`
+
+## Enforcement limits (read this)
+
+- **Not all rules are automated.** Manual rules (tagged `manual_checklist=true`) appear in `out/manual-checklist.md`.
+- **PDF QA is heuristic.** It depends on text extraction and will miss some layout failures.
+- **Renderer variance exists.** Profiles aim for determinism, but output still depends on the PDF engine + fonts.
+- **Trust contract is explicit.** Run `iftypeset report` to generate `out/trust-contract.md` with current limits.
+
+## Lint suppression (explicit, auditable)
+
+You can suppress specific rules in a document when needed:
+
+- Inline directive (applies to the next non-empty line):
+ - ``
+- Front matter allowlist:
+ - `iftypeset_ignore: [CMOS.PUNCTUATION.PARENS_BRACKETS.BALANCE, LINK.WRAP.RISK]`
+
+Suppression works by rule id or diagnostic code and should be used sparingly.
+
+## Session resilience (avoid “lost work”)
+
+If a chat/session resets, trust the repo, not the transcript:
+
+- Quick resume: `./scripts/resume.sh`
+- Audit repo state: `./scripts/audit.sh`
+- Run CI sanity checks: `./scripts/ci.sh`
+- Create a portable restore point: `./scripts/checkpoint.sh "short note"`
+
+Details: `docs/07-session-resilience.md`
+Handoff snapshot: `docs/08-handoff.md`
+Project status: `docs/09-project-status.md`
+Downloadable summary: `docs/11-project-summary.md`
+Rendering pipeline: `docs/17-rendering-pipeline.md`
+Non-commercial WebTypography profile: `docs/18-webtypography-nc.md`
+Agent notes: `AGENTS.md`
+External review pack: `docs/14-external-review.md`
+Docker runtime: `docs/15-docker.md`
## PDF renderers
-`render-pdf` will use the first available engine in this order:
+`render-pdf` defaults to `playwright` and does not fall back silently.
-- `playwright` (Python module)
-- `chromium` / `chromium-browser` / `google-chrome`
-- `wkhtmltopdf`
-- `weasyprint` (Python module)
+- `playwright` (preferred; supports header/footer templates and avoids Chromium CLI “date/path” headers/footers)
+- Optional (explicit `--engine` only): `wkhtmltopdf`, `weasyprint`
-If none are installed, the command exits with a clear message but still leaves HTML artifacts for QA.
+If no engine is present, the command exits with a clear message but still leaves HTML artifacts for QA.
diff --git a/STATUS.md b/STATUS.md
index c1ed3e6..f2b45b7 100644
--- a/STATUS.md
+++ b/STATUS.md
@@ -1,42 +1,68 @@
# iftypeset status (pubstyle)
-**Updated:** 2026-01-03
+**Updated:** 2026-01-04
**Project root:** `/root/ai-workspace/iftypeset/`
## What exists (working today)
- **Spec + schema:** `spec/schema/rule.schema.json`, `spec/manifest.yaml`
-- **Profiles:** `spec/profiles/*.yaml` (`web_pdf`, `print_pdf`, `dense_tech`, `memo`, `slide_deck`)
+- **Profiles:** `spec/profiles/*.yaml` (`web_pdf`, `print_pdf`, `dense_tech`, `memo`, `slide_deck`, `webtypography_nc` non-commercial)
- **Post-render QA gates:** `spec/quality_gates.yaml`
+- **PDF-aware QA (heuristic):** Poppler text extraction via `pdftotext` + `pdftohtml -xml` with page-aware incidents (`widow_pdf`, `orphan_pdf`, `stranded_heading_pdf`, `overfull_line_pdf`, `overfull_bbox_pdf`)
+- **HTML QA (v0):** catches bare URL/DOI/email wrapping, overfull tokens, code/table overflow (profile-aware thresholds)
+- **Deterministic lint coverage:** DOI references, ordinal suffix errors, and note-marker placement (alongside existing punctuation/link safety checks)
- **Rule registry (seeded):** `spec/rules/**.ndjson`
+- **House pointers (no quotes):** `spec/house/HOUSE_EDITORIAL_POINTERS.md`
- **Indexes (derived):** `spec/indexes/*.json` (rebuildable)
-- **CLI:** `validate-spec`, `report`, `lint`, `render-html`, `render-pdf`, `qa`, `emit-css`
+- **CLI:** `validate-spec`, `report`, `lint`, `render-html`, `render-pdf`, `qa`, `emit-css`, `doctor`, `bundle`, `run`
+ - `render-pdf --engine ` to force a specific renderer.
+ - `run --require-pdf` to fail the pipeline if PDF rendering fails.
+- **Renderer default:** `playwright` is the default engine for PDF typesetting.
+- **CLI introspection:** `profiles list`, `gates show`, `rules list/show`
+- **Config defaults:** `iftypeset.yaml` (CLI flags override)
+- **Run summary artifact:** `out/run-summary.json` (CI-style pipeline output)
+- **Multi-doc run mode:** `iftypeset run --input ` writes per-doc outputs under `out/docs/` and a top-level run index at `out/report/index.html`
- **Ephemeral extraction helpers:** `tools/` (Chicago OCR is grep-only, temp files deleted)
- **Forgejo integration note:** `forgejo/README.md`
- **Fixtures + tests:** `fixtures/` and `tests/`
- **CI script:** `scripts/ci.sh` (validate-spec, report, unit tests)
+- **Docker runtime:** `Dockerfile` + `docs/15-docker.md` (Playwright + Poppler + fonts)
+- **“Don’t lose work” tooling:** `scripts/audit.sh`, `scripts/checkpoint.sh`, `scripts/state.sh`, `scripts/resume.sh` + `docs/07-session-resilience.md`
+- **Trust contract artifacts:** `out/trust-contract.md` + `out/trust-contract.json` (generated by `report`)
+- **Report index:** `out/report/index.html` (artifact hub from `report`)
+- **Doctor report:** `out/doctor.md` + `out/doctor.json` (environment + determinism)
+- **Bundle artifact:** `out/iftypeset-bundle.tar.gz` + `out/bundle-manifest.json` (portable review pack)
## Rule corpus snapshot
From `out/coverage-report.json`:
-- **Total rules:** 307
-- **By category:** citations 61, numbers 62, punctuation 55, layout 46, headings 32, tables 23, typography 15, links 5, accessibility 4, code 4
-- **By enforcement:** manual 186, typeset 62, lint 46, postrender 13
-- **By severity:** must 28, should 263, warn 16
+- **Total rules:** 524
+- **By category:** editorial 45, abbreviations 27, accessibility 22, backmatter 18, citations 61, code 28, figures 22, frontmatter 20, headings 32, i18n 27, layout 46, links 21, numbers 62, punctuation 55, tables 23, typography 15
+- **By enforcement:** manual 379, typeset 62, lint 70, postrender 13
+- **By severity:** must 37, should 470, warn 17
## Current rule batches
+- `spec/rules/abbreviations/v1_abbreviations_003.ndjson` (27)
- `spec/rules/accessibility/v1_accessibility_001.ndjson` (4)
+- `spec/rules/accessibility/v1_accessibility_003.ndjson` (18)
+- `spec/rules/backmatter/v1_backmatter_003.ndjson` (18)
- `spec/rules/citations/v1_citations_001.ndjson` (16)
- `spec/rules/citations/v1_citations_002.ndjson` (45)
- `spec/rules/code/v1_code_001.ndjson` (4)
+- `spec/rules/code/v1_code_003.ndjson` (24)
+- `spec/rules/editorial/v1_editorial_001.ndjson` (45)
+- `spec/rules/figures/v1_figures_003.ndjson` (22)
+- `spec/rules/frontmatter/v1_frontmatter_003.ndjson` (20)
- `spec/rules/headings/v1_headings_001.ndjson` (12)
- `spec/rules/headings/v1_headings_002.ndjson` (20)
+- `spec/rules/i18n/v1_i18n_003.ndjson` (27)
- `spec/rules/layout/v1_layout_001.ndjson` (12)
- `spec/rules/layout/v1_layout_002.ndjson` (30)
- `spec/rules/layout/v1_layout_003.ndjson` (4)
- `spec/rules/links/v1_links_001.ndjson` (5)
+- `spec/rules/links/v1_links_003.ndjson` (16)
- `spec/rules/numbers/v1_numbers_001.ndjson` (12)
- `spec/rules/numbers/v1_numbers_002.ndjson` (50)
- `spec/rules/punctuation/v1_punctuation_001.ndjson` (15)
@@ -52,6 +78,9 @@ From `out/coverage-report.json`:
- `PYTHONPATH=src python3 -m iftypeset.cli validate-spec --spec spec --build-indexes`
- Lint:
- `PYTHONPATH=src python3 -m iftypeset.cli lint --input fixtures/sample.md --out out --profile web_pdf`
+- Run end-to-end pipeline:
+ - `PYTHONPATH=src python3 -m iftypeset.cli run --input fixtures/sample.md --out out --profile web_pdf --degraded-ok`
+ - `PYTHONPATH=src python3 -m iftypeset.cli run --input fixtures/sample.md --out out --profile web_pdf --require-pdf`
- Render HTML + CSS:
- `PYTHONPATH=src python3 -m iftypeset.cli render-html --input fixtures/sample.md --out out --profile web_pdf`
- Render PDF (if renderer installed):
@@ -73,6 +102,6 @@ From `out/coverage-report.json`:
## Next work (highest leverage)
-- Add new batches for: `figures`, `frontmatter`, `backmatter`, `abbreviations`, `i18n`, and expand `accessibility`.
-- Grow post-render QA rule coverage (widows/orphans, heading keeps, overflow) beyond the current seed set.
-- Add a real PDF-layout analyzer when a stable renderer is selected (widows/orphans, overflow).
+- Extend deterministic lint coverage for citations (author-date patterns, bibliography normalization) and locale/i18n rules where feasible.
+- Deepen typeset/CSS profile mapping for tables, figures, and code to reduce manual cleanup before PDF export (and to reduce QA incidents).
+- Expand editorial automation beyond manual checklists (safe heuristics like headline ALL-CAPS checks and abbreviation definition hints).
diff --git a/app/CLI_SPEC.md b/app/CLI_SPEC.md
index 5a4621d..d9a08ec 100644
--- a/app/CLI_SPEC.md
+++ b/app/CLI_SPEC.md
@@ -6,14 +6,23 @@ The CLI is designed for CI use: deterministic outputs, stable exit codes, and JS
This is the *target* contract; v0 currently implements a subset per-command.
+Precedence (highest → lowest): CLI flags → `iftypeset.yaml` → hard defaults.
+
* `--spec `: Spec root directory (default: `spec/`).
* `--input `: Markdown file or directory (where applicable).
* `--out `: Output directory (default: `out/`).
-* `--profile `: One of: `web_pdf`, `print_pdf`, `dense_tech`, `memo`, `slide_deck` (where applicable).
+* `--profile `: One of: `web_pdf`, `print_pdf`, `dense_tech`, `memo`, `slide_deck`, `webtypography_nc` (non-commercial).
+* `--config `: Path to `iftypeset.yaml` (defaults to `./iftypeset.yaml` when present).
+* `--engine `: Preferred PDF engine (default: `playwright`; `auto` is treated as `playwright`; Chromium CLI engine is banned).
+* `--font-dir `: Additional font directory (repeatable) to supply corporate fonts at render time.
+* `--strict-fonts`: Enforce a fonts contract for PDF rendering (fail if primary profile fonts are missing or not embedded in the PDF).
* `--strict`: Use strict thresholds in `spec/quality_gates.yaml` (QA/report).
* `--format `: Lint output format.
* `--fail-on `: Lowest severity that fails `lint` (default: `must`).
* `--degraded-ok`: Allow degraded mode without failing (lint/render-html).
+* `--fix`: Apply safe deterministic fixes (lint/run).
+* `--fix-mode `: Fix mode for `--fix` (lint/run).
+* `--lint-fixed`: When rewriting fixes, lint the fixed output instead of the original (lint/run).
* `--version`: Print tool version and exit.
## Command: `validate-spec`
@@ -29,8 +38,52 @@ Outputs:
Exit codes:
* `0`: ok
-* `4`: config/schema error
-* `5`: internal error
+* `2`: config/schema error
+
+## Command: `profiles list`
+
+Purpose:
+
+* List available profile ids in the current spec.
+
+Outputs:
+
+* JSON to stdout (`profiles: [...]`)
+
+Exit codes:
+
+* `0`: ok
+* `2`: config error
+
+## Command: `gates show`
+
+Purpose:
+
+* Show QA gate thresholds for a profile (`--strict` selects strict mode).
+
+Outputs:
+
+* JSON to stdout (`gates: {...}`)
+
+Exit codes:
+
+* `0`: ok
+* `2`: config error
+
+## Command: `rules list` / `rules show`
+
+Purpose:
+
+* List rules with basic filters, or show a full rule record by id.
+
+Outputs:
+
+* JSON to stdout (`rules: [...]` or `rule: {...}`)
+
+Exit codes:
+
+* `0`: ok
+* `2`: config error / rule not found
## Command: `report`
@@ -42,13 +95,78 @@ Outputs:
* `out/coverage-report.json`
* `out/coverage-summary.md`
+* `out/report/index.html`
Exit codes:
* `0`: report built
-* `2`: coverage floor violated (only when rule batches exist)
-* `4`: config/schema error
-* `5`: internal error
+* `1`: coverage floor violated (only when rule batches exist)
+* `2`: config/schema error
+
+## Command: `doctor`
+
+Purpose:
+
+* Emit environment and determinism diagnostics (renderer, Poppler, fonts, locale).
+
+Outputs:
+
+* `out/doctor.json`
+* `out/doctor.md`
+
+Exit codes:
+
+* `0`: ok
+* `2`: config error
+
+## Command: `bundle`
+
+Purpose:
+
+* Create a portable tarball of `out/` artifacts with a sha256 manifest for external review.
+
+Outputs:
+
+* `out/bundle-manifest.json`
+* `out/iftypeset-bundle.tar.gz` (default; override with `--bundle`)
+
+Exit codes:
+
+* `0`: ok
+
+Notes:
+
+* Files larger than `--max-size-mb` are skipped and recorded in the manifest.
+* Bundle entries are sorted and stored with fixed mtimes for deterministic output.
+
+## Command: `run`
+
+Purpose:
+
+* One-shot CI pipeline: validate → lint → render-html → render-pdf (best effort) → qa → report.
+
+Outputs:
+
+* All artifacts from the underlying commands.
+* `out/run-summary.json`
+* When `--input` is a directory or glob, per-doc artifacts are written under `out/docs//` and
+ `out/report/index.html` becomes a multi-doc index.
+
+Exit codes:
+
+* `0`: pipeline ok (lint + qa + report passed)
+* `1`: gate failed (lint/qa/report/degraded render-html)
+* `2`: config error
+* `3`: renderer/tool error (only when `--require-pdf` is set)
+
+Notes:
+
+* PDF rendering failures are recorded as warnings in `run-summary.json` and do not fail the run **unless**
+ `--require-pdf` is set.
+* Use `--skip-pdf` to omit PDF rendering entirely when only HTML QA is desired.
+* Use `--engine` to force a specific renderer (useful for reproducible CI).
+* Use `--font-dir` to mount a corporate fonts directory and avoid fallback fonts.
+* Use `--strict-fonts` (or profile `fonts.require_primary: true`) to fail fast if font fallback would occur.
## Command: `lint`
@@ -67,11 +185,15 @@ Outputs:
* `out/fix-suggestions.json` (only when `--fix --fix-mode suggest`)
* `out/fixed/*.md` (only when `--fix --fix-mode rewrite`)
+Notes:
+
+* `--lint-fixed` re-lints the rewritten output so diagnostics reflect the fixed text.
+
Exit codes:
* `0`: ok
-* `2`: lint failed (fail-on threshold exceeded, or degraded mode without `--degraded-ok`)
-* `4`: config error
+* `1`: lint failed (fail-on threshold exceeded, or degraded mode without `--degraded-ok`)
+* `2`: config error
## Command: `render-html`
@@ -89,14 +211,14 @@ Outputs:
Exit codes:
* `0`: ok
-* `2`: degraded mode without `--degraded-ok`
-* `4`: config error
+* `1`: degraded mode without `--degraded-ok`
+* `2`: config error
## Command: `render-pdf`
Purpose:
-* Render Markdown to PDF using the first available engine (playwright/chromium/wkhtmltopdf/weasyprint).
+* Render Markdown to PDF using the configured engine (default: `playwright`; `--engine auto` is treated as `playwright`; Chromium CLI engine is not supported).
Outputs:
@@ -110,7 +232,13 @@ Exit codes:
* `0`: ok
* `3`: renderer missing or engine error (see `out/render-log.json`)
-* `4`: config error
+* `2`: config error
+
+Notes:
+
+* Use `--engine` to force a specific renderer (e.g., `--engine wkhtmltopdf`).
+* Use `--font-dir` to supply additional font directories for the renderer (e.g., corporate fonts).
+* Use `--strict-fonts` (or profile `fonts.require_primary: true`) to prevent silent font fallbacks in shipped PDFs.
## Command: `qa`
@@ -118,13 +246,22 @@ Purpose:
* Run deterministic post-render QA checks (HTML analysis v0) and enforce numeric gates from `spec/quality_gates.yaml`.
+Args:
+
+* `--out `: output directory containing `render.html` / `render.pdf` (default: `out/`)
+* `--html `: HTML to analyze (default: `/render.html`)
+* `--pdf `: optional PDF path for reporting (default: `/render.pdf`)
+* `--strict`: use strict thresholds from `spec/quality_gates.yaml`
+* `--format `: optional SARIF output for CI annotations
+
Outputs:
* `out/layout-report.json`
* `out/qa-report.json`
+* `out/qa-report.sarif` (when `--format sarif`)
Exit codes:
* `0`: gates pass
-* `2`: gates fail
-* `4`: config error / missing `out/render.html`
+* `1`: gates fail
+* `2`: config error / missing HTML input
diff --git a/docs/01-demo-acceptance.md b/docs/01-demo-acceptance.md
index 4abe0c2..8882fdc 100644
--- a/docs/01-demo-acceptance.md
+++ b/docs/01-demo-acceptance.md
@@ -6,7 +6,7 @@ This doc defines what “ship‑ready” means for `iftypeset` (pubstyle): a det
- Produce **consistently good-looking** outputs from plain Markdown without manual layout heroics.
- Provide **machine-verifiable QA gates** (layout/report JSON) suitable for CI.
-- Keep the system **renderer-agnostic** via adapters (Chromium / WeasyPrint / Prince / Antenna House / Vivliostyle, etc.).
+- Keep the system **renderer-agnostic** via adapters (Playwright / WeasyPrint / Prince / Antenna House / Vivliostyle, etc.).
- Preserve legal constraints: **rules are paraphrases + pointers**, never book text.
## Definition of Done (v0.1)
@@ -95,4 +95,3 @@ For a convincing “this is real” demo:
- [ ] CI fails on spec regression (coverage floors, schema validation).
- [ ] Degraded mode emits its report artifacts and never silently “fixes” content.
- [ ] Renderer adapters are documented (how `auto` chooses, how to pin).
-
diff --git a/docs/04-renderer-strategy.md b/docs/04-renderer-strategy.md
index debc49f..b9efb42 100644
--- a/docs/04-renderer-strategy.md
+++ b/docs/04-renderer-strategy.md
@@ -25,15 +25,15 @@ class PdfEngine(Protocol):
The CLI should support:
-- `--engine auto|chromium|weasyprint|prince|antenna|vivliostyle|wkhtmltopdf`
+- `--engine auto|playwright|weasyprint|prince|antenna|vivliostyle|wkhtmltopdf`
- `--engine-opts `
## “Majors” to target (pragmatic)
### Tier 1 (easy to run, common)
-1) **Chromium / Headless browser**
-- via Playwright or system Chromium (`chrome --headless --print-to-pdf`)
+1) **Playwright (browser-backed PDF)**
+- via Playwright (preferred)
- Pros: ubiquitous, good HTML/CSS coverage, easy containerization.
- Cons: paged-media features vary; footnotes/running headers are limited unless carefully built.
@@ -86,7 +86,7 @@ For every PDF render, write `out/render-log.json` including:
- invocation args
- environment hints (OS, locale)
- “self-contained” mode on/off
-- fonts resolved (what was available vs requested)
+- fonts policy + resolution (requested primary fonts, what fontconfig matched, and what fonts were embedded in the PDF)
- any warnings from the engine
If the engine is a browser:
@@ -106,7 +106,7 @@ If the engine is a browser:
## Recommended v0.1 path (fastest)
1) Implement adapters for:
- - Chromium/Playwright (auto-detect)
+ - Playwright (auto-detect)
- WeasyPrint (if installed)
2) Keep Prince/AH as optional adapters (stub + docs) until needed.
3) Use QA gates as the real value:
@@ -123,4 +123,3 @@ Once adapters exist, add an integration job that renders the same fixtures throu
- major layout regressions (e.g., table clipping incidents)
We don’t need pixel-perfect equivalence; we need “quality gates still pass”.
-
diff --git a/docs/06-project-overview.md b/docs/06-project-overview.md
index 2fe405e..80d985c 100644
--- a/docs/06-project-overview.md
+++ b/docs/06-project-overview.md
@@ -22,9 +22,20 @@ We have a working foundation that is intentionally boring:
- A **profile system** (`spec/profiles/*.yaml`) that maps typographic intent into deterministic render tokens (page size, margins, font stacks, measure targets, hyphenation policy).
- **Post-render QA gates** (`spec/quality_gates.yaml`) that define hard numeric thresholds for layout failures.
- A working CLI surface (`iftypeset.cli`) that can validate the spec, emit coverage reports, lint Markdown, render HTML/CSS, render PDF (via available engines), and run QA.
+- `report` now generates a human HTML index at `out/report/index.html` linking all artifacts.
Current progress is tracked in `STATUS.md` and `out/coverage-summary.md`.
+## What changed (2026-01-04)
+
+- Expanded the rule registry with new category batches (abbreviations, i18n, frontmatter, backmatter, figures) and the first editorial batch (house-style, pointer-backed).
+- Implemented deterministic lint enforcement for key MUST rules plus DOI references, ordinal suffix errors, and note-marker placement, with safe `--fix` modes.
+- Strengthened HTML-only QA and added PDF-aware QA (Poppler `pdftotext` + `pdftohtml -xml`) for page-aware heuristics; incidents include `widow_pdf`, `orphan_pdf`, `stranded_heading_pdf`, `overfull_line_pdf`, `overfull_bbox_pdf`, and `runt_final_page_pdf`.
+- Improved degraded-mode parsing heuristics to reduce false positives and added fixtures/tests to keep `scripts/ci.sh` green.
+- Added a human-friendly report index (`out/report/index.html`) for quick artifact navigation.
+- Added a pinned Docker runtime (Playwright + Poppler + fonts) for reproducible CI/local runs (`docs/15-docker.md`).
+- Deepened profile tokens and CSS handling for tables, figures, and code blocks (table layout + wrapping, figure sizing, code block padding/wrap) to reduce overflow risk.
+
## Where we are going (v0.1 → v1)
### v0.1: “Publishing CI” for a single Markdown input
@@ -32,7 +43,7 @@ Current progress is tracked in `STATUS.md` and `out/coverage-summary.md`.
The v0.1 goal is *not* to be the best renderer. It’s to be the most reliable pipeline:
- deterministic HTML/CSS output for a chosen profile
-- PDF generation via adapters (Chromium first, others later)
+- PDF generation via adapters (Playwright default; others later)
- QA reports that catch common layout failures and fail the build when thresholds are exceeded
- an honest manual checklist for rules that cannot be automated
@@ -70,4 +81,3 @@ The differentiator is not “Markdown to PDF”. It’s:
**B) enforceable layout QA** (fail the build when it’s sloppy).
That’s what makes it compatible with governance workflows (hash/sign artifacts, attach QA reports, reproduce later) and usable in constrained CI environments (like Forgejo PDF export workers).
-
diff --git a/docs/07-session-resilience.md b/docs/07-session-resilience.md
index 480688b..44435eb 100644
--- a/docs/07-session-resilience.md
+++ b/docs/07-session-resilience.md
@@ -14,11 +14,60 @@ This project adds a few boring mechanisms to make resuming work deterministic.
From the repo root:
-- `./scripts/audit.sh`
+- `./scripts/resume.sh` (recommended)
+- `./scripts/audit.sh` (raw)
+- `./scripts/state.sh` (writes `docs/SESSION_STATE.md` for pasteable state)
- `./scripts/ci.sh`
If both look sane, you’re back.
+## Multi-session coordination (avoid Codex waiting)
+
+When running multiple Codex sessions in parallel, coordinate through the repo:
+
+- Task queue: `docs/13-task-board.md`
+- Session context: `docs/SESSION_STATE.md`
+- Durable restore points: `docs/CHECKPOINTS.md` + `out/checkpoints/`
+
+Workflow:
+
+1. Pick a task from `docs/13-task-board.md` and **claim it** (owner + working_set).
+2. Stay inside your `working_set` to avoid conflicts.
+3. Run `./scripts/ci.sh`.
+4. Create a restore point: `./scripts/checkpoint.sh "task : "`
+5. Mark the task done and paste the checkpoint reference.
+
+If a change must block others (shared files), create a temporary lock file:
+
+- `docs/LOCK_ .md`
+
+## Coordination contract (short)
+
+Use this when handing off across sessions:
+
+1. **Claim the task** in `docs/13-task-board.md`.
+2. **Declare the working set** in `docs/SESSION_STATE.md`.
+3. **Lock shared areas** via `docs/LOCK_ .md` if needed.
+4. **Checkpoint after changes** (`./scripts/checkpoint.sh "note"`).
+5. **Close the task** and paste the checkpoint reference.
+
+## “It looks rolled back” (most common disconnect trap)
+
+If you resume a session and it looks like files “disappeared”, it’s almost always one of:
+
+- You’re looking at a **clean git checkout** somewhere else (remote machine / new container) and the prior work was never committed.
+- You’re looking at a **stale copy outside the repo** (see warning below).
+
+What to do:
+
+1. Run `./scripts/audit.sh` and inspect the `git status --porcelain` output.
+2. Check `out/checkpoints/` for the latest `iftypeset_checkpoint_*.tar.gz`.
+3. If you need to move the work to a new machine/session, copy the latest checkpoint tarball and extract it:
+
+ - `tar -xzf out/checkpoints/iftypeset_checkpoint_.tar.gz -C `
+
+Important: checkpoints snapshot the repo tree (including untracked files). They are the durable “chat-proof” handoff mechanism even when you don’t want to commit yet.
+
## Create a checkpoint (2 minutes)
When you finish a meaningful chunk of work (new rule batches, QA changes, renderer changes), run:
@@ -30,6 +79,7 @@ This:
- runs CI and stores the CI JSON in `out/checkpoints/`
- creates a compressed snapshot tarball in `out/checkpoints/`
- appends a new entry to `docs/CHECKPOINTS.md` with the snapshot hash
+- writes `docs/SESSION_STATE.md` so the snapshot includes a pasteable “resume context”
This gives you a **portable restore point** even if the chat transcript is gone.
@@ -38,3 +88,10 @@ This gives you a **portable restore point** even if the chat transcript is gone.
- Push to a remote early (Forgejo/GitHub). A remote is the best anti-loss mechanism.
- Treat `STATUS.md` as the “1-page truth” for what exists and what’s next.
- Don’t rely on chat logs for state; copy any critical decisions into `docs/`.
+
+## Common “it looks rolled back” trap
+
+If you have multiple status documents on disk, prefer the one inside the repo:
+
+- ✅ canonical: `ai-workspace/iftypeset/docs/09-project-status.md`
+- ⚠️ non-canonical copies (e.g., `/root/docs/09-project-status.md`) can drift and misreport counts.
diff --git a/docs/08-handoff.md b/docs/08-handoff.md
new file mode 100644
index 0000000..dcc37ba
--- /dev/null
+++ b/docs/08-handoff.md
@@ -0,0 +1,89 @@
+# Handoff (context checkpoint) — `iftypeset`
+
+This file exists for one purpose: prevent “chat drift” when a session resets.
+
+If the conversation disappears, this doc + `./scripts/audit.sh` is enough to resume work.
+
+## What this project is
+
+`iftypeset` (pubstyle) is a thin, deterministic **Markdown → HTML → PDF** pipeline with:
+
+- A **machine-readable rule registry** (`spec/rules/**.ndjson`) with **paraphrased** rules + **pointer refs** (Chicago/Bringhurst), never book text.
+- **Profiles** (`spec/profiles/*.yaml`) that map typographic intent → render tokens/CSS.
+- **QA gates** (`spec/quality_gates.yaml`) that fail builds when layout degrades.
+
+Core principle: quality must be **measurable and enforceable**, not “looks fine on my machine”.
+
+## What is working (today)
+
+- CLI (end-to-end): `validate-spec`, `report`, `lint`, `render-html`, `render-pdf`, `qa`, `emit-css`.
+- Rendering: HTML deterministic; PDF works when a PDF engine is available (Playwright is the default).
+- QA (v0): HTML-based heuristics + gate evaluation; emits `layout-report.json` with incident details.
+- Rule registry: seeded and schema-validated; coverage report is generated in CI.
+- CI: `./scripts/ci.sh` runs spec validation + report + unit tests.
+- Session resilience:
+ - `./scripts/audit.sh` prints git + coverage snapshot + checkpoint info.
+ - `./scripts/checkpoint.sh "note"` creates a restore tarball and records it in `docs/CHECKPOINTS.md`.
+
+## How to resume in 30 seconds
+
+From repo root:
+
+```bash
+./scripts/audit.sh
+./scripts/ci.sh
+```
+
+If CI passes, you are back.
+
+## Latest checkpoint (restore point)
+
+Run `./scripts/audit.sh` to see the latest checkpoint path + sha256.
+
+If you need to create a new restore point:
+
+```bash
+./scripts/checkpoint.sh "short note about what changed"
+```
+
+## Where to look first
+
+- Status and counts: `STATUS.md`
+- Project status (narrative): `docs/09-project-status.md`
+- Architecture: `app/ARCHITECTURE.md`
+- CLI contract: `app/CLI_SPEC.md`
+- External evaluation prompt: `docs/05-external-evaluation-prompt.md`
+- Renderer strategy: `docs/04-renderer-strategy.md`
+- Session resilience: `docs/07-session-resilience.md`
+- Rule schema + contracts: `spec/schema/rule.schema.json`, `spec/manifest.yaml`
+
+## Non-negotiables (don’t drift)
+
+- Do **not** OCR/transcribe Chicago/Bringhurst into the repo.
+- Rules are **paraphrases** + **pointer refs** only.
+- OCR is allowed only **ephemerally** to locate pointers (stdout/temp deleted).
+- If a rule cannot be automated, mark it `manual_checklist=true` and ensure it lands in checklist output.
+
+## What remains (next high-leverage work)
+
+1) **Deepen post-render QA**
+ - Current QA is HTML-based v0.
+ - Next step is PDF-aware inspection for widows/orphans, stranded headings, and clipping when a renderer is pinned.
+
+2) **Increase enforced coverage where it buys down real pain**
+ - Citations and i18n where deterministic checks are feasible.
+ - Links/DOIs wrapping policies and table/code overflow strategies across profiles.
+
+3) **Forgejo integration**
+ - Apply profile CSS to Forgejo’s PDF exporter and emit QA reports as export artifacts.
+ - See `forgejo/README.md`.
+
+4) **More rule batches**
+ - Build out figures/links/code/frontmatter/backmatter/i18n breadth, then tighten enforcement coverage where feasible.
+
+## “Don’t lose work” reminder
+
+Chat logs are not durable. The repo is.
+
+- When you finish a chunk: `./scripts/checkpoint.sh "note"`
+- When you resume: `./scripts/audit.sh` + `./scripts/ci.sh`
diff --git a/docs/09-project-status.md b/docs/09-project-status.md
new file mode 100644
index 0000000..aff1b6a
--- /dev/null
+++ b/docs/09-project-status.md
@@ -0,0 +1,149 @@
+# `iftypeset` — Project Status (2026-01-03)
+
+## What This Project Is
+
+`iftypeset` is a thin, deterministic **typeset runtime** for turning Markdown into:
+
+- Stable, shareable HTML (`render-html`)
+- A PDF (`render-pdf`)
+- Machine-readable quality reports (`lint`, `qa`, `report`)
+
+It is paired with a **machine-readable rule registry** derived from:
+
+- Chicago Manual of Style (CMOS 18)
+- Bringhurst (*Elements of Typographic Style*)
+
+Important: rule records are **paraphrases only** with **pointer refs** (e.g., `CMOS18 §6.2 p377 (scan p10)`). This repo must not contain book text.
+
+## What Works Today
+
+Verified on `master` via `./scripts/ci.sh` (spec validate + report + unit tests):
+
+- End-to-end CLI: `validate-spec`, `report`, `lint`, `render-html`, `render-pdf`, `qa`, `emit-css`
+- Deterministic lint engine with safe rewrite mode (`lint --fix --fix-mode rewrite`)
+- Deterministic HTML rendering; PDF rendering works when an engine is available (Playwright is the default)
+- QA analyzer (HTML + PDF heuristics) with incident details:
+ - long/bare URL/DOI/email wrap incidents
+ - overfull token detection
+ - table/code overflow incidents (profile-aware thresholds)
+ - PDF-aware widow/orphan heuristics via Poppler text extraction (`pdftotext -layout`)
+ - PDF-aware runt final page detection (short last page heuristics)
+- CI wiring for Forgejo: `.forgejo/workflows/ci.yml`
+- Session resilience tooling:
+ - `./scripts/audit.sh` prints a compact truth snapshot (git + coverage + checkpoints)
+ - `./scripts/checkpoint.sh "note"` creates a portable restore tarball recorded in `docs/CHECKPOINTS.md`
+
+## Rule Registry Snapshot (Real Counts)
+
+From `out/coverage-report.json` (generated by `PYTHONPATH=src python3 -m iftypeset.cli report --spec spec --out out`):
+
+- **Total rules:** 524
+- **Enforcement split:** manual 379, typeset 62, lint 70, postrender 13
+- **Severity split:** must 37, should 470, warn 17
+
+Category counts:
+
+- editorial 45
+- citations 61
+- numbers 62
+- punctuation 55
+- layout 46
+- headings 32
+- tables 23
+- links 21
+- i18n 27
+- abbreviations 27
+- code 28
+- accessibility 22
+- frontmatter 20
+- backmatter 18
+- figures 22
+
+## Coverage Map Summary (Sections)
+
+Generated by `python3 tools/coverage_summary.py --coverage-dir spec/coverage --out-json out/coverage-summary.json --out-md out/coverage-summary.md`:
+
+- BRING: 64 sections, 284 rules (all partial)
+- CMOS18: 176 sections, 550 rules (all partial)
+- Total unique rule_ids across coverage maps: 834
+- typography 15
+
+Interpretation:
+
+- The registry is intentionally larger than the enforcement surface.
+- Many rules remain `manual_checklist=true` by design until we have deterministic enforcement for them.
+
+## What This Is *Not* Yet
+
+- A full “publication-grade PDF QA” system. PDF-aware checks exist, but are heuristic (text extraction based) and limited in scope.
+- A complete automated implementation of Chicago/Bringhurst. The registry is pointer-backed; enforcement is incremental and explicit.
+
+## How To Run (Quick)
+
+```bash
+cd /root/ai-workspace/iftypeset
+```
+
+Validate + rebuild indexes:
+
+```bash
+PYTHONPATH=src python3 -m iftypeset.cli validate-spec --spec spec --build-indexes
+```
+
+Generate coverage report:
+
+```bash
+PYTHONPATH=src python3 -m iftypeset.cli report --spec spec --out out --build-indexes
+```
+
+Lint (and optionally autofix):
+
+```bash
+PYTHONPATH=src python3 -m iftypeset.cli lint --input fixtures/sample.md --out out --profile web_pdf
+PYTHONPATH=src python3 -m iftypeset.cli lint --input fixtures/sample.md --out out --profile web_pdf --fix --fix-mode rewrite
+```
+
+Render HTML + PDF:
+
+```bash
+PYTHONPATH=src python3 -m iftypeset.cli render-html --input fixtures/sample.md --out out --profile web_pdf
+PYTHONPATH=src python3 -m iftypeset.cli render-pdf --input fixtures/sample.md --out out --profile web_pdf
+```
+
+Run QA:
+
+```bash
+PYTHONPATH=src python3 -m iftypeset.cli qa --out out --profile web_pdf
+```
+
+Sanity check:
+
+```bash
+./scripts/ci.sh
+```
+
+## Don’t Lose Work (Session Resets)
+
+Chat logs are not durable. The repo is.
+
+- Snapshot: `./scripts/audit.sh`
+- Restore point: `./scripts/checkpoint.sh "short note"`
+- Checkpoint index: `docs/CHECKPOINTS.md`
+
+## What Remains (Prioritized)
+
+1) **Improve post-render QA beyond current heuristics**
+ - PDF-aware stranded headings / keep-with-next violations
+ - more reliable overflow/clipping detection when a renderer is pinned
+
+2) **Increase *implemented* rule coverage where it matters**
+ - citations normalization / author-date variants where feasible
+ - i18n/locale-driven checks (without pretending perfect automation)
+ - link/DOI wrapping policies (reduce broken PDFs)
+
+3) **Forgejo integration**
+ - use `iftypeset` as the Forgejo typeset/export worker
+ - emit QA artifacts as export attachments
+
+4) **Continue adding rule batches**
+ - prioritize what breaks real documents: figures, references, complex tables, long code blocks
diff --git a/docs/10-project-brief.md b/docs/10-project-brief.md
new file mode 100644
index 0000000..fd42da2
--- /dev/null
+++ b/docs/10-project-brief.md
@@ -0,0 +1,79 @@
+# `iftypeset` — Project Brief (downloadable)
+
+## What This Is
+
+`iftypeset` is a deterministic **Markdown → HTML → PDF** pipeline with:
+
+- A **machine-readable rule registry** (Chicago/Bringhurst-backed pointers; paraphrased rules only)
+- **Profiles** that map typographic intent → rendering tokens (`spec/profiles/*.yaml`)
+- **QA gates** that fail builds when layout degrades (`spec/quality_gates.yaml`)
+
+The wedge is not “perfect typography by AI”. The wedge is **CI for document quality**: measurable, reproducible, auditable.
+
+## Non‑Negotiables
+
+- No bulk OCR/transcription of Chicago/Bringhurst into the repo (copyright).
+- Rules are paraphrases with pointer refs (e.g., `CMOS18 §X.Y pNN (scan pMM)`).
+- If a rule cannot be automated safely, it must be tagged `manual_checklist=true` and emitted in `out/manual-checklist.md`.
+
+## Where We Are (2026‑01‑03 snapshot)
+
+Verified via `./scripts/ci.sh` (validate-spec + report + tests):
+
+- CLI: `validate-spec`, `report`, `lint`, `render-html`, `render-pdf`, `qa`, `emit-css`
+- Deterministic lint with safe rewrite mode (`lint --fix --fix-mode rewrite`)
+- Deterministic HTML rendering; PDF rendering works when an engine is available
+- QA (HTML-based v0) with incident details:
+ - bare URL/DOI/email wrap risk
+ - overfull token detection
+ - table/code overflow (profile-aware thresholds)
+- Forgejo CI workflow: `.forgejo/workflows/ci.yml`
+- Session resilience tooling:
+ - `./scripts/audit.sh`, `./scripts/resume.sh`, `./scripts/checkpoint.sh`
+ - checkpoints tracked in `docs/CHECKPOINTS.md`
+
+Rule registry snapshot (from `out/coverage-report.json`):
+
+- Total rules: 524
+- Enforced: 145 (lint + typeset + postrender)
+- Manual: 379
+
+The repo also emits a “trust contract” describing what is enforced vs manual:
+
+- `out/trust-contract.md`
+- `out/trust-contract.json`
+
+## What’s Next (priority order)
+
+1) **Make QA less “HTML heuristic” and more layout-aware**
+ - Add at least one truly page-aware detector (widows/orphans or stranded headings) with measurable thresholds.
+
+2) **Increase enforced coverage where it reduces real PDF pain**
+ - citations normalization variants
+ - link/DOI handling + wrap policy
+ - table/code overflow strategies
+
+3) **Forgejo integration**
+ - run `iftypeset` as a PDF export/typeset worker
+ - attach QA artifacts to exports
+
+4) **Expand rule batches**
+ - continue adding pointer-backed rules for remaining categories (figures, front/back matter, etc.)
+ - promote high-confidence rules from `manual` → `lint/typeset/postrender` incrementally
+
+## Quick Commands
+
+From repo root:
+
+- Resume sanity snapshot: `./scripts/resume.sh`
+- CI sanity: `./scripts/ci.sh`
+- Portable restore point: `./scripts/checkpoint.sh "note"`
+
+## Canonical “single source of truth” docs
+
+- `docs/09-project-status.md` (most current, short + factual)
+- `docs/06-project-overview.md` (narrative overview)
+- `docs/05-external-evaluation-prompt.md` (external review prompt)
+- `docs/07-session-resilience.md` (how to avoid “lost work”)
+- `docs/CHECKPOINTS.md` (restore points)
+
diff --git a/docs/11-project-summary.md b/docs/11-project-summary.md
new file mode 100644
index 0000000..16e79f9
--- /dev/null
+++ b/docs/11-project-summary.md
@@ -0,0 +1,130 @@
+# `iftypeset` — Project Summary (downloadable)
+
+## What this is
+
+`iftypeset` is a deterministic **document-quality runtime** for turning Markdown into:
+
+- `render.html` + `render.css` (stable, shareable)
+- `render.pdf` (stable *given pinned engine + fonts*)
+- quality artifacts (`lint-report.json`, `layout-report.json`, `qa-report.json`, `coverage-report.json`)
+
+The differentiator is **measurement + enforceability**:
+
+- A machine‑readable **rule registry** (`spec/rules/**.ndjson`) derived from Chicago/Bringhurst as **paraphrases only**, with **pointer refs** (no book text).
+- **Profiles** (`spec/profiles/*.yaml`) that map typographic intent into render tokens.
+- **QA gates** (`spec/quality_gates.yaml`) that fail builds when layout degrades.
+
+Positioning (honest): this is **CI for document quality**, not “we perfectly implement Chicago/Bringhurst.”
+
+## What works today (verified)
+
+Verified locally via `./scripts/ci.sh` (spec validate + report + tests):
+
+- CLI pipeline: `validate-spec`, `report`, `lint`, `render-html`, `render-pdf`, `qa`, `emit-css`
+- Deterministic lint (with safe rewrite mode) + manual checklist emission
+- Deterministic HTML output; PDF rendering works when an engine is available (Playwright is the default)
+- QA analyzer:
+ - HTML heuristics: bare URL/DOI/email wrap, overfull tokens, table/code overflow (profile-aware)
+ - PDF heuristics: widows/orphans via Poppler text extraction (`pdftotext -layout`)
+- Session resilience:
+ - `./scripts/audit.sh` (truth snapshot)
+ - `./scripts/state.sh` (writes `docs/SESSION_STATE.md`)
+ - `./scripts/checkpoint.sh "note"` (portable restore tarball + entry in `docs/CHECKPOINTS.md`)
+- “Trust contract” artifact emitted by `report`:
+ - `out/trust-contract.md` and `out/trust-contract.json`
+ - makes enforcement vs manual + QA limitations explicit
+
+## Rule registry snapshot (real counts)
+
+From `out/coverage-report.json` (generated by `report`):
+
+- Total rules: **524**
+- Enforcement split: **manual 379**, **typeset 62**, **lint 70**, **postrender 13**
+- Editorial category is no longer empty: **45** house-pointer editorial rules (manual-first)
+
+Interpretation:
+
+- The registry is intentionally broader than enforcement.
+- Manual rules are not a weakness if the system is explicit and generates checklists deterministically.
+
+## How to run (quick start)
+
+From repo root:
+
+```bash
+./scripts/ci.sh
+```
+
+Minimal manual run:
+
+```bash
+PYTHONPATH=src python3 -m iftypeset.cli validate-spec --spec spec --build-indexes
+PYTHONPATH=src python3 -m iftypeset.cli lint --input fixtures/sample.md --out out --profile web_pdf
+PYTHONPATH=src python3 -m iftypeset.cli render-html --input fixtures/sample.md --out out --profile web_pdf
+PYTHONPATH=src python3 -m iftypeset.cli render-pdf --input fixtures/sample.md --out out --profile web_pdf
+PYTHONPATH=src python3 -m iftypeset.cli qa --out out --profile web_pdf
+```
+
+## “Don’t lose work” (session resets)
+
+Chat logs are not durable. The repo is.
+
+- Resume: `./scripts/resume.sh`
+- Snapshot: `./scripts/audit.sh`
+- Pasteable state: `./scripts/state.sh` (updates `docs/SESSION_STATE.md`)
+- Restore point: `./scripts/checkpoint.sh "short note"`
+
+If a session “looks rolled back”, it’s usually because work wasn’t committed yet. Check:
+
+- `git status --porcelain`
+- `out/checkpoints/iftypeset_checkpoint_*.tar.gz`
+- `docs/CHECKPOINTS.md`
+
+## What remains (next work, prioritized)
+
+### 1) Deepen PDF-aware QA (beyond widows/orphans)
+
+High leverage detectors:
+
+- stranded headings / keep-with-next violations (PDF-aware)
+- more reliable overflow/clipping detection (tables/code, page bounds)
+
+Goal: make `qa` failures correlate strongly with “this PDF looks broken.”
+
+### 2) Increase implemented enforcement where it buys down real pain
+
+Focus areas:
+
+- citations normalization + i18n/locale checks where deterministic
+- link/DOI/email wrapping policies (reduce broken PDFs)
+- table + code overflow strategies across profiles
+
+Rule of thumb: implement what repeatedly causes layout incidents in fixtures.
+
+### 3) Forgejo integration (export worker)
+
+Target: use `iftypeset` as Forgejo’s typeset/export worker:
+
+- apply profiles + CSS to exported docs
+- emit QA artifacts as export attachments
+- treat “PDF export quality” as CI, not a best-effort feature
+
+### 4) Expand rule batches responsibly
+
+Continue batches where they matter for real docs:
+
+- figures, frontmatter/backmatter, references, long code blocks, complex tables
+- keep paraphrase + pointer discipline; no book text in repo
+
+## Canonical docs (start here)
+
+- `README.md`
+- `STATUS.md`
+- `docs/06-project-overview.md`
+- `docs/07-session-resilience.md`
+- `docs/08-handoff.md`
+- `docs/09-project-status.md`
+- `docs/10-project-brief.md`
+- `docs/05-external-evaluation-prompt.md`
+- `app/ARCHITECTURE.md`
+- `app/CLI_SPEC.md`
diff --git a/docs/12-codex-max-workload.md b/docs/12-codex-max-workload.md
new file mode 100644
index 0000000..7651cb9
--- /dev/null
+++ b/docs/12-codex-max-workload.md
@@ -0,0 +1,118 @@
+# Codex Max Workload (High-Leverage) — Forgejo PDF Integration + PDF QA Expansion
+
+This is the **next big acceleration chunk** for `iftypeset`.
+
+Goal: make `iftypeset` visibly valuable in the real world by wiring it into the existing Forgejo PDF export worker, then deepen PDF QA so we catch real pagination failures (beyond widows/orphans).
+
+## Non-negotiables
+
+- Do **not** OCR/transcribe Chicago/Bringhurst into the repo(s). Paraphrases + pointers only.
+- Keep dependencies minimal. Prefer stdlib + existing tooling already present in the environment.
+- Keep outputs deterministic. If a dependency/version makes determinism impossible, document it in a “trust contract” note instead of pretending.
+
+## Target repos
+
+- `iftypeset`: `/root/ai-workspace/iftypeset`
+- `forgejo-pdf`: `/root/ai-workspace/forgejo-pdf`
+
+## Part A — Integrate `iftypeset` CSS into Forgejo PDF export (primary goal)
+
+### A1) Understand current Forgejo PDF pipeline
+
+In `/root/ai-workspace/forgejo-pdf`, identify:
+
+- where Markdown is converted to HTML
+- where CSS is selected/loaded (currently `basic.css`, `professional.css`, etc.)
+- where PDF is rendered (Chromium / Playwright / Puppeteer / wkhtmltopdf / etc.)
+- how configuration is passed (env vars, config file, CLI args)
+
+Write a short “current pipeline” note in `forgejo-pdf/worker/pdf/README.md` (or existing docs file) so we can reason about changes later.
+
+### A2) Add a new theme option: `iftypeset-web_pdf`
+
+We want Forgejo to be able to select:
+
+- `basic`
+- `professional`
+- `iftypeset-web_pdf` (new)
+
+Implementation constraints:
+
+- The CSS file must ship with the worker (no network fetch at runtime).
+- The CSS must load **after** any base CSS so it can override.
+- The result should still render correctly even if some fonts are missing (font stack fallbacks).
+
+### A3) Generate and vendor the CSS from `iftypeset`
+
+In `iftypeset` the command exists:
+
+`iftypeset emit-css --spec spec --profile web_pdf --out out-css`
+
+Pick one approach:
+
+1. **Vendored CSS in `forgejo-pdf`** (recommended for now):
+ - Generate `out-css/iftypeset_web_pdf.css`
+ - Copy into `forgejo-pdf/worker/pdf/assets/css/iftypeset-web_pdf.css`
+ - Add a small “refresh script” in `forgejo-pdf/scripts/update_iftypeset_css.sh` that regenerates and copies the file.
+ - Document the source-of-truth as `iftypeset` + the refresh script.
+
+2. **Build-time generation** (optional later):
+ - During `forgejo-pdf` build, call `iftypeset emit-css` and bundle the output.
+
+### A4) Wire it into the render code path
+
+Update the Forgejo PDF worker so that selecting the new theme:
+
+- includes the CSS file in the HTML head
+- produces PDFs/HTML without breaking existing themes
+
+### A5) Tests + validation
+
+Add a minimal smoke test in `forgejo-pdf` that:
+
+- renders a small known fixture Markdown
+- verifies that the resulting HTML references `iftypeset-web_pdf.css`
+- (optional) verifies PDF generation completes
+
+Avoid checking in large PDF binaries. Prefer small text-based assertions (e.g., HTML contains a ` ` to the CSS).
+
+### A6) Documentation
+
+Update both repos:
+
+- `iftypeset/forgejo/README.md`: “how to enable `iftypeset-web_pdf` theme in forgejo-pdf”
+- `forgejo-pdf` docs: new theme option + how to refresh CSS
+
+## Part B — Expand PDF QA beyond widows/orphans (secondary goal)
+
+We already have PDF-aware widows/orphans via Poppler `pdftotext -layout`.
+
+Add 1–2 additional PDF incident kinds **without adding heavy dependencies**:
+
+1. **Stranded headings** (most valuable)
+ - detect headings at end of a page with insufficient following content (heuristic)
+2. **Overfull/clipping approximation**
+ - flag suspicious long lines that exceed measure, using `pdftotext -layout` and profile measure targets as heuristics
+
+Requirements:
+
+- Emit incidents with enough context to be actionable (page number, snippet, rule/tag).
+- Update `spec/quality_gates.yaml` metrics if needed (or map into existing ones).
+- Add fixtures + tests in `iftypeset/tests/` for the new incidents.
+- Update `STATUS.md` and `docs/06-project-overview.md` if behavior changes.
+
+## Completion checklist (what “done” looks like)
+
+- Forgejo PDF worker can render using `iftypeset-web_pdf` theme.
+- A refresh script exists to sync CSS from `iftypeset`.
+- Both repos have docs explaining how to use it.
+- CI stays green in both repos (or a clear note exists if one repo lacks CI).
+- `iftypeset` PDF QA reports at least one new PDF incident kind beyond widows/orphans.
+
+## After each major chunk
+
+- Run:
+ - `bash /root/ai-workspace/iftypeset/scripts/ci.sh`
+ - create an `iftypeset` checkpoint: `bash /root/ai-workspace/iftypeset/scripts/checkpoint.sh "note"`
+ - and if you touch `forgejo-pdf`, do the equivalent if that repo has checkpoint tooling (otherwise document `git rev-parse HEAD`).
+
diff --git a/docs/13-task-board.md b/docs/13-task-board.md
new file mode 100644
index 0000000..7a35758
--- /dev/null
+++ b/docs/13-task-board.md
@@ -0,0 +1,158 @@
+# Task Board (Multi-Session Coordination)
+
+This file is the **single coordination surface** for parallel Codex sessions.
+
+Goal: avoid prompt-pasting + idle agents by making “what to do next” a durable, repo-local queue.
+
+## Product contract (read first)
+
+`iftypeset` is a **Document CI tool**, not a “pretty PDF generator”.
+
+- Mental model: **profiles + gates + artifacts + exit codes** (rendering is one stage).
+- The one command humans/CI want: `iftypeset run --input --profile --out out/`
+- Keep this contract true as tasks evolve; don’t optimize for “looks nice locally” at the expense of determinism and CI clarity.
+- Full contract + CLI shape lives in `docs/14-document-ci-model.md`.
+
+## Live readiness gate (if.typeset) (not live)
+
+Black/white:
+- `if.typeset` remains `preview` in `if.registry.json` until all criteria below are satisfied and publicly reviewable.
+
+Gate criteria (all MUST be true):
+1) Public landing page exists at `/if/typeset` with a clear Document CI contract and no compliance claims.
+2) At least 1 public demo pack exists with reproducible steps and `if.trace` receipts (HTML-first links, one URL per line).
+3) Public contract exists for the `iftypeset run` pipeline (inputs, profiles, outputs, exit codes).
+4) Status flip to `live` happens only after the above are verified.
+
+## How to use this board
+
+1. **Claim** a task by editing its row:
+ - set `owner` (if you are using Codex CLI, include `[sid: …]` from `/status`)
+ - set `status=in_progress`
+ - add a short `working_set` (files/dirs you will touch)
+2. Do the work.
+3. Run `./scripts/ci.sh`.
+4. Create a restore point: `./scripts/checkpoint.sh "task : "`
+5. Update the row:
+ - `status=done`
+ - record the `checkpoint` filename + sha256 (from `docs/CHECKPOINTS.md`)
+
+## Coverage milestones (CMOS / BRING)
+
+Coverage is tracked in `spec/coverage/**` by **section**. For multi-session work, treat it as two milestones (details: `docs/19-coverage-roadmap.md`):
+
+- **Milestone A (mapped):** drive `status` from `uncovered` → `partial` by adding at least one paraphrased rule with a valid pointer (`source_refs`) and wiring `rule_ids` for that section.
+- **Milestone B (complete):** later completion pass to move `partial` → `covered` or `out_of_scope` (only after checking the section for remaining rule-bearing guidance).
+
+Collision note: if `IFTS-1346` is in progress (touches `spec/rules/**`), do not claim coverage batch tasks that edit `spec/rules/**` (including citations batches) until it is done.
+
+## Conflict avoidance rules (strict)
+
+- Do not work on the **same files** in parallel sessions.
+- If you must touch a shared file (e.g., `STATUS.md`), do it in a **small final pass** and announce it here first.
+- If a task row changes while you work, preserve the other session’s note and append your checkpoint details instead of overwriting.
+- Prefer **one area per session**:
+ - `src/iftypeset/*` (runtime)
+ - `spec/*` (registry + profiles)
+ - `../forgejo-pdf/*` (integration)
+ - `docs/*` (documentation)
+
+## Optional lock files (when needed)
+
+If a task must block others, create a lock file:
+
+- `docs/LOCK_ .md`
+
+Template:
+
+```text
+owner:
+created_at_utc:
+scope:
+notes:
+```
+
+Delete the lock when done.
+
+---
+
+## Queue
+
+Columns:
+- `status`: `todo` | `in_progress` | `blocked` | `done`
+- `owner`: human/session label (e.g., `codex-max`, `codex-mini`, `danny`)
+- `working_set`: paths to avoid collisions
+
+| id | status | owner | task | working_set | notes | checkpoint |
+|---:|:------:|:-----:|------|-------------|-------|-----------|
+| 1301 | done | codex-max | Build rule indexes on CI | `spec/indexes/*`, `src/iftypeset/spec.py` | Already wired in `scripts/ci.sh`; `index_builder.py` writes deterministically (sorted keys). Verified current behavior. | out/checkpoints/iftypeset_checkpoint_2026-01-04T05-20-47Z.tar.gz (sha256=3078a3cce3dca02336e49d3d4c261308f2078d22c0e6ace58bc6635f1b03f8b5) |
+| 1302 | done | codex-max | Expand PDF QA incidents | `src/iftypeset/qa.py`, `tests/test_qa.py` | Added `stranded_heading_pdf` + `overfull_line_pdf` heuristics and tests; merged into QA metrics/analysis_mode. | out/checkpoints/iftypeset_checkpoint_2026-01-04T05-20-47Z.tar.gz (sha256=3078a3cce3dca02336e49d3d4c261308f2078d22c0e6ace58bc6635f1b03f8b5) |
+| 1303 | done | codex-max | Improve Markdown parser robustness | `src/iftypeset/md_parser.py`, `tests/test_md_parser.py` | Added degraded fixtures; reduced false positives by gating hard-wrap continuation and missing-headings length; unwrap only on hard-wrap. | out/checkpoints/iftypeset_checkpoint_2026-01-04T05-58-38Z.tar.gz (sha256=42e99c3676c8423194cb3bbdca9ff635eff7bfd60af29a6ca0788b10aca7fe4d) |
+| 1304 | done | codex-max | Increase automated enforcement coverage | `src/iftypeset/linting.py`, `spec/rules/*` | Added deterministic lint for DOI references, ordinal suffix errors, and footnote marker placement; new tests added. | out/checkpoints/iftypeset_checkpoint_2026-01-04T06-03-53Z.tar.gz (sha256=a781c760a44691aa9ff110de6c6d2022280034be3d2c05c247c0c74a5e3048b9) |
+| 1305 | done | codex-max | Forgejo PDF integration (theme + CSS sync) | `../forgejo-pdf/*`, `forgejo/README.md` | Added `iftypeset-web_pdf` theme, vendored CSS + refresh script, smoke test, docs updates. Forgejo repo has no checkpoint; see current workspace state. | out/checkpoints/iftypeset_checkpoint_2026-01-04T05-20-47Z.tar.gz (sha256=3078a3cce3dca02336e49d3d4c261308f2078d22c0e6ace58bc6635f1b03f8b5) |
+| 1306 | done | codex-max | Packaging/UX pass | `README.md`, `STATUS.md`, `docs/06-project-overview.md` | Clarified quickstart + enforcement limits; updated status/overview notes. | out/checkpoints/iftypeset_checkpoint_2026-01-04T06-05-22Z.tar.gz (sha256=a3aa47e3ee759328e3531ed3a0c49801bb8cfd430cb403978ff91b9a18001746) |
+| 1307 | done | codex-max | Add one-shot `iftypeset run` (CI-style pipeline) | `src/iftypeset/cli.py`, `src/iftypeset/reporting.py`, `app/CLI_SPEC.md`, `README.md` | Added `run` command with `run-summary.json`, updated CLI spec/README, added integration test. | out/checkpoints/iftypeset_checkpoint_2026-01-04T06-10-01Z.tar.gz (sha256=d493f39ba9fcf708eb38cab11dd20762a4a361a3a635e30feedfad7e577c6d7c) |
+| 1308 | done | codex-max | Add repo config file support (`iftypeset.yaml`) | `src/iftypeset/config.py` (new), `src/iftypeset/cli.py`, `README.md`, `app/CLI_SPEC.md` | Added config loader + CLI overrides, docs and integration test. | out/checkpoints/iftypeset_checkpoint_2026-01-04T06-16-12Z.tar.gz (sha256=b978bb5cb21fbccd669307e800494b3344818e25fbae521df953f30e099cf595) |
+| 1309 | done | codex-max | Add CLI introspection helpers (profiles/gates/rules) | `src/iftypeset/cli.py`, `README.md`, `app/CLI_SPEC.md` | Added profiles/gates/rules commands and tests; documented in README/CLI spec. | out/checkpoints/iftypeset_checkpoint_2026-01-04T06-18-36Z.tar.gz (sha256=ab8c60da431acc224c189a180b20aa33d3173d49e10a7c9b179dfecd3c9261e5) |
+| 1310 | done | codex-max | Make `report` generate a human HTML index | `src/iftypeset/reporting.py`, `src/iftypeset/cli.py`, `docs/06-project-overview.md` | Added `out/report/index.html` summary + artifact links; tests updated. | out/checkpoints/iftypeset_checkpoint_2026-01-04T06-21-49Z.tar.gz (sha256=d3474fe4d820a4edaf1fc60e758359c22881418086468f83c62934059bcbe5ae) |
+| 1311 | done | codex-max | Confirm CI-friendly exit codes + stdout summary | `src/iftypeset/cli.py`, `app/CLI_SPEC.md`, `tests/test_integration.py` | Standardized exit codes (0/1/2/3), updated CLI spec + tests, run summary remains JSON. | out/checkpoints/iftypeset_checkpoint_2026-01-04T06-26-42Z.tar.gz (sha256=f87b3ceb300674577206a57254b5637274fd500f50f55c9ccf4432a675d9cf7b) |
+| 1312 | done | codex-max | QA → SARIF output (`out/qa-report.sarif`) | `src/iftypeset/qa.py`, `src/iftypeset/cli.py`, `app/CLI_SPEC.md`, `tests/test_qa.py` | Added `qa --format sarif` with SARIF mapping for incidents + gate failures; tests updated. | out/checkpoints/iftypeset_checkpoint_2026-01-04T09-44-43Z.tar.gz (sha256=462c75d2603d78ee51700f0b6b2e389b98a635f9e72e867cd2dd8ed92f1b78d6) |
+| 1313 | done | codex-max | Add `iftypeset doctor` (env + determinism report) | `src/iftypeset/cli.py`, `src/iftypeset/reporting.py`, `docs/*` | Added doctor command + reports, docs, and integration test. | out/checkpoints/iftypeset_checkpoint_2026-01-04T09-48-23Z.tar.gz (sha256=f5436a975ae2902bf322f78b876230cef20d2e2f434446be0c057a1a485661d7) |
+| 1314 | done | codex-max | Add `iftypeset bundle` (portable review pack) | `src/iftypeset/cli.py`, `src/iftypeset/reporting.py`, `scripts/*`, `docs/*` | Added bundle command + manifest + tests; updated docs. | out/checkpoints/iftypeset_checkpoint_2026-01-04T09-53-39Z.tar.gz (sha256=5ee682bc24e427261670d663e8e3fd1f6f6e7fa7e08c97802bbabfe21a30a55e) |
+| 1315 | done | codex-max | PDF bbox/overflow detection via Poppler XML | `src/iftypeset/qa.py`, `tests/test_qa.py` | Added `pdftohtml -xml` parsing for bbox overflow + incidents/tests/docs. | out/checkpoints/iftypeset_checkpoint_2026-01-04T10-06-12Z.tar.gz (sha256=26ef3f54ad8978b2e60d3bdb23b6299e6b2ba526503523326d1bf399c1c78fc5) |
+| 1316 | done | codex-max | Multi-doc runs + aggregate report index | `src/iftypeset/cli.py`, `src/iftypeset/reporting.py`, `tests/test_integration.py` | Added multi-doc `run` with per-doc outputs + top-level run index. | out/checkpoints/iftypeset_checkpoint_2026-01-04T10-01-21Z.tar.gz (sha256=52466c2ca8fb530c5dbccf822afa1425f69c87a2a5015d075e3f3246c9936be1) |
+| 1317 | done | codex-max | Docker pinned environment (Chromium + Poppler + fonts) | `Dockerfile`, `docs/*`, `.forgejo/workflows/*` | Added Dockerfile, .dockerignore, docs, and manual Docker CI workflow. | out/checkpoints/iftypeset_checkpoint_2026-01-04T10-09-36Z.tar.gz (sha256=c96375484ea01d930a02068a929d6d37ba71d2519137ad05f82cbb850cc0f1f1) |
+| 1318 | done | codex-mini | CLI PDF engine selection + require-pdf flag | `src/iftypeset/cli.py`, `src/iftypeset/rendering.py`, `src/iftypeset/config.py`, `app/CLI_SPEC.md`, `README.md`, `STATUS.md`, `tests/test_integration.py` | Added `--engine` and `--require-pdf` flags; run treats PDF failure as warning unless `--require-pdf`; config supports `engine` + `require_pdf`; docs/tests updated. | out/checkpoints/iftypeset_checkpoint_2026-01-04T14-41-49Z.tar.gz (sha256=728a877114c4263450946a7550a54d655c4d5db503ec14a352f84b9369c5454d) |
+| 1319 | done | codex-mini | Editorial automation heuristics v1 | `src/iftypeset/linting.py`, `spec/rules/editorial/*`, `tests/test_linting.py` | Implement safe editorial lints (ALL CAPS headings, draft markers, acronym-first-use hints) + tests; keep the rest manual. | Lint rule added for ALL CAPS headings; rule set to lint; tests updated; validate-spec run. Pytest not available in env. |
+| 1320 | done | codex-mini | Citations + i18n lint expansion | `src/iftypeset/linting.py`, `spec/rules/citations/*`, `spec/rules/i18n/*`, `tests/test_linting.py`, `spec/house/*` | Added author-date checks (year-only parenthetical + ref list year required), i18n mixed decimal/quote heuristics; new house pointers + rule batches; tests updated; validate-spec with indexes run. | |
+| 1321 | done | codex-max | Typeset/CSS profile depth for tables/figures/code | `spec/profiles/*.yaml`, `src/iftypeset/rendering.py`, `docs/06-project-overview.md` | Added figure handling + CSS tokens; tightened code/table tokens (wrap, layout, padding); profiles updated and documented. | out/checkpoints/iftypeset_checkpoint_2026-01-04T16-50-45Z.tar.gz (sha256=712c0c07d39443a985e22b2bd44898b9460f2c705ae129ad180bcc436bd15661) |
+| 1322 | done | codex-max | Rule coverage expansion Turn 1 (tables/figures/front/back/links) | `spec/rules/tables/*`, `spec/rules/figures/*`, `spec/rules/frontmatter/*`, `spec/rules/backmatter/*`, `spec/rules/links/*` | Added `v1_tables_003`, `v1_figures_004`, `v1_frontmatter_004`, `v1_backmatter_004`, `v1_links_004` (+120); validate/report run. | out/checkpoints/iftypeset_checkpoint_2026-01-04T15-36-58Z.tar.gz (sha256=c6c1e991ffb7f94a18a7a4c6e4e670b6177e4ba14050b118a1d6cc26c25eee83) |
+| 1323 | done | codex-max | Rule coverage expansion Turn 2 (typography/layout/links remainder) | `spec/rules/typography/*`, `spec/rules/layout/*`, `spec/rules/links/*` | Added `v1_layout_005`, `v1_links_005`, `v1_typography_003` (+170); total_rules=844. | out/checkpoints/iftypeset_checkpoint_2026-01-04T16-03-52Z.tar.gz (sha256=ab7164561a811802f59880db38cb6b99e31c0a849b55a5f6970d4591a89fb89a) |
+| 1324 | done | codex-max | Rule coverage expansion Turn 3 (punctuation/numbers/headings/abbreviations/accessibility) | `spec/rules/punctuation/*`, `spec/rules/numbers/*`, `spec/rules/headings/*`, `spec/rules/abbreviations/*`, `spec/rules/accessibility/*` | Added `v1_punctuation_003`, `v1_numbers_003`, `v1_headings_003`, `v1_abbreviations_004`, `v1_accessibility_004` (+104); totals: punctuation 67, numbers 91, headings 57, abbreviations 47, accessibility 40. | out/checkpoints/iftypeset_checkpoint_2026-01-04T16-27-47Z.tar.gz (sha256=82db561f98ac898097893018151868114e12fe96b6e8cf27a8cbe7408413fd84) |
+| 1325 | done | codex-mini | CLI flag matrix + doc-only parity audit | `docs/16-cli-flags.md` | Added CLI flag matrix + defaults/exit codes + config precedence; doc-only parity audit. | |
+| 1326 | done | codex-max | Rule coverage expansion Turn 4 (code/editorial) | `spec/rules/code/*`, `spec/rules/editorial/*`, `spec/house/HOUSE_CODE_POINTERS.md` | Added `v1_code_004`, `v1_editorial_002` (+38) and `HOUSE_CODE_POINTERS.md`; validate/report/CI run. | out/checkpoints/iftypeset_checkpoint_2026-01-04T17-05-45Z.tar.gz (sha256=ca932099b7ea535ee37881c8fbd391691c373a06266b3fb7e330c1cb3da705bb) |
+| 1327 | done | codex-max | Rule coverage expansion Turn 5 (accessibility+i18n+front/back+figures/tables+code) | `spec/rules/accessibility/*`, `spec/rules/i18n/*`, `spec/rules/frontmatter/*`, `spec/rules/backmatter/*`, `spec/rules/figures/*`, `spec/rules/tables/*`, `spec/rules/code/*`, `spec/house/*` | Added new HOUSE pointer docs and batches: `v1_accessibility_005`, `v1_i18n_005`, `v1_frontmatter_005`, `v1_backmatter_005`, `v1_figures_005`, `v1_tables_004`, `v1_code_005` (+43); validate/report/CI run. | out/checkpoints/iftypeset_checkpoint_2026-01-04T17-36-14Z.tar.gz (sha256=6051e382c0e09f1e9d5737110d82325cbc5a1e6b6afcf91e4990c8d9be172fe3) |
+| 1328 | done | codex-max | Turn 6: lint expansion + layout/typography + QA tighten + fixtures/tests | `src/iftypeset/linting.py`, `spec/rules/*`, `spec/quality_gates.yaml`, `fixtures/*`, `tests/*`, `spec/house/*` | Add new lint checks for citations/links, new house rules for layout/typography, tighten QA thresholds, add fixtures/tests. | out/checkpoints/iftypeset_checkpoint_2026-01-04T18-31-45Z.tar.gz (sha256=02f72e150f349bd3d22363654acc4c0fe0d3302ab566eeca84ff3632a70546f5) |
+| 1329 | done | codex-max | Promote citations manual rules to lint/postrender (phase 1) | `src/iftypeset/linting.py`, `spec/rules/citations/*`, `tests/test_linting.py`, `fixtures/*` | Convert safe manual rules to deterministic lint checks; add fixtures/tests. | out/checkpoints/iftypeset_checkpoint_2026-01-04T19-00-46Z.tar.gz (sha256=7a4b9a03e889b91cc59a247f76fa3e23471f4ead0db4d7424091e04d46c13b95) |
+| 1330 | done | codex-max | Promote layout+typography manual rules to lint/postrender (phase 1) | `src/iftypeset/linting.py`, `src/iftypeset/qa.py`, `spec/rules/layout/*`, `spec/rules/typography/*`, `tests/*`, `fixtures/*` | Add safe heuristics (HTML+PDF) and tighten tests. | out/checkpoints/iftypeset_checkpoint_2026-01-04T19-23-16Z.tar.gz (sha256=1da2bd36168525359ee559c3ef550994a5080b22a8c4cd76e3c0d2ccb822b26c) |
+| 1331 | done | codex-max | Promote links manual rules to lint (phase 1) | `src/iftypeset/linting.py`, `spec/rules/links/*`, `tests/test_linting.py`, `fixtures/*` | Add deterministic URL lint checks; add fixtures/tests. | out/checkpoints/iftypeset_checkpoint_2026-01-04T19-23-16Z.tar.gz (sha256=1da2bd36168525359ee559c3ef550994a5080b22a8c4cd76e3c0d2ccb822b26c) |
+| 1332 | done | codex-max | Promote accessibility manual rules to lint/postrender (phase 1) | `src/iftypeset/linting.py`, `src/iftypeset/qa.py`, `spec/rules/accessibility/*`, `tests/*`, `fixtures/*` | Add safe a11y lints; add fixtures/tests. | out/checkpoints/iftypeset_checkpoint_2026-01-04T19-23-16Z.tar.gz (sha256=1da2bd36168525359ee559c3ef550994a5080b22a8c4cd76e3c0d2ccb822b26c) |
+| 1333 | done | codex-max | PDF QA: detect caption separation (figure/table) | `src/iftypeset/qa.py`, `spec/rules/layout/*`, `tests/test_qa.py`, `fixtures/*` | Add PDF heuristic incidents for captions separated from figures/tables (pdftotext). | out/checkpoints/iftypeset_checkpoint_2026-01-04T19-36-17Z.tar.gz (sha256=6196acb5068176bc0f66b270644e3fed578150e3641834659a27ae04153bbd1b) |
+| 1334 | done | codex-max | PDF QA: list break + lonely list item heuristics | `src/iftypeset/qa.py`, `spec/rules/layout/*`, `tests/test_qa.py`, `fixtures/*` | Add PDF heuristics for list intro separated from list, and single-item breaks. | out/checkpoints/iftypeset_checkpoint_2026-01-04T19-36-17Z.tar.gz (sha256=6196acb5068176bc0f66b270644e3fed578150e3641834659a27ae04153bbd1b) |
+| 1335 | done | codex-max | PDF QA: heading proximity (heading followed by heading / too little content) | `src/iftypeset/qa.py`, `spec/rules/layout/*`, `tests/test_qa.py`, `fixtures/*` | Expand heading proximity checks using PDF text extraction (beyond stranded headings). | out/checkpoints/iftypeset_checkpoint_2026-01-04T19-36-17Z.tar.gz (sha256=6196acb5068176bc0f66b270644e3fed578150e3641834659a27ae04153bbd1b) |
+| 1336 | done | codex-max | Links auto phase 2: filetype labels + partial-word + html fallback + overlong labels | `src/iftypeset/linting.py`, `spec/rules/links/*`, `tests/test_linting.py`, `fixtures/*` | Add deterministic link text checks and auto lint rules. | out/checkpoints/iftypeset_checkpoint_2026-01-04T21-30-06Z.tar.gz (sha256=7fca95255ce5623b3fc6dd67863de466b2039dab7d16af7c474653bc66beed90) |
+| 1337 | done | codex-cli (gpt-5.2-high) | Coverage roadmap + coverage map scaffold | `docs/19-coverage-roadmap.md`, `spec/coverage/**`, `docs/13-task-board.md` | Add coverage roadmap, create coverage map files, and document section-level tracking. | out/checkpoints/iftypeset_checkpoint_2026-01-07T03-01-18Z.tar.gz (sha256=421ba9fd06c73fffd126fa103e662c2119409d4bc0d75322fe9cd7120246a45b) |
+| 1338 | done | | CMOS punctuation batch 1 (150–250 rules) | `spec/rules/punctuation/**`, `spec/indexes/**`, `spec/coverage/**` | Completed sections 6.17–6.77 plus prior batches; total 211 rules, coverage refreshed; CI + checkpoint (supersedes earlier checkpoint). | out/checkpoints/iftypeset_checkpoint_2026-01-07T13-21-20Z.tar.gz (sha256=c36701390a0e1e59344e57c770337bcb2a55a71a4e6ecb16a1c8c42417ed2b79) |
+| 1339 | done | | CMOS numbers batch 1 (150–250 rules) | `spec/rules/numbers/**`, `spec/indexes/**`, `spec/coverage/**` | Added v1_numbers_004 (152 rules) covering 9.1–9.36 plus coverage updates; CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-07T13-28-12Z.tar.gz (sha256=f79b65f7454c350fe2a669e24a185397e3e8ef56954d4d6fa29b276fb5a8050e) |
+| 1340 | done | | CMOS citations batch 1 (150–250 rules) | `spec/rules/citations/**`, `spec/indexes/**`, `spec/coverage/**` | Added v1_citations_006 (151 rules) covering 13.1–13.29, updated CMOS coverage map; CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-07T15-05-23Z.tar.gz (sha256=bb048267c831e00a7004c647b2cadb28a4211bade86920dda3658b421de948cc) |
+| 1341 | done | | BRING typography + layout batch 1 (150–250 rules) | `spec/rules/typography/**`, `spec/rules/layout/**`, `spec/indexes/**`, `spec/coverage/**` | Generated BRING coverage map for 213 existing typography/layout rules (57 sections); indexes + CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-07T13-34-42Z.tar.gz (sha256=ed49ff31a6f3aa04b8163c8eb2ef793a7374eb292a6f63182229e73aebfa3894) |
+| 1342 | done | | BRING headings + lists batch 1 (150–250 rules) | `spec/rules/headings/**`, `spec/indexes/**`, `spec/coverage/**` | Added BRING headings sections to coverage map (now 62 sections); indexes + CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-07T13-37-21Z.tar.gz (sha256=650e5c1cb14e2a7cf101606ed33b0c779351a9a777f944bafd05b5a5e49c21c7) |
+| 1343 | done | | Tables + figures batch 1 (CMOS+BRING) | `spec/rules/tables/**`, `spec/rules/figures/**`, `spec/indexes/**`, `spec/coverage/**` | Mapped 107 existing CMOS/BRING table+figure rules into coverage; indexes + CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-07T13-39-56Z.tar.gz (sha256=d06a4325110722325a5c1664b9aab658ae7daa873e3a3580e78e79a9d4c787ea) |
+| 1344 | done | | Links + code batch 1 (CMOS+BRING) | `spec/rules/links/**`, `spec/rules/code/**`, `spec/indexes/**`, `spec/coverage/**` | Added 12 CMOS/BRING rules (links + code) and merged into coverage; CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-07T13-45-22Z.tar.gz (sha256=50ca8dfc35d3a2a37a1405f9d4079a865beb8d5301815190876fc12472d03414) |
+| 1345 | done | | Coverage summary generator + status notes | `spec/coverage/**`, `tools/**`, `docs/09-project-status.md` | Added `tools/coverage_summary.py`, wrote JSON/MD outputs, updated status doc with coverage metrics; CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-07T13-48-30Z.tar.gz (sha256=acdfb749162d6cc68015252fcc5fb97e761d86b49a1a37d0feb0c069145db743) |
+| 1346 | done | codex-cli (gpt-5) [sid: 019b9959-198d-7f22-b5f6-e7b598c8392b] | Enforcement uplift: convert top manual rules | `src/iftypeset/linting.py`, `src/iftypeset/qa.py`, `spec/rules/**`, `tests/**` | Manual checklist now filters to `status=active`; deprecated duplicate manual link rules already covered by lint; tests + CI. | out/checkpoints/iftypeset_checkpoint_2026-01-08T02-32-29Z.tar.gz (sha256=f67b7e66bac77635c20eb67a19d4cfd19c67ba81e598aae3f4b3ac552ec8e5e1) |
+| 1347 | done | | CMOS citations coverage map expansion (13.30–13.54) | `spec/coverage/**`, `spec/indexes/**`, `docs/CHECKPOINTS.md`, `docs/SESSION_STATE.md` | Added uncovered stubs with pointers for sections 13.30–13.54; CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-07T16-16-51Z.tar.gz (sha256=1bd425530e38b0c184036284c599f3848005865655cd82529e8426753824bbfc) |
+| 1348 | done | codex-cli (gpt-5) [sid: 019b9959-198d-7f22-b5f6-e7b598c8392b] | CMOS citations batch 2 (13.30–13.54) | `spec/rules/citations/**`, `spec/indexes/**`, `spec/coverage/**` | Paraphrase rules for shortened citations + note commentary sections; update coverage; CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-07T16-58-28Z.tar.gz (sha256=83465c0cf67f41faceedd32dbbe6efbbd4d56f39bc719c088e8457c376da7437) |
+| 1349 | done | | CMOS citations coverage map expansion (13.55–13.73) | `spec/coverage/**`, `spec/indexes/**`, `docs/CHECKPOINTS.md`, `docs/SESSION_STATE.md` | Added uncovered stubs with pointers for sections 13.55–13.73; CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-07T16-18-36Z.tar.gz (sha256=d92bd833941d14e8c3e1a7ad08e474d324c1f84b30122e82f2226e988b6d0957) |
+| 1350 | done | codex-cli (gpt-5) [sid: 019b9959-198d-7f22-b5f6-e7b598c8392b] | CMOS citations batch 3 (13.55–13.73) | `spec/rules/citations/**`, `spec/indexes/**`, `spec/coverage/cmos18_sections.json` | Added missing section rules + mapped existing rules into coverage; CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T03-30-39Z.tar.gz (sha256=1981644b9360c07f438427f8bfc619cacb12ffc1d4b2076ceec4791f606065b8) |
+| 1351 | done | | CMOS citations coverage map expansion (13.74–13.90) | `spec/coverage/**`, `spec/indexes/**`, `docs/CHECKPOINTS.md`, `docs/SESSION_STATE.md` | Added uncovered stubs for sections 13.74–13.89; 13.90 heading not found in OCR (update: §13.90 located later; coverage entry added in task 1366). CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-07T16-21-51Z.tar.gz (sha256=ae332081fec080e14467a820461818cea1a7d8bc826a6b1efaa4c3589bd8c75c) |
+| 1352 | done | codex-cli (gpt-5) [sid: 019b9959-198d-7f22-b5f6-e7b598c8392b] | CMOS citations batch 4 (13.74–13.90) | `spec/rules/citations/**`, `spec/indexes/**`, `spec/coverage/cmos18_sections.json` | Added missing author-name/bibliography rules and mapped 13.74–13.89; 13.90 heading not found in OCR (update: coverage entry added in task 1366). CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T03-34-08Z.tar.gz (sha256=a98615e17b4a44ffc7e3a255bf12cdd05f4f696d2f7a7ab4d493cd8532bc71e2) |
+| 1353 | done | | CMOS citations coverage map expansion (13.92–13.108) | `spec/coverage/**`, `spec/indexes/**`, `docs/CHECKPOINTS.md`, `docs/SESSION_STATE.md` | Added uncovered stubs for sections 13.92–13.108; 13.91/13.94/13.99/13.107 headings not found in OCR (update: §13.91/§13.94/§13.107 located later; coverage entries added in task 1366; §13.99 still not found). CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-07T16-23-38Z.tar.gz (sha256=38c1ee8a4dd1aa04acce09a5467a1b83e03a0e5d2a11fb901936cf4431360936) |
+| 1354 | done | codex-cli (gpt-5) [sid: 019b9959-198d-7f22-b5f6-e7b598c8392b] | CMOS citations batch 5 (13.92–13.108) | `spec/rules/citations/**`, `spec/indexes/**`, `spec/coverage/cmos18_sections.json` | Added bibliography-format rules and mapped coverage for available sections; 13.94/13.99/13.107 headings not found in OCR (update: §13.94/§13.107 located later; coverage entries added in task 1366; §13.99 still not found). CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T03-37-40Z.tar.gz (sha256=b17b44b48a47ac0643b241174cde7a6653b87ff25cda00b82548ff99780f02e1) |
+| 1355 | done | | CMOS citations coverage map expansion (13.111–13.128) | `spec/coverage/**`, `spec/indexes/**`, `docs/CHECKPOINTS.md`, `docs/SESSION_STATE.md` | Added uncovered stubs for sections 13.111–13.128; 13.110 heading not found in OCR (update: §13.110 located later; coverage entry added in task 1366). CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-07T16-25-43Z.tar.gz (sha256=7f61613b84b51f111bc427def728eab42a0e250b4fce3a3281f0b03f17737045) |
+| 1356 | done | codex-cli (gpt-5) [sid: 019b9959-198d-7f22-b5f6-e7b598c8392b] | CMOS citations batch 6 (13.111–13.128) | `spec/rules/citations/**`, `spec/indexes/**`, `spec/coverage/cmos18_sections.json` | Added missing author-date rules and mapped 13.111–13.128; 13.110 heading not found in OCR (update: coverage entry added in task 1366). CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T03-42-42Z.tar.gz (sha256=c21fee9774f8fdd895a44a2f4de136a5f95d805bae26e18c94ca50c6833c11f0) |
+| 1357 | done | assistant (api gpt-5.2) | Session ID hygiene in `iftypeset/AGENTS.md` | `AGENTS.md`, `docs/13-task-board.md` | Added session-id hygiene section to `iftypeset/AGENTS.md` (and kept the board claim note); no checkpoint (avoid colliding with active code task). | |
+| 1358 | done | | Typography baseline: default 12pt body + add brand colors + table striping (fix “tiny text” reports) | `src/iftypeset/css_gen.py`, `spec/profiles/dense_tech.yaml`, `spec/profiles/memo.yaml`, `docs/CHECKPOINTS.md`, `docs/SESSION_STATE.md`, `AGENTS.md`, `docs/13-task-board.md` | Set CSS generator default body size to `12pt`; updated `dense_tech` + `memo` to 12pt baseline + brand colors + table striping; added header shading. Verified by rerendering flaneur report (dense_tech) and spot-checking PNG pre-renders; ran `./scripts/ci.sh`. | out/checkpoints/iftypeset_checkpoint_2026-01-07T17-34-10Z.tar.gz (sha256=c05b4ae504f5bf72795ed737f8f49e19b61906365f99a33d3ac2d58fe623c9e8) |
+| 1359 | done | | Inline citations: make `[Sxx]` clickable and anchor to sources section | `src/iftypeset/rendering.py`, `docs/CHECKPOINTS.md`, `docs/SESSION_STATE.md`, `docs/13-task-board.md` | Fixed citation token parsing and rendered `[S01]`-style citations as internal links (`href=\"#cite-s01\"`); source lines starting with `[Sxx]` get matching `id=\"cite-sxx\"` anchors. Verified via `render-html` grep + `./scripts/ci.sh`. | out/checkpoints/iftypeset_checkpoint_2026-01-07T20-16-27Z.tar.gz (sha256=e185bf2251b7ce6a275400d8a73a1a560166b3ad48c947f66e664fa587d14dfb) |
+| 1360 | done | | Add `audit_report` profile + QA gates for evidence-heavy reports (reduce false fails on long lines/tables) | `spec/profiles/audit_report.yaml`, `spec/quality_gates.yaml`, `docs/CHECKPOINTS.md`, `docs/SESSION_STATE.md`, `docs/13-task-board.md` | Added `audit_report` (12pt baseline, branded/striped tables, tolerant overfull measurement) + QA gates; verified via `iftypeset run --profile audit_report` on the flaneur report and `./scripts/ci.sh`. | out/checkpoints/iftypeset_checkpoint_2026-01-07T20-30-14Z.tar.gz (sha256=444a88b90bba249221931a45e07685328758bdc8db8a20b103ab494ff46202a6) |
+| 1361 | done | codex-cli (gpt-5) [sid: 019b9959-198d-7f22-b5f6-e7b598c8392b] | Milestone B: BRING completion pass (partial → covered/out_of_scope) | `spec/coverage/bring_sections.json`, `spec/indexes/**` | Marked all BRING sections as `covered`; CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T03-53-19Z.tar.gz (sha256=6f86b0c6d00fd44c1be67dad1ce5b3dbc0624254a1a93cfe684d7d68d63cb060) |
+| 1362 | done | codex-cli (gpt-5) [sid: 019b9959-198d-7f22-b5f6-e7b598c8392b] | Milestone B: CMOS ch6 completion pass (punctuation sections) | `spec/coverage/cmos18_sections.json`, `spec/indexes/**` | Marked all tracked CMOS chapter 6 sections as `covered`; CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T03-55-03Z.tar.gz (sha256=1c36b33ade3802dfb16a5fb72ce8e51c9ed7497f86c0ef2b18603d5bcd2e524e) |
+| 1363 | done | codex-cli (gpt-5) [sid: 019b9959-198d-7f22-b5f6-e7b598c8392b] | Milestone B: CMOS ch9 completion pass (numbers sections) | `spec/coverage/cmos18_sections.json`, `spec/indexes/**` | Marked all tracked CMOS chapter 9 sections as `covered`; CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T03-56-40Z.tar.gz (sha256=f39d4c1668222d7b12b3ea2e6e3d773ccfedda2b1b1a5e409f715a875e831309) |
+| 1364 | done | codex-cli (gpt-5) [sid: 019b9959-198d-7f22-b5f6-e7b598c8392b] | Milestone B: CMOS ch13 completion pass (citations sections) | `spec/coverage/cmos18_sections.json`, `spec/indexes/**` | Marked all tracked CMOS chapter 13 sections as `covered`; CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T03-59-57Z.tar.gz (sha256=dd5c3236276eff74443e04e43f10844dcb21402e45e6c584d67cb6cf6fb25f79) |
+| 1365 | done | codex-cli (gpt-5) [sid: 019b9959-198d-7f22-b5f6-e7b598c8392b] | Milestone B: CMOS ch1/ch3/ch5/ch15 completion pass | `spec/coverage/cmos18_sections.json`, `spec/indexes/**` | Marked all tracked CMOS chapter 1/3/5/15 sections as `covered`; CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T03-58-16Z.tar.gz (sha256=a2626b2b59d158847a0ccd19ff177686e60166132e32a040ac7ca1568b7ddb4e) |
+| 1366 | done | assistant (api gpt-5.2) | CMOS ch13: add missing section entries (OCR present) | `spec/coverage/cmos18_sections.json`, `docs/13-task-board.md`, `spec/indexes/**`, `docs/CHECKPOINTS.md`, `docs/SESSION_STATE.md` | Added coverage entries for §13.90/§13.91/§13.94/§13.107/§13.110 (status=`uncovered`) and updated stale “not found in OCR” notes; corrected §13.109 pointer; note: §13.90 pointer + §13.99 were corrected/added in task 1367. CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T04-57-18Z.tar.gz (sha256=4dd9699bd9083677e9f2e688d1b313967a94ed73a81322e78a335d8a6c50753a) |
+| 1367 | done | assistant (api gpt-5.2) | CMOS ch13: close uncovered gaps (13.90/13.91/13.94/13.99/13.107/13.110) | `spec/rules/citations/**`, `spec/coverage/cmos18_sections.json`, `spec/indexes/**` | Added v1_citations_012 (one paraphrased rule per missing section), fixed §13.90/§13.110 pointer drift, added missing §13.99 coverage entry, and wired `rule_ids` (status→`partial`). CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T06-22-01Z.tar.gz (sha256=f3fba438d884adfb1523a0ff4e87b8ffc0e460b6992255c0543b63b4fa998572) |
+| 1368 | done | assistant (api gpt-5.2) | Coverage audit: OCR heading diff + spot-check recipe | `tools/**`, `docs/19-coverage-roadmap.md`, `docs/13-task-board.md` | Added `tools/coverage_ocr_audit.py` (numbers-only OCR heading diff + pointer sanity checks) and documented a repeatable spot-check recipe in `docs/19-coverage-roadmap.md`. CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T06-22-01Z.tar.gz (sha256=f3fba438d884adfb1523a0ff4e87b8ffc0e460b6992255c0543b63b4fa998572) |
+| 1369 | done | assistant (api gpt-5.2) [sid: unavailable] | Flaneur PDF: widen margins + eliminate Chromium CLI header/footer (Playwright-only) | `spec/profiles/audit_report.yaml`, `src/iftypeset/rendering.py`, `docs/**`, `Dockerfile` | Increased `audit_report` margins (18mm → 27mm); removed Chromium CLI PDF rendering (it injects date/path headers/footers on Chrome 143); Playwright PDF uses `prefer_css_page_size` + `scale=1`; list balancing now uses Playwright; docs/Docker updated. CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T09-39-02Z.tar.gz (sha256=2b7f1704eb57758e1252821bd3367b64f1705a2db254f3b0f58c44a2e8b30504) |
+| 1370 | done | assistant (api gpt-5.2) [sid: unavailable] | Rendering contract: ban Chromium engine + pin Python 3.12 for Playwright | `src/iftypeset/cli.py`, `src/iftypeset/rendering.py`, `Dockerfile`, `pyproject.toml`, `requirements.txt`, `docs/**`, `app/CLI_SPEC.md` | Chromium engine is banned at CLI parse-time; `--engine auto` routes to Playwright; CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T13-39-43Z.tar.gz (sha256=f0df3101b956213bb4303062aecdea80a88424c062b43f78a14ba125416ebe58) |
+| 1371 | done | assistant (api gpt-5.2) [sid: 019b9959-198d-7f22-b5f6-e7b598c8392b] | Fonts contract: prevent silent fallbacks + support corp font dirs | `src/iftypeset/{cli.py,rendering.py}`, `spec/profiles/audit_report.yaml`, `docs/**`, `app/CLI_SPEC.md` | Enforced a fonts contract (profile `fonts.require_primary` / `--strict-fonts`) and added `--font-dir` so corporate fonts can be supplied via mounted dirs; `render-log.json` now records font policy + embedded fonts. CI + checkpoint. | out/checkpoints/iftypeset_checkpoint_2026-01-08T17-55-08Z.tar.gz (sha256=23350894a965367138202c23fbe073400a38b5b936ceff75ae1faa80e6771552) |
diff --git a/docs/14-document-ci-model.md b/docs/14-document-ci-model.md
new file mode 100644
index 0000000..2c78e28
--- /dev/null
+++ b/docs/14-document-ci-model.md
@@ -0,0 +1,155 @@
+# `iftypeset` as Document CI (the mental model)
+
+`iftypeset` should behave like **eslint + a renderer + a preflight tool + a report generator**.
+
+Rendering is *one* stage. The product is: **profiles + gates + artifacts + exit codes**.
+
+This document is the “shared understanding” for humans and Codex sessions.
+
+---
+
+## The pipeline
+
+**Input:** Markdown (plus assets)
+**Profile:** `web_pdf`, `print_pdf`, `dense_tech`, `memo`, `slide_deck`
+**Pipeline:** `validate → lint → render → qa → report`
+**Output:**
+
+- Machine artifacts (`*.json`, optionally `*.sarif`)
+- Human artifacts (`*.md` and an `out/report/index.html`)
+- Deterministic outputs (or explicit nondeterminism in the trust contract)
+- Exit codes that CI can gate on (no “looks good on my machine”)
+
+---
+
+## The one command humans and CI want
+
+```bash
+iftypeset run --input docs/spec.md --profile web_pdf --out out
+```
+
+Expected behavior:
+
+- Runs the full pipeline.
+- Writes artifacts under `out/`.
+- Exits **non-zero** when must-level gates fail.
+- Prints a short, boring summary to stdout (what failed, where to look).
+
+---
+
+## Subcommands (when you want control)
+
+### Spec + registry
+
+```bash
+iftypeset validate-spec --spec spec --build-indexes
+iftypeset profiles list
+iftypeset gates show --profile web_pdf
+iftypeset rules list --category links
+iftypeset rules show HOUSE.LINKS.URLS.PREFER_HTTPS
+```
+
+### Lint (source-level)
+
+```bash
+iftypeset lint --input docs/spec.md --profile web_pdf --out out
+iftypeset lint --input docs/spec.md --profile web_pdf --out out --fix --fix-mode rewrite
+```
+
+### Rendering (adapter-based)
+
+```bash
+iftypeset render-html --input docs/spec.md --profile web_pdf --out out
+iftypeset render-pdf --input docs/spec.md --profile web_pdf --out out
+```
+
+### Post-render QA (where the money is)
+
+```bash
+iftypeset qa --out out --profile web_pdf
+```
+
+### Reports (human artifact hub + trust contract)
+
+```bash
+iftypeset report --spec spec --out out
+```
+
+Outputs a clickable hub:
+
+- `out/report/index.html`
+- `out/trust-contract.md` and `out/trust-contract.json`
+
+---
+
+## Exit codes (CI-friendly)
+
+The CLI should be unambiguous:
+
+- `0`: pass (no failing gates)
+- `1`: gate failed (must violations / gate thresholds breached)
+- `2`: usage/config error (bad flags, missing profile, missing input)
+- `3`: internal/tool error (renderer crash, missing dependency)
+
+If we ever add “nondeterminism detected” as a separate code, it must be documented here and in `app/CLI_SPEC.md`.
+
+---
+
+## Artifacts (what you keep)
+
+The durable contract is: everything important is written to `out/` and is stable across runs.
+
+Minimum set:
+
+- `out/lint-report.json`
+- `out/manual-checklist.md` (and optionally `.json`)
+- `out/render.html` + `out/render.css`
+- `out/render.pdf` (when a PDF engine is available)
+- `out/layout-report.json`
+- `out/qa-report.json`
+- `out/run-summary.json`
+- `out/trust-contract.{md,json}`
+- `out/report/index.html`
+
+The trust contract must state, in plain language:
+
+- what is enforced automatically vs manual checklist
+- QA limitations (what we detect vs what we currently miss)
+- determinism assumptions (renderer version, fonts, locale)
+
+---
+
+## Configuration
+
+Repo defaults live in `iftypeset.yaml`. Priority order:
+
+1. CLI flags
+2. `iftypeset.yaml`
+3. profile defaults
+4. hard defaults
+
+Humans need predictable overrides because humans are chaos.
+
+---
+
+## Profiles are the product
+
+A profile is a contract, not a vibe:
+
+- which rules apply
+- which are `must` vs `should`
+- which incidents fail gates
+- which tokens/CSS are used
+- which renderer(s) are recommended
+
+Everything emitted should name the profile explicitly.
+
+---
+
+## Traps to avoid
+
+- Treating `iftypeset` as “pretty PDF generator” instead of CI for doc quality.
+- Shipping false authority (big rule counts) without a clear enforced/manual split.
+- Overfitting to one renderer (adapters are the point).
+- Sneaking copyrighted text into the repo (paraphrase + pointer discipline is non-negotiable).
+
diff --git a/docs/14-external-review.md b/docs/14-external-review.md
new file mode 100644
index 0000000..db56f4d
--- /dev/null
+++ b/docs/14-external-review.md
@@ -0,0 +1,212 @@
+# iftypeset external review pack (public technical overview)
+
+This document is a self-contained brief for external reviewers. It explains what the project does, what is implemented today, how to verify it locally, and what limitations remain. It does not include any copyrighted book text.
+
+## Scope and non-negotiables
+
+- No Chicago/Bringhurst text is stored here. Rules are paraphrases with pointer refs only.
+- The runtime is deterministic by design, but PDF output still depends on the chosen renderer and fonts.
+- QA is rule- and heuristic-based; it does not claim perfect layout verification.
+
+## What iftypeset is
+
+`iftypeset` is a deterministic Markdown -> HTML -> PDF pipeline with:
+
+- a machine-readable rule registry (NDJSON) with paraphrased rules + pointers
+- profiles that map typographic intent into CSS tokens
+- lint + QA gates that surface layout failures and fail builds in CI
+
+The core value is not "pretty PDF." It is verifiable, repeatable quality gates and explicit limits.
+
+## What is implemented now
+
+Runtime surface (CLI):
+
+- `validate-spec`, `report`, `lint`, `render-html`, `render-pdf`, `qa`, `emit-css`, `run`
+- introspection: `profiles list`, `gates show`, `rules list`, `rules show`
+
+Artifacts produced:
+
+- `out/lint-report.json`, `out/manual-checklist.md/json`
+- `out/render.html`, `out/render.css`, `out/render.pdf` (if renderer present)
+- `out/layout-report.json`, `out/qa-report.json`
+- `out/coverage-report.json`, `out/coverage-summary.md`
+- `out/trust-contract.md/json`
+- `out/report/index.html` (HTML index of all artifacts)
+- `out/run-summary.json` (CI-style run summary)
+
+## Quick verification (local)
+
+From the repo root:
+
+```bash
+python3 -m venv .venv
+. .venv/bin/activate
+python3 -m pip install -r requirements.txt
+python3 -m pip install -e .
+
+iftypeset validate-spec --spec spec --build-indexes
+iftypeset run --input fixtures/sample.md --out out --profile web_pdf --degraded-ok --skip-pdf
+iftypeset report --spec spec --out out
+```
+
+Expected files after a successful run:
+
+- `out/run-summary.json`
+- `out/report/index.html`
+- `out/lint-report.json`
+- `out/render.html`
+- `out/layout-report.json`
+- `out/qa-report.json`
+
+If you have a PDF engine installed, omit `--skip-pdf` and expect `out/render.pdf` + `out/render-log.json`.
+
+## Proof points (code excerpts)
+
+Console entrypoint (shows the CLI is installed as a tool):
+
+```toml
+[project.scripts]
+iftypeset = "iftypeset.cli:main"
+```
+
+CI pipeline definition (ensures spec validation + report + tests run):
+
+```bash
+run_step "validate-spec" env PYTHONPATH=src python3 -m iftypeset.cli validate-spec --spec spec --build-indexes
+run_step "report" env PYTHONPATH=src python3 -m iftypeset.cli report --spec spec --out out --build-indexes
+run_step "tests" python3 -m unittest discover -s tests -p 'test_*.py'
+```
+
+End-to-end integration test (lint -> render -> qa):
+
+```python
+lint = subprocess.run([... "lint", "--input", fixture, "--out", out_dir, "--profile", "web_pdf"], ...)
+render = subprocess.run([... "render-html", "--input", fixture, "--out", out_dir, "--profile", "web_pdf"], ...)
+qa = subprocess.run([... "qa", "--out", out_dir, "--profile", "web_pdf"], ...)
+```
+
+CI-style `run` command writes a single summary artifact:
+
+```json
+{
+ "ok": true,
+ "exit_code": 0,
+ "started_at_utc": "...",
+ "finished_at_utc": "...",
+ "steps": [
+ {"name": "validate-spec", "rc": 0, "ok": true},
+ {"name": "lint", "rc": 0, "ok": true},
+ {"name": "render-html", "rc": 0, "ok": true},
+ {"name": "render-pdf", "rc": 3, "ok": false},
+ {"name": "qa", "rc": 0, "ok": true},
+ {"name": "report", "rc": 0, "ok": true}
+ ]
+}
+```
+
+## Rule registry (how to read it)
+
+- NDJSON files in `spec/rules/**.ndjson`
+- Schema in `spec/schema/rule.schema.json`
+- Pointers in `source_refs` (e.g., `CMOS18 §X.Y pNNN (scan pMMM)` or `HOUSE §... pN`)
+- No verbatim book text is stored in this repo
+
+Example record shape (paraphrased, non-quoted):
+
+```json
+{
+ "id": "HOUSE.LINKS.URLS.PREFER_HTTPS",
+ "category": "links",
+ "severity": "should",
+ "enforcement": "lint",
+ "rule_text": "Prefer https links in published outputs."
+}
+```
+
+## Lint and manual checklist
+
+- Automated rules are enforced in `src/iftypeset/linting.py`.
+- Non-automated rules are tagged `manual_checklist=true` and emitted to `out/manual-checklist.md`.
+- This ensures reviewers see what still needs human validation.
+
+## QA (HTML + PDF)
+
+HTML analysis:
+
+- detects overfull tokens, table/code overflow risk, long URL wrapping risk
+
+PDF analysis (heuristic):
+
+- uses Poppler (`pdfinfo`, `pdftotext -layout`) to extract per-page text
+- detects widows/orphans, stranded headings, overfull lines
+- warnings are explicit about heuristic limits
+
+## Renderers
+
+`render-pdf` uses the requested engine (default: `playwright`):
+
+1) `playwright` (preferred; supports header/footer templates)
+2) `wkhtmltopdf` (explicit `--engine wkhtmltopdf` only)
+3) `weasyprint` (explicit `--engine weasyprint` only)
+
+If no engine is present, `render-pdf` returns exit code 3 and QA continues with HTML.
+
+## Trust contract
+
+`iftypeset report` generates:
+
+- `out/trust-contract.md`
+- `out/trust-contract.json`
+
+These explicitly state:
+
+- enforced vs manual coverage
+- QA limitations
+- determinism assumptions
+
+This is the preferred artifact for external review.
+
+## Production readiness (what is true today)
+
+Verified by CI and tests:
+
+- spec validation and coverage reporting are deterministic
+- lint emits JSON + manual checklist and is stable across runs
+- HTML rendering is deterministic given the same inputs
+- QA gates are enforced with explicit exit codes
+- `run` provides a single CI-friendly summary artifact
+
+Known limitations:
+
+- PDF QA is heuristic, not geometry-accurate
+- PDF output depends on renderer + font availability, but `render-log.json` records font resolution/embedding and profiles can enforce a strict fonts contract to prevent silent fallbacks
+- not all rules are automated; manual checklist remains required
+
+## Where to look in the repo
+
+- CLI: `src/iftypeset/cli.py`
+- Linting: `src/iftypeset/linting.py`
+- QA: `src/iftypeset/qa.py`
+- Rendering: `src/iftypeset/rendering.py`
+- Rule schema: `spec/schema/rule.schema.json`
+- Rule batches: `spec/rules/**.ndjson`
+- Profiles: `spec/profiles/*.yaml`
+- Trust contract: `out/trust-contract.md` (generated)
+- Report index: `out/report/index.html` (generated)
+
+## Forgejo integration (worker)
+
+The Forgejo worker can load the `iftypeset-web_pdf` theme (vendored CSS). See:
+
+- `forgejo/README.md` in this repo
+- `worker/pdf/README.md` in the forgejo-pdf repo
+
+## Contact and review checklist
+
+For external review, please verify:
+
+1) `iftypeset run` succeeds and produces `out/run-summary.json`
+2) `out/report/index.html` links to all expected artifacts
+3) `out/trust-contract.md` reflects the current enforcement split
+4) `out/manual-checklist.md` exists and is non-empty
diff --git a/docs/15-docker.md b/docs/15-docker.md
new file mode 100644
index 0000000..1445a09
--- /dev/null
+++ b/docs/15-docker.md
@@ -0,0 +1,64 @@
+# Docker runtime (pinned, reproducible)
+
+Goal: provide a **deterministic-ish** runtime that includes Playwright (browser-based PDF), Poppler, and fonts so
+Markdown → HTML → PDF pipelines behave the same in CI and on developer machines.
+
+## What’s included
+
+- Base image: `python:3.12.12-slim-bookworm`
+- Renderers: `playwright` (drives a headless browser for PDF)
+- QA tools: `poppler-utils` (`pdfinfo`, `pdftotext`, `pdftohtml`)
+- Fonts: `fonts-dejavu-core`, `fonts-liberation`, `fonts-noto-core`
+
+The Dockerfile lives at `Dockerfile` and installs pinned Python deps from `requirements.txt`.
+
+## Build
+
+```bash
+docker build -t iftypeset:dev .
+```
+
+## Run (single document)
+
+```bash
+docker run --rm \
+ -v "$PWD":/workspace \
+ -w /workspace \
+ iftypeset:dev \
+ iftypeset run --input fixtures/sample.md --out out --profile web_pdf --degraded-ok
+```
+
+## Corporate fonts (optional)
+
+To avoid font fallback drift (e.g., when shipping reader-facing PDFs), mount a directory containing `.ttf`/`.otf` files and pass it via `--font-dir`:
+
+```bash
+docker run --rm \
+ -v "$PWD":/workspace \
+ -v "$PWD/fonts":/fonts:ro \
+ -w /workspace \
+ iftypeset:dev \
+ iftypeset run --input fixtures/sample.md --out out --profile audit_report --font-dir /fonts --strict-fonts
+```
+
+## Run (directory / multi-doc)
+
+```bash
+docker run --rm \
+ -v "$PWD":/workspace \
+ -w /workspace \
+ iftypeset:dev \
+ iftypeset run --input fixtures --out out --profile web_pdf --degraded-ok --skip-pdf
+```
+
+## Version pinning notes
+
+- The base image tag is pinned to a specific Python + Debian release.
+- System package versions are pinned by the Debian snapshot at build time.
+- For auditability, run `iftypeset doctor --spec spec --out out` inside the container and
+ record `out/doctor.md` with the exact tool versions.
+
+## CI usage (Forgejo)
+
+A manual Forgejo workflow (`.forgejo/workflows/docker-ci.yml`) builds this image and runs
+`scripts/ci.sh` inside the container. Trigger it when you want an environment-pinned check.
diff --git a/docs/16-cli-flags.md b/docs/16-cli-flags.md
new file mode 100644
index 0000000..f21e5eb
--- /dev/null
+++ b/docs/16-cli-flags.md
@@ -0,0 +1,168 @@
+# iftypeset CLI flags (current v0 + parity notes)
+
+This file captures the **current CLI surface** (as of 2026-01-04) from `iftypeset --help` and per-command `--help`, plus how config overrides are resolved. It is doc-only; no code/spec edits.
+
+Sources used:
+- `app/CLI_SPEC.md` (target contract)
+- `src/iftypeset/config.py` (config precedence + keys)
+- CLI help output for each command
+
+## Precedence and config
+
+Order of precedence (highest → lowest):
+1. CLI flags
+2. `iftypeset.yaml` (in repo root or `spec/..`)
+3. Hard defaults
+
+Config sections:
+- `defaults`: global fallback values
+- Per-command section by name (hyphen → underscore)
+ - `render_html` / `render_pdf` also read from `render` section
+
+Supported config keys (from `config.py`):
+- `spec`, `out`, `profile`, `strict`, `format`, `fail_on`, `degraded_ok`,
+ `fix`, `fix_mode`, `self_contained`, `engine`, `require_pdf`, `skip_pdf`
+
+## Top-level flags
+
+```
+iftypeset [-h] [--config CONFIG] [--version]
+```
+
+- `--config`: path to `iftypeset.yaml` (default: `./iftypeset.yaml` when present)
+- `--version`: print version and exit
+
+## Command index (current)
+
+| Command | Purpose (short) | Required args | Key optional flags |
+| --- | --- | --- | --- |
+| `validate-spec` | Validate spec/rules; optional index build | none | `--spec`, `--out`, `--build-indexes` |
+| `profiles list` | List profiles | none | `--spec` |
+| `gates show` | Show QA gates | none | `--spec`, `--profile`, `--strict` |
+| `rules list` | List rules with filters | none | `--spec`, `--category`, `--enforcement`, `--severity`, `--tag` |
+| `rules show` | Show rule by id | `rule_id` | `--spec` |
+| `report` | Coverage + report artifacts | none | `--spec`, `--out`, `--strict`, `--build-indexes` |
+| `doctor` | Environment diagnostics | none | `--spec`, `--out` |
+| `bundle` | Bundle out/ artifacts | none | `--out`, `--bundle`, `--max-size-mb` |
+| `run` | Full pipeline | `--input` | `--spec`, `--out`, `--profile`, `--strict`, `--format`, `--fail-on`, `--degraded-ok`, `--fix`, `--fix-mode`, `--self-contained`, `--engine`, `--require-pdf`, `--skip-pdf` |
+| `lint` | Lint + manual checklist | `--input` | `--spec`, `--out`, `--profile`, `--format`, `--fail-on`, `--degraded-ok`, `--fix`, `--fix-mode` |
+| `render-html` | Deterministic HTML/CSS | `--input` | `--spec`, `--out`, `--profile`, `--self-contained`, `--degraded-ok` |
+| `render-pdf` | Render PDF | `--input` | `--spec`, `--out`, `--profile`, `--self-contained`, `--engine` |
+| `qa` | Post-render QA | none | `--spec`, `--out`, `--html`, `--pdf`, `--profile`, `--strict`, `--format` |
+| `emit-css` | Emit profile CSS | none | `--spec`, `--profile`, `--out` |
+
+## Detailed flags by command
+
+### validate-spec
+```
+iftypeset validate-spec [--spec SPEC] [--out OUT] [--build-indexes]
+```
+- `--spec`: spec root (default: `./spec`)
+- `--out`: output dir (default: `./out`)
+- `--build-indexes`: write indexes to `spec/indexes/`
+
+### profiles list
+```
+iftypeset profiles list [--spec SPEC]
+```
+
+### gates show
+```
+iftypeset gates show [--spec SPEC] [--profile PROFILE] [--strict]
+```
+
+### rules list
+```
+iftypeset rules list [--spec SPEC] [--category CATEGORY]
+ [--enforcement ENFORCEMENT] [--severity SEVERITY] [--tag TAG]
+```
+
+### rules show
+```
+iftypeset rules show [--spec SPEC] rule_id
+```
+
+### report
+```
+iftypeset report [--spec SPEC] [--out OUT] [--strict] [--build-indexes]
+```
+
+### doctor
+```
+iftypeset doctor [--spec SPEC] [--out OUT]
+```
+
+### bundle
+```
+iftypeset bundle [--out OUT] [--bundle BUNDLE] [--max-size-mb MAX_SIZE_MB]
+```
+
+### run
+```
+iftypeset run --input INPUT [--spec SPEC] [--out OUT]
+ [--profile PROFILE] [--strict] [--format {json,sarif,text}]
+ [--fail-on {must,should,warn}] [--degraded-ok]
+ [--fix] [--fix-mode {suggest,rewrite}] [--lint-fixed]
+ [--self-contained] [--engine ENGINE]
+ [--require-pdf] [--skip-pdf]
+```
+
+### lint
+```
+iftypeset lint --input INPUT [--spec SPEC] [--out OUT]
+ [--profile PROFILE] [--format {json,sarif,text}]
+ [--fail-on {must,should,warn}] [--degraded-ok]
+ [--fix] [--fix-mode {suggest,rewrite}] [--lint-fixed]
+```
+
+### render-html
+```
+iftypeset render-html --input INPUT [--spec SPEC] [--out OUT]
+ [--profile PROFILE] [--self-contained] [--degraded-ok]
+```
+
+### render-pdf
+```
+iftypeset render-pdf --input INPUT [--spec SPEC] [--out OUT]
+ [--profile PROFILE] [--self-contained] [--engine ENGINE]
+```
+
+### qa
+```
+iftypeset qa [--spec SPEC] [--out OUT] [--html HTML] [--pdf PDF]
+ [--profile PROFILE] [--strict] [--format {json,sarif}]
+```
+
+### emit-css
+```
+iftypeset emit-css [--spec SPEC] [--profile PROFILE] [--out OUT]
+```
+
+## Defaults (current)
+
+- `spec`: `./spec`
+- `out`: `./out`
+- `profile`: `web_pdf` (unless overridden by config)
+- `engine`: `playwright` (for `run` and `render-pdf`; use `--engine auto` for fallback)
+- `format`: `json` (when supported)
+- `fail-on`: `must`
+- `max-size-mb`: `50`
+
+## Exit codes (documented target)
+
+The current CLI aligns to the exit code model in `app/CLI_SPEC.md`:
+- `0`: success
+- `1`: gates/thresholds failed (lint/qa/report)
+- `2`: config/schema error
+- `3`: renderer/tool error (pdf)
+
+## Parity notes vs `app/CLI_SPEC.md`
+
+- `--config` exists at top-level and is honored by `config.py`.
+- `run` includes `--require-pdf` and `--skip-pdf`, matching the spec.
+- `lint` supports `--fix` and `--fix-mode`.
+- `lint` supports `--lint-fixed` to lint the rewritten output when using `--fix --fix-mode rewrite`.
+- `qa` supports `--format sarif` (HTML/PDF QA output).
+- `doctor`, `bundle`, and `emit-css` are implemented and documented.
+
+If new flags are added in code, update this file and the task board parity task.
diff --git a/docs/17-rendering-pipeline.md b/docs/17-rendering-pipeline.md
new file mode 100644
index 0000000..c24b44b
--- /dev/null
+++ b/docs/17-rendering-pipeline.md
@@ -0,0 +1,84 @@
+# Rendering pipeline (Markdown -> HTML -> PDF)
+
+This doc explains how a page is built. iftypeset always renders HTML + CSS first, then optionally renders PDF.
+
+## Flow diagram (file flow)
+
+```
+Markdown (.md)
+ |
+ v
+parse_markdown (src/iftypeset/md_parser.py)
+ |
+ v
+render-html (src/iftypeset/rendering.py)
+ |-- out/render.html
+ |-- out/render.css
+ |-- out/typeset-report.json
+ |-- out/degraded-mode-report.json (if degraded input)
+ |
+ v
+render-pdf (engine adapter)
+ |-- out/render.pdf
+ |-- out/render-log.json
+ |
+ v
+qa (src/iftypeset/qa.py)
+ |-- out/layout-report.json
+ |-- out/qa-report.json
+```
+
+Lint and reporting are parallel entry points that do not require PDF:
+
+```
+lint (src/iftypeset/linting.py)
+ |-- out/lint-report.json
+ |-- out/manual-checklist.md
+
+report (src/iftypeset/reporting.py)
+ |-- out/report/index.html
+ |-- out/coverage-report.json
+ |-- out/trust-contract.md
+ |-- out/trust-contract.json
+```
+
+## Step-by-step (what actually happens)
+
+1) Read Markdown, normalize newlines, detect degraded input, and unwrap hard wraps when needed.
+2) Parse Markdown into blocks (heading, paragraph, list, code fence, blockquote, table).
+3) Render HTML by mapping blocks to tags and applying inline transforms:
+ - Links and images are preserved
+ - Citation tokens like [S01] are wrapped for styling
+ - Optional small-caps wrapping for acronyms (profile-controlled)
+4) Generate CSS from the selected profile:
+ - Page size and margins
+ - Fonts and sizes
+ - Colors, tables, lists, figures, code blocks
+ - Running-head config (if enabled for supported engines)
+5) Render PDF using the requested engine (default: Playwright):
+ - Writes a render log with engine versions and warnings
+6) QA scans HTML output, and if a PDF exists it also runs PDF-aware heuristics.
+
+## Where to change behavior
+
+- Profiles and tokens: `spec/profiles/*.yaml`
+- HTML mapping + table typing: `src/iftypeset/rendering.py`
+- CSS generation: `src/iftypeset/css_gen.py`
+- Markdown parsing: `src/iftypeset/md_parser.py`
+- QA rules and thresholds: `src/iftypeset/qa.py`, `spec/quality_gates.yaml`
+- Lint rules and logic: `src/iftypeset/linting.py`, `spec/rules/**`
+
+## Commands (repro)
+
+```
+iftypeset render-html --input fixtures/sample.md --out out --profile web_pdf
+iftypeset render-pdf --input fixtures/sample.md --out out --profile web_pdf
+iftypeset qa --out out --profile web_pdf
+```
+
+## Notes on determinism
+
+- HTML + CSS is deterministic for the same input + profile.
+- PDF output depends on the renderer and installed fonts; versions are recorded in `out/render-log.json`.
+- Profiles can enable a strict fonts contract (`fonts.require_primary: true`) and the CLI can force it via `--strict-fonts`; use `--font-dir` to supply corporate fonts and avoid silent fallbacks.
+- Running heads are injected only for engines that support header/footer templates.
diff --git a/docs/18-webtypography-nc.md b/docs/18-webtypography-nc.md
new file mode 100644
index 0000000..29423fb
--- /dev/null
+++ b/docs/18-webtypography-nc.md
@@ -0,0 +1,31 @@
+# WebTypography profile (non-commercial)
+
+This repo includes a **non-commercial** profile inspired by WebTypography.net.
+
+## Profile id
+
+- `webtypography_nc`
+
+## License and attribution
+
+The profile is derived from guidance in WebTypography.net, which is licensed
+under **CC BY-NC 4.0** (Attribution-NonCommercial).
+
+If you use this profile, you must:
+
+- Attribute the source (WebTypography.net / clagnut/webtypography).
+- Use it **only for non-commercial purposes**.
+
+License reference:
+
+- https://creativecommons.org/licenses/by-nc/4.0/
+
+Source repository:
+
+- https://github.com/clagnut/webtypography
+
+## Notes
+
+- This profile is optional and not the default.
+- It is kept separate so commercial use of `iftypeset` can avoid non-commercial
+ constraints by selecting a different profile (e.g., `web_pdf`).
diff --git a/docs/19-coverage-roadmap.md b/docs/19-coverage-roadmap.md
new file mode 100644
index 0000000..6270b6f
--- /dev/null
+++ b/docs/19-coverage-roadmap.md
@@ -0,0 +1,92 @@
+# Rule Coverage Roadmap (CMOS / Bringhurst)
+
+Goal: move coverage close to **100% of rule-bearing sections** in the Chicago Manual of Style (18th ed) and Bringhurst (Elements of Typographic Style), without reproducing book text.
+
+## Definition of "100%"
+
+Coverage is **section-based**, not "full-book OCR." To keep multi-session work honest and queueable, we track two milestones:
+
+- **Milestone A (mapped):** a section is no longer `uncovered` once at least one paraphrased rule exists with a valid pointer. In practice this corresponds to `status=partial` in the coverage map.
+- **Milestone B (complete):** a section is only considered complete once it is marked `covered` or `out_of_scope`.
+ - `covered` means a completion pass was done and the section’s rule-bearing guidance is believed to be fully represented as paraphrased rules (no verbatim text).
+ - `out_of_scope` means the section is primarily narrative/historical/non-prescriptive and is explicitly excluded.
+
+This avoids over-claiming: `partial` means “some rules exist”, not “we’re done.”
+
+## Inputs (local only)
+
+- `/root/docs/_uploads/The Chicago Manual of Style (18th ed OCR).pdf`
+- `/root/docs/_uploads/Robert Bringhurst – The Elements of Typographic Style (OCR).pdf`
+
+OCR is used only to locate sections + page pointers. No verbatim text enters the repo.
+
+## Artifacts (new)
+
+- `spec/coverage/cmos18_sections.json`
+- `spec/coverage/bring_sections.json`
+- `spec/coverage/README.md`
+- `spec/coverage/coverage_summary.json` (optional, derived)
+
+Each entry should track: `section_id`, `title`, `pointer`, `status` (`uncovered|partial|covered|out_of_scope`), and `rule_ids[]`.
+
+## Phases
+
+### Phase 0: Coverage Map Scaffold
+- Create coverage files + schema conventions.
+- Seed with top-level sections and a few subsections to validate the workflow.
+
+### Phase 1: High-Impact Rules (CMOS)
+- numbers, punctuation, citations, headings, links.
+- Batch size: 150–250 rules per category.
+
+### Phase 2: Structure + Layout (BRING + CMOS)
+- typography, layout, widows/orphans, tables, figures.
+- Translate to `typeset`/`postrender` where possible.
+
+### Phase 3: Remaining Categories
+- code, front/back matter, accessibility, i18n.
+
+### Phase 4: Enforcement Uplift
+- Convert top-impact manual rules to `lint`/`postrender` where feasible.
+- Tighten QA gates without breaking deterministic behavior.
+
+## Rules of engagement
+
+- Paraphrase only; no verbatim text.
+- If exact wording is required, use: `Exact wording required—refer to pointer`.
+- Every rule must include a `source_refs` pointer.
+- Prefer **numbers-only** audits when validating coverage maps against OCR.
+- Run:
+ - `PYTHONPATH=src python3 -m iftypeset.cli validate-spec --spec spec --build-indexes`
+ - `./scripts/ci.sh`
+- Checkpoint after meaningful batches: `./scripts/checkpoint.sh "extraction batch "`
+
+## Spot checks (numbers only)
+
+To reduce “missing section” drift, use the OCR audit helper to compare **section numbers only**
+against the coverage map within a scan range (and to sanity-check pointer scan/printed pages).
+
+Example (CMOS18 chapter 13 slice):
+
+```bash
+python3 tools/coverage_ocr_audit.py \
+ --pdf "/root/docs/_uploads/The Chicago Manual of Style (18th ed OCR).pdf" \
+ --coverage spec/coverage/cmos18_sections.json \
+ --chapter 13 \
+ --scan-start 840 \
+ --scan-end 870 \
+ --out-json out/coverage-ocr-audit-ch13.json \
+ --out-md out/coverage-ocr-audit-ch13.md
+```
+
+Interpretation:
+- `OCR-only` section ids likely need new coverage entries.
+- `Coverage-only` section ids often indicate pointer drift or OCR weirdness (verify the scan page).
+- `Printed page mismatches` are strong signals that a pointer is wrong or that the scan page is not the referenced content.
+
+## Progress metrics
+
+- `% sections mapped` per book (non-`uncovered`).
+- `% sections complete` per book (`covered` + `out_of_scope`).
+- `must` rules implemented coverage (CI floor = 95%).
+- Overall implemented coverage (CI floor = 80%).
diff --git a/docs/CHECKPOINTS.md b/docs/CHECKPOINTS.md
index a0a03d3..03994ee 100644
--- a/docs/CHECKPOINTS.md
+++ b/docs/CHECKPOINTS.md
@@ -7,6 +7,7 @@ How to create a checkpoint:
- `./scripts/checkpoint.sh "short note about what changed"`
Each entry records the snapshot tarball path + sha256 and the CI JSON for that moment.
+Newer entries also include a `details` markdown file with a diffstat + working tree counts to make changes reviewable even if chat context is lost.
## 2026-01-03T20:09:44Z
@@ -15,3 +16,810 @@ Each entry records the snapshot tarball path + sha256 and the CI JSON for that m
- ci_json: `out/checkpoints/ci_2026-01-03T20-09-44Z.json`
- note: first checkpoint test
+
+## 2026-01-03T20:54:58Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-03T20-54-58Z.tar.gz`
+- snapshot_sha256: `adbc13a46b0141253f74fe7f0c9e2705f044525251831ac4ba4141a7e19d97bc`
+- ci_json: `out/checkpoints/ci_2026-01-03T20-54-58Z.json`
+- note: expanded rules to 479; CI green
+
+
+## 2026-01-03T21:02:54Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-03T21-02-54Z.tar.gz`
+- snapshot_sha256: `2014ff7c106196144541a76474f2a3251bcc2efef37e4d0f9d9a68820ba0521c`
+- ci_json: `out/checkpoints/ci_2026-01-03T21-02-54Z.json`
+- note: update STATUS to 479 rules; add repo AGENTS.md
+
+
+## 2026-01-03T21:08:41Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-03T21-08-41Z.tar.gz`
+- snapshot_sha256: `1a6a072f8efca84d0fa86e36a342822d7bf12e0af58e71b39a985cec898352c8`
+- ci_json: `out/checkpoints/ci_2026-01-03T21-08-41Z.json`
+- note: codex-max: QA analyzer improvements + lint rewrite safety + new fixtures/tests
+
+
+## 2026-01-03T21:21:04Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-03T21-21-04Z.tar.gz`
+- snapshot_sha256: `feab598ca674e5d54922276c926bbbd20f0da343046f1e9788cd3225810bf8fd`
+- ci_json: `out/checkpoints/ci_2026-01-03T21-21-04Z.json`
+- note: add docs/08-handoff.md; link from README
+
+
+## 2026-01-03T22:04:18Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-03T22-04-18Z.tar.gz`
+- snapshot_sha256: `cedfca7d70a93e0526e63b9833aa6a3c29703b51dc90d12c626141096a6a096e`
+- ci_json: `out/checkpoints/ci_2026-01-03T22-04-18Z.json`
+- note: add editorial rules: v1_editorial_001
+
+
+## 2026-01-03T22:12:03Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-03T22-12-03Z.tar.gz`
+- snapshot_sha256: `2a31b12bacf66ad38137d006d62b1f5093c0b84a1cf40b455c7605f8b50ea7ef`
+- ci_json: `out/checkpoints/ci_2026-01-03T22-12-03Z.json`
+- note: resume script + canonical status trap note
+
+
+## 2026-01-03T22:13:31Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-03T22-13-31Z.tar.gz`
+- snapshot_sha256: `017f0d4622586676454e0379a31361a1aeadf0fe41e89e8c353e7ac5362062e8`
+- ci_json: `out/checkpoints/ci_2026-01-03T22-13-31Z.json`
+- note: include AGENTS.md in checkpoints
+
+
+## 2026-01-03T22:19:23Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-03T22-19-23Z.tar.gz`
+- snapshot_sha256: `233e117f2973b77d6912788063bec4888c0e510ff07efd6aa2af484d2665e30a`
+- ci_json: `out/checkpoints/ci_2026-01-03T22-19-23Z.json`
+- note: trust contract + entrypoint
+
+
+## 2026-01-03T22:41:27Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-03T22-41-27Z.tar.gz`
+- snapshot_sha256: `089af30bbe08d0433534b667bf0fb9bd5a2af65c57d8e4e4dbab92e99c5759c1`
+- ci_json: `out/checkpoints/ci_2026-01-03T22-41-27Z.json`
+- note: docs: add project brief + session resilience note
+
+
+## 2026-01-03T22:57:22Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-03T22-57-22Z.tar.gz`
+- snapshot_sha256: `aba3cf17cb9a9d5793598fbda600f0c0fd026fea43565f031860419629ea6b3c`
+- ci_json: `out/checkpoints/ci_2026-01-03T22-57-22Z.json`
+- note: session state artifact + checkpoint integration
+
+
+## 2026-01-03T23:41:09Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-03T23-41-09Z.tar.gz`
+- snapshot_sha256: `35940c6df1c134281e3cfe9b14dc54c5a9c2fa018edd863cde7f9734d267ee22`
+- ci_json: `out/checkpoints/ci_2026-01-03T23-41-09Z.json`
+- note: pdf-aware QA (widows/orphans)
+
+
+## 2026-01-04T00:29:13Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T00-29-13Z.tar.gz`
+- snapshot_sha256: `dabe0e2acb1c83afcfa0ffe4ddd448439ad8b99267d22fbfb4a71ce2a09f542f`
+- ci_json: `out/checkpoints/ci_2026-01-04T00-29-13Z.json`
+- note: audit+session-state refresh
+
+
+## 2026-01-04T05:20:47Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T05-20-47Z.tar.gz`
+- snapshot_sha256: `3078a3cce3dca02336e49d3d4c261308f2078d22c0e6ace58bc6635f1b03f8b5`
+- ci_json: `out/checkpoints/ci_2026-01-04T05-20-47Z.json`
+- note: forgejo integration + pdf qa expansion
+
+## 2026-01-04T05:58:38Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T05-58-38Z.tar.gz`
+- snapshot_sha256: `42e99c3676c8423194cb3bbdca9ff635eff7bfd60af29a6ca0788b10aca7fe4d`
+- ci_json: `out/checkpoints/ci_2026-01-04T05-58-38Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T05-58-38Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=48 (modified=20, untracked=28)
+- note: task 1303: md parser robustness
+
+
+## 2026-01-04T06:03:53Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T06-03-53Z.tar.gz`
+- snapshot_sha256: `a781c760a44691aa9ff110de6c6d2022280034be3d2c05c247c0c74a5e3048b9`
+- ci_json: `out/checkpoints/ci_2026-01-04T06-03-53Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T06-03-53Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=48 (modified=20, untracked=28)
+- note: task 1304: lint enforcement coverage
+
+
+## 2026-01-04T06:04:12Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T06-04-12Z.tar.gz`
+- snapshot_sha256: `da61e7582893074d5c288ded916c75d3306d960847692ad2f9e7cfa326fab502`
+- ci_json: `out/checkpoints/ci_2026-01-04T06-04-12Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T06-04-12Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=48 (modified=20, untracked=28)
+- note: task board: add CI-style CLI roadmap tasks
+
+
+## 2026-01-04T06:05:22Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T06-05-22Z.tar.gz`
+- snapshot_sha256: `a3aa47e3ee759328e3531ed3a0c49801bb8cfd430cb403978ff91b9a18001746`
+- ci_json: `out/checkpoints/ci_2026-01-04T06-05-22Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T06-05-22Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=48 (modified=20, untracked=28)
+- note: task 1306: packaging and UX
+
+
+## 2026-01-04T06:10:01Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T06-10-01Z.tar.gz`
+- snapshot_sha256: `d493f39ba9fcf708eb38cab11dd20762a4a361a3a635e30feedfad7e577c6d7c`
+- ci_json: `out/checkpoints/ci_2026-01-04T06-10-01Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T06-10-01Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=49 (modified=21, untracked=28)
+- note: task 1307: run pipeline
+
+
+## 2026-01-04T06:16:12Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T06-16-12Z.tar.gz`
+- snapshot_sha256: `b978bb5cb21fbccd669307e800494b3344818e25fbae521df953f30e099cf595`
+- ci_json: `out/checkpoints/ci_2026-01-04T06-16-12Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T06-16-12Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=50 (modified=21, untracked=29)
+- note: task 1308: config support
+
+
+## 2026-01-04T06:18:36Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T06-18-36Z.tar.gz`
+- snapshot_sha256: `ab8c60da431acc224c189a180b20aa33d3173d49e10a7c9b179dfecd3c9261e5`
+- ci_json: `out/checkpoints/ci_2026-01-04T06-18-36Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T06-18-36Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=50 (modified=21, untracked=29)
+- note: task 1309: cli introspection
+
+
+## 2026-01-04T06:21:49Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T06-21-49Z.tar.gz`
+- snapshot_sha256: `d3474fe4d820a4edaf1fc60e758359c22881418086468f83c62934059bcbe5ae`
+- ci_json: `out/checkpoints/ci_2026-01-04T06-21-49Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T06-21-49Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=50 (modified=21, untracked=29)
+- note: task 1310: report index
+
+
+## 2026-01-04T06:26:42Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T06-26-42Z.tar.gz`
+- snapshot_sha256: `f87b3ceb300674577206a57254b5637274fd500f50f55c9ccf4432a675d9cf7b`
+- ci_json: `out/checkpoints/ci_2026-01-04T06-26-42Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T06-26-42Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=50 (modified=21, untracked=29)
+- note: task 1311: exit codes
+
+
+## 2026-01-04T09:44:43Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T09-44-43Z.tar.gz`
+- snapshot_sha256: `462c75d2603d78ee51700f0b6b2e389b98a635f9e72e867cd2dd8ed92f1b78d6`
+- ci_json: `out/checkpoints/ci_2026-01-04T09-44-43Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T09-44-43Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=52 (modified=21, untracked=31)
+- note: task 1312: qa sarif
+
+
+## 2026-01-04T09:48:23Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T09-48-23Z.tar.gz`
+- snapshot_sha256: `f5436a975ae2902bf322f78b876230cef20d2e2f434446be0c057a1a485661d7`
+- ci_json: `out/checkpoints/ci_2026-01-04T09-48-23Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T09-48-23Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=52 (modified=21, untracked=31)
+- note: task 1313: doctor report
+
+
+## 2026-01-04T09:53:39Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T09-53-39Z.tar.gz`
+- snapshot_sha256: `5ee682bc24e427261670d663e8e3fd1f6f6e7fa7e08c97802bbabfe21a30a55e`
+- ci_json: `out/checkpoints/ci_2026-01-04T09-53-39Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T09-53-39Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=52 (modified=21, untracked=31)
+- note: task 1314: bundle
+
+
+## 2026-01-04T10:01:21Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T10-01-21Z.tar.gz`
+- snapshot_sha256: `52466c2ca8fb530c5dbccf822afa1425f69c87a2a5015d075e3f3246c9936be1`
+- ci_json: `out/checkpoints/ci_2026-01-04T10-01-21Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T10-01-21Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=52 (modified=21, untracked=31)
+- note: task 1316: multi-doc run index
+
+
+## 2026-01-04T10:06:12Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T10-06-12Z.tar.gz`
+- snapshot_sha256: `26ef3f54ad8978b2e60d3bdb23b6299e6b2ba526503523326d1bf399c1c78fc5`
+- ci_json: `out/checkpoints/ci_2026-01-04T10-06-12Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T10-06-12Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=52 (modified=21, untracked=31)
+- note: task 1315: pdf bbox overflow
+
+
+## 2026-01-04T10:09:36Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T10-09-36Z.tar.gz`
+- snapshot_sha256: `c96375484ea01d930a02068a929d6d37ba71d2519137ad05f82cbb850cc0f1f1`
+- ci_json: `out/checkpoints/ci_2026-01-04T10-09-36Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T10-09-36Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=56 (modified=21, untracked=35)
+- note: task 1317: docker runtime
+
+
+## 2026-01-04T14:41:49Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T14-41-49Z.tar.gz`
+- snapshot_sha256: `728a877114c4263450946a7550a54d655c4d5db503ec14a352f84b9369c5454d`
+- ci_json: `out/checkpoints/ci_2026-01-04T14-41-49Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T14-41-49Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=58 (modified=22, untracked=36)
+- note: cli engine + require-pdf config/docs/tests
+
+
+## 2026-01-04T15:36:58Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T15-36-58Z.tar.gz`
+- snapshot_sha256: `c6c1e991ffb7f94a18a7a4c6e4e670b6177e4ba14050b118a1d6cc26c25eee83`
+- ci_json: `out/checkpoints/ci_2026-01-04T15-36-58Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T15-36-58Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=60 (modified=22, untracked=38)
+- note: turn1 rules: tables+figures+front/back+links
+
+
+## 2026-01-04T16:03:52Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T16-03-52Z.tar.gz`
+- snapshot_sha256: `ab7164561a811802f59880db38cb6b99e31c0a849b55a5f6970d4591a89fb89a`
+- ci_json: `out/checkpoints/ci_2026-01-04T16-03-52Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T16-03-52Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=63 (modified=22, untracked=41)
+- note: rule coverage expansion turn 2
+
+
+## 2026-01-04T16:27:47Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T16-27-47Z.tar.gz`
+- snapshot_sha256: `82db561f98ac898097893018151868114e12fe96b6e8cf27a8cbe7408413fd84`
+- ci_json: `out/checkpoints/ci_2026-01-04T16-27-47Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T16-27-47Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=67 (modified=22, untracked=45)
+- note: rule coverage expansion turn 3
+
+
+## 2026-01-04T16:50:45Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T16-50-45Z.tar.gz`
+- snapshot_sha256: `712c0c07d39443a985e22b2bd44898b9460f2c705ae129ad180bcc436bd15661`
+- ci_json: `out/checkpoints/ci_2026-01-04T16-50-45Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T16-50-45Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=81 (modified=81, untracked=0)
+- note: profile tokens for tables/figures/code
+
+
+## 2026-01-04T17:05:45Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T17-05-45Z.tar.gz`
+- snapshot_sha256: `ca932099b7ea535ee37881c8fbd391691c373a06266b3fb7e330c1cb3da705bb`
+- ci_json: `out/checkpoints/ci_2026-01-04T17-05-45Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T17-05-45Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=85 (modified=81, untracked=4)
+- note: task 1326: rule coverage turn 4 (code/editorial)
+
+
+## 2026-01-04T17:36:14Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T17-36-14Z.tar.gz`
+- snapshot_sha256: `6051e382c0e09f1e9d5737110d82325cbc5a1e6b6afcf91e4990c8d9be172fe3`
+- ci_json: `out/checkpoints/ci_2026-01-04T17-36-14Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T17-36-14Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=95 (modified=82, untracked=13)
+- note: task 1327: rule coverage turn 5 (a11y+i18n+front/back+figures/tables+code)
+
+
+## 2026-01-04T18:31:45Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T18-31-45Z.tar.gz`
+- snapshot_sha256: `02f72e150f349bd3d22363654acc4c0fe0d3302ab566eeca84ff3632a70546f5`
+- ci_json: `out/checkpoints/ci_2026-01-04T18-31-45Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T18-31-45Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=102 (modified=83, untracked=19)
+- note: task 1328: turn 6 (lint+rules+qa+fixtures)
+
+
+## 2026-01-04T19:00:46Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T19-00-46Z.tar.gz`
+- snapshot_sha256: `7a4b9a03e889b91cc59a247f76fa3e23471f4ead0db4d7424091e04d46c13b95`
+- ci_json: `out/checkpoints/ci_2026-01-04T19-00-46Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T19-00-46Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=104 (modified=83, untracked=21)
+- note: task 1329: citations lint promotion phase 1
+
+
+## 2026-01-04T19:23:16Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T19-23-16Z.tar.gz`
+- snapshot_sha256: `1da2bd36168525359ee559c3ef550994a5080b22a8c4cd76e3c0d2ccb822b26c`
+- ci_json: `out/checkpoints/ci_2026-01-04T19-23-16Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T19-23-16Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=111 (modified=84, untracked=27)
+- note: tasks 1330-1332: auto lint expansion
+
+
+## 2026-01-04T19:36:17Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T19-36-17Z.tar.gz`
+- snapshot_sha256: `6196acb5068176bc0f66b270644e3fed578150e3641834659a27ae04153bbd1b`
+- ci_json: `out/checkpoints/ci_2026-01-04T19-36-17Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T19-36-17Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=112 (modified=84, untracked=28)
+- note: tasks 1333-1335: pdf qa caption/list/heading heuristics
+
+
+## 2026-01-04T21:30:06Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-04T21-30-06Z.tar.gz`
+- snapshot_sha256: `7fca95255ce5623b3fc6dd67863de466b2039dab7d16af7c474653bc66beed90`
+- ci_json: `out/checkpoints/ci_2026-01-04T21-30-06Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-04T21-30-06Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=113 (modified=84, untracked=29)
+- note: task 1336: links auto phase 2
+
+
+## 2026-01-07T03:01:18Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T03-01-18Z.tar.gz`
+- snapshot_sha256: `421ba9fd06c73fffd126fa103e662c2119409d4bc0d75322fe9cd7120246a45b`
+- ci_json: `out/checkpoints/ci_2026-01-07T03-01-18Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T03-01-18Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=123 (modified=85, untracked=38)
+- note: task 1337 coverage roadmap + scaffold
+
+
+## 2026-01-07T03:09:55Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T03-09-55Z.tar.gz`
+- snapshot_sha256: `188bf9e09d842f3e958cd9bfa456230920f19523abf890ab2cb432f6817de9b8`
+- ci_json: `out/checkpoints/ci_2026-01-07T03-09-55Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T03-09-55Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=124 (modified=85, untracked=39)
+- note: task 1338 punctuation batch 1 (partial)
+
+
+## 2026-01-07T05:45:19Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T05-45-19Z.tar.gz`
+- snapshot_sha256: `dda82df0cf543fa8b52c5fd04962c8cebb1cd6ee1cd2db6528e7041660adf7ea`
+- ci_json: `out/checkpoints/ci_2026-01-07T05-45-19Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T05-45-19Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=124 (modified=85, untracked=39)
+- note: task 1338 punctuation batch 1 (sections 6.14-6.138)
+
+
+## 2026-01-07T05:52:06Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T05-52-06Z.tar.gz`
+- snapshot_sha256: `aab17fda1c849d96f3393ca60b5937be0478bd53728269878a92a7f1d1c914ea`
+- ci_json: `out/checkpoints/ci_2026-01-07T05-52-06Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T05-52-06Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=124 (modified=85, untracked=39)
+- note: task 1338 punctuation batch 1 (lists 6.139-6.143)
+
+
+## 2026-01-07T12:52:31Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T12-52-31Z.tar.gz`
+- snapshot_sha256: `9b47532fb8b9dfa54eeda74e29b1c2082cf4b6781ebeb33a2ed4e5688478ff1f`
+- ci_json: `out/checkpoints/ci_2026-01-07T12-52-31Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T12-52-31Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=124 (modified=85, untracked=39)
+- note: task 1338 punctuation batch 1 (sections 6.17-6.54)
+
+
+## 2026-01-07T13:21:20Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T13-21-20Z.tar.gz`
+- snapshot_sha256: `c36701390a0e1e59344e57c770337bcb2a55a71a4e6ecb16a1c8c42417ed2b79`
+- ci_json: `out/checkpoints/ci_2026-01-07T13-21-20Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T13-21-20Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=125 (modified=85, untracked=40)
+- note: task 1338 punctuation batch 1 (commas/semicolons/questions)
+
+
+## 2026-01-07T13:28:12Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T13-28-12Z.tar.gz`
+- snapshot_sha256: `f79b65f7454c350fe2a669e24a185397e3e8ef56954d4d6fa29b276fb5a8050e`
+- ci_json: `out/checkpoints/ci_2026-01-07T13-28-12Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T13-28-12Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=125 (modified=85, untracked=40)
+- note: task 1339 numbers batch 1 (9.1-9.36)
+
+
+## 2026-01-07T13:34:42Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T13-34-42Z.tar.gz`
+- snapshot_sha256: `ed49ff31a6f3aa04b8163c8eb2ef793a7374eb292a6f63182229e73aebfa3894`
+- ci_json: `out/checkpoints/ci_2026-01-07T13-34-42Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T13-34-42Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=125 (modified=85, untracked=40)
+- note: task 1341 bring typography+layout coverage map
+
+
+## 2026-01-07T13:37:21Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T13-37-21Z.tar.gz`
+- snapshot_sha256: `650e5c1cb14e2a7cf101606ed33b0c779351a9a777f944bafd05b5a5e49c21c7`
+- ci_json: `out/checkpoints/ci_2026-01-07T13-37-21Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T13-37-21Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=125 (modified=85, untracked=40)
+- note: task 1342 bring headings+lists coverage map
+
+
+## 2026-01-07T13:39:56Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T13-39-56Z.tar.gz`
+- snapshot_sha256: `d06a4325110722325a5c1664b9aab658ae7daa873e3a3580e78e79a9d4c787ea`
+- ci_json: `out/checkpoints/ci_2026-01-07T13-39-56Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T13-39-56Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=125 (modified=85, untracked=40)
+- note: task 1343 tables+figures coverage map
+
+
+## 2026-01-07T13:45:22Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T13-45-22Z.tar.gz`
+- snapshot_sha256: `50ca8dfc35d3a2a37a1405f9d4079a865beb8d5301815190876fc12472d03414`
+- ci_json: `out/checkpoints/ci_2026-01-07T13-45-22Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T13-45-22Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=128 (modified=85, untracked=43)
+- note: task 1344 links+code rules batch 1
+
+
+## 2026-01-07T13:48:30Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T13-48-30Z.tar.gz`
+- snapshot_sha256: `acdfb749162d6cc68015252fcc5fb97e761d86b49a1a37d0feb0c069145db743`
+- ci_json: `out/checkpoints/ci_2026-01-07T13-48-30Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T13-48-30Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=130 (modified=86, untracked=44)
+- note: task 1345 coverage summary generator
+
+
+## 2026-01-07T15:05:23Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T15-05-23Z.tar.gz`
+- snapshot_sha256: `bb048267c831e00a7004c647b2cadb28a4211bade86920dda3658b421de948cc`
+- ci_json: `out/checkpoints/ci_2026-01-07T15-05-23Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T15-05-23Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=130 (modified=86, untracked=44)
+- note: task 1340: citations batch 1
+
+
+## 2026-01-07T16:16:51Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T16-16-51Z.tar.gz`
+- snapshot_sha256: `1bd425530e38b0c184036284c599f3848005865655cd82529e8426753824bbfc`
+- ci_json: `out/checkpoints/ci_2026-01-07T16-16-51Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T16-16-51Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=130 (modified=86, untracked=44)
+- note: task 1347: CMOS citations coverage stubs 13.30-13.54
+
+
+## 2026-01-07T16:18:36Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T16-18-36Z.tar.gz`
+- snapshot_sha256: `d92bd833941d14e8c3e1a7ad08e474d324c1f84b30122e82f2226e988b6d0957`
+- ci_json: `out/checkpoints/ci_2026-01-07T16-18-36Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T16-18-36Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=130 (modified=86, untracked=44)
+- note: task 1349: CMOS citations coverage stubs 13.55-13.73
+
+
+## 2026-01-07T16:21:51Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T16-21-51Z.tar.gz`
+- snapshot_sha256: `ae332081fec080e14467a820461818cea1a7d8bc826a6b1efaa4c3589bd8c75c`
+- ci_json: `out/checkpoints/ci_2026-01-07T16-21-51Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T16-21-51Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=130 (modified=86, untracked=44)
+- note: task 1351: CMOS citations coverage stubs 13.74-13.89
+
+
+## 2026-01-07T16:23:38Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T16-23-38Z.tar.gz`
+- snapshot_sha256: `38c1ee8a4dd1aa04acce09a5467a1b83e03a0e5d2a11fb901936cf4431360936`
+- ci_json: `out/checkpoints/ci_2026-01-07T16-23-38Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T16-23-38Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=130 (modified=86, untracked=44)
+- note: task 1353: CMOS citations coverage stubs 13.92-13.108
+
+
+## 2026-01-07T16:25:43Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T16-25-43Z.tar.gz`
+- snapshot_sha256: `7f61613b84b51f111bc427def728eab42a0e250b4fce3a3281f0b03f17737045`
+- ci_json: `out/checkpoints/ci_2026-01-07T16-25-43Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T16-25-43Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=130 (modified=86, untracked=44)
+- note: task 1355: CMOS citations coverage stubs 13.111-13.128
+
+
+## 2026-01-07T16:58:28Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T16-58-28Z.tar.gz`
+- snapshot_sha256: `83465c0cf67f41faceedd32dbbe6efbbd4d56f39bc719c088e8457c376da7437`
+- ci_json: `out/checkpoints/ci_2026-01-07T16-58-28Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T16-58-28Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=131 (modified=86, untracked=45)
+- note: task 1348: cmos citations 13.30-13.54 rules+coverage
+
+
+## 2026-01-07T17:34:10Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T17-34-10Z.tar.gz`
+- snapshot_sha256: `c05b4ae504f5bf72795ed737f8f49e19b61906365f99a33d3ac2d58fe623c9e8`
+- ci_json: `out/checkpoints/ci_2026-01-07T17-34-10Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T17-34-10Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=131 (modified=86, untracked=45)
+- note: task 1358: 12pt baseline + brand colors + table striping
+
+
+## 2026-01-07T20:16:27Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T20-16-27Z.tar.gz`
+- snapshot_sha256: `e185bf2251b7ce6a275400d8a73a1a560166b3ad48c947f66e664fa587d14dfb`
+- ci_json: `out/checkpoints/ci_2026-01-07T20-16-27Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T20-16-27Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=131 (modified=86, untracked=45)
+- note: task 1359: clickable [Sxx] citations
+
+
+## 2026-01-07T20:30:14Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-07T20-30-14Z.tar.gz`
+- snapshot_sha256: `444a88b90bba249221931a45e07685328758bdc8db8a20b103ab494ff46202a6`
+- ci_json: `out/checkpoints/ci_2026-01-07T20-30-14Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-07T20-30-14Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=132 (modified=86, untracked=46)
+- note: task 1360: audit_report profile + QA gates
+
+
+## 2026-01-08T02:32:29Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T02-32-29Z.tar.gz`
+- snapshot_sha256: `f67b7e66bac77635c20eb67a19d4cfd19c67ba81e598aae3f4b3ac552ec8e5e1`
+- ci_json: `out/checkpoints/ci_2026-01-08T02-32-29Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T02-32-29Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=132 (modified=86, untracked=46)
+- note: task 1346: enforcement uplift (deprecate dup link rules; checklist filters status)
+
+
+## 2026-01-08T03:30:39Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T03-30-39Z.tar.gz`
+- snapshot_sha256: `1981644b9360c07f438427f8bfc619cacb12ffc1d4b2076ceec4791f606065b8`
+- ci_json: `out/checkpoints/ci_2026-01-08T03-30-39Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T03-30-39Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=133 (modified=86, untracked=47)
+- note: task 1350: CMOS citations mapped (13.55–13.73)
+
+
+## 2026-01-08T03:34:08Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T03-34-08Z.tar.gz`
+- snapshot_sha256: `a98615e17b4a44ffc7e3a255bf12cdd05f4f696d2f7a7ab4d493cd8532bc71e2`
+- ci_json: `out/checkpoints/ci_2026-01-08T03-34-08Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T03-34-08Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=134 (modified=86, untracked=48)
+- note: task 1352: CMOS citations mapped (13.74–13.89)
+
+
+## 2026-01-08T03:37:40Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T03-37-40Z.tar.gz`
+- snapshot_sha256: `b17b44b48a47ac0643b241174cde7a6653b87ff25cda00b82548ff99780f02e1`
+- ci_json: `out/checkpoints/ci_2026-01-08T03-37-40Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T03-37-40Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=135 (modified=86, untracked=49)
+- note: task 1354: CMOS citations mapped (13.92–13.108)
+
+
+## 2026-01-08T03:42:42Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T03-42-42Z.tar.gz`
+- snapshot_sha256: `c21fee9774f8fdd895a44a2f4de136a5f95d805bae26e18c94ca50c6833c11f0`
+- ci_json: `out/checkpoints/ci_2026-01-08T03-42-42Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T03-42-42Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=136 (modified=86, untracked=50)
+- note: task 1356: CMOS citations mapped (13.111–13.128)
+
+
+## 2026-01-08T03:53:19Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T03-53-19Z.tar.gz`
+- snapshot_sha256: `6f86b0c6d00fd44c1be67dad1ce5b3dbc0624254a1a93cfe684d7d68d63cb060`
+- ci_json: `out/checkpoints/ci_2026-01-08T03-53-19Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T03-53-19Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=136 (modified=86, untracked=50)
+- note: task 1361: BRING completion pass (covered)
+
+
+## 2026-01-08T03:55:03Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T03-55-03Z.tar.gz`
+- snapshot_sha256: `1c36b33ade3802dfb16a5fb72ce8e51c9ed7497f86c0ef2b18603d5bcd2e524e`
+- ci_json: `out/checkpoints/ci_2026-01-08T03-55-03Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T03-55-03Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=136 (modified=86, untracked=50)
+- note: task 1362: CMOS ch6 completion pass (covered)
+
+
+## 2026-01-08T03:56:40Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T03-56-40Z.tar.gz`
+- snapshot_sha256: `f39d4c1668222d7b12b3ea2e6e3d773ccfedda2b1b1a5e409f715a875e831309`
+- ci_json: `out/checkpoints/ci_2026-01-08T03-56-40Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T03-56-40Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=136 (modified=86, untracked=50)
+- note: task 1363: CMOS ch9 completion pass (covered)
+
+
+## 2026-01-08T03:58:16Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T03-58-16Z.tar.gz`
+- snapshot_sha256: `a2626b2b59d158847a0ccd19ff177686e60166132e32a040ac7ca1568b7ddb4e`
+- ci_json: `out/checkpoints/ci_2026-01-08T03-58-16Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T03-58-16Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=136 (modified=86, untracked=50)
+- note: task 1365: CMOS ch1/ch3/ch5/ch15 completion pass (covered)
+
+
+## 2026-01-08T03:59:57Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T03-59-57Z.tar.gz`
+- snapshot_sha256: `dd5c3236276eff74443e04e43f10844dcb21402e45e6c584d67cb6cf6fb25f79`
+- ci_json: `out/checkpoints/ci_2026-01-08T03-59-57Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T03-59-57Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=136 (modified=86, untracked=50)
+- note: task 1364: CMOS ch13 completion pass (covered)
+
+
+## 2026-01-08T04:57:18Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T04-57-18Z.tar.gz`
+- snapshot_sha256: `4dd9699bd9083677e9f2e688d1b313967a94ed73a81322e78a335d8a6c50753a`
+- ci_json: `out/checkpoints/ci_2026-01-08T04-57-18Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T04-57-18Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=136 (modified=86, untracked=50)
+- note: task 1366: add missing CMOS13 sections
+
+
+## 2026-01-08T06:22:01Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T06-22-01Z.tar.gz`
+- snapshot_sha256: `f3fba438d884adfb1523a0ff4e87b8ffc0e460b6992255c0543b63b4fa998572`
+- ci_json: `out/checkpoints/ci_2026-01-08T06-22-01Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T06-22-01Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=138 (modified=86, untracked=52)
+- note: tasks 1367/1368: ch13 gaps + OCR audit tool
+
+
+## 2026-01-08T09:39:02Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T09-39-02Z.tar.gz`
+- snapshot_sha256: `2b7f1704eb57758e1252821bd3367b64f1705a2db254f3b0f58c44a2e8b30504`
+- ci_json: `out/checkpoints/ci_2026-01-08T09-39-02Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T09-39-02Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=139 (modified=87, untracked=52)
+- note: task 1369: flaneur PDF margins + playwright-only
+
+
+## 2026-01-08T13:39:43Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T13-39-43Z.tar.gz`
+- snapshot_sha256: `f0df3101b956213bb4303062aecdea80a88424c062b43f78a14ba125416ebe58`
+- ci_json: `out/checkpoints/ci_2026-01-08T13-39-43Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T13-39-43Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=143 (modified=91, untracked=52)
+- note: task 1370: ban chromium engine + pin python 3.12
+
+
+## 2026-01-08T17:55:08Z
+
+- snapshot: `out/checkpoints/iftypeset_checkpoint_2026-01-08T17-55-08Z.tar.gz`
+- snapshot_sha256: `23350894a965367138202c23fbe073400a38b5b936ceff75ae1faa80e6771552`
+- ci_json: `out/checkpoints/ci_2026-01-08T17-55-08Z.json`
+- details: `out/checkpoints/checkpoint_2026-01-08T17-55-08Z.md`
+- git: `master` `626779d`
+- working_tree: dirty_paths=143 (modified=91, untracked=52)
+- note: task 1371: strict fonts + --font-dir
+
diff --git a/docs/SESSION_STATE.md b/docs/SESSION_STATE.md
new file mode 100644
index 0000000..8b35209
--- /dev/null
+++ b/docs/SESSION_STATE.md
@@ -0,0 +1,34 @@
+# Session State (generated)
+
+- generated_at_utc: `2026-01-08T17:55:32Z`
+- repo_root: `/root/ai-workspace/iftypeset`
+- git: `master` @ `626779d`
+- working_tree: dirty_paths=143 (modified=91, untracked=52)
+- latest_checkpoint: `out/checkpoints/iftypeset_checkpoint_2026-01-08T13-39-43Z.tar.gz`
+- latest_checkpoint_sha256: `f0df3101b956213bb4303062aecdea80a88424c062b43f78a14ba125416ebe58`
+- rules_total: `1657`
+- enforcement_split: `{'lint': 108, 'manual': 1392, 'postrender': 25, 'typeset': 132}`
+- categories: `{'abbreviations': 47, 'accessibility': 48, 'backmatter': 46, 'citations': 280, 'code': 58, 'editorial': 63, 'figures': 57, 'frontmatter': 47, 'headings': 57, 'i18n': 35, 'layout': 150, 'links': 70, 'numbers': 243, 'punctuation': 278, 'tables': 66, 'typography': 112}`
+
+## Canonical Docs
+- `README.md`
+- `STATUS.md`
+- `docs/06-project-overview.md`
+- `docs/07-session-resilience.md`
+- `docs/09-project-status.md`
+- `docs/10-project-brief.md`
+- `docs/12-codex-max-workload.md`
+- `docs/13-task-board.md`
+- `docs/17-rendering-pipeline.md`
+- `docs/CHECKPOINTS.md`
+
+## Fast Resume
+- `./scripts/resume.sh`
+- `./scripts/audit.sh`
+- `./scripts/state.sh`
+- `./scripts/ci.sh`
+- `./scripts/checkpoint.sh "note"`
+
+## Notes
+- If a chat/session resets and things look “rolled back”, check `latest_checkpoint` above and extract it on a new machine.
+- This file is copied into `docs/SESSION_STATE.md` so it is included in checkpoint snapshots (since `out/` is excluded).
diff --git a/fixtures/accessibility_alt_quality.md b/fixtures/accessibility_alt_quality.md
new file mode 100644
index 0000000..d128d61
--- /dev/null
+++ b/fixtures/accessibility_alt_quality.md
@@ -0,0 +1,6 @@
+# Alt text quality
+
+Avoid generic or filename-like alt text:
+
+
+
diff --git a/fixtures/citations_author_date_missing_refs.md b/fixtures/citations_author_date_missing_refs.md
new file mode 100644
index 0000000..aebc7c6
--- /dev/null
+++ b/fixtures/citations_author_date_missing_refs.md
@@ -0,0 +1,5 @@
+# Author-date without references
+
+Smith (2020) established the baseline for the method.
+
+Jones (2021) extended the approach with new evidence.
diff --git a/fixtures/citations_footnotes_sequence.md b/fixtures/citations_footnotes_sequence.md
new file mode 100644
index 0000000..a811892
--- /dev/null
+++ b/fixtures/citations_footnotes_sequence.md
@@ -0,0 +1,7 @@
+# Footnote sequence
+
+This sentence has a note.[^2] This next one has another.[^1]
+
+[^1]: First note.
+[^2]: Second note.
+
diff --git a/fixtures/citations_notes_lint.md b/fixtures/citations_notes_lint.md
new file mode 100644
index 0000000..4643e08
--- /dev/null
+++ b/fixtures/citations_notes_lint.md
@@ -0,0 +1,9 @@
+# Notes Lint Sample
+
+This sentence uses a bracketed numeric citation [1] that should be flagged.
+
+## Heading with note[^1] inline
+
+Some prose with a footnote marker.[^1]
+
+[^1]: Ibid., 12.
diff --git a/fixtures/degraded_hardwrap.md b/fixtures/degraded_hardwrap.md
new file mode 100644
index 0000000..7e40bf1
--- /dev/null
+++ b/fixtures/degraded_hardwrap.md
@@ -0,0 +1,26 @@
+this is a wrapped paragraph
+that continues on the next line
+without paragraph breaks and
+keeps wrapping as if copied
+from a pdf or scan with hard
+line breaks inserted by width
+this should be detected as
+a hard wrapped block and
+then unwrapped when parsing
+so lint can normalize text
+and avoid false line breaks
+this fixture stays short per
+line to trigger density checks
+and keep continuation patterns
+consistent across many lines
+so the parser sees hard wrap
+instead of a list or a poem
+each line starts with lowercase
+and avoids ending punctuation
+to emulate mid sentence wraps
+with enough lines to trip
+the degraded mode heuristic
+and confirm unwrapping works
+for deterministic parsing
+the last lines continue this
+pattern to stay long enough
diff --git a/fixtures/degraded_missing_headings.md b/fixtures/degraded_missing_headings.md
new file mode 100644
index 0000000..8b0df31
--- /dev/null
+++ b/fixtures/degraded_missing_headings.md
@@ -0,0 +1,12 @@
+this paragraph line is intentionally long enough to avoid hard wrap detection while still lacking headings.
+another long paragraph line that reads like a continuous note and should only trigger missing headings.
+third long line to exceed the minimum line count for missing headings without looking wrapped.
+fourth line keeps the text flowing with punctuation at the end to reduce continuation signals.
+fifth line stays long and descriptive to simulate a plain memo without structure.
+sixth line continues the memo format while staying well above the short line threshold.
+seventh line is similar in length and ends with a period to break any wrap heuristic.
+eighth line remains long and complete in order to avoid hard wrap density.
+ninth line is also a complete sentence with proper punctuation and spacing.
+tenth line maintains the same pattern so the parser sees consistent long lines.
+eleventh line extends the note into a longer block while still avoiding headings.
+twelfth line finalizes the sample to ensure missing headings is flagged for longer docs.
diff --git a/fixtures/editorial_draft_markers.md b/fixtures/editorial_draft_markers.md
new file mode 100644
index 0000000..978d1ef
--- /dev/null
+++ b/fixtures/editorial_draft_markers.md
@@ -0,0 +1,7 @@
+# Draft markers
+
+TODO: replace this sentence with real content.
+This section is TBD.
+
+Lorem ipsum dolor sit amet.
+
diff --git a/fixtures/editorial_structure_headings_lists.md b/fixtures/editorial_structure_headings_lists.md
new file mode 100644
index 0000000..ca330f3
--- /dev/null
+++ b/fixtures/editorial_structure_headings_lists.md
@@ -0,0 +1,15 @@
+Intro paragraph one.
+
+Intro paragraph two.
+
+- bullet one
+- bullet two
+
+# Late Title
+
+## Trailing colon:
+
+- only one item
+
+# Second Title
+
diff --git a/fixtures/layout_spacing.md b/fixtures/layout_spacing.md
index 91e3ccb..79abe7f 100644
--- a/fixtures/layout_spacing.md
+++ b/fixtures/layout_spacing.md
@@ -1,6 +1,13 @@
# Layout Spacing
-This paragraph is followed by another paragraph that should preserve
-consistent spacing in the rendered output.
+First paragraph.
-This is the follow-up paragraph.
+
+
+Second paragraph.
+
+## Empty Section
+
+## Next Section
+
+Body text.
diff --git a/fixtures/links_auto_checks.md b/fixtures/links_auto_checks.md
new file mode 100644
index 0000000..c74dada
--- /dev/null
+++ b/fixtures/links_auto_checks.md
@@ -0,0 +1,21 @@
+# Links Auto Checks
+
+See [stage](https://staging.example.com/path).
+
+See [internal](http://internal.local/path).
+
+See [ftp](ftp://example.com/file).
+
+See [track](https://example.com/page?utm_source=x).
+
+See [session](https://example.com/page?session=abc).
+
+See [invite](https://example.com/invite?token=abc1234567890).
+
+See [reset](https://example.com/reset?token=abc).
+
+See [login](https://example.com/login).
+
+See [creds](https://user:pass@example.com/).
+
+See [private](http://10.0.0.1/path).
diff --git a/fixtures/links_disallowed_schemes.md b/fixtures/links_disallowed_schemes.md
new file mode 100644
index 0000000..e15a51c
--- /dev/null
+++ b/fixtures/links_disallowed_schemes.md
@@ -0,0 +1,5 @@
+# Disallowed link schemes
+
+Do not ship outputs with links like file://etc/passwd or javascript:alert(1).
+Avoid localhost URLs such as http://localhost:8000/test in published docs.
+
diff --git a/fixtures/links_hazards.md b/fixtures/links_hazards.md
new file mode 100644
index 0000000..ccee284
--- /dev/null
+++ b/fixtures/links_hazards.md
@@ -0,0 +1,11 @@
+# Link hazards
+
+See [protocol-relative](//example.com/path).
+
+See [text fragment](https://example.com/page#:~:text=alpha).
+
+See [signed link](https://example.com/file?X-Amz-Signature=abc&X-Amz-Expires=3600).
+
+See [shortener](https://bit.ly/abc).
+
+See [ip literal](http://192.168.1.10/path).
diff --git a/fixtures/short_note.md b/fixtures/short_note.md
new file mode 100644
index 0000000..55307ba
--- /dev/null
+++ b/fixtures/short_note.md
@@ -0,0 +1,6 @@
+this is a short note without headings
+it is only a few lines long
+and should not be treated as degraded
+because the document is too small
+for structural inference or hard wrap
+the parser should leave it untouched
diff --git a/fixtures/typography_emphasis.md b/fixtures/typography_emphasis.md
new file mode 100644
index 0000000..cc2ff56
--- /dev/null
+++ b/fixtures/typography_emphasis.md
@@ -0,0 +1,9 @@
+# Typography Emphasis
+
+This has **BOLD TEXT THAT GOES ON FOR MANY WORDS TO TRIGGER A LONG BOLD WARNING**.
+
+This has *italics that stretch across many words and should be flagged for length in prose and reading comfort in long spans*.
+
+This has ***bold italics that are also long enough to trigger a warning***.
+
+This has **ALL CAPS TEXT** in bold.
diff --git a/forgejo/README.md b/forgejo/README.md
index 586327e..5e3825d 100644
--- a/forgejo/README.md
+++ b/forgejo/README.md
@@ -33,23 +33,17 @@ In Forgejo terms:
1. Generate CSS from a profile:
```bash
-cd /root/ai-workspace/iftypeset
-PYTHONPATH=src python3 -m iftypeset.cli emit-css --spec spec --profile web_pdf --out /tmp/iftypeset-css
+cd /root/ai-workspace/forgejo-pdf
+./scripts/update_iftypeset_css.sh
```
-2. Copy CSS into the worker assets directory:
-
-```bash
-cp /tmp/iftypeset-css/render.css /root/ai-workspace/forgejo-pdf/worker/pdf/assets/css/iftypeset-web_pdf.css
-```
-
-3. Add a new `pdf.typography` option in the worker config contract (example):
+2. Select the new `pdf.typography` option in the worker config contract (example):
- `basic`
- `professional`
- `iftypeset-web_pdf` (new)
-4. Update `render_pdf.js` selection logic to map that value to a CSS filename in `assets/css/`.
+3. The worker will load `professional.css` first and then `iftypeset-web_pdf.css` as an override.
This is the safest first step: no new dependencies in the worker container, no new runtime calls, just a different stylesheet.
diff --git a/pyproject.toml b/pyproject.toml
index 313d3d1..b5b7c47 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -2,7 +2,7 @@
name = "iftypeset"
version = "0.1.0"
description = "Publication-quality typesetting runtime (Markdown→HTML→PDF) with Chicago/Bringhurst-backed rule registry pointers."
-requires-python = ">=3.11"
+requires-python = ">=3.12,<3.13"
dependencies = [
"pyyaml>=6.0",
"jsonschema>=4.19",
@@ -13,4 +13,3 @@ iftypeset = "iftypeset.cli:main"
[tool.pytest.ini_options]
testpaths = ["tests"]
-
diff --git a/requirements.txt b/requirements.txt
index a3f1ecb..55e4ef6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,3 @@
PyYAML==6.0.2
jsonschema==4.19.2
+playwright==1.41.2
diff --git a/scripts/checkpoint.sh b/scripts/checkpoint.sh
index ed39ce9..cb04ff4 100755
--- a/scripts/checkpoint.sh
+++ b/scripts/checkpoint.sh
@@ -14,27 +14,73 @@ echo "== running ci ==" >&2
ci_json="$(./scripts/ci.sh)"
echo "$ci_json" > "out/checkpoints/ci_${safe_ts}.json"
+echo "== writing session state ==" >&2
+./scripts/state.sh >/dev/null
+
+git_branch="(unknown)"
+git_head_short=""
+dirty_count="0"
+modified_count="0"
+untracked_count="0"
+diffstat=""
+diffstat_lines="0"
+diffstat_note=""
+
+if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
+ git_branch="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "(unknown)")"
+ git_head_short="$(git rev-parse --short HEAD 2>/dev/null || echo "")"
+ porcelain="$(git status --porcelain=v1 2>/dev/null || true)"
+ if [ -n "${porcelain}" ]; then
+ dirty_count="$(printf "%s\n" "${porcelain}" | wc -l | awk '{print $1}')"
+ untracked_count="$(printf "%s\n" "${porcelain}" | grep -c '^??' || true)"
+ modified_count="$(printf "%s\n" "${porcelain}" | grep -vc '^??' || true)"
+ fi
+ diffstat="$(git diff --stat 2>/dev/null || true)"
+ if [ -n "${diffstat}" ]; then
+ diffstat_lines="$(printf "%s\n" "${diffstat}" | wc -l | awk '{print $1}')"
+ if [ "${diffstat_lines}" -gt 200 ]; then
+ diffstat="$(printf "%s\n" "${diffstat}" | head -n 200)"
+ diffstat_note="(diffstat truncated to first 200 lines)"
+ fi
+ fi
+fi
+
tar_path="out/checkpoints/iftypeset_checkpoint_${safe_ts}.tar.gz"
+details_path="out/checkpoints/checkpoint_${safe_ts}.md"
echo "== creating snapshot ${tar_path} ==" >&2
+snapshot_paths=(.forgejo .gitignore README.md STATUS.md app docs fixtures forgejo pyproject.toml requirements.txt scripts spec src tests tools)
+if [ -f AGENTS.md ]; then
+ snapshot_paths+=(AGENTS.md)
+fi
tar \
--exclude=".git" \
--exclude=".venv" \
--exclude="out" \
-czf "$tar_path" \
- .forgejo .gitignore README.md STATUS.md app docs fixtures forgejo pyproject.toml requirements.txt scripts spec src tests tools
+ "${snapshot_paths[@]}"
sha="$(sha256sum "$tar_path" | awk '{print $1}')"
-cat > "out/checkpoints/checkpoint_${safe_ts}.md" < "${details_path}" <> docs/CHECKPOINTS.md </dev/null 2>&1; then
+ git_branch="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "?")"
+ git_head="$(git rev-parse HEAD 2>/dev/null || echo "")"
+ git_head_short="$(git rev-parse --short HEAD 2>/dev/null || echo "")"
+ porcelain="$(git status --porcelain=v1 2>/dev/null || true)"
+ if [ -n "${porcelain}" ]; then
+ git_dirty_count="$(printf "%s\n" "${porcelain}" | wc -l | awk '{print $1}')"
+ git_untracked_count="$(printf "%s\n" "${porcelain}" | grep -c '^??' || true)"
+ git_modified_count="$(printf "%s\n" "${porcelain}" | grep -vc '^??' || true)"
+ fi
+fi
+
+latest_checkpoint_path=""
+latest_checkpoint_sha256=""
+if ls out/checkpoints/iftypeset_checkpoint_*.tar.gz >/dev/null 2>&1; then
+ latest_checkpoint_path="$(ls -1t out/checkpoints/iftypeset_checkpoint_*.tar.gz | head -n 1)"
+ latest_checkpoint_sha256="$(sha256sum "${latest_checkpoint_path}" | awk '{print $1}')"
+fi
+
+export IFTS_STATE_TS="${ts}"
+export IFTS_STATE_ROOT="${ROOT}"
+export IFTS_STATE_GIT_BRANCH="${git_branch}"
+export IFTS_STATE_GIT_HEAD="${git_head}"
+export IFTS_STATE_GIT_HEAD_SHORT="${git_head_short}"
+export IFTS_STATE_GIT_DIRTY_COUNT="${git_dirty_count}"
+export IFTS_STATE_GIT_MODIFIED_COUNT="${git_modified_count}"
+export IFTS_STATE_GIT_UNTRACKED_COUNT="${git_untracked_count}"
+export IFTS_STATE_CHECKPOINT_PATH="${latest_checkpoint_path}"
+export IFTS_STATE_CHECKPOINT_SHA256="${latest_checkpoint_sha256}"
+
+python3 - <<'PY'
+import json
+import os
+from pathlib import Path
+
+
+def _read_json(path: str):
+ p = Path(path)
+ if not p.exists():
+ return None
+ try:
+ return json.loads(p.read_text())
+ except Exception:
+ return None
+
+
+ts = os.environ.get("IFTS_STATE_TS", "")
+root = os.environ.get("IFTS_STATE_ROOT", "")
+git_branch = os.environ.get("IFTS_STATE_GIT_BRANCH", "")
+git_head = os.environ.get("IFTS_STATE_GIT_HEAD", "")
+git_head_short = os.environ.get("IFTS_STATE_GIT_HEAD_SHORT", "")
+dirty_count = int(os.environ.get("IFTS_STATE_GIT_DIRTY_COUNT", "0") or "0")
+modified_count = int(os.environ.get("IFTS_STATE_GIT_MODIFIED_COUNT", "0") or "0")
+untracked_count = int(os.environ.get("IFTS_STATE_GIT_UNTRACKED_COUNT", "0") or "0")
+checkpoint_path = os.environ.get("IFTS_STATE_CHECKPOINT_PATH", "")
+checkpoint_sha256 = os.environ.get("IFTS_STATE_CHECKPOINT_SHA256", "")
+
+coverage = _read_json("out/coverage-report.json") or {}
+counts = coverage.get("counts", {}) if isinstance(coverage, dict) else {}
+
+trust_contract_md = Path("out/trust-contract.md").exists()
+trust_contract_json = Path("out/trust-contract.json").exists()
+
+state = {
+ "generated_at_utc": ts,
+ "repo_root": root,
+ "git": {
+ "branch": git_branch or None,
+ "head": git_head or None,
+ "head_short": git_head_short or None,
+ "dirty_paths_count": dirty_count,
+ "modified_paths_count": modified_count,
+ "untracked_paths_count": untracked_count,
+ },
+ "latest_checkpoint": {
+ "path": checkpoint_path or None,
+ "sha256": checkpoint_sha256 or None,
+ },
+ "coverage": {
+ "generated_at_utc": coverage.get("generated_at_utc") if isinstance(coverage, dict) else None,
+ "counts": counts or None,
+ },
+ "artifacts": {
+ "trust_contract_md": trust_contract_md,
+ "trust_contract_json": trust_contract_json,
+ "coverage_report_json": Path("out/coverage-report.json").exists(),
+ "manual_checklist_md": Path("out/manual-checklist.md").exists(),
+ },
+ "canonical_docs": [
+ "README.md",
+ "STATUS.md",
+ "docs/06-project-overview.md",
+ "docs/07-session-resilience.md",
+ "docs/09-project-status.md",
+ "docs/10-project-brief.md",
+ "docs/12-codex-max-workload.md",
+ "docs/13-task-board.md",
+ "docs/17-rendering-pipeline.md",
+ "docs/CHECKPOINTS.md",
+ ],
+ "resume_commands": [
+ "./scripts/resume.sh",
+ "./scripts/audit.sh",
+ "./scripts/state.sh",
+ "./scripts/ci.sh",
+ "./scripts/checkpoint.sh \"note\"",
+ ],
+}
+
+Path("out/session-state.json").write_text(json.dumps(state, indent=2, sort_keys=True) + "\n")
+
+lines = []
+lines.append("# Session State (generated)\n")
+lines.append(f"- generated_at_utc: `{ts}`")
+lines.append(f"- repo_root: `{root}`")
+if git_branch and git_head_short:
+ lines.append(f"- git: `{git_branch}` @ `{git_head_short}`")
+elif git_branch:
+ lines.append(f"- git: `{git_branch}`")
+else:
+ lines.append("- git: `(not detected)`")
+lines.append(
+ f"- working_tree: dirty_paths={dirty_count} (modified={modified_count}, untracked={untracked_count})"
+)
+if checkpoint_path:
+ lines.append(f"- latest_checkpoint: `{checkpoint_path}`")
+ lines.append(f"- latest_checkpoint_sha256: `{checkpoint_sha256}`")
+else:
+ lines.append("- latest_checkpoint: `(none yet)`")
+
+total_rules = None
+try:
+ total_rules = counts.get("total_rules")
+except Exception:
+ total_rules = None
+if total_rules is not None:
+ lines.append(f"- rules_total: `{total_rules}`")
+ by_enf = counts.get("by_enforcement") or {}
+ by_cat = counts.get("by_category") or {}
+ if by_enf:
+ lines.append(f"- enforcement_split: `{by_enf}`")
+ if by_cat:
+ lines.append(f"- categories: `{by_cat}`")
+else:
+ lines.append("- rules_total: `(unknown; run ./scripts/ci.sh)`")
+
+lines.append("")
+lines.append("## Canonical Docs")
+for d in state["canonical_docs"]:
+ lines.append(f"- `{d}`")
+
+lines.append("")
+lines.append("## Fast Resume")
+for c in state["resume_commands"]:
+ lines.append(f"- `{c}`")
+
+lines.append("")
+lines.append("## Notes")
+lines.append(
+ "- If a chat/session resets and things look “rolled back”, check `latest_checkpoint` above and extract it on a new machine."
+)
+lines.append(
+ "- This file is copied into `docs/SESSION_STATE.md` so it is included in checkpoint snapshots (since `out/` is excluded)."
+)
+
+md = "\n".join(lines) + "\n"
+Path("out/session-state.md").write_text(md)
+Path("docs/SESSION_STATE.md").write_text(md)
+PY
+
+echo "wrote: out/session-state.json out/session-state.md docs/SESSION_STATE.md" >&2
diff --git a/spec/coverage/README.md b/spec/coverage/README.md
new file mode 100644
index 0000000..e0b4b66
--- /dev/null
+++ b/spec/coverage/README.md
@@ -0,0 +1,42 @@
+# Coverage Map (Section Tracking)
+
+This directory tracks coverage by **section**, not by raw rule count.
+
+We do not store OCR text. Entries reference sections and pointers only.
+
+## Files
+
+- `cmos18_sections.json`
+- `bring_sections.json`
+
+## Schema (per file)
+
+```json
+{
+ "book": "CMOS18",
+ "source": "The Chicago Manual of Style, 18th ed (OCR)",
+ "updated_utc": "YYYY-MM-DDTHH:MM:SSZ",
+ "sections": [
+ {
+ "section_id": "§1",
+ "title": "Section title",
+ "pointer": "CMOS18 §1 p1",
+ "status": "uncovered",
+ "rule_ids": []
+ }
+ ]
+}
+```
+
+## Status values
+
+- `uncovered`: no rules mapped yet.
+- `partial`: some rules mapped, section not fully covered.
+- `covered`: all rule-bearing guidance mapped into paraphrased rules.
+- `out_of_scope`: narrative or non-prescriptive section.
+
+## Rules of engagement
+
+- Paraphrase only. Never include book text.
+- Use precise pointers in `source_refs`.
+- If exact wording is required: `Exact wording required—refer to pointer`.
diff --git a/spec/coverage/bring_sections.json b/spec/coverage/bring_sections.json
new file mode 100644
index 0000000..6edf896
--- /dev/null
+++ b/spec/coverage/bring_sections.json
@@ -0,0 +1,803 @@
+{
+ "book": "BRING",
+ "source": "The Elements of Typographic Style (OCR)",
+ "updated_utc": "2026-01-08T03:52:36Z",
+ "sections": [
+ {
+ "section_id": "1.2.2",
+ "title": "Section 1.2.2",
+ "pointer": "BRING §1.2.2 p20 (scan p19)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.HEADINGS.STRUCTURE.MATCH_TEXT_LOGIC",
+ "BRING.HEADINGS.DEGRADED.INFER_STRUCTURE",
+ "BRING.HEADINGS.NUMBERING.CONSISTENT_STYLE",
+ "BRING.HEADINGS.NUMBERING.NO_GAPS",
+ "BRING.HEADINGS.NUMBERING.PUNCTUATION.CONSISTENT",
+ "BRING.HEADINGS.NUMBERING.PREFIXES.CONSISTENT",
+ "BRING.HEADINGS.TOC.MATCH",
+ "BRING.HEADINGS.NUMBERING.SUBLEVELS.DECIMAL_STYLE",
+ "BRING.HEADINGS.NUMBERING.APPENDIX_LABELS"
+ ]
+ },
+ {
+ "section_id": "1.2.3",
+ "title": "Section 1.2.3",
+ "pointer": "BRING §1.2.3 p21 (scan p20)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.HEADINGS.RELATED_ELEMENTS.COHERENT"
+ ]
+ },
+ {
+ "section_id": "1.2.4",
+ "title": "Section 1.2.4",
+ "pointer": "BRING §1.2.4 p22 (scan p21)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.TYPEFACE.PURPOSE_MATCH_CONTENT",
+ "BRING.TYPOGRAPHY.TYPEFACE.LIMIT_NUMBER",
+ "BRING.TYPOGRAPHY.TYPEFACE.SIMILAR_FACES_AVOID",
+ "BRING.TYPOGRAPHY.TYPEFACE.CONTRAST_INTENTIONAL",
+ "BRING.TYPOGRAPHY.TYPEFACE.MIXING_BY_ROLE_ONLY"
+ ]
+ },
+ {
+ "section_id": "1.2.5",
+ "title": "Section 1.2.5",
+ "pointer": "BRING §1.2.5 p23 (scan p22)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.PAGE.HEAD_FOOT_BANDS.CONSISTENT",
+ "BRING.LAYOUT.PAGE.BLANKS.INTENTIONAL",
+ "BRING.LAYOUT.PAGE.FRAME.TEXTBLOCK_BALANCE",
+ "BRING.LAYOUT.MARGINS.FACING_PAGES.INNER_OUTER",
+ "BRING.LAYOUT.ELEMENT_RELATIONSHIPS.VISIBLE",
+ "BRING.LAYOUT.TEXTBLOCK.CONSISTENT_WIDTH",
+ "BRING.LAYOUT.FLOATS.PLACEMENT.NEAR_REFERENCE",
+ "BRING.LAYOUT.GRID.ALIGN_ELEMENTS"
+ ]
+ },
+ {
+ "section_id": "2.1.1",
+ "title": "Section 2.1.1",
+ "pointer": "BRING §2.1.1 p25",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.SPACING.WORD_SPACE.DEFINE"
+ ]
+ },
+ {
+ "section_id": "2.1.2",
+ "title": "Section 2.1.2",
+ "pointer": "BRING §2.1.2 p26 (scan p25)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.MEASURE.TARGET_RANGE_CHARS",
+ "BRING.LAYOUT.MEASURE.ADJUST_FOR_TYPE_SIZE",
+ "BRING.LAYOUT.MEASURE.AVOID_TOO_LONG",
+ "BRING.LAYOUT.MEASURE.AVOID_TOO_SHORT",
+ "BRING.LAYOUT.MEASURE.CONSISTENT_WITHIN_SECTION",
+ "BRING.LAYOUT.MEASURE.CHANGE_FOR_LISTS",
+ "BRING.LAYOUT.MEASURE.CODE_BLOCKS.WRAP_POLICY",
+ "BRING.LAYOUT.COLUMNS.BALANCE_LENGTHS",
+ "BRING.LAYOUT.MEASURE.COMFORTABLE_RANGE",
+ "BRING.LAYOUT.MEASURE.MULTICOLUMN_TARGETS"
+ ]
+ },
+ {
+ "section_id": "2.1.3",
+ "title": "Section 2.1.3",
+ "pointer": "BRING §2.1.3 p27",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.JUSTIFICATION.RAGGED_RIGHT_IF_NEEDED",
+ "BRING.CODE.MONO_RAGGED_RIGHT",
+ "BRING.CODE.RAG.NO_MIN_LINE",
+ "BRING.CODE.RAG.NO_AUTO_HYPHENATION",
+ "BRING.CODE.RAG.FIXED_WORD_SPACES",
+ "BRING.CODE.RAG.NO_LETTERSPACING",
+ "BRING.CODE.RAG.AVOID_FAKE_JUSTIFY"
+ ]
+ },
+ {
+ "section_id": "2.1.4",
+ "title": "Section 2.1.4",
+ "pointer": "BRING §2.1.4 p27",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.SPACING.SENTENCE_SPACE.SINGLE"
+ ]
+ },
+ {
+ "section_id": "2.1.5",
+ "title": "Section 2.1.5",
+ "pointer": "BRING §2.1.5 p30 (scan p29)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.SPACING.INITIALS.THIN_SPACE"
+ ]
+ },
+ {
+ "section_id": "2.1.6",
+ "title": "Section 2.1.6",
+ "pointer": "BRING §2.1.6 p30 (scan p29)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.TRACKING.CAPS_SMALLCAPS_AND_LONG_DIGITS",
+ "BRING.TYPOGRAPHY.NUMBER_STRINGS.SPACE_FOR_READABILITY",
+ "BRING.TYPOGRAPHY.CAPS.TRACKING_REVIEW"
+ ]
+ },
+ {
+ "section_id": "2.1.7",
+ "title": "Section 2.1.7",
+ "pointer": "BRING §2.1.7 p31 (scan p30)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.TRACKING.LOWERCASE.AVOID"
+ ]
+ },
+ {
+ "section_id": "2.1.8",
+ "title": "Section 2.1.8",
+ "pointer": "BRING §2.1.8 p32-33",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.KERNING.CONSISTENT_OR_NONE"
+ ]
+ },
+ {
+ "section_id": "2.1.9",
+ "title": "Section 2.1.9",
+ "pointer": "BRING §2.1.9 p35 (scan p34)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.LETTERFORMS.AVOID_DISTORTION"
+ ]
+ },
+ {
+ "section_id": "2.1.10",
+ "title": "Section 2.1.10",
+ "pointer": "BRING §2.1.10 p35 (scan p34)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.ALIGNMENT.DONT_STRETCH_SPACE"
+ ]
+ },
+ {
+ "section_id": "2.2.1",
+ "title": "Section 2.2.1",
+ "pointer": "BRING §2.2.1 p36 (scan p35)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_HEADINGS",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_CAPTIONS",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_TABLES",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_BLOCK_QUOTES",
+ "BRING.LAYOUT.LEADING.CHOOSE_BASE",
+ "BRING.LAYOUT.LEADING.CONSISTENT_BODY",
+ "BRING.LAYOUT.LEADING.ADJUST_FOR_SIZE_CHANGES",
+ "BRING.LAYOUT.LEADING.AVOID_TOO_TIGHT",
+ "BRING.LAYOUT.LEADING.AVOID_TOO_LOOSE",
+ "BRING.LAYOUT.LEADING.ALIGN_BASELINE_GRID"
+ ]
+ },
+ {
+ "section_id": "2.2.2",
+ "title": "Section 2.2.2",
+ "pointer": "BRING §2.2.2 p37 (scan p36)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.VERTICAL_RHYTHM.MEASURED_INTERVALS.MULTIPLES",
+ "BRING.LAYOUT.LEADING.NEGATIVE.AVOID_CONTINUOUS_TEXT"
+ ]
+ },
+ {
+ "section_id": "2.2.3",
+ "title": "Section 2.2.3",
+ "pointer": "BRING §2.2.3 p39 (scan p38)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.PAGE.DENSITY.DONT_SUFFOCATE",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.HEADINGS.BEFORE_AFTER",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.LISTS.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.TABLES.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.FIGURES.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.CAPTIONS.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.FOOTNOTES.SPACING"
+ ]
+ },
+ {
+ "section_id": "2.3.1",
+ "title": "Section 2.3.1",
+ "pointer": "BRING §2.3.1 p39 (scan p38)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.PARAGRAPH.OPENING_FLUSH_LEFT",
+ "BRING.LAYOUT.PARAGRAPH.RUN_IN_HEADS.CONSISTENT",
+ "BRING.LAYOUT.PARAGRAPH.DROP_CAPS.ALIGN_BASELINE"
+ ]
+ },
+ {
+ "section_id": "2.3.2",
+ "title": "Section 2.3.2",
+ "pointer": "BRING §2.3.2 p39 (scan p38)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.PARAGRAPH.BLOCK_STYLE.CONSISTENT",
+ "BRING.LAYOUT.PARAGRAPH.SECTION_BREAKS.CLEAR",
+ "BRING.LAYOUT.PARAGRAPH.AFTER_QUOTE.FLUSH",
+ "BRING.LAYOUT.PARAGRAPH.INDENT_AFTER_FIRST",
+ "BRING.LAYOUT.PARAGRAPH.INDENT_OR_SPACE_NOT_BOTH",
+ "BRING.LAYOUT.PARAGRAPH.NO_INDENT_AFTER_BLOCKS",
+ "BRING.LAYOUT.PARAGRAPH.INDENT_SIZE.CONSISTENT",
+ "BRING.LAYOUT.PARAGRAPH.BLANK_LINES.SPARING",
+ "BRING.LAYOUT.DEGRADED.HARD_WRAP_REFLOW",
+ "BRING.HEADINGS.PARAGRAPH_INDENT.AFTER_HEAD_NONE"
+ ]
+ },
+ {
+ "section_id": "2.3.3",
+ "title": "Section 2.3.3",
+ "pointer": "BRING §2.3.3 p40 (scan p39)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.BLOCK_QUOTES.EXTRA_LEAD",
+ "BRING.LAYOUT.BLOCK_QUOTES.BEFORE_AFTER_SPACING",
+ "BRING.LAYOUT.BLOCK_QUOTES.INDENT_OR_NARROW",
+ "BRING.LAYOUT.BLOCK_QUOTES.AVOID_CROWDING",
+ "BRING.HEADINGS.BLOCK_QUOTE.SPACING_AROUND"
+ ]
+ },
+ {
+ "section_id": "2.3.4",
+ "title": "Section 2.3.4",
+ "pointer": "BRING §2.3.4 p41 (scan p40)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.PARAGRAPH.INDENT.PROPORTIONAL",
+ "BRING.LAYOUT.PARAGRAPH.INDENT.NOT_TOO_DEEP",
+ "BRING.LAYOUT.PARAGRAPH.INDENT.WITHIN_MEASURE",
+ "BRING.LAYOUT.PARAGRAPH.LISTS.HANGING_INDENT",
+ "BRING.LAYOUT.PARAGRAPH.LISTS.ALIGN_WITH_BODY"
+ ]
+ },
+ {
+ "section_id": "2-4.1",
+ "title": "Section 2-4.1",
+ "pointer": "BRING §2-4.1 p42",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.RHYTHM.RULES_SERVE_TEXT"
+ ]
+ },
+ {
+ "section_id": "2-4.2",
+ "title": "Section 2-4.2",
+ "pointer": "BRING §2-4.2 p42",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.HYPHENATION.MIN_LEFT_RIGHT"
+ ]
+ },
+ {
+ "section_id": "2-4.3",
+ "title": "Section 2-4.3",
+ "pointer": "BRING §2-4.3 p42",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.HYPHENATION.STUB_END_AVOID"
+ ]
+ },
+ {
+ "section_id": "2-4.4",
+ "title": "Section 2-4.4",
+ "pointer": "BRING §2-4.4 p43",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.HYPHENATION.MAX_CONSECUTIVE_LINES"
+ ]
+ },
+ {
+ "section_id": "2-4.5",
+ "title": "Section 2-4.5",
+ "pointer": "BRING §2-4.5 p43",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.HYPHENATION.AVOID_PROPER_NAMES"
+ ]
+ },
+ {
+ "section_id": "2-4.6",
+ "title": "Section 2-4.6",
+ "pointer": "BRING §2-4.6 p43",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.HYPHENATION.LANGUAGE_DICTIONARY.MATCH"
+ ]
+ },
+ {
+ "section_id": "2-4.7",
+ "title": "Section 2-4.7",
+ "pointer": "BRING §2-4.7 p43",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.HYPHENATION.HARD_SPACES.SHORT_EXPRESSIONS"
+ ]
+ },
+ {
+ "section_id": "2-4.8",
+ "title": "Section 2-4.8",
+ "pointer": "BRING §2-4.8 p43",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.HYPHENATION.AVOID_AFTER_SHORT_LINE",
+ "BRING.LAYOUT.LINEBREAKS.AVOID_SAME_WORD_START"
+ ]
+ },
+ {
+ "section_id": "2.4.9",
+ "title": "Section 2.4.9",
+ "pointer": "BRING §2.4.9 p44 (scan p43)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.PARAGRAPH.AVOID_WIDOW_START",
+ "BRING.LAYOUT.PARAGRAPH.AVOID_WIDOW_END",
+ "BRING.LAYOUT.PAGINATION.KEEP_FIGURE_WITH_CAPTION",
+ "BRING.LAYOUT.PAGINATION.KEEP_TABLE_WITH_HEADER",
+ "BRING.LAYOUT.PAGINATION.KEEP_LIST_WITH_INTRO",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_AFTER_HEADING",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_BEFORE_LAST_LINE",
+ "BRING.LAYOUT.PAGINATION.AVOID_LONELY_LINE_IN_LISTS",
+ "BRING.LAYOUT.PAGINATION.AVOID_STRANDED_CAPTIONS"
+ ]
+ },
+ {
+ "section_id": "2-4.9",
+ "title": "Section 2-4.9",
+ "pointer": "BRING §2-4.9 p44",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.PAGINATION.ORPHANS_AVOID",
+ "BRING.LAYOUT.PAGINATION.WIDOWS_AVOID"
+ ]
+ },
+ {
+ "section_id": "2-4.10",
+ "title": "Section 2-4.10",
+ "pointer": "BRING §2-4.10 p44",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.PAGINATION.BALANCE_FACING_PAGES"
+ ]
+ },
+ {
+ "section_id": "2-4.11",
+ "title": "Section 2-4.11",
+ "pointer": "BRING §2-4.11 p44",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.HYPHENATION.AVOID_NEAR_INTERRUPTION"
+ ]
+ },
+ {
+ "section_id": "2.5",
+ "title": "Section 2.5",
+ "pointer": "BRING §2.5 p41 (scan p40)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.SIZE.BODY_SIZE_MATCH_MEASURE",
+ "BRING.TYPOGRAPHY.SIZE.LEADING_RELATION"
+ ]
+ },
+ {
+ "section_id": "3.2.1",
+ "title": "Section 3.2.1",
+ "pointer": "BRING §3.2.1 p46 (scan p45)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_AVOID_LONG_RUNS",
+ "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_SHORT_LABELS_ONLY",
+ "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_FOR_ACRONYMS",
+ "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_NOT_FOR_LONG_PASSAGES",
+ "BRING.TYPOGRAPHY.CAPS.MIXED_CAPS_CONSISTENT",
+ "BRING.TYPOGRAPHY.CAPS.AVOID_FOR_EMPHASIS",
+ "BRING.TYPOGRAPHY.CAPS.ROMAN_NUMERALS_SPACING"
+ ]
+ },
+ {
+ "section_id": "3.3",
+ "title": "Section 3.3",
+ "pointer": "BRING §3.3 p50 (scan p49)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.LIGATURES.STANDARD_ON_BODY",
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_CODE_URLS",
+ "BRING.TYPOGRAPHY.LIGATURES.FI_FL_COLLISIONS",
+ "BRING.TYPOGRAPHY.LIGATURES.KEEP_CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "3.3.1",
+ "title": "Section 3.3.1",
+ "pointer": "BRING §3.3.1 p50 (scan p49)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_SPARING",
+ "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_IN_DISPLAY"
+ ]
+ },
+ {
+ "section_id": "3.3.2",
+ "title": "Section 3.3.2",
+ "pointer": "BRING §3.3.2 p52 (scan p51)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ALL_CAPS",
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ACRONYMS",
+ "BRING.TYPOGRAPHY.LIGATURES.DO_NOT_USE_IF_AMBIGUOUS",
+ "BRING.TYPOGRAPHY.LIGATURES.REVIEW_FOR_LANGUAGE"
+ ]
+ },
+ {
+ "section_id": "4.2",
+ "title": "Section 4.2",
+ "pointer": "BRING §4.2 p65 (scan p64)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.HEADINGS.CAPITALIZATION.CONSISTENT",
+ "BRING.HEADINGS.WEIGHT_SIZE.HIERARCHY_SCALE",
+ "BRING.HEADINGS.SPACING.VERTICAL_RHYTHM",
+ "BRING.HEADINGS.STYLE.PALETTE_LIMIT",
+ "BRING.HEADINGS.LENGTH.CONCISE",
+ "BRING.HEADINGS.NO_TERMINAL_PERIOD",
+ "BRING.HEADINGS.NO_TERMINAL_COLON",
+ "BRING.HEADINGS.QUESTION_MARK_ONLY_IF_QUESTION",
+ "BRING.HEADINGS.NO_HYPHENATION",
+ "BRING.HEADINGS.NO_SINGLE_WORD_LINE",
+ "BRING.HEADINGS.BREAKS.AT_PHRASE_BOUNDARIES",
+ "BRING.HEADINGS.AVOID_STACKED_LEVELS",
+ "BRING.HEADINGS.SUBHEADS.PARALLEL_GRAMMAR",
+ "BRING.HEADINGS.WIDTH.BALANCED",
+ "BRING.HEADINGS.AVOID_ABBREVIATIONS",
+ "BRING.HEADINGS.CASE.PROPER_NOUNS_PRESERVE",
+ "BRING.HEADINGS.LEADIN_TEXT.BEFORE_LIST",
+ "BRING.HEADINGS.HIERARCHY.MAX_DEPTH",
+ "BRING.HEADINGS.SECTION_OPENING.PARAGRAPH_REQUIRED",
+ "BRING.HEADINGS.SUBHEADS.STYLE_CONTRIBUTES_TO_WHOLE"
+ ]
+ },
+ {
+ "section_id": "4.2.1",
+ "title": "Section 4.2.1",
+ "pointer": "BRING §4.2.1 p65 (scan p64)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.HEADINGS.RUN_IN.STANDALONE.CONSISTENT",
+ "BRING.HEADINGS.ALIGNMENT.CONSISTENT_LEVEL",
+ "BRING.HEADINGS.MARGIN_HEADS.CLEAR_GUTTER",
+ "BRING.HEADINGS.HIERARCHY.NO_SKIPPED_LEVELS",
+ "BRING.HEADINGS.RUN_IN.END_PUNCTUATION",
+ "BRING.HEADINGS.RUN_IN.SEPARATION.CONSISTENT",
+ "BRING.HEADINGS.SUBHEADS.CROSSHEADS_SIDEHEADS.CHOOSE_DELIBERATELY",
+ "BRING.HEADINGS.SUBHEADS.RIGHT_SIDEHEADS.VISIBILITY",
+ "BRING.HEADINGS.SUBHEADS.MARGIN_HEADS.RUNNING_SHOULDERHEADS",
+ "BRING.HEADINGS.SUBHEADS.LEVELS.AS_MANY_AS_NEEDED"
+ ]
+ },
+ {
+ "section_id": "4.2.2",
+ "title": "Section 4.2.2",
+ "pointer": "BRING §4.2.2 p65 (scan p64)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.HEADINGS.CONTRAST.CLEAR_HIERARCHY",
+ "BRING.HEADINGS.SUBHEADS.MIXING_SYMM_ASYMM.AVOID_HAPHAZARD",
+ "BRING.HEADINGS.SUBHEADS.MIXING.HIERARCHY_PLACEMENT"
+ ]
+ },
+ {
+ "section_id": "4.3.2",
+ "title": "Section 4.3.2",
+ "pointer": "BRING §4.3.2 p68 (scan p67)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.WEIGHT.HIERARCHY_CLEAR",
+ "BRING.TYPOGRAPHY.WEIGHT.AVOID_TOO_MANY_WEIGHTS",
+ "BRING.TYPOGRAPHY.WEIGHT.BOLD_IN_LONG_PASSAGES_AVOID",
+ "BRING.TYPOGRAPHY.WEIGHT.HEAVY_WEIGHTS_SHORT_LABELS"
+ ]
+ },
+ {
+ "section_id": "4.3.3",
+ "title": "Section 4.3.3",
+ "pointer": "BRING §4.3.3 p69 (scan p68)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.SIZE.SCALE_CONSISTENT",
+ "BRING.TYPOGRAPHY.SIZE.AVOID_TOO_MANY_SIZES",
+ "BRING.TYPOGRAPHY.SIZE.SMALL_TEXT_MINIMUM",
+ "BRING.TYPOGRAPHY.SIZE.DISPLAY_SIZE_BALANCE"
+ ]
+ },
+ {
+ "section_id": "4.4",
+ "title": "Section 4.4",
+ "pointer": "BRING §4.4 p70 (scan p69)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TABLES.TITLES.CONSISTENT_PLACEMENT",
+ "BRING.TABLES.CAPTIONS.CLEAR"
+ ]
+ },
+ {
+ "section_id": "4.4.1",
+ "title": "Section 4.4.1",
+ "pointer": "BRING §4.4.1 p70 (scan p69)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TABLES.HEADERS.CONCISE",
+ "BRING.TABLES.HEADERS.ALIGN_WITH_COLUMNS",
+ "BRING.TABLES.UNITS.IN_HEADERS",
+ "BRING.TABLES.STUB_COLUMN.USE",
+ "BRING.TABLES.GROUPING.WHITESPACE",
+ "BRING.TABLES.ROW_SPACING.READABLE",
+ "BRING.TABLES.COLUMN_ALIGNMENT.CONSISTENT",
+ "BRING.TABLES.SOURCES.NOTES.DISTINCT",
+ "BRING.TABLES.MULTI_LINE_HEADERS.AVOID",
+ "BRING.TABLES.NUMERIC_PRECISION.CONSISTENT",
+ "BRING.TABLES.DATA_TYPES.NOT_MIXED",
+ "BRING.TABLES.ORDER.LOGICAL",
+ "BRING.TABLES.DEGRADED.REBUILD_COLUMNS",
+ "BRING.TABLES.EDIT_AS_TEXT.READABILITY",
+ "BRING.TABLES.FURNITURE.MINIMIZE",
+ "BRING.TABLES.TEXT_ORIENTATION.HORIZONTAL",
+ "BRING.TABLES.TYPE_SIZE.READABLE",
+ "BRING.TABLES.GUIDES.READING_DIRECTION"
+ ]
+ },
+ {
+ "section_id": "4.4.3",
+ "title": "Section 4.4.3",
+ "pointer": "BRING §4.4.3 p111 (scan p110)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.NUMERALS.TABULAR_FOR_TABLES",
+ "BRING.TYPOGRAPHY.NUMERALS.SLASHED_ZERO_IF_CONFUSION",
+ "BRING.TYPOGRAPHY.NUMERALS.FRACTIONS_TRUE_GLYPHS",
+ "BRING.TYPOGRAPHY.NUMERALS.SUPERIOR_INFERIOR_FOR_NOTES",
+ "BRING.LAYOUT.COLUMNS.COUNT.MODERATE",
+ "BRING.LAYOUT.COLUMNS.WIDTH.CONSISTENT",
+ "BRING.LAYOUT.COLUMNS.GUTTER.CONSISTENT",
+ "BRING.LAYOUT.COLUMNS.GUTTER.SUFFICIENT",
+ "BRING.LAYOUT.COLUMNS.ALIGN_BASELINES",
+ "BRING.LAYOUT.COLUMNS.SPAN_POLICY.FIGURES",
+ "BRING.LAYOUT.COLUMNS.SPAN_POLICY.TABLES",
+ "BRING.LAYOUT.COLUMNS.SIDEBARS.DISTINCT_MEASURE",
+ "BRING.LAYOUT.COLUMNS.RAGGED_BOTTOM.AVOID",
+ "BRING.LAYOUT.COLUMNS.USE_FOR_LONG_LISTS"
+ ]
+ },
+ {
+ "section_id": "4.4.4",
+ "title": "Section 4.4.4",
+ "pointer": "BRING §4.4.4 p72 (scan p71)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.NUMERALS.OLDSTYLE_FOR_TEXT",
+ "BRING.TYPOGRAPHY.NUMERALS.LINING_FOR_CAPS_AND_DISPLAY",
+ "BRING.TYPOGRAPHY.NUMERALS.PROPORTIONAL_FOR_PROSE",
+ "BRING.TYPOGRAPHY.NUMERALS.CONSISTENT_STYLE_WITHIN_SECTION",
+ "BRING.TYPOGRAPHY.NUMERALS.MIXED_STYLE_AVOID",
+ "BRING.TYPOGRAPHY.NUMERALS.FIGURE_STYLE_FOR_CAPTIONS",
+ "BRING.TYPOGRAPHY.NUMERALS.SMALL_CAPS_AND_FIGURES",
+ "BRING.TYPOGRAPHY.NUMERALS.AVOID_LINING_IN_LOWERCASE"
+ ]
+ },
+ {
+ "section_id": "6.1.1",
+ "title": "Section 6.1.1",
+ "pointer": "BRING §6.1.1 p93 (scan p92)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.TYPEFACE.TEXT_FACES_FOR_BODY",
+ "BRING.TYPOGRAPHY.TYPEFACE.DISPLAY_FACES_FOR_DISPLAY",
+ "BRING.TYPOGRAPHY.TYPEFACE.FALLBACKS_COMPATIBLE_METRICS",
+ "BRING.TYPOGRAPHY.TYPEFACE.GLYPH_COVERAGE_REQUIRED",
+ "BRING.TYPOGRAPHY.TYPEFACE.OPTICAL_SIZES_USE",
+ "BRING.TYPOGRAPHY.TYPEFACE.FAMILY_WITH_VARIANTS",
+ "BRING.TYPOGRAPHY.TYPEFACE.LEGIBILITY_AT_SIZE"
+ ]
+ },
+ {
+ "section_id": "6.5.1",
+ "title": "Section 6.5.1",
+ "pointer": "BRING §6.5.1 p102 (scan p101)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.FAMILY.SINGLE_FAMILY_BODY",
+ "BRING.TYPOGRAPHY.FAMILY.METRICS_MATCH_WHEN_MIXING",
+ "BRING.TYPOGRAPHY.FAMILY.LIMIT_STYLE_VARIANTS"
+ ]
+ },
+ {
+ "section_id": "6.5.2",
+ "title": "Section 6.5.2",
+ "pointer": "BRING §6.5.2 p103 (scan p102)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.FAMILY.TRUE_ITALICS",
+ "BRING.TYPOGRAPHY.FAMILY.TRUE_SMALL_CAPS",
+ "BRING.TYPOGRAPHY.FAMILY.SMALL_CAPS_SPARE",
+ "BRING.TYPOGRAPHY.FAMILY.ITALIC_FOR_SUBTLE_EMPHASIS",
+ "BRING.TYPOGRAPHY.FAMILY.ITALIC_PUNCTUATION_MATCH"
+ ]
+ },
+ {
+ "section_id": "6.5.3",
+ "title": "Section 6.5.3",
+ "pointer": "BRING §6.5.3 p103 (scan p102)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.FAMILY.AVOID_FAUX_BOLD",
+ "BRING.TYPOGRAPHY.FAMILY.USE_DESIGNED_WEIGHTS",
+ "BRING.TYPOGRAPHY.FAMILY.BOLD_FOR_STRONG_EMPHASIS",
+ "BRING.TYPOGRAPHY.FAMILY.WEIGHT_CONTRAST_CLEAR",
+ "BRING.TYPOGRAPHY.BOLD.SPARING_USE",
+ "BRING.TYPOGRAPHY.BOLD.AVOID_LONG_PASSAGES",
+ "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ALL_CAPS",
+ "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ITALICS_LONG",
+ "BRING.TYPOGRAPHY.BOLD.LABELS_SHORT",
+ "BRING.TYPOGRAPHY.BOLD.HEADING_HIERARCHY_BALANCE"
+ ]
+ },
+ {
+ "section_id": "6.5.5",
+ "title": "Section 6.5.5",
+ "pointer": "BRING §6.5.5 p105 (scan p104)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.SERIF.BODY_TEXT_DEFAULT",
+ "BRING.TYPOGRAPHY.SERIF.SANS_FOR_DISPLAY",
+ "BRING.TYPOGRAPHY.SERIF.AVOID_MIX_SAME_ROLE",
+ "BRING.TYPOGRAPHY.SERIF.SERIF_SANS_BALANCE"
+ ]
+ },
+ {
+ "section_id": "7.2.1",
+ "title": "Section 7.2.1",
+ "pointer": "BRING §7.2.1 p122 (scan p121)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.ITALICS.SPARING",
+ "BRING.TYPOGRAPHY.ITALICS.LONG_SPANS_AVOID",
+ "BRING.TYPOGRAPHY.ITALICS.TERMS_INTRODUCED_SPARE",
+ "BRING.TYPOGRAPHY.ITALICS.PUNCTUATION_FOLLOWS_STYLE",
+ "BRING.TYPOGRAPHY.ITALICS.EMPHASIS_NOT_UNDERLINE",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_STACKED_EMPHASIS",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_NUMERAL_ITALICS"
+ ]
+ },
+ {
+ "section_id": "7.2.2",
+ "title": "Section 7.2.2",
+ "pointer": "BRING §7.2.2 p124 (scan p123)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.ITALICS.TITLES_STANDALONE_WORKS",
+ "BRING.TYPOGRAPHY.ITALICS.CONSISTENT_TITLE_TREATMENT"
+ ]
+ },
+ {
+ "section_id": "7.2.7",
+ "title": "Section 7.2.7",
+ "pointer": "BRING §7.2.7 p130 (scan p129)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_IN_ALL_CAPS_HEADINGS",
+ "BRING.TYPOGRAPHY.ITALICS.HEADINGS_AVOID",
+ "BRING.TYPOGRAPHY.ITALICS.RUNNING_HEADS_AVOID"
+ ]
+ },
+ {
+ "section_id": "8.3",
+ "title": "Section 8.3",
+ "pointer": "BRING §8.3 p160 (scan p117)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.PAGE.SHAPE.PROPORTIONATE",
+ "BRING.LAYOUT.PAGE.WHITE_SPACE.DISTRIBUTION"
+ ]
+ },
+ {
+ "section_id": "8.3.1",
+ "title": "Section 8.3.1",
+ "pointer": "BRING §8.3.1 p160 (scan p117)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.PAGE.TEXTBLOCK.POSITION"
+ ]
+ },
+ {
+ "section_id": "8.4.2",
+ "title": "Section 8.4.2",
+ "pointer": "BRING §8.4.2 p163 (scan p162)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.TYPOGRAPHY.CONTRAST.FONT_PAIRING_MATCH",
+ "BRING.TYPOGRAPHY.CONTRAST.AVOID_EXTREME_MIX",
+ "BRING.TYPOGRAPHY.SERIF.PAIR_WITH_COMPATIBLE_XHEIGHT",
+ "BRING.TYPOGRAPHY.SERIF.STROKE_CONTRAST_COMPATIBLE"
+ ]
+ },
+ {
+ "section_id": "8.5",
+ "title": "Section 8.5",
+ "pointer": "BRING §8.5 p165 (scan p120)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.MARGINS.PROPORTION.BALANCED",
+ "BRING.LAYOUT.MARGINS.CONSISTENT.ACROSS_SECTIONS",
+ "BRING.LAYOUT.MARGINS.RUNNING_HEAD.CLEARANCE",
+ "BRING.LAYOUT.MARGINS.FOOTNOTE.CLEARANCE",
+ "BRING.LAYOUT.MARGINS.AVOID_CROWDING",
+ "BRING.LAYOUT.MARGINS.NOTES.OUTSIDE_TEXTBLOCK"
+ ]
+ },
+ {
+ "section_id": "8.5.1",
+ "title": "Section 8.5.1",
+ "pointer": "BRING §8.5.1 p165 (scan p120)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.MARGINS.OUTER_LARGER_THAN_INNER",
+ "BRING.LAYOUT.MARGINS.GUTTER.ALLOW_BINDING"
+ ]
+ },
+ {
+ "section_id": "8.5.2",
+ "title": "Section 8.5.2",
+ "pointer": "BRING §8.5.2 p165 (scan p120)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.MARGINS.TOP_BOTTOM.BALANCE",
+ "BRING.LAYOUT.MARGINS.BLEED.ONLY_WHEN_ENABLED"
+ ]
+ },
+ {
+ "section_id": "8.6.1",
+ "title": "Section 8.6.1",
+ "pointer": "BRING §8.6.1 p166 (scan p121)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.PAGE.ODD_EVEN.CONSISTENT",
+ "BRING.LAYOUT.PAGE.OPENING_SPREAD.RULE"
+ ]
+ },
+ {
+ "section_id": "8.8.3",
+ "title": "Section 8.8.3",
+ "pointer": "BRING §8.8.3 p178 (scan p122)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.PAGE.SPREADS.BALANCE_CONTENT",
+ "BRING.LAYOUT.PAGE.SPREADS.ALIGN_BASELINES",
+ "BRING.LAYOUT.PAGE.FACING_ELEMENTS.ALIGN"
+ ]
+ },
+ {
+ "section_id": "9.4",
+ "title": "Section 9.4",
+ "pointer": "BRING §9.4 p42 (scan p41)",
+ "status": "covered",
+ "rule_ids": [
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_IN_EQUATIONS",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_IN_BLOCK_QUOTES",
+ "BRING.LAYOUT.PAGINATION.BALANCE_FINAL_PAGE",
+ "BRING.LAYOUT.PAGINATION.AVOID_EXCESS_WHITE_SPACE",
+ "BRING.LAYOUT.PAGINATION.CLEAR_SECTION_BREAKS"
+ ]
+ }
+ ]
+}
diff --git a/spec/coverage/cmos18_sections.json b/spec/coverage/cmos18_sections.json
new file mode 100644
index 0000000..f2ee466
--- /dev/null
+++ b/spec/coverage/cmos18_sections.json
@@ -0,0 +1,3230 @@
+{
+ "book": "CMOS18",
+ "source": "The Chicago Manual of Style, 18th ed (OCR)",
+ "updated_utc": "2026-01-08T06:14:15Z",
+ "sections": [
+ {
+ "section_id": "1.42",
+ "title": "Section 1.42",
+ "pointer": "CMOS18 §1.42 p48 (scan p1122)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.TABLES.WIDTH.FIT_PAGE",
+ "CMOS.TABLES.ROTATION.LANDSCAPE.WHEN_NEEDED",
+ "CMOS.TABLES.SPLITS.AVOID_ROW_BREAKS",
+ "CMOS.TABLES.SPLITS.REPEAT_HEADERS"
+ ]
+ },
+ {
+ "section_id": "1.82",
+ "title": "Section 1.82",
+ "pointer": "CMOS18 §1.82 p82 (scan p1122)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.TABLES.COLUMN_ORDER.LOGICAL",
+ "CMOS.TABLES.ROW_ORDER.LOGICAL",
+ "CMOS.TABLES.SORTING.LOGICAL",
+ "CMOS.TABLES.DATA_TYPES.NOT_MIXED",
+ "CMOS.TABLES.SUBTOTALS.CLEAR"
+ ]
+ },
+ {
+ "section_id": "3.1",
+ "title": "Section 3.1",
+ "pointer": "CMOS18 §3.1 p120",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.FIGURES.ACCESSIBILITY.ALT_TEXT",
+ "CMOS.FIGURES.ASPECT_RATIO.PRESERVE",
+ "CMOS.FIGURES.CAPTION.LENGTH.REASONABLE",
+ "CMOS.FIGURES.CAPTION.PLACEMENT.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.PUNCTUATION.CONSISTENT",
+ "CMOS.FIGURES.CAPTIONS.PRESENT",
+ "CMOS.FIGURES.COLOR.NOT_SOLE_SIGNAL",
+ "CMOS.FIGURES.CONTRAST.SUFFICIENT",
+ "CMOS.FIGURES.CREDIT.SOURCE_WHEN_REQUIRED",
+ "CMOS.FIGURES.FILENAME.STABLE",
+ "CMOS.FIGURES.FORMAT.VECTOR_WHEN_POSSIBLE",
+ "CMOS.FIGURES.LEGENDS.EXPLAIN_SYMBOLS",
+ "CMOS.FIGURES.MARGINS.AVOID_CLIPPING",
+ "CMOS.FIGURES.NUMBERING.SEQUENTIAL",
+ "CMOS.FIGURES.NUMBERING.WITHIN_CHAPTERS",
+ "CMOS.FIGURES.PLACEMENT.NEAR_MENTION",
+ "CMOS.FIGURES.REFERENCES.IN_TEXT",
+ "CMOS.FIGURES.RESOLUTION.RASTER_SUFFICIENT",
+ "CMOS.FIGURES.SCALE.LEGIBLE",
+ "CMOS.FIGURES.SENSITIVE.DATA.REDACT",
+ "CMOS.FIGURES.TABLE_VS_FIGURE.CHOOSE",
+ "CMOS.FIGURES.UNITS.LABEL_AXES"
+ ]
+ },
+ {
+ "section_id": "3.2",
+ "title": "Section 3.2",
+ "pointer": "CMOS18 §3.2 p38 (scan p1123)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.TABLES.CAPTIONS.PRESENT",
+ "CMOS.TABLES.TITLES.PLACEMENT.CONSISTENT",
+ "CMOS.TABLES.TITLES.NUMBERING.SEQUENTIAL",
+ "CMOS.TABLES.TITLES.SCOPE.CONSISTENT",
+ "CMOS.TABLES.CAPTIONS.CLARITY",
+ "CMOS.TABLES.CAPTIONS.BREVITY"
+ ]
+ },
+ {
+ "section_id": "3.3",
+ "title": "Section 3.3",
+ "pointer": "CMOS18 §3.3 p11 (scan p1122)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.FIGURES.COLOR.PALETTE.CONSISTENT",
+ "CMOS.FIGURES.LINE_WEIGHTS.CONSISTENT",
+ "CMOS.FIGURES.SYMBOLS.CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "3.5",
+ "title": "Section 3.5",
+ "pointer": "CMOS18 §3.5 p64 (scan p1123)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.FIGURES.CAPTION.PREFIX.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.NUMBER.MATCH_LABEL",
+ "CMOS.FIGURES.CAPTION.ALIGNMENT.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.FONT.CONSISTENT",
+ "CMOS.FIGURES.SIZE.MATCH_READABILITY",
+ "CMOS.FIGURES.KEY.READABLE",
+ "CMOS.FIGURES.SCALING.UNIFORM"
+ ]
+ },
+ {
+ "section_id": "3.6",
+ "title": "Section 3.6",
+ "pointer": "CMOS18 §3.6 p16 (scan p1122)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.TABLES.REFERENCES.IN_TEXT",
+ "CMOS.TABLES.HEADERS.REQUIRED",
+ "CMOS.TABLES.HEADERS.ALIGNMENT.CONSISTENT",
+ "CMOS.TABLES.HEADERS.CAPITALIZATION.CONSISTENT",
+ "CMOS.TABLES.STUB_COLUMN.USE"
+ ]
+ },
+ {
+ "section_id": "3.8",
+ "title": "Section 3.8",
+ "pointer": "CMOS18 §3.8 p15 (scan p1122)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.FIGURES.PLACEMENT.TOP_OR_BOTTOM.CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "3.12",
+ "title": "Section 3.12",
+ "pointer": "CMOS18 §3.12 p24 (scan p1122)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.FIGURES.LABELS.FONT.CONSISTENT",
+ "CMOS.FIGURES.LABELS.AVOID_OVERLAP",
+ "CMOS.FIGURES.ANNOTATIONS.CONSISTENT_STYLE",
+ "CMOS.FIGURES.AXES.UNITS.CONSISTENT",
+ "CMOS.FIGURES.EMBEDDED_TEXT.MINIMAL",
+ "CMOS.FIGURES.MULTIPART.PANEL_LABELS",
+ "CMOS.FIGURES.PANEL_ORDER.LOGICAL"
+ ]
+ },
+ {
+ "section_id": "3.34",
+ "title": "Section 3.34",
+ "pointer": "CMOS18 §3.34 p33 (scan p1122)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.FIGURES.LIST_OF_FIGURES.WHEN_NEEDED",
+ "CMOS.FIGURES.LIST_ENTRIES.MATCH_CAPTIONS"
+ ]
+ },
+ {
+ "section_id": "3.38",
+ "title": "Section 3.38",
+ "pointer": "CMOS18 §3.38 p39 (scan p1122)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.FIGURES.PLACEMENT.AVOID_SPLIT",
+ "CMOS.FIGURES.CALL_OUTS.AVOID_OVERLAP",
+ "CMOS.FIGURES.CROP.AVOID_LOSS",
+ "CMOS.FIGURES.BLEED.ONLY_WHEN_ENABLED",
+ "CMOS.FIGURES.ORIENTATION.CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "5.207",
+ "title": "Section 5.207",
+ "pointer": "CMOS18 §5.207 p207 (scan p1123)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.TABLES.MISSING_VALUES.EXPLAIN",
+ "CMOS.TABLES.NOTES.ORDERED_MARKERS",
+ "CMOS.TABLES.SOURCE.NOTES.DISTINCT",
+ "CMOS.TABLES.FOOTNOTES.PLACEMENT",
+ "CMOS.TABLES.ABBREVIATIONS.EXPLAIN"
+ ]
+ },
+ {
+ "section_id": "5.254",
+ "title": "Section 5.254",
+ "pointer": "CMOS18 §5.254 p84 (scan p1123)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.TABLES.ROW_SPACING.READABLE",
+ "CMOS.TABLES.COLUMN_SPACING.READABLE",
+ "CMOS.TABLES.RULES.MINIMAL",
+ "CMOS.TABLES.GRIDLINES.LIGHT",
+ "CMOS.TABLES.GROUPING.WHITESPACE",
+ "CMOS.TABLES.SHADING.SPARING"
+ ]
+ },
+ {
+ "section_id": "6.1",
+ "title": "Punctuation overview",
+ "pointer": "CMOS18 §6.1 p377 (scan p400)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.OVERVIEW.FUNCTION.CLARITY",
+ "CMOS.PUNCTUATION.OVERVIEW.CONSISTENT.PRINCIPLES",
+ "CMOS.PUNCTUATION.OVERVIEW.CONTEXT.REGISTER"
+ ]
+ },
+ {
+ "section_id": "6.2",
+ "title": "Punctuation in relation to surrounding text (italics)",
+ "pointer": "CMOS18 §6.2 p378 (scan p400)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.ITALICS.SURROUNDING_STYLE",
+ "CMOS.PUNCTUATION.ITALICS.TITLE_OWNERSHIP"
+ ]
+ },
+ {
+ "section_id": "6.3",
+ "title": "Punctuation with boldface or color",
+ "pointer": "CMOS18 §6.3 p379 (scan p401)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.BOLD_COLOR.SEMANTIC_OWNERSHIP",
+ "CMOS.PUNCTUATION.BOLD_COLOR.CASE_BY_CASE"
+ ]
+ },
+ {
+ "section_id": "6.4",
+ "title": "Punctuation and font style (aesthetic system)",
+ "pointer": "CMOS18 §6.4 p379 (scan p401)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.PRINT_ONLY",
+ "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.ELECTRONIC_PREFERS_LOGICAL"
+ ]
+ },
+ {
+ "section_id": "6.5",
+ "title": "Parentheses and brackets in relation to surrounding text",
+ "pointer": "CMOS18 §6.5 p380 (scan p402)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.MATCH_SURROUNDING",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.LINE_ALONE",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.PRINT_HAIR_SPACE"
+ ]
+ },
+ {
+ "section_id": "6.6",
+ "title": "Quotation marks in relation to surrounding text",
+ "pointer": "CMOS18 §6.6 p380 (scan p402)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.QUOTES.MATCH_SURROUNDING",
+ "CMOS.PUNCTUATION.QUOTES.LINE_ALONE",
+ "CMOS.PUNCTUATION.QUOTES.ITALIC_TITLE_EXCEPTION"
+ ]
+ },
+ {
+ "section_id": "6.7",
+ "title": "Punctuation spacing in typeset text",
+ "pointer": "CMOS18 §6.7 p381 (scan p403)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.SPACING.ONE_SPACE_SENTENCES",
+ "CMOS.PUNCTUATION.SPACING.ONE_SPACE_AFTER_COLON",
+ "CMOS.PUNCTUATION.SPACING.DESIGN_SPECIFIED"
+ ]
+ },
+ {
+ "section_id": "6.8",
+ "title": "Punctuation with URLs and email addresses",
+ "pointer": "CMOS18 §6.8 p381 (scan p403)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.URLS.PUNCTUATE_NORMALLY",
+ "CMOS.PUNCTUATION.URLS.NO_WRAPPERS",
+ "CMOS.PUNCTUATION.URLS.TRAILING_PUNCTUATION",
+ "CMOS.PUNCTUATION.URLS.HYPERTEXT_EXCLUDES_PUNCTUATION",
+ "CMOS.LINKS.PUNCTUATE_NORMALLY",
+ "CMOS.LINKS.NO_WRAPPERS",
+ "CMOS.LINKS.TRAILING_PUNCTUATION_OUTSIDE",
+ "CMOS.LINKS.HYPERLINK_EXCLUDES_PUNCTUATION",
+ "CMOS.LINKS.URL_ONLY_LINE_NO_PUNCT",
+ "CMOS.LINKS.REPHRASE_IF_URL_ENDS_PUNCT"
+ ]
+ },
+ {
+ "section_id": "6.9",
+ "title": "Punctuation in relation to closing quotation marks",
+ "pointer": "CMOS18 §6.9 p381 (scan p403)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.QUOTES.US_STYLE_PERIODS_COMMAS",
+ "CMOS.PUNCTUATION.QUOTES.APOSTROPHE_NOT_QUOTE",
+ "CMOS.PUNCTUATION.QUOTES.ALT_STYLE.DOCUMENT"
+ ]
+ },
+ {
+ "section_id": "6.14",
+ "title": "Display lines and parenthetical sentences",
+ "pointer": "CMOS18 §6.14 p384 (scan p405)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.PERIODS.OMIT_DISPLAY_LINES",
+ "CMOS.PUNCTUATION.PARENS.AVOID_MULTIPLE_SENTENCES"
+ ]
+ },
+ {
+ "section_id": "6.15",
+ "title": "Ellipses for omission or trailing thought",
+ "pointer": "CMOS18 §6.15 p384 (scan p405)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.ELLIPSIS.USE_CASES"
+ ]
+ },
+ {
+ "section_id": "6.16",
+ "title": "Comma principles by logic and register",
+ "pointer": "CMOS18 §6.16 p384 (scan p405)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.LOGIC_OVER_PAUSE",
+ "CMOS.PUNCTUATION.COMMAS.REGISTER.FLEX"
+ ]
+ },
+ {
+ "section_id": "6.17",
+ "title": "Commas in pairs",
+ "pointer": "CMOS18 §6.17 p385 (scan p407)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.PAIRS.SECOND_REQUIRED",
+ "CMOS.PUNCTUATION.COMMAS.PAIRS.TITLES_EXCEPTION"
+ ]
+ },
+ {
+ "section_id": "6.18",
+ "title": "Commas with parentheses and brackets",
+ "pointer": "CMOS18 §6.18 p385 (scan p407)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.PARENS.TRAILING",
+ "CMOS.PUNCTUATION.COMMAS.BRACKETS.EDITORIAL",
+ "CMOS.PUNCTUATION.COMMAS.PARENS_BRACKETS.AFTER_CLOSING",
+ "CMOS.PUNCTUATION.COMMAS.BRACKETS.EDITORIAL_INSERT"
+ ]
+ },
+ {
+ "section_id": "6.19",
+ "title": "Serial commas",
+ "pointer": "CMOS18 §6.19 p385 (scan p407)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.PAIR_WITH_AND",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.ALL_CONJUNCTIONS_NO_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.REQUIRED",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.PAIR_LAST_ITEM",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.AMBIGUITY_REWORD",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.AS_WELL_AS",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.ALL_CONJUNCTIONS"
+ ]
+ },
+ {
+ "section_id": "6.20",
+ "title": "Commas with etc. and et al.",
+ "pointer": "CMOS18 §6.20 p387 (scan p409)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.ETC.FINAL_ELEMENT",
+ "CMOS.PUNCTUATION.COMMAS.ETC_ETAL.STYLE",
+ "CMOS.PUNCTUATION.COMMAS.ETC.TRAILING",
+ "CMOS.PUNCTUATION.COMMAS.ETC_SINGLE_ITEM",
+ "CMOS.PUNCTUATION.COMMAS.ETC.FORMAL_LIMIT"
+ ]
+ },
+ {
+ "section_id": "6.21",
+ "title": "Omit serial commas before ampersands",
+ "pointer": "CMOS18 §6.21 p387 (scan p409)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.AMPERSAND.NO_SERIAL"
+ ]
+ },
+ {
+ "section_id": "6.22",
+ "title": "Commas with independent clauses",
+ "pointer": "CMOS18 §6.22 p387 (scan p409)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.CONJUNCTION",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.SHORT_OMIT",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.SHORT"
+ ]
+ },
+ {
+ "section_id": "6.23",
+ "title": "Comma splices",
+ "pointer": "CMOS18 §6.23 p388 (scan p410)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.COMMA_SPLICE.AVOID_FORMAL",
+ "CMOS.PUNCTUATION.COMMAS.SPLICES.AVOID_FORMAL",
+ "CMOS.PUNCTUATION.COMMAS.SPLICES.EDITORIAL_DISCRETION"
+ ]
+ },
+ {
+ "section_id": "6.24",
+ "title": "Commas with compound predicates",
+ "pointer": "CMOS18 §6.24 p388 (scan p410)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.THEN_SHORTHAND",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.SERIES",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.NO_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.CLARITY",
+ "CMOS.PUNCTUATION.COMMAS.AND_THEN"
+ ]
+ },
+ {
+ "section_id": "6.25",
+ "title": "Commas with imperative clauses",
+ "pointer": "CMOS18 §6.25 p389 (scan p411)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.IMPERATIVE_CLAUSES.DEFAULT",
+ "CMOS.PUNCTUATION.COMMAS.IMPERATIVE_CLAUSES"
+ ]
+ },
+ {
+ "section_id": "6.26",
+ "title": "Commas after introductory dependent clauses",
+ "pointer": "CMOS18 §6.26 p390 (scan p412)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_INTRODUCTORY",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_INTRO"
+ ]
+ },
+ {
+ "section_id": "6.27",
+ "title": "Commas with dependent clauses following the main clause",
+ "pointer": "CMOS18 §6.27 p390 (scan p412)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING_RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING_NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING.RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING.NONRESTRICTIVE"
+ ]
+ },
+ {
+ "section_id": "6.28",
+ "title": "Commas with consecutive conjunctions",
+ "pointer": "CMOS18 §6.28 p391 (scan p413)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.CONSECUTIVE_CONJUNCTIONS.NO_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.CONSECUTIVE_CONJUNCTIONS"
+ ]
+ },
+ {
+ "section_id": "6.29",
+ "title": "Commas with relative clauses",
+ "pointer": "CMOS18 §6.29 p392 (scan p414)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_THAT_WHICH",
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_NONRESTRICTIVE"
+ ]
+ },
+ {
+ "section_id": "6.30",
+ "title": "Commas with appositives",
+ "pointer": "CMOS18 §6.30 p392 (scan p414)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.APPOSITIVES.NONRESTRICTIVE"
+ ]
+ },
+ {
+ "section_id": "6.31",
+ "title": "Relationship names and commas",
+ "pointer": "CMOS18 §6.31 p393 (scan p415)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIPS.UNIQUE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIPS.AVOID_POSSESSIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_NAMES",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_AWKWARD_POSSESSIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_ALWAYS_USE"
+ ]
+ },
+ {
+ "section_id": "6.32",
+ "title": "Commas with descriptive phrases",
+ "pointer": "CMOS18 §6.32 p394 (scan p416)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASE",
+ "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASES.NONRESTRICTIVE"
+ ]
+ },
+ {
+ "section_id": "6.33",
+ "title": "Commas with participial phrases",
+ "pointer": "CMOS18 §6.33 p394 (scan p416)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL.LINKING_VERB",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_INTRO",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_MID_END",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_LINKING_VERB"
+ ]
+ },
+ {
+ "section_id": "6.34",
+ "title": "Commas with adverbial phrases",
+ "pointer": "CMOS18 §6.34 p395 (scan p417)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL.INTRO_OPTIONAL",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL.MID_END",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_INTRO_OPTIONAL",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_MID",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_END",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_INVERTED"
+ ]
+ },
+ {
+ "section_id": "6.35",
+ "title": "Commas with phrases after conjunctions",
+ "pointer": "CMOS18 §6.35 p396 (scan p418)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.PHRASE_PLUS_CONJUNCTION",
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTION_PLUS_PHRASE.PREDICATE",
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTION_PLUS_PHRASE.INDEPENDENT"
+ ]
+ },
+ {
+ "section_id": "6.36",
+ "title": "Commas with introductory phrases",
+ "pointer": "CMOS18 §6.36 p396 (scan p418)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.INTRO_PHRASES.GENERAL"
+ ]
+ },
+ {
+ "section_id": "6.37",
+ "title": "Commas with introductory yes/no",
+ "pointer": "CMOS18 §6.37 p397 (scan p419)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.INTRO_YES_NO"
+ ]
+ },
+ {
+ "section_id": "6.38",
+ "title": "Commas with introductory oh/ah",
+ "pointer": "CMOS18 §6.38 p397 (scan p419)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.INTRO_OH_AH"
+ ]
+ },
+ {
+ "section_id": "6.39",
+ "title": "Commas with coordinate adjectives",
+ "pointer": "CMOS18 §6.39 p397 (scan p419)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.COORDINATE_ADJECTIVES"
+ ]
+ },
+ {
+ "section_id": "6.40",
+ "title": "Commas with repeated adjectives",
+ "pointer": "CMOS18 §6.40 p398 (scan p420)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.REPEATED_ADJECTIVES.USE_COMMA"
+ ]
+ },
+ {
+ "section_id": "6.41",
+ "title": "Commas with dates",
+ "pointer": "CMOS18 §6.41 p398 (scan p420)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.DATES.NO_COMMA_OTHER_STYLES",
+ "CMOS.PUNCTUATION.COMMAS.DATES.MONTH_DAY_YEAR",
+ "CMOS.PUNCTUATION.COMMAS.DATES.ALTERNATE_SYSTEMS"
+ ]
+ },
+ {
+ "section_id": "6.42",
+ "title": "Commas with addresses",
+ "pointer": "CMOS18 §6.42 p398 (scan p420)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.ADDRESSES.MAILING_SPARING",
+ "CMOS.PUNCTUATION.COMMAS.ADDRESSES.RUN_IN"
+ ]
+ },
+ {
+ "section_id": "6.43",
+ "title": "Commas with quotations",
+ "pointer": "CMOS18 §6.43 p399 (scan p421)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.DIALOGUE_VERB_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.NO_COMMA_CONJUNCTION",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.DIALOGUE",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.THAT_WHETHER"
+ ]
+ },
+ {
+ "section_id": "6.44",
+ "title": "Commas with quoted or italicized titles",
+ "pointer": "CMOS18 §6.44 p400 (scan p422)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.TITLES.APPOSITIVE_RULE",
+ "CMOS.PUNCTUATION.COMMAS.TITLES_AND_EXPRESSIONS"
+ ]
+ },
+ {
+ "section_id": "6.45",
+ "title": "Commas with questions",
+ "pointer": "CMOS18 §6.45 p400 (scan p422)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.QUESTIONS.DIRECT_IN_SENTENCE",
+ "CMOS.PUNCTUATION.COMMAS.QUESTIONS.INDIRECT",
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_QUESTIONS",
+ "CMOS.PUNCTUATION.COMMAS.INDIRECT_QUESTIONS"
+ ]
+ },
+ {
+ "section_id": "6.46",
+ "title": "Commas with Jr., Sr., and similar",
+ "pointer": "CMOS18 §6.46 p401 (scan p423)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.NONE",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.RUNNING",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.INVERTED"
+ ]
+ },
+ {
+ "section_id": "6.47",
+ "title": "Commas with Inc., Ltd., and similar",
+ "pointer": "CMOS18 §6.47 p402 (scan p424)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.INC_LTD.NONE",
+ "CMOS.PUNCTUATION.COMMAS.CORPORATE_SUFFIX"
+ ]
+ },
+ {
+ "section_id": "6.48",
+ "title": "Commas with not phrases",
+ "pointer": "CMOS18 §6.48 p402 (scan p424)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.NOT_PHRASE",
+ "CMOS.PUNCTUATION.COMMAS.NOT_PHRASES"
+ ]
+ },
+ {
+ "section_id": "6.49",
+ "title": "Commas with correlative conjunctions",
+ "pointer": "CMOS18 §6.49 p402 (scan p424)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE.PREDICATE",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE.INDEPENDENT_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE_PHRASES",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE_CLAUSES"
+ ]
+ },
+ {
+ "section_id": "6.50",
+ "title": "Commas with the more...the more",
+ "pointer": "CMOS18 §6.50 p403 (scan p425)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.THE_MORE_THE_MORE"
+ ]
+ },
+ {
+ "section_id": "6.51",
+ "title": "Commas with parenthetical elements",
+ "pointer": "CMOS18 §6.51 p403 (scan p425)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICALS.SLIGHT_BREAK",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_ELEMENTS",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_HEAVY"
+ ]
+ },
+ {
+ "section_id": "6.52",
+ "title": "Commas with conjunctive adverbs",
+ "pointer": "CMOS18 §6.52 p403 (scan p425)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTIVE_ADVERBS"
+ ]
+ },
+ {
+ "section_id": "6.53",
+ "title": "Commas with such as and including",
+ "pointer": "CMOS18 §6.53 p404 (scan p426)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.SUCH_AS_INCLUDING"
+ ]
+ },
+ {
+ "section_id": "6.54",
+ "title": "Commas with that is and namely",
+ "pointer": "CMOS18 §6.54 p404 (scan p426)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.THAT_IS.TRAILING_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.IE_EG.PARENS",
+ "CMOS.PUNCTUATION.COMMAS.THAT_IS_NAMELY"
+ ]
+ },
+ {
+ "section_id": "6.55",
+ "title": "Commas with explanatory alternatives",
+ "pointer": "CMOS18 §6.55 p405 (scan p427)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.EXPLANATORY_ALTERNATIVES"
+ ]
+ },
+ {
+ "section_id": "6.56",
+ "title": "Commas with too or either",
+ "pointer": "CMOS18 §6.56 p405 (scan p427)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.TOO_EITHER.OMIT",
+ "CMOS.PUNCTUATION.COMMAS.TOO_MID_SENTENCE"
+ ]
+ },
+ {
+ "section_id": "6.57",
+ "title": "Commas for direct address and salutations",
+ "pointer": "CMOS18 §6.57 p405 (scan p427)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS",
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS.GREETINGS"
+ ]
+ },
+ {
+ "section_id": "6.58",
+ "title": "Commas indicating elision",
+ "pointer": "CMOS18 §6.58 p406 (scan p428)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.ELISION"
+ ]
+ },
+ {
+ "section_id": "6.59",
+ "title": "Commas between homonyms",
+ "pointer": "CMOS18 §6.59 p406 (scan p429)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.HOMONYMS.CLARITY"
+ ]
+ },
+ {
+ "section_id": "6.60",
+ "title": "Avoid semicolons in dialogue",
+ "pointer": "CMOS18 §6.60 p407 (scan p429)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.SEMICOLONS.AVOID_DIALOGUE"
+ ]
+ },
+ {
+ "section_id": "6.61",
+ "title": "Semicolons with conjunctive adverbs",
+ "pointer": "CMOS18 §6.61 p407 (scan p429)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.SEMICOLONS.CONJUNCTIVE_ADVERBS"
+ ]
+ },
+ {
+ "section_id": "6.62",
+ "title": "Semicolons with that is and for example",
+ "pointer": "CMOS18 §6.62 p407 (scan p430)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.SEMICOLONS.THAT_IS_CLAUSE"
+ ]
+ },
+ {
+ "section_id": "6.63",
+ "title": "Semicolons before conjunctions",
+ "pointer": "CMOS18 §6.63 p407 (scan p430)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.SEMICOLONS.BEFORE_CONJUNCTION"
+ ]
+ },
+ {
+ "section_id": "6.64",
+ "title": "Semicolons in a complex series",
+ "pointer": "CMOS18 §6.64 p408 (scan p430)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.SEMICOLONS.COMPLEX_SERIES"
+ ]
+ },
+ {
+ "section_id": "6.65",
+ "title": "Colons for amplification or emphasis",
+ "pointer": "CMOS18 §6.65 p409 (scan p431)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COLONS.AMPLIFY_OR_ILLUSTRATE",
+ "CMOS.PUNCTUATION.COLONS.EMPHASIS_SECOND_CLAUSE"
+ ]
+ },
+ {
+ "section_id": "6.66",
+ "title": "Space after colon",
+ "pointer": "CMOS18 §6.66 p409 (scan p432)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COLONS.ONE_SPACE"
+ ]
+ },
+ {
+ "section_id": "6.67",
+ "title": "Capitalization after colon",
+ "pointer": "CMOS18 §6.67 p409 (scan p432)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COLONS.CAPITALIZATION"
+ ]
+ },
+ {
+ "section_id": "6.68",
+ "title": "Colons with as follows",
+ "pointer": "CMOS18 §6.68 p409 (scan p432)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COLONS.AS_FOLLOWS"
+ ]
+ },
+ {
+ "section_id": "6.69",
+ "title": "Colons to introduce quotations or questions",
+ "pointer": "CMOS18 §6.69 p409 (scan p432)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COLONS.QUOTATIONS"
+ ]
+ },
+ {
+ "section_id": "6.70",
+ "title": "Colons in formal greetings",
+ "pointer": "CMOS18 §6.70 p411 (scan p433)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COLONS.FORMAL_GREETINGS"
+ ]
+ },
+ {
+ "section_id": "6.71",
+ "title": "Avoid colons after incomplete lead-ins",
+ "pointer": "CMOS18 §6.71 p411 (scan p433)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COLONS.AVOID_INCOMPLETE_LEADIN"
+ ]
+ },
+ {
+ "section_id": "6.72",
+ "title": "Use of the question mark",
+ "pointer": "CMOS18 §6.72 p411 (scan p434)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.QUESTION_MARKS.DIRECT"
+ ]
+ },
+ {
+ "section_id": "6.73",
+ "title": "Direct and indirect questions",
+ "pointer": "CMOS18 §6.73 p411 (scan p434)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.QUESTION_MARKS.DIRECT_INDIRECT"
+ ]
+ },
+ {
+ "section_id": "6.74",
+ "title": "Question marks with surrounding punctuation",
+ "pointer": "CMOS18 §6.74 p412 (scan p435)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.QUESTION_MARKS.SURROUNDING"
+ ]
+ },
+ {
+ "section_id": "6.75",
+ "title": "Use of the exclamation point",
+ "pointer": "CMOS18 §6.75 p412 (scan p435)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.EXCLAMATION.USE_SPARING"
+ ]
+ },
+ {
+ "section_id": "6.76",
+ "title": "Exclamation rather than question",
+ "pointer": "CMOS18 §6.76 p412 (scan p435)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.EXCLAMATION.RHETORICAL"
+ ]
+ },
+ {
+ "section_id": "6.77",
+ "title": "Bracketed exclamation points",
+ "pointer": "CMOS18 §6.77 p412 (scan p435)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.EXCLAMATION.BRACKETED_AVOID"
+ ]
+ },
+ {
+ "section_id": "6.78",
+ "title": "Exclamation points with quoted matter",
+ "pointer": "CMOS18 §6.78 p414 (scan p436)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.EXCLAMATION.QUOTE_PLACEMENT"
+ ]
+ },
+ {
+ "section_id": "6.79",
+ "title": "Hyphen, en dash, and em dash distinctions",
+ "pointer": "CMOS18 §6.79 p414 (scan p436)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.DASHES.DISTINCT_TYPES"
+ ]
+ },
+ {
+ "section_id": "6.81",
+ "title": "Hyphens for noninclusive numbers and spelled letters",
+ "pointer": "CMOS18 §6.81 p415 (scan p437)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.HYPHENS.SEPARATORS"
+ ]
+ },
+ {
+ "section_id": "6.83",
+ "title": "Avoid en dashes with from or between",
+ "pointer": "CMOS18 §6.83 p415 (scan p437)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.AVOID_FROM_BETWEEN"
+ ]
+ },
+ {
+ "section_id": "6.88",
+ "title": "Line breaks with en dashes",
+ "pointer": "CMOS18 §6.88 p418 (scan p440)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.LINE_BREAKS"
+ ]
+ },
+ {
+ "section_id": "6.89",
+ "title": "Spaced en dashes in British style",
+ "pointer": "CMOS18 §6.89 p418 (scan p440)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.SPACED_BRITISH"
+ ]
+ },
+ {
+ "section_id": "6.90",
+ "title": "Minus signs versus en dashes",
+ "pointer": "CMOS18 §6.90 p418 (scan p440)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.MINUS_SIGN"
+ ]
+ },
+ {
+ "section_id": "6.91",
+ "title": "Em dashes as parenthetical breaks",
+ "pointer": "CMOS18 §6.91 p418 (scan p440)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.ALTERNATIVE_TO_PARENS"
+ ]
+ },
+ {
+ "section_id": "6.95",
+ "title": "Avoid nested em dashes and stacked punctuation",
+ "pointer": "CMOS18 §6.95 p419 (scan p441)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.AVOID_NESTED",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.PUNCTUATION_BEFORE"
+ ]
+ },
+ {
+ "section_id": "6.96",
+ "title": "Line breaks with em dashes",
+ "pointer": "CMOS18 §6.96 p420 (scan p442)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.LINE_BREAKS_DETAIL"
+ ]
+ },
+ {
+ "section_id": "6.97",
+ "title": "Em dash dialogue style",
+ "pointer": "CMOS18 §6.97 p420 (scan p442)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.DIALOGUE_STYLE"
+ ]
+ },
+ {
+ "section_id": "6.98",
+ "title": "Avoid em dash bullets in formal prose",
+ "pointer": "CMOS18 §6.98 p420 (scan p442)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.LISTS_TABLES"
+ ]
+ },
+ {
+ "section_id": "6.99",
+ "title": "Two-em and three-em dashes for omissions",
+ "pointer": "CMOS18 §6.99 p421 (scan p443)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.DASHES.TWO_EM.OMISSIONS"
+ ]
+ },
+ {
+ "section_id": "6.124",
+ "title": "Apostrophe uses",
+ "pointer": "CMOS18 §6.124 p429 (scan p451)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.APOSTROPHE.USE_CASES"
+ ]
+ },
+ {
+ "section_id": "6.125",
+ "title": "Typographic apostrophes",
+ "pointer": "CMOS18 §6.125 p429 (scan p451)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.APOSTROPHE.SMART"
+ ]
+ },
+ {
+ "section_id": "6.127",
+ "title": "Word spaces and nonbreaking spaces",
+ "pointer": "CMOS18 §6.127 p430 (scan p452)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.SPACING.WORD_SPACE_DEFAULT",
+ "CMOS.PUNCTUATION.SPACING.NONBREAKING"
+ ]
+ },
+ {
+ "section_id": "6.128",
+ "title": "Fixed-width spaces by exception",
+ "pointer": "CMOS18 §6.128 p430 (scan p452)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.SPACING.FIXED_WIDTHS"
+ ]
+ },
+ {
+ "section_id": "6.132",
+ "title": "Abbreviation periods at sentence end",
+ "pointer": "CMOS18 §6.132 p432 (scan p454)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.PERIODS.NO_DOUBLE_AT_SENTENCE_END"
+ ]
+ },
+ {
+ "section_id": "6.133",
+ "title": "Periods with question or exclamation marks",
+ "pointer": "CMOS18 §6.133 p433 (scan p454)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.PERIODS.NOT_WITH_QM_EXCL"
+ ]
+ },
+ {
+ "section_id": "6.134",
+ "title": "Commas after quotes ending in question or exclamation marks",
+ "pointer": "CMOS18 §6.134 p433 (scan p454)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.COMMAS.QUOTE_ENDING_QM_EXCL"
+ ]
+ },
+ {
+ "section_id": "6.135",
+ "title": "Dual question and exclamation marks",
+ "pointer": "CMOS18 §6.135 p433 (scan p454)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.QUESTION_EXCLAMATION.DUAL_MARKS"
+ ]
+ },
+ {
+ "section_id": "6.136",
+ "title": "Question marks introducing lists",
+ "pointer": "CMOS18 §6.136 p434 (scan p456)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.QUESTION_MARKS.LIST_INTRO"
+ ]
+ },
+ {
+ "section_id": "6.137",
+ "title": "Emoji spacing and punctuation",
+ "pointer": "CMOS18 §6.137 p434 (scan p456)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.EMOJIS.PUNCTUATION"
+ ]
+ },
+ {
+ "section_id": "6.138",
+ "title": "List parallelism and format consistency",
+ "pointer": "CMOS18 §6.138 p435 (scan p456)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.LISTS.PARALLEL_ELEMENTS",
+ "CMOS.PUNCTUATION.LISTS.NUMERALS_ONLY_IF_NEEDED",
+ "CMOS.PUNCTUATION.LISTS.CONSISTENT_FORMAT"
+ ]
+ },
+ {
+ "section_id": "6.139",
+ "title": "Run-in versus vertical lists",
+ "pointer": "CMOS18 §6.139 p435 (scan p457)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SHORT_SIMPLE",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.LONG_OR_MULTI"
+ ]
+ },
+ {
+ "section_id": "6.140",
+ "title": "Run-in list formatting",
+ "pointer": "CMOS18 §6.140 p435 (scan p457)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.LISTS.RUNIN.MARKERS.PARENS",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.LETTERS.ITALIC_OPTION",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.INTRO_COMPLETE_COLON",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SEPARATORS",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SENTENCE_ITEMS_VERTICAL"
+ ]
+ },
+ {
+ "section_id": "6.141",
+ "title": "Vertical list capitalization, punctuation, and format",
+ "pointer": "CMOS18 §6.141 p436 (scan p458)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.INTRO_COLON",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.UNORDERED_FRAGMENTS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.ORDERED_MARKERS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.CAPITALIZATION_CONSISTENT",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.END_PUNCT_SENTENCES",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.RUNOVER_ALIGN",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.MULTI_COLUMN_SHORT_ITEMS"
+ ]
+ },
+ {
+ "section_id": "6.142",
+ "title": "Sentence-style vertical lists and list alternatives",
+ "pointer": "CMOS18 §6.142 p438 (scan p460)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.LISTS.AVOID_VERTICAL_FOR_LONG_SENTENCES",
+ "CMOS.PUNCTUATION.LISTS.MIXED_SENTENCE_TYPES",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_PUNCTUATION",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_LOWERCASE",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_CONJUNCTION",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_USE_ONLY_FOR_EMPHASIS"
+ ]
+ },
+ {
+ "section_id": "6.143",
+ "title": "Multilevel lists and outline formatting",
+ "pointer": "CMOS18 §6.143 p438 (scan p460)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.OUTLINE_MARKERS",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.RUNOVER_ALIGN",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.PUNCTUATION_LEVELS",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.MULTI_DIGIT_ALIGN"
+ ]
+ },
+ {
+ "section_id": "9.1",
+ "title": "Numbers overview",
+ "pointer": "CMOS18 §9.1 p590 (scan p612)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.S9_1.OVERVIEW.FACTORS",
+ "CMOS.NUMBERS.S9_1.READABILITY_OVER_CONSISTENCY",
+ "CMOS.NUMBERS.S9_1.GENERAL_WORKS_SCOPE"
+ ]
+ },
+ {
+ "section_id": "9.2",
+ "title": "General principles for numerals versus words",
+ "pointer": "CMOS18 §9.2 p590 (scan p612)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.SPELLING.ONE_TO_ONE_HUNDRED.DEFAULT",
+ "CMOS.NUMBERS.CONSISTENCY.MIXED_FORMS.AVOID",
+ "CMOS.NUMBERS.RULE_SELECTION.GENERAL_OR_ALTERNATIVE",
+ "CMOS.NUMBERS.S9_2.GENERAL_RULE.ZERO_TO_ONE_HUNDRED",
+ "CMOS.NUMBERS.S9_2.ROUND_MULTIPLES.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_2.NONROUND.ABOVE_ONE_HUNDRED"
+ ]
+ },
+ {
+ "section_id": "9.3",
+ "title": "Alternative rule (zero through nine)",
+ "pointer": "CMOS18 §9.3 p590 (scan p612)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.RULE_SELECTION.ALTERNATIVE_ZERO_TO_NINE",
+ "CMOS.NUMBERS.S9_3.ALTERNATIVE_RULE.ZERO_TO_NINE",
+ "CMOS.NUMBERS.S9_3.ALTERNATIVE_ROUND_MULTIPLES"
+ ]
+ },
+ {
+ "section_id": "9.4",
+ "title": "Hundreds, thousands, and hundred thousands",
+ "pointer": "CMOS18 §9.4 p591 (scan p613)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.ROUND_NUMBERS.SPELL_OUT",
+ "CMOS.NUMBERS.S9_4.HUNDREDS_THOUSANDS.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_4.NONROUND.LARGE_NUMERALS",
+ "CMOS.NUMBERS.S9_4.MIXED_LARGE_CONTEXTS",
+ "CMOS.NUMBERS.S9_4.APPROXIMATIONS.SPELLED_OUT"
+ ]
+ },
+ {
+ "section_id": "9.5",
+ "title": "Numbers beginning a sentence",
+ "pointer": "CMOS18 §9.5 p591 (scan p613)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.SENTENCE_START.AVOID_NUMERAL",
+ "CMOS.NUMBERS.S9_5.SENTENCE_INITIAL.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_5.SENTENCE_INITIAL.RECAST",
+ "CMOS.NUMBERS.S9_5.TWO_NUMBERS.SAME_CATEGORY",
+ "CMOS.NUMBERS.S9_5.YEARS.MAY_BEGIN",
+ "CMOS.NUMBERS.S9_5.ALPHANUMERIC.MAY_BEGIN"
+ ]
+ },
+ {
+ "section_id": "9.6",
+ "title": "Ordinals",
+ "pointer": "CMOS18 §9.6 p592 (scan p614)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.ORDINALS.SUFFIX.CORRECT",
+ "CMOS.NUMBERS.ORDINALS.CONSISTENT_FORM",
+ "CMOS.NUMBERS.S9_6.ORDINALS.RULE_PARALLEL",
+ "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.ND_RD",
+ "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.NO_SUPERSCRIPT",
+ "CMOS.NUMBERS.S9_6.NTH_DEGREE.ITALIC_N",
+ "CMOS.NUMBERS.S9_6.ZERO.ORDINAL_TH"
+ ]
+ },
+ {
+ "section_id": "9.7",
+ "title": "Consistency and flexibility",
+ "pointer": "CMOS18 §9.7 p592 (scan p614)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.DENSE_CONTEXT.USE_NUMERALS",
+ "CMOS.NUMBERS.S9_7.CONSISTENT_CONTEXT",
+ "CMOS.NUMBERS.S9_7.CATEGORY_TRIGGER",
+ "CMOS.NUMBERS.S9_7.CROSS_CATEGORY.MIX_OK",
+ "CMOS.NUMBERS.S9_7.AVOID_DENSE_WORDS",
+ "CMOS.NUMBERS.S9_7.SENTENCE_START_EXCEPTION",
+ "CMOS.NUMBERS.S9_7.DOCUMENT_EXCEPTIONS"
+ ]
+ },
+ {
+ "section_id": "9.8",
+ "title": "When numerals are always used",
+ "pointer": "CMOS18 §9.8 p593 (scan p615)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.CONTEXTS.ALWAYS_NUMERALS",
+ "CMOS.NUMBERS.S9_8.ABBREVIATED_UNITS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.PERCENT.NUMERALS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.PAGES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.CHAPTERS_PARTS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.NOTES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.SECTIONS_PARAS_LINES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.FIGURES_TABLES_EQUATIONS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.BOXES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.ACT_SCENE",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.VOLUMES_ISSUES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.EXAMPLES_QUESTIONS_RULES",
+ "CMOS.NUMBERS.S9_8.TITLE_NUMBERS",
+ "CMOS.NUMBERS.S9_8.SYMBOLS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.PLACES.STREETS_ROOMS",
+ "CMOS.NUMBERS.S9_8.DATES.NUMERALS",
+ "CMOS.NUMBERS.S9_8.GRADES_LEVELS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.CLOTHING_SIZES.NUMERALS",
+ "CMOS.NUMBERS.S9_8.SEVERITY_CLASSIFICATIONS",
+ "CMOS.NUMBERS.S9_8.SCORES_VOTES.NUMERALS"
+ ]
+ },
+ {
+ "section_id": "9.9",
+ "title": "Millions, billions, and larger",
+ "pointer": "CMOS18 §9.9 p595 (scan p617)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.LARGE_VALUES.MILLIONS_BILLIONS",
+ "CMOS.NUMBERS.S9_9.MILLIONS_BILLIONS.GENERAL_RULE",
+ "CMOS.NUMBERS.S9_9.MIXED_NUMERAL_WORD.FRACTIONS",
+ "CMOS.NUMBERS.S9_9.CONSISTENCY.WITH_FRACTIONS",
+ "CMOS.NUMBERS.S9_9.BILLION_TRILLION.LOCALE_CHECK"
+ ]
+ },
+ {
+ "section_id": "9.10",
+ "title": "Powers of ten",
+ "pointer": "CMOS18 §9.10 p596 (scan p618)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.SCIENTIFIC.POWERS_OF_TEN",
+ "CMOS.NUMBERS.SCIENTIFIC.NOTATION.MANTISSA_RANGE",
+ "CMOS.NUMBERS.SCIENTIFIC.NOTATION.TIMES_SYMBOL",
+ "CMOS.NUMBERS.S9_10.SCIENTIFIC_NOTATION.USE",
+ "CMOS.NUMBERS.S9_10.POWERS_OF_TEN",
+ "CMOS.NUMBERS.S9_10.NEGATIVE_POWERS",
+ "CMOS.NUMBERS.S9_10.SCI_NOTATION.CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "9.11",
+ "title": "SI prefixes for large and small quantities",
+ "pointer": "CMOS18 §9.11 p596 (scan p618)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.SI_PREFIXES.NO_HYPHEN",
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.LARGE",
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.SMALL",
+ "CMOS.NUMBERS.S9_11.PREFIX_SYMBOLS",
+ "CMOS.NUMBERS.S9_11.MYR_GYR"
+ ]
+ },
+ {
+ "section_id": "9.12",
+ "title": "Binary and other bases",
+ "pointer": "CMOS18 §9.12 p596 (scan p618)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.BASES.NON_DECIMAL.NO_GROUPING",
+ "CMOS.NUMBERS.S9_12.BASE_INDICATOR",
+ "CMOS.NUMBERS.S9_12.BASE_PREFIXES",
+ "CMOS.NUMBERS.S9_12.BASE_SUBSCRIPT",
+ "CMOS.NUMBERS.S9_12.NO_COMMAS.IN_BASE",
+ "CMOS.NUMBERS.S9_12.BINARY_PREFIXES",
+ "CMOS.NUMBERS.S9_12.DECIMAL_PREFIXES"
+ ]
+ },
+ {
+ "section_id": "9.13",
+ "title": "Dex notation",
+ "pointer": "CMOS18 §9.13 p597 (scan p619)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.S9_13.DEX.DEFINITION"
+ ]
+ },
+ {
+ "section_id": "9.14",
+ "title": "Physical quantities",
+ "pointer": "CMOS18 §9.14 p597 (scan p619)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.NUMERALS.MEASUREMENTS.UNITS",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.GENERAL_RULE",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.COMMON_NUMERALS",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.EXACT_VALUES",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.CONSISTENCY"
+ ]
+ },
+ {
+ "section_id": "9.15",
+ "title": "Simple fractions",
+ "pointer": "CMOS18 §9.15 p597 (scan p619)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.FRACTIONS.SIMPLE.SPELL_OUT",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.HYPHENATE",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.EMPHASIS_EXCEPTION",
+ "CMOS.NUMBERS.S9_15.DECIMAL_FRACTIONS.NUMERALS"
+ ]
+ },
+ {
+ "section_id": "9.16",
+ "title": "Whole numbers plus fractions",
+ "pointer": "CMOS18 §9.16 p598 (scan p620)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.FRACTIONS.MIXED.WHOLE_PLUS_FRACTION",
+ "CMOS.NUMBERS.FRACTIONS.ADJECTIVAL.HYPHENATE",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.SHORT_SPELLED_OUT",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.NUMERALS",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.FRACTION_SYMBOLS",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.MEASUREMENTS"
+ ]
+ },
+ {
+ "section_id": "9.17",
+ "title": "Fractions in mathematical contexts",
+ "pointer": "CMOS18 §9.17 p598 (scan p620)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.FRACTIONS.MATH.NUMERALS",
+ "CMOS.NUMBERS.FRACTIONS.SLASH_INLINE",
+ "CMOS.NUMBERS.S9_17.FRACTIONS.RUNNING_TEXT.SLASH",
+ "CMOS.NUMBERS.S9_17.CASE_FRACTIONS.USE_WITH_CARE",
+ "CMOS.NUMBERS.S9_17.FRACTIONS.PARENS_BEFORE_SYMBOLS",
+ "CMOS.NUMBERS.S9_17.ALGEBRAIC.SLASH",
+ "CMOS.NUMBERS.S9_17.FRACTIONS.IN_NUMERATOR_DENOMINATOR",
+ "CMOS.NUMBERS.S9_17.EXPONENT_FRACTIONS.SLASH",
+ "CMOS.NUMBERS.S9_17.DISPLAYED_FRACTIONS.BAR",
+ "CMOS.NUMBERS.S9_17.SLASH_BINDING"
+ ]
+ },
+ {
+ "section_id": "9.18",
+ "title": "Numbers with abbreviations and symbols",
+ "pointer": "CMOS18 §9.18 p598 (scan p620)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.S9_18.ABBREVIATIONS.NUMERALS_ONLY",
+ "CMOS.NUMBERS.S9_18.NO_HYPHEN.NUMERAL_UNIT",
+ "CMOS.NUMBERS.S9_18.PRIME_SYMBOLS",
+ "CMOS.NUMBERS.S9_18.SPACING.NUMERAL_UNIT",
+ "CMOS.NUMBERS.S9_18.NO_SPACE.DEGREE_PERCENT_PRIME",
+ "CMOS.NUMBERS.S9_18.UNIT_WITHOUT_NUMERAL.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_18.SCIENTIFIC_CONTEXT.NUMERALS"
+ ]
+ },
+ {
+ "section_id": "9.19",
+ "title": "Repeated units",
+ "pointer": "CMOS18 §9.19 p599 (scan p621)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.UNITS.REPEATED.OMIT_REPEAT",
+ "CMOS.NUMBERS.DEGRADED.HARD_WRAP_UNITS",
+ "CMOS.NUMBERS.RANGES.REPEAT_UNIT_IF_AMBIG",
+ "CMOS.NUMBERS.RANGES.UNITS.PLACEMENT_CONSISTENT",
+ "CMOS.NUMBERS.UNITS.SPACE_BETWEEN_NUMBER_UNIT",
+ "CMOS.NUMBERS.S9_19.REPEAT_UNITS.CLOSED_UP",
+ "CMOS.NUMBERS.S9_19.UNIT_SPACED.SINGLE",
+ "CMOS.NUMBERS.S9_19.UNIT_REPETITION.CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "9.20",
+ "title": "Percentages",
+ "pointer": "CMOS18 §9.20 p599 (scan p621)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.PERCENTAGES.NUMERALS",
+ "CMOS.NUMBERS.PERCENTAGES.SYMBOL_OR_WORD.CONSISTENT",
+ "CMOS.NUMBERS.PERCENTAGES.SYMBOL_NO_SPACE",
+ "CMOS.NUMBERS.S9_20.PERCENT.NUMERALS",
+ "CMOS.NUMBERS.S9_20.PERCENT.WORD_VS_SYMBOL",
+ "CMOS.NUMBERS.S9_20.PERCENT.LESS_FREQUENT",
+ "CMOS.NUMBERS.S9_20.PERCENT_VS_PERCENTAGE",
+ "CMOS.NUMBERS.S9_20.PERCENT_RANGES.REPEAT"
+ ]
+ },
+ {
+ "section_id": "9.21",
+ "title": "Decimal fractions and leading zero",
+ "pointer": "CMOS18 §9.21 p600 (scan p622)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.DECIMALS.LEADING_ZERO",
+ "CMOS.NUMBERS.DECIMALS.NUMERALS",
+ "CMOS.NUMBERS.DECIMALS.TRAILING_ZEROS.AVOID",
+ "CMOS.NUMBERS.S9_21.DECIMALS.NUMERALS",
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.CONTEXT",
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.OMIT_PROBABILITIES",
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.CALIBERS",
+ "CMOS.NUMBERS.S9_21.UNITS.LESS_THAN_ONE",
+ "CMOS.NUMBERS.S9_21.DECIMAL_CONTEXT.CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "9.22",
+ "title": "Money",
+ "pointer": "CMOS18 §9.22 p600 (scan p622)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.CURRENCY.FORMAT.SYMBOL_PLACEMENT",
+ "CMOS.NUMBERS.CURRENCY.WORDS_VS_SYMBOLS",
+ "CMOS.NUMBERS.CURRENCY.SYMBOL_ADJACENT",
+ "CMOS.NUMBERS.CURRENCY.RANGES.REPEAT_SYMBOL",
+ "CMOS.NUMBERS.S9_22.MONEY.SPELL_OUT_SMALL",
+ "CMOS.NUMBERS.S9_22.MONEY.NUMERALS_EXACT",
+ "CMOS.NUMBERS.S9_22.MONEY.DECIMALS.ONLY_WHEN_MIXED",
+ "CMOS.NUMBERS.S9_22.MONEY.SINGULAR_VERB",
+ "CMOS.NUMBERS.S9_22.MONEY.SYMBOL_OR_WORD",
+ "CMOS.NUMBERS.S9_22.MONEY.MINIMUM_DECIMALS"
+ ]
+ },
+ {
+ "section_id": "9.23",
+ "title": "Non-US currencies using the dollar symbol",
+ "pointer": "CMOS18 §9.23 p601 (scan p623)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.CURRENCY.NON_US.DISAMBIGUATE",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.DISAMBIGUATE",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.ISO_CODES",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.CONTEXT_CLEAR"
+ ]
+ },
+ {
+ "section_id": "9.24",
+ "title": "British currency",
+ "pointer": "CMOS18 §9.24 p601 (scan p623)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.S9_24.BRITISH.POUND_SYMBOL",
+ "CMOS.NUMBERS.S9_24.BRITISH.PENCE_SYMBOL",
+ "CMOS.NUMBERS.S9_24.BRITISH.DECIMAL_FORMAT"
+ ]
+ },
+ {
+ "section_id": "9.25",
+ "title": "Other currencies",
+ "pointer": "CMOS18 §9.25 p602 (scan p624)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.CURRENCY.ISO_CODES",
+ "CMOS.NUMBERS.CURRENCY.CODE_POSITION.CONSISTENT",
+ "CMOS.NUMBERS.S9_25.OTHER_CURRENCIES.DECIMAL",
+ "CMOS.NUMBERS.S9_25.CURRENCY_CODES.SPACING",
+ "CMOS.NUMBERS.S9_25.CURRENCY_CODES.CONSISTENT",
+ "CMOS.NUMBERS.S9_25.ISO_CODES.FORMAL"
+ ]
+ },
+ {
+ "section_id": "9.26",
+ "title": "Large monetary amounts",
+ "pointer": "CMOS18 §9.26 p602 (scan p624)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.CURRENCY.LARGE_AMOUNTS",
+ "CMOS.NUMBERS.S9_26.LARGE_MONEY.NUMERALS",
+ "CMOS.NUMBERS.S9_26.LARGE_MONEY.MIXED",
+ "CMOS.NUMBERS.S9_26.K_THOUSANDS",
+ "CMOS.NUMBERS.S9_26.MONEY.COMMAS"
+ ]
+ },
+ {
+ "section_id": "9.27",
+ "title": "Currency with dates",
+ "pointer": "CMOS18 §9.27 p602 (scan p624)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.CURRENCY.HISTORICAL.YEAR_CONTEXT",
+ "CMOS.NUMBERS.S9_27.CURRENCY_YEAR.PARENS_NO_SPACE",
+ "CMOS.NUMBERS.S9_27.CURRENCY_YEAR.CODES_SPACING"
+ ]
+ },
+ {
+ "section_id": "9.28",
+ "title": "Numbered divisions in books and documents",
+ "pointer": "CMOS18 §9.28 p603 (scan p625)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.REFERENCES.PAGE_CHAPTER_FIGURE",
+ "CMOS.NUMBERS.S9_28.DIVISIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_28.FRONT_MATTER.ROMAN",
+ "CMOS.NUMBERS.S9_28.BIBLICAL_REFERENCES"
+ ]
+ },
+ {
+ "section_id": "9.29",
+ "title": "Periodical references",
+ "pointer": "CMOS18 §9.29 p603 (scan p625)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.PERIODICALS.VOLUME_ISSUE",
+ "CMOS.NUMBERS.S9_29.PERIODICALS.ORDER",
+ "CMOS.NUMBERS.S9_29.PERIODICALS.OMIT_WORDS"
+ ]
+ },
+ {
+ "section_id": "9.30",
+ "title": "Numbered divisions in legal instruments",
+ "pointer": "CMOS18 §9.30 p603 (scan p625)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.PREFER_ARABIC",
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.MIXED_LEVELS"
+ ]
+ },
+ {
+ "section_id": "9.31",
+ "title": "The year used alone",
+ "pointer": "CMOS18 §9.31 p604 (scan p626)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.DATES.CONSISTENT_FORMAT",
+ "CMOS.NUMBERS.DATES.YEAR_NUMERALS",
+ "CMOS.NUMBERS.S9_31.YEAR_STANDALONE",
+ "CMOS.NUMBERS.S9_31.YEAR_SENTENCE_START_ALLOWED"
+ ]
+ },
+ {
+ "section_id": "9.32",
+ "title": "The year abbreviated",
+ "pointer": "CMOS18 §9.32 p604 (scan p626)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.DATES.ABBREVIATED_YEAR",
+ "CMOS.NUMBERS.S9_32.ABBREVIATED_YEAR.APOSTROPHE"
+ ]
+ },
+ {
+ "section_id": "9.33",
+ "title": "Month and day",
+ "pointer": "CMOS18 §9.33 p604 (scan p626)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.DATES.MONTH_DAY_STYLE",
+ "CMOS.NUMBERS.DATES.ORDINALS.AVOID",
+ "CMOS.NUMBERS.S9_33.MONTH_DAY.CARDINALS",
+ "CMOS.NUMBERS.S9_33.DAY_WITHOUT_MONTH.ORDINAL",
+ "CMOS.NUMBERS.S9_33.MONTH_DAY_YEAR.COMMA"
+ ]
+ },
+ {
+ "section_id": "9.34",
+ "title": "Centuries",
+ "pointer": "CMOS18 §9.34 p605 (scan p627)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.CENTURIES.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_34.CENTURIES.ORDINAL_LOWERCASE",
+ "CMOS.NUMBERS.S9_34.CENTURIES.NUMERAL_PLURALS",
+ "CMOS.NUMBERS.S9_34.CENTURY_TURN.AVOID_AMBIGUITY"
+ ]
+ },
+ {
+ "section_id": "9.35",
+ "title": "Decades",
+ "pointer": "CMOS18 §9.35 p605 (scan p627)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.DECADES.CONSISTENT_FORM",
+ "CMOS.NUMBERS.S9_35.DECADES.NO_APOSTROPHE",
+ "CMOS.NUMBERS.S9_35.DECADES.FIRST_DECADE",
+ "CMOS.NUMBERS.S9_35.DECADES.SECOND_DECADE"
+ ]
+ },
+ {
+ "section_id": "9.36",
+ "title": "Eras",
+ "pointer": "CMOS18 §9.36 p606 (scan p628)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.ERAS.BCE_CE",
+ "CMOS.NUMBERS.S9_36.ERAS.ABBREVIATION_PLACEMENT",
+ "CMOS.NUMBERS.S9_36.ERAS.NO_PERIODS",
+ "CMOS.NUMBERS.S9_36.ERAS.CENTURY_PLACEMENT"
+ ]
+ },
+ {
+ "section_id": "9.37",
+ "title": "All-numeral dates",
+ "pointer": "CMOS18 §9.37 p607 (scan p629)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.DATES.ALL_NUMERAL",
+ "CMOS.NUMBERS.DATES.DAY_MONTH_ORDER.CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "9.38",
+ "title": "ISO dates",
+ "pointer": "CMOS18 §9.38 p607 (scan p629)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.DATES.ISO_8601"
+ ]
+ },
+ {
+ "section_id": "9.39",
+ "title": "Time of day",
+ "pointer": "CMOS18 §9.39 p607 (scan p629)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.TIME.GENERAL_NUMERALS",
+ "CMOS.NUMBERS.TIME.LEADING_ZERO_MINUTES",
+ "CMOS.NUMBERS.TIME.RANGES.CONSISTENT_FORMAT",
+ "CMOS.NUMBERS.TIME.AM_PM.CONSISTENT_SPACING",
+ "CMOS.NUMBERS.TIME.ZONE.INCLUDE_WHEN_AMBIGUOUS",
+ "CMOS.NUMBERS.TIME.SECONDS.OMIT_IF_NOT_NEEDED",
+ "CMOS.NUMBERS.TIME.SECONDS.INCLUDE_FOR_PRECISION"
+ ]
+ },
+ {
+ "section_id": "9.40",
+ "title": "Noon and midnight",
+ "pointer": "CMOS18 §9.40 p608 (scan p630)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.TIME.NOON_MIDNIGHT"
+ ]
+ },
+ {
+ "section_id": "9.41",
+ "title": "Twenty-four-hour system",
+ "pointer": "CMOS18 §9.41 p608 (scan p630)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.TIME.TWENTY_FOUR_HOUR"
+ ]
+ },
+ {
+ "section_id": "9.42",
+ "title": "ISO time",
+ "pointer": "CMOS18 §9.42 p609 (scan p631)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.TIME.ISO_STYLE"
+ ]
+ },
+ {
+ "section_id": "9.43",
+ "title": "Numbers with proper names and titles",
+ "pointer": "CMOS18 §9.43 p609 (scan p631)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.NAMES.MONARCHS_POPES"
+ ]
+ },
+ {
+ "section_id": "9.46",
+ "title": "Vehicles and vessels",
+ "pointer": "CMOS18 §9.46 p610 (scan p632)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.VEHICLES.VESSELS_NUMBERS"
+ ]
+ },
+ {
+ "section_id": "9.52",
+ "title": "Addresses and thoroughfares",
+ "pointer": "CMOS18 §9.52 p611 (scan p633)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.PLACES.HIGHWAYS"
+ ]
+ },
+ {
+ "section_id": "9.53",
+ "title": "Street names",
+ "pointer": "CMOS18 §9.53 p611 (scan p633)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.PLACES.STREETS"
+ ]
+ },
+ {
+ "section_id": "9.54",
+ "title": "Buildings and apartments",
+ "pointer": "CMOS18 §9.54 p611 (scan p633)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.PLACES.BUILDINGS_APTS"
+ ]
+ },
+ {
+ "section_id": "9.55",
+ "title": "Plurals and punctuation of numbers",
+ "pointer": "CMOS18 §9.55 p612 (scan p634)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.PLURALS.DECADE.NO_APOSTROPHE",
+ "CMOS.NUMBERS.PLURALS.SPELLED_OUT"
+ ]
+ },
+ {
+ "section_id": "9.56",
+ "title": "Digit grouping",
+ "pointer": "CMOS18 §9.56 p612 (scan p634)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.GROUPING.THOUSANDS_SEPARATOR"
+ ]
+ },
+ {
+ "section_id": "9.57",
+ "title": "Decimal markers and normalization",
+ "pointer": "CMOS18 §9.57 p613 (scan p635)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.DECIMAL_MARKER.LOCALE",
+ "CMOS.NUMBERS.DEGRADED.NUMERAL_NORMALIZATION"
+ ]
+ },
+ {
+ "section_id": "9.58",
+ "title": "SI digit grouping",
+ "pointer": "CMOS18 §9.58 p613 (scan p635)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.DIGIT_GROUPING.SI_SPACE"
+ ]
+ },
+ {
+ "section_id": "9.59",
+ "title": "Telephone numbers",
+ "pointer": "CMOS18 §9.59 p614 (scan p636)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.TELEPHONE.FORMAT",
+ "CMOS.NUMBERS.TELEPHONE.COUNTRY_CODE.WHEN_INTERNATIONAL",
+ "CMOS.NUMBERS.TELEPHONE.SEPARATORS.CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "9.60",
+ "title": "Ratios",
+ "pointer": "CMOS18 §9.60 p615 (scan p637)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.RATIOS.FORMAT",
+ "CMOS.NUMBERS.RATIOS.COLON_SPACING"
+ ]
+ },
+ {
+ "section_id": "9.61",
+ "title": "Outline numerals",
+ "pointer": "CMOS18 §9.61 p615 (scan p637)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.LISTS.OUTLINE.NUMERAL_STYLE"
+ ]
+ },
+ {
+ "section_id": "9.62",
+ "title": "Inclusive numbers",
+ "pointer": "CMOS18 §9.62 p615 (scan p637)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.RANGES.EN_DASH.USE",
+ "CMOS.NUMBERS.RANGES.NO_MIXED_FROM_BETWEEN",
+ "CMOS.TABLES.UNITS.IN_HEADERS",
+ "CMOS.TABLES.UNITS.CONSISTENT",
+ "CMOS.TABLES.ALIGNMENT.NUMERIC_DECIMAL",
+ "CMOS.TABLES.ALIGNMENT.TEXT_LEFT",
+ "CMOS.TABLES.ROUNDING.CONSISTENT",
+ "CMOS.TABLES.PRECISION.CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "9.63",
+ "title": "Inclusive ranges (page numbers)",
+ "pointer": "CMOS18 §9.63 p616 (scan p638)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.INCLUSIVE_RANGES.PAGE_NUMBERS.SHORTEN"
+ ]
+ },
+ {
+ "section_id": "9.65",
+ "title": "Inclusive numbers (general)",
+ "pointer": "CMOS18 §9.65 p617 (scan p639)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.INCLUSIVE.COMMAS",
+ "CMOS.NUMBERS.INCLUSIVE.SHORTEN_SECOND_NUMBER"
+ ]
+ },
+ {
+ "section_id": "9.66",
+ "title": "Inclusive years",
+ "pointer": "CMOS18 §9.66 p617 (scan p639)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.INCLUSIVE.YEARS",
+ "CMOS.NUMBERS.INCLUSIVE.YEARS.CENTURY_CROSSING"
+ ]
+ },
+ {
+ "section_id": "9.67",
+ "title": "Roman numerals",
+ "pointer": "CMOS18 §9.67 p617 (scan p639)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.NUMBERS.ROMAN_NUMERALS.USE",
+ "CMOS.NUMBERS.ROMAN_NUMERALS.CASE_CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "13.1",
+ "title": "Section 13.1",
+ "pointer": "CMOS18 §13.1 p776 (scan p798)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_1.ALL_SOURCE_TYPES",
+ "CMOS.CITATIONS.S13_1.DISCIPLINE_POLICY",
+ "CMOS.CITATIONS.S13_1.PURPOSE.COPYRIGHT",
+ "CMOS.CITATIONS.S13_1.PURPOSE.COURTESY",
+ "CMOS.CITATIONS.S13_1.PURPOSE.ETHICS",
+ "CMOS.CITATIONS.S13_1.SUFFICIENT_INFO"
+ ]
+ },
+ {
+ "section_id": "13.2",
+ "title": "Section 13.2",
+ "pointer": "CMOS18 §13.2 p776 (scan p798)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_2.AUTHOR_DATE_SYSTEM",
+ "CMOS.CITATIONS.S13_2.DEFAULT_SYSTEM",
+ "CMOS.CITATIONS.S13_2.DISCIPLINE_PREFERENCE",
+ "CMOS.CITATIONS.S13_2.JOURNAL_INSTRUCTIONS",
+ "CMOS.CITATIONS.S13_2.NOTES_BIBLIOGRAPHY_OPTIONAL",
+ "CMOS.CITATIONS.S13_2.NOTES_SYSTEM",
+ "CMOS.CITATIONS.S13_2.STYLE_ELEMENTS.SHARED",
+ "CMOS.CITATIONS.S13_2.SYSTEMS.TWO_TYPES",
+ "CMOS.CITATIONS.S13_2.SYSTEM_SWITCHING"
+ ]
+ },
+ {
+ "section_id": "13.3",
+ "title": "Section 13.3",
+ "pointer": "CMOS18 §13.3 p777 (scan p799)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_3.JOURNALS.HOUSE_STYLE",
+ "CMOS.CITATIONS.S13_3.LEGAL.BLUEBOOK",
+ "CMOS.CITATIONS.S13_3.OTHER_SYSTEMS.AMA_CSE",
+ "CMOS.CITATIONS.S13_3.OTHER_SYSTEMS.MLA_APA",
+ "CMOS.CITATIONS.S13_3.SOURCE_MANUALS"
+ ]
+ },
+ {
+ "section_id": "13.4",
+ "title": "Section 13.4",
+ "pointer": "CMOS18 §13.4 p777 (scan p799)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_4.CONSISTENCY.REQUIRED",
+ "CMOS.CITATIONS.S13_4.DOCUMENTED_DEVIATIONS",
+ "CMOS.CITATIONS.S13_4.FLEXIBILITY.BY_AGREEMENT",
+ "CMOS.CITATIONS.S13_4.JOURNALS.STRICT"
+ ]
+ },
+ {
+ "section_id": "13.5",
+ "title": "Section 13.5",
+ "pointer": "CMOS18 §13.5 p777 (scan p799)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_5.ACADEMIC_EXPECTATION",
+ "CMOS.CITATIONS.S13_5.AVOID_TANGENTIAL",
+ "CMOS.CITATIONS.S13_5.CITE_RELEVANT",
+ "CMOS.CITATIONS.S13_5.INFORMAL_SOURCES",
+ "CMOS.CITATIONS.S13_5.NONACADEMIC.MENTIONS_OK"
+ ]
+ },
+ {
+ "section_id": "13.6",
+ "title": "Section 13.6",
+ "pointer": "CMOS18 §13.6 p777 (scan p799)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_6.LINK_TITLE_PREFERRED",
+ "CMOS.CITATIONS.S13_6.URL.FINAL_ELEMENT",
+ "CMOS.CITATIONS.S13_6.URLS.EASILY_FOUND",
+ "CMOS.CITATIONS.S13_6.URLS.IN_MANUSCRIPT",
+ "CMOS.CITATIONS.S13_6.URLS.READER_NEEDED"
+ ]
+ },
+ {
+ "section_id": "13.7",
+ "title": "Section 13.7",
+ "pointer": "CMOS18 §13.7 p778 (scan p798)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_7.DOI.NO_PREFIX",
+ "CMOS.CITATIONS.S13_7.DOI.PREFERRED",
+ "CMOS.CITATIONS.S13_7.DOI.RESOLUTION",
+ "CMOS.CITATIONS.S13_7.DOI.URL_FORM"
+ ]
+ },
+ {
+ "section_id": "13.8",
+ "title": "Section 13.8",
+ "pointer": "CMOS18 §13.8 p778 (scan p798)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_8.PERMALINK.PREFERRED",
+ "CMOS.CITATIONS.S13_8.PERMALINK.TEST",
+ "CMOS.CITATIONS.S13_8.PREFERRED_ORDER",
+ "CMOS.CITATIONS.S13_8.SUBSCRIPTION_URLS"
+ ]
+ },
+ {
+ "section_id": "13.9",
+ "title": "Section 13.9",
+ "pointer": "CMOS18 §13.9 p779 (scan p796)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_9.DATABASE_NAME_OK",
+ "CMOS.CITATIONS.S13_9.SHORTEN_LONG_URLS",
+ "CMOS.CITATIONS.S13_9.SHORT_URLS.ARE_NOT_SHORTENERS",
+ "CMOS.CITATIONS.S13_9.URL_TO_MAIN_PAGE"
+ ]
+ },
+ {
+ "section_id": "13.10",
+ "title": "Section 13.10",
+ "pointer": "CMOS18 §13.10 p779 (scan p796)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_10.DATABASES.NAME_INSTEAD",
+ "CMOS.CITATIONS.S13_10.DATABASE_IN_CITATION",
+ "CMOS.CITATIONS.S13_10.DOI_PRECEDENCE",
+ "CMOS.CITATIONS.S13_10.TEST_LOGGED_OUT"
+ ]
+ },
+ {
+ "section_id": "13.11",
+ "title": "Section 13.11",
+ "pointer": "CMOS18 §13.11 p780 (scan p796)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_11.NO_SHORTENERS_IN_MS",
+ "CMOS.CITATIONS.S13_11.PUBLISHER_OPTION",
+ "CMOS.CITATIONS.S13_11.SHORTENERS.OBSCURE"
+ ]
+ },
+ {
+ "section_id": "13.12",
+ "title": "Section 13.12",
+ "pointer": "CMOS18 §13.12 p780 (scan p796)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_12.URLS.CASE_SENSITIVE",
+ "CMOS.CITATIONS.S13_12.URLS.NO_SENTENCE_START",
+ "CMOS.CITATIONS.S13_12.URLS.NO_SPACES",
+ "CMOS.CITATIONS.S13_12.URLS.PROTOCOL",
+ "CMOS.CITATIONS.S13_12.URLS.PUNCTUATION_AFTER",
+ "CMOS.CITATIONS.S13_12.URLS.TRAILING_SLASH"
+ ]
+ },
+ {
+ "section_id": "13.13",
+ "title": "Section 13.13",
+ "pointer": "CMOS18 §13.13 p780 (scan p796)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_13.BACKUPS",
+ "CMOS.CITATIONS.S13_13.CITATIONS.REVIEW",
+ "CMOS.CITATIONS.S13_13.METADATA.CHECK_FIELDS",
+ "CMOS.CITATIONS.S13_13.METADATA.MISSING",
+ "CMOS.CITATIONS.S13_13.REPAIR_AT_SOURCE",
+ "CMOS.CITATIONS.S13_13.STRIP_CODES",
+ "CMOS.CITATIONS.S13_13.TOOLS.USE_METADATA"
+ ]
+ },
+ {
+ "section_id": "13.14",
+ "title": "Section 13.14",
+ "pointer": "CMOS18 §13.14 p781 (scan p796)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_14.CITE_VERSION",
+ "CMOS.CITATIONS.S13_14.DEVICE_SPECIFIC",
+ "CMOS.CITATIONS.S13_14.ONLINE.URL_INDICATOR",
+ "CMOS.CITATIONS.S13_14.SAME_URL.FORMATS"
+ ]
+ },
+ {
+ "section_id": "13.15",
+ "title": "Section 13.15",
+ "pointer": "CMOS18 §13.15 p781 (scan p796)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.NOT_REQUIRED",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.PUBLISHER_POLICY",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.RECORD_ANYWAY",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.UNVERIFIABLE"
+ ]
+ },
+ {
+ "section_id": "13.16",
+ "title": "Section 13.16",
+ "pointer": "CMOS18 §13.16 p782 (scan p796)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.FORMAT",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.PREFERENCE",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.WHEN_ONLY_DATE",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.WIKIS"
+ ]
+ },
+ {
+ "section_id": "13.17",
+ "title": "Section 13.17",
+ "pointer": "CMOS18 §13.17 p782 (scan p796)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_17.ARCHIVE_SERVICES",
+ "CMOS.CITATIONS.S13_17.PRESERVE.CRISIS_SOURCES",
+ "CMOS.CITATIONS.S13_17.PRESERVE.FORMAT_OPTIONS",
+ "CMOS.CITATIONS.S13_17.PRESERVE.NONPUBLISHED"
+ ]
+ },
+ {
+ "section_id": "13.18",
+ "title": "Section 13.18",
+ "pointer": "CMOS18 §13.18 p782 (scan p796)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_18.BIBLIO.INVERT_FIRST_AUTHOR",
+ "CMOS.CITATIONS.S13_18.BIBLIO.SHORTENED_NOTES",
+ "CMOS.CITATIONS.S13_18.NAMES.NORMAL_ORDER",
+ "CMOS.CITATIONS.S13_18.NOTES.SENTENCE_STYLE",
+ "CMOS.CITATIONS.S13_18.NOTES_BIBLIO.OVERVIEW",
+ "CMOS.CITATIONS.S13_18.NO_BIBLIO.FULL_FIRST_NOTE"
+ ]
+ },
+ {
+ "section_id": "13.19",
+ "title": "Section 13.19",
+ "pointer": "CMOS18 §13.19 p783 (scan p796)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.BIBLIO",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.CONSISTENT",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.NOTES",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.NOUN_FORMS"
+ ]
+ },
+ {
+ "section_id": "13.20",
+ "title": "Section 13.20",
+ "pointer": "CMOS18 §13.20 p783 (scan p796)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_20.BIBLIO.BOOKS.NO_PAGES",
+ "CMOS.CITATIONS.S13_20.BIBLIO.PAGE_RANGE",
+ "CMOS.CITATIONS.S13_20.ELECTRONIC.SHORT_DOCS",
+ "CMOS.CITATIONS.S13_20.LOCATORS.ALTERNATIVES",
+ "CMOS.CITATIONS.S13_20.NOTES.PAGE_SPECIFIC",
+ "CMOS.CITATIONS.S13_20.PAGE_RANGE.EN_DASH"
+ ]
+ },
+ {
+ "section_id": "13.21",
+ "title": "Section 13.21",
+ "pointer": "CMOS18 §13.21 p784 (scan p796)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_21.EXAMPLES.BIBLIO_SHORTENED",
+ "CMOS.CITATIONS.S13_21.EXAMPLES.CHAPTER14",
+ "CMOS.CITATIONS.S13_21.EXAMPLES.SHORT_FORMS"
+ ]
+ },
+ {
+ "section_id": "13.22",
+ "title": "Section 13.22",
+ "pointer": "CMOS18 §13.22 p784 (scan p796)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_22.BOOK_EDITOR_ONLY",
+ "CMOS.CITATIONS.S13_22.BOOK_EDITOR_ONLY.SHORTENED_NO_ED",
+ "CMOS.CITATIONS.S13_22.BOOK_PLACE_OMIT",
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.NOTE_BIBLIO",
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.PAGE_IN_NOTES",
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.SHORTENED"
+ ]
+ },
+ {
+ "section_id": "13.23",
+ "title": "Section 13.23",
+ "pointer": "CMOS18 §13.23 p785 (scan p808)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.BIBLIO_MORE_THAN_SIX",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.BIBLIO_UP_TO_SIX",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.NOTES_ET_AL",
+ "CMOS.CITATIONS.S13_23.NO_BIBLIO.NOTES_UP_TO_SIX",
+ "CMOS.CITATIONS.S13_23.TWO_AUTHORS.BIBLIO_INVERT_FIRST",
+ "CMOS.CITATIONS.S13_23.TWO_AUTHORS.NOTES_LIST_BOTH"
+ ]
+ },
+ {
+ "section_id": "13.24",
+ "title": "Section 13.24",
+ "pointer": "CMOS18 §13.24 p786 (scan p808)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_24.AUTHOR_PLUS_EDITOR.BIBLIO_SPELL_OUT",
+ "CMOS.CITATIONS.S13_24.AUTHOR_PLUS_EDITOR.NOTES_ABBREVIATE"
+ ]
+ },
+ {
+ "section_id": "13.25",
+ "title": "Section 13.25",
+ "pointer": "CMOS18 §13.25 p786 (scan p809)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.BIBLIO_NO_PAGE_RANGE",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.INCLUDE_AUTHOR",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.INCLUDE_EDITOR",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.IN_BEFORE_BOOK",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.NOTES_PAGE_LOCATOR",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.QUOTE_TITLE"
+ ]
+ },
+ {
+ "section_id": "13.26",
+ "title": "Section 13.26",
+ "pointer": "CMOS18 §13.26 p786 (scan p809)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_26.JOURNAL.BIBLIO_PAGE_RANGE",
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_ISSUE",
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_VOLUME",
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_YEAR",
+ "CMOS.CITATIONS.S13_26.JOURNAL.NOTES_PAGE_SPECIFIC",
+ "CMOS.CITATIONS.S13_26.JOURNAL.OMIT_MONTH_SEASON",
+ "CMOS.CITATIONS.S13_26.JOURNAL.ONLINE.URL_OR_DOI",
+ "CMOS.CITATIONS.S13_26.JOURNAL.PAGE_COLON",
+ "CMOS.CITATIONS.S13_26.JOURNAL.TITLE_ITALIC",
+ "CMOS.CITATIONS.S13_26.JOURNAL.VOLUME_FORMAT"
+ ]
+ },
+ {
+ "section_id": "13.27",
+ "title": "Section 13.27",
+ "pointer": "CMOS18 §13.27 p787 (scan p809)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.MANUSCRIPT_SUPERSCRIPT_OK",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.NOTES_FULL_SIZE",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.NOTES_PERIOD",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.TEXT_SUPERSCRIPT",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.BASELINE_FALLBACK",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.CONSISTENT_SPACING",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.NOTES_FULL_SIZE",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.NO_PERIOD",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.TEXT_SUPERSCRIPT"
+ ]
+ },
+ {
+ "section_id": "13.28",
+ "title": "Section 13.28",
+ "pointer": "CMOS18 §13.28 p788 (scan p810)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.CONSECUTIVE",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.NO_BOOKWIDE_RUN",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SEPARATE_SYSTEMS",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SYMBOLS_FOR_FEW",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SYMBOL_SEQUENCE_STANDARD",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.TABLE_NOTES_SEPARATE"
+ ]
+ },
+ {
+ "section_id": "13.29",
+ "title": "Section 13.29",
+ "pointer": "CMOS18 §13.29 p788 (scan p810)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AFTER_PUNCTUATION",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AFTER_QUOTE",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AVOID_MIDCLAUSE",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.BEFORE_DASH",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.PLACEMENT_END_SENTENCE"
+ ]
+ },
+ {
+ "section_id": "13.30",
+ "title": "Section 13.30",
+ "pointer": "CMOS18 §13.30 p789 (scan p811)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.NOTE_MARKERS.HEADINGS_END"
+ ]
+ },
+ {
+ "section_id": "13.31",
+ "title": "Section 13.31",
+ "pointer": "CMOS18 §13.31 p789 (scan p811)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.MULTIPLE_CITATIONS.SINGLE_NOTE"
+ ]
+ },
+ {
+ "section_id": "13.32",
+ "title": "Section 13.32",
+ "pointer": "CMOS18 §13.32 p790 (scan p812)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES_BIBLIO.SUBSEQUENT_NOTES.SHORT_FORM"
+ ]
+ },
+ {
+ "section_id": "13.33",
+ "title": "Section 13.33",
+ "pointer": "CMOS18 §13.33 p790 (scan p812)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.SHORT_FORM.BASIC_ELEMENTS"
+ ]
+ },
+ {
+ "section_id": "13.34",
+ "title": "Section 13.34",
+ "pointer": "CMOS18 §13.34 p790 (scan p812)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.SHORT_FORM.CROSS_REFERENCE"
+ ]
+ },
+ {
+ "section_id": "13.35",
+ "title": "Section 13.35",
+ "pointer": "CMOS18 §13.35 p791 (scan p813)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_35.SHORT_FORM.DISTINCT_TITLE"
+ ]
+ },
+ {
+ "section_id": "13.36",
+ "title": "Section 13.36",
+ "pointer": "CMOS18 §13.36 p791 (scan p813)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_36.SHORT_FORM.DISAMBIGUATE_AUTHOR"
+ ]
+ },
+ {
+ "section_id": "13.37",
+ "title": "Section 13.37",
+ "pointer": "CMOS18 §13.37 p791 (scan p813)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.IBID.MINIMIZE_OR_AVOID"
+ ]
+ },
+ {
+ "section_id": "13.38",
+ "title": "Section 13.38",
+ "pointer": "CMOS18 §13.38 p793 (scan p815)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_38.IBID.IMMEDIATE_PRECEDENT"
+ ]
+ },
+ {
+ "section_id": "13.39",
+ "title": "Section 13.39",
+ "pointer": "CMOS18 §13.39 p793 (scan p815)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_39.IBID.LOCATOR_REQUIRED"
+ ]
+ },
+ {
+ "section_id": "13.40",
+ "title": "Section 13.40",
+ "pointer": "CMOS18 §13.40 p793 (scan p815)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_40.SHORT_FORM.AVOID_OP_CIT"
+ ]
+ },
+ {
+ "section_id": "13.41",
+ "title": "Section 13.41",
+ "pointer": "CMOS18 §13.41 p794 (scan p816)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.QUOTE_IN_NOTE.LOCATOR"
+ ]
+ },
+ {
+ "section_id": "13.42",
+ "title": "Section 13.42",
+ "pointer": "CMOS18 §13.42 p794 (scan p816)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.SUBSTANTIVE.SEPARATE_FROM_SOURCE"
+ ]
+ },
+ {
+ "section_id": "13.43",
+ "title": "Section 13.43",
+ "pointer": "CMOS18 §13.43 p794 (scan p816)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.LONG_NOTES.PARAGRAPHING"
+ ]
+ },
+ {
+ "section_id": "13.44",
+ "title": "Section 13.44",
+ "pointer": "CMOS18 §13.44 p794 (scan p816)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.FOOTNOTES.PAGE_BREAKS"
+ ]
+ },
+ {
+ "section_id": "13.45",
+ "title": "Section 13.45",
+ "pointer": "CMOS18 §13.45 p796 (scan p818)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_45.NOTES.CITATION_FIRST"
+ ]
+ },
+ {
+ "section_id": "13.46",
+ "title": "Section 13.46",
+ "pointer": "CMOS18 §13.46 p796 (scan p818)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.FOOTNOTES_VS_ENDNOTES.CHOOSE"
+ ]
+ },
+ {
+ "section_id": "13.47",
+ "title": "Section 13.47",
+ "pointer": "CMOS18 §13.47 p796 (scan p818)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_47.NOTES.SYSTEMS.DONT_MIX"
+ ]
+ },
+ {
+ "section_id": "13.48",
+ "title": "Section 13.48",
+ "pointer": "CMOS18 §13.48 p797 (scan p819)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_48.ENDNOTES.GROUP_BY_CHAPTER"
+ ]
+ },
+ {
+ "section_id": "13.49",
+ "title": "Section 13.49",
+ "pointer": "CMOS18 §13.49 p797 (scan p819)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.ENDNOTES.PLACEMENT"
+ ]
+ },
+ {
+ "section_id": "13.50",
+ "title": "Section 13.50",
+ "pointer": "CMOS18 §13.50 p797 (scan p819)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.ENDNOTES.RUNNING_HEADS"
+ ]
+ },
+ {
+ "section_id": "13.51",
+ "title": "Section 13.51",
+ "pointer": "CMOS18 §13.51 p800 (scan p822)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.ENDNOTES.AVOID_IBID"
+ ]
+ },
+ {
+ "section_id": "13.52",
+ "title": "Section 13.52",
+ "pointer": "CMOS18 §13.52 p800 (scan p822)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_52.ENDNOTES.NAVIGATION_CUES"
+ ]
+ },
+ {
+ "section_id": "13.53",
+ "title": "Section 13.53",
+ "pointer": "CMOS18 §13.53 p801 (scan p823)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.AUTHOR_DATE_PLUS_NOTES"
+ ]
+ },
+ {
+ "section_id": "13.54",
+ "title": "Section 13.54",
+ "pointer": "CMOS18 §13.54 p801 (scan p823)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_54.AUTHOR_DATE.NOTES.COMMENTARY_ONLY"
+ ]
+ },
+ {
+ "section_id": "13.55",
+ "title": "Section 13.55",
+ "pointer": "CMOS18 §13.55 p801 (scan p823)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.UNNUMBERED.NOT_FOR_SOURCES"
+ ]
+ },
+ {
+ "section_id": "13.56",
+ "title": "Section 13.56",
+ "pointer": "CMOS18 §13.56 p803 (scan p825)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_56.NOTES.DUAL_STREAMS.DISTINCT_LABELS"
+ ]
+ },
+ {
+ "section_id": "13.57",
+ "title": "Section 13.57",
+ "pointer": "CMOS18 §13.57 p803 (scan p825)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_57.NOTES.SEPARATE_SOURCE_VS_COMMENTARY"
+ ]
+ },
+ {
+ "section_id": "13.58",
+ "title": "Section 13.58",
+ "pointer": "CMOS18 §13.58 p805 (scan p827)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.SOURCE_NOTES.REPRINTS"
+ ]
+ },
+ {
+ "section_id": "13.59",
+ "title": "Section 13.59",
+ "pointer": "CMOS18 §13.59 p807 (scan p829)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_59.NOTES.MULTI_EDITIONS.CITE_VERSION_USED"
+ ]
+ },
+ {
+ "section_id": "13.60",
+ "title": "Section 13.60",
+ "pointer": "CMOS18 §13.60 p807 (scan p829)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES.AVOID_OVERLONG"
+ ]
+ },
+ {
+ "section_id": "13.61",
+ "title": "Section 13.61",
+ "pointer": "CMOS18 §13.61 p807 (scan p829)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_61.BIBLIOGRAPHY.SCOPE.LABEL_CLEARLY"
+ ]
+ },
+ {
+ "section_id": "13.62",
+ "title": "Section 13.62",
+ "pointer": "CMOS18 §13.62 p808 (scan p830)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_62.BIBLIOGRAPHY.ENTRY_COMPLETENESS.MORE_THAN_SHORT_FORM"
+ ]
+ },
+ {
+ "section_id": "13.63",
+ "title": "Section 13.63",
+ "pointer": "CMOS18 §13.63 p808 (scan p830)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_63.BIBLIOGRAPHY.CONSISTENT_ELEMENT_ORDER"
+ ]
+ },
+ {
+ "section_id": "13.64",
+ "title": "Section 13.64",
+ "pointer": "CMOS18 §13.64 p809 (scan p831)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_64.BIBLIOGRAPHY.SUBSECTIONS.CLEAR_HEADINGS"
+ ]
+ },
+ {
+ "section_id": "13.65",
+ "title": "Section 13.65",
+ "pointer": "CMOS18 §13.65 p809 (scan p831)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES_BIBLIO.BIBLIOGRAPHY.INCLUDE_WHEN_USED"
+ ]
+ },
+ {
+ "section_id": "13.66",
+ "title": "Section 13.66",
+ "pointer": "CMOS18 §13.66 p810 (scan p832)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_66.BIBLIOGRAPHY.INCLUDE_ONLY_PER_SCOPE"
+ ]
+ },
+ {
+ "section_id": "13.67",
+ "title": "Section 13.67",
+ "pointer": "CMOS18 §13.67 p812 (scan p834)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_67.BIBLIOGRAPHY.ANNOTATIONS.CONSISTENT_AND_DISTINCT"
+ ]
+ },
+ {
+ "section_id": "13.68",
+ "title": "Section 13.68",
+ "pointer": "CMOS18 §13.68 p812 (scan p834)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_68.BIBLIOGRAPHY.ENTRY_TYPES.NOT_MIXED"
+ ]
+ },
+ {
+ "section_id": "13.69",
+ "title": "Section 13.69",
+ "pointer": "CMOS18 §13.69 p816 (scan p838)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.NOTES_BIBLIO.BIBLIOGRAPHY.SORT_BY_AUTHOR"
+ ]
+ },
+ {
+ "section_id": "13.70",
+ "title": "Section 13.70",
+ "pointer": "CMOS18 §13.70 p816 (scan p838)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.SAME_AUTHOR.ORDER"
+ ]
+ },
+ {
+ "section_id": "13.71",
+ "title": "Section 13.71",
+ "pointer": "CMOS18 §13.71 p817 (scan p839)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_71.BIBLIOGRAPHY.ALPHABETIZATION.PREFIXES_POLICY"
+ ]
+ },
+ {
+ "section_id": "13.72",
+ "title": "Section 13.72",
+ "pointer": "CMOS18 §13.72 p817 (scan p839)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_72.BIBLIOGRAPHY.SORTING.DIACRITICS_AND_TRANSLITERATION"
+ ]
+ },
+ {
+ "section_id": "13.73",
+ "title": "Section 13.73",
+ "pointer": "CMOS18 §13.73 p818 (scan p840)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.REPEATED_NAMES.THREE_EM_DASH"
+ ]
+ },
+ {
+ "section_id": "13.74",
+ "title": "Section 13.74",
+ "pointer": "CMOS18 §13.74 p819 (scan p841)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.CONSISTENT_FORM"
+ ]
+ },
+ {
+ "section_id": "13.75",
+ "title": "Section 13.75",
+ "pointer": "CMOS18 §13.75 p819 (scan p841)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.PUBLISHED_FORM"
+ ]
+ },
+ {
+ "section_id": "13.76",
+ "title": "Section 13.76",
+ "pointer": "CMOS18 §13.76 p820 (scan p842)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.INITIALS_PREFERRED"
+ ]
+ },
+ {
+ "section_id": "13.77",
+ "title": "Section 13.77",
+ "pointer": "CMOS18 §13.77 p820 (scan p842)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_LIST.LENGTH.POLICY"
+ ]
+ },
+ {
+ "section_id": "13.78",
+ "title": "Section 13.78",
+ "pointer": "CMOS18 §13.78 p821 (scan p843)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.MULTI_AUTHORS.ORDER"
+ ]
+ },
+ {
+ "section_id": "13.79",
+ "title": "Section 13.79",
+ "pointer": "CMOS18 §13.79 p821 (scan p843)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.SAME_SURNAME.DISAMBIGUATE"
+ ]
+ },
+ {
+ "section_id": "13.80",
+ "title": "Section 13.80",
+ "pointer": "CMOS18 §13.80 p822 (scan p844)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.CORPORATE_AUTHORS.USE_AS_AUTHOR"
+ ]
+ },
+ {
+ "section_id": "13.81",
+ "title": "Section 13.81",
+ "pointer": "CMOS18 §13.81 p822 (scan p844)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.NO_AUTHOR.TITLE_LEAD"
+ ]
+ },
+ {
+ "section_id": "13.82",
+ "title": "Section 13.82",
+ "pointer": "CMOS18 §13.82 p823 (scan p845)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.PSEUDONYMS.CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "13.83",
+ "title": "Section 13.83",
+ "pointer": "CMOS18 §13.83 p824 (scan p846)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.NO_AUTHOR.EDITOR_AS_LEAD_WHEN_APPROPRIATE"
+ ]
+ },
+ {
+ "section_id": "13.84",
+ "title": "Section 13.84",
+ "pointer": "CMOS18 §13.84 p824 (scan p846)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.ALT_NAMES.CROSSREF"
+ ]
+ },
+ {
+ "section_id": "13.85",
+ "title": "Section 13.85",
+ "pointer": "CMOS18 §13.85 p825 (scan p847)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.SUFFIXES.INCLUDE"
+ ]
+ },
+ {
+ "section_id": "13.86",
+ "title": "Section 13.86",
+ "pointer": "CMOS18 §13.86 p825 (scan p847)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.PARTICLES.CONSISTENT_FORMAT"
+ ]
+ },
+ {
+ "section_id": "13.87",
+ "title": "Section 13.87",
+ "pointer": "CMOS18 §13.87 p826 (scan p848)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.CONTRIBUTOR_ROLES.LABEL_CLEARLY"
+ ]
+ },
+ {
+ "section_id": "13.88",
+ "title": "Section 13.88",
+ "pointer": "CMOS18 §13.88 p826 (scan p848)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.MULTIPLE_CONTRIBUTORS.POLICY_CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "13.89",
+ "title": "Section 13.89",
+ "pointer": "CMOS18 §13.89 p826 (scan p848)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.GROUP_AUTHORS.SUBUNITS.CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "13.90",
+ "title": "Section 13.90",
+ "pointer": "CMOS18 §13.90 p827 (scan p849)",
+ "status": "partial",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_90.TITLE_PUNCTUATION.CHANGES.POLICY_LIMITED"
+ ]
+ },
+ {
+ "section_id": "13.91",
+ "title": "Section 13.91",
+ "pointer": "CMOS18 §13.91 p827 (scan p849)",
+ "status": "partial",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_91.TITLE_SUBTITLE.SEPARATOR.COLON"
+ ]
+ },
+ {
+ "section_id": "13.92",
+ "title": "Section 13.92",
+ "pointer": "CMOS18 §13.92 p827 (scan p849)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_92.BIBLIOGRAPHY.BOOKS.CORE_ELEMENTS"
+ ]
+ },
+ {
+ "section_id": "13.93",
+ "title": "Section 13.93",
+ "pointer": "CMOS18 §13.93 p828 (scan p850)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_93.BIBLIOGRAPHY.EDITED_VOLUMES.ROLE_MARKING"
+ ]
+ },
+ {
+ "section_id": "13.94",
+ "title": "Section 13.94",
+ "pointer": "CMOS18 §13.94 p828 (scan p850)",
+ "status": "partial",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_94.TITLES.TRAILING_PHRASE.PLACEMENT"
+ ]
+ },
+ {
+ "section_id": "13.95",
+ "title": "Section 13.95",
+ "pointer": "CMOS18 §13.95 p828 (scan p850)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_95.BIBLIOGRAPHY.CHAPTERS.IN_EDITED_COLLECTIONS"
+ ]
+ },
+ {
+ "section_id": "13.96",
+ "title": "Section 13.96",
+ "pointer": "CMOS18 §13.96 p829 (scan p851)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_96.BIBLIOGRAPHY.JOURNAL_ARTICLES.VOLUME_ISSUE_PAGES"
+ ]
+ },
+ {
+ "section_id": "13.97",
+ "title": "Section 13.97",
+ "pointer": "CMOS18 §13.97 p829 (scan p851)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_97.BIBLIOGRAPHY.NEWSPAPER_MAGAZINE.DATES"
+ ]
+ },
+ {
+ "section_id": "13.98",
+ "title": "Section 13.98",
+ "pointer": "CMOS18 §13.98 p830 (scan p852)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_98.BIBLIOGRAPHY.THESES_DISSERTATIONS.INSTITUTION"
+ ]
+ },
+ {
+ "section_id": "13.99",
+ "title": "Section 13.99",
+ "pointer": "CMOS18 §13.99 p831 (scan p853)",
+ "status": "partial",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_99.LONG_TITLES.TRUNCATION.AVOID"
+ ]
+ },
+ {
+ "section_id": "13.100",
+ "title": "Section 13.100",
+ "pointer": "CMOS18 §13.100 p831 (scan p853)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_100.BIBLIOGRAPHY.ONLINE.SOURCE_STABILITY"
+ ]
+ },
+ {
+ "section_id": "13.101",
+ "title": "Section 13.101",
+ "pointer": "CMOS18 §13.101 p832 (scan p854)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_101.BIBLIOGRAPHY.EBOOKS.EDITION_AND_FORMAT"
+ ]
+ },
+ {
+ "section_id": "13.102",
+ "title": "Section 13.102",
+ "pointer": "CMOS18 §13.102 p833 (scan p855)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_102.BIBLIOGRAPHY.AUDIOVISUAL.CREDITS"
+ ]
+ },
+ {
+ "section_id": "13.103",
+ "title": "Section 13.103",
+ "pointer": "CMOS18 §13.103 p835 (scan p857)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_103.BIBLIOGRAPHY.SOCIAL_MEDIA.ARCHIVE"
+ ]
+ },
+ {
+ "section_id": "13.104",
+ "title": "Section 13.104",
+ "pointer": "CMOS18 §13.104 p835 (scan p857)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_104.BIBLIOGRAPHY.PUBLIC_DOCUMENTS.IDENTIFIERS"
+ ]
+ },
+ {
+ "section_id": "13.105",
+ "title": "Section 13.105",
+ "pointer": "CMOS18 §13.105 p835 (scan p857)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_105.BIBLIOGRAPHY.REPORTS.ISSUING_BODY_AND_VERSION"
+ ]
+ },
+ {
+ "section_id": "13.106",
+ "title": "Section 13.106",
+ "pointer": "CMOS18 §13.106 p836 (scan p858)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_106.BIBLIOGRAPHY.DATASETS.VERSION_AND_PROVENANCE"
+ ]
+ },
+ {
+ "section_id": "13.107",
+ "title": "Section 13.107",
+ "pointer": "CMOS18 §13.107 p836 (scan p858)",
+ "status": "partial",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_107.AUTHOR_DATE.REFERENCE_LIST.MULTI_AUTHOR.ORDERING"
+ ]
+ },
+ {
+ "section_id": "13.108",
+ "title": "Section 13.108",
+ "pointer": "CMOS18 §13.108 p836 (scan p858)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_108.BIBLIOGRAPHY.PLATFORMS.PERMALINKS_PREFERRED"
+ ]
+ },
+ {
+ "section_id": "13.109",
+ "title": "Section 13.109",
+ "pointer": "CMOS18 §13.109 p836 (scan p858)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.FIGURES.CAPTION.CREDITS.INLINE_OR_NOTE",
+ "CMOS.FIGURES.PERMISSIONS.DOCUMENTED"
+ ]
+ },
+ {
+ "section_id": "13.110",
+ "title": "Section 13.110",
+ "pointer": "CMOS18 §13.110 p837 (scan p859)",
+ "status": "partial",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_110.AUTHOR_DATE.JOURNAL_ARTICLES.CORE_FIELDS"
+ ]
+ },
+ {
+ "section_id": "13.111",
+ "title": "Section 13.111",
+ "pointer": "CMOS18 §13.111 p837 (scan p859)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.S13_111.AUTHOR_DATE.REFERENCE_LIST.REQUIRED"
+ ]
+ },
+ {
+ "section_id": "13.112",
+ "title": "Section 13.112",
+ "pointer": "CMOS18 §13.112 p838 (scan p860)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ALPHABETICAL"
+ ]
+ },
+ {
+ "section_id": "13.113",
+ "title": "Section 13.113",
+ "pointer": "CMOS18 §13.113 p838 (scan p860)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REPEATED_NAMES"
+ ]
+ },
+ {
+ "section_id": "13.114",
+ "title": "Section 13.114",
+ "pointer": "CMOS18 §13.114 p839 (scan p861)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.SAME_AUTHOR_SAME_YEAR.SUFFIXES"
+ ]
+ },
+ {
+ "section_id": "13.115",
+ "title": "Section 13.115",
+ "pointer": "CMOS18 §13.115 p839 (scan p861)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.NO_AUTHOR.TITLE_KEY"
+ ]
+ },
+ {
+ "section_id": "13.116",
+ "title": "Section 13.116",
+ "pointer": "CMOS18 §13.116 p840 (scan p862)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.NO_DATE.POLICY"
+ ]
+ },
+ {
+ "section_id": "13.117",
+ "title": "Section 13.117",
+ "pointer": "CMOS18 §13.117 p840 (scan p862)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.LOCATORS"
+ ]
+ },
+ {
+ "section_id": "13.118",
+ "title": "Section 13.118",
+ "pointer": "CMOS18 §13.118 p841 (scan p863)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.EXTRA_INFO"
+ ]
+ },
+ {
+ "section_id": "13.119",
+ "title": "Section 13.119",
+ "pointer": "CMOS18 §13.119 p841 (scan p863)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.PLACEMENT"
+ ]
+ },
+ {
+ "section_id": "13.120",
+ "title": "Section 13.120",
+ "pointer": "CMOS18 §13.120 p842 (scan p864)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.DIRECT_QUOTES"
+ ]
+ },
+ {
+ "section_id": "13.121",
+ "title": "Section 13.121",
+ "pointer": "CMOS18 §13.121 p843 (scan p865)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_AUTHORS.POLICY"
+ ]
+ },
+ {
+ "section_id": "13.122",
+ "title": "Section 13.122",
+ "pointer": "CMOS18 §13.122 p843 (scan p865)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.CORPORATE_AUTHORS.SHORT_FORM"
+ ]
+ },
+ {
+ "section_id": "13.123",
+ "title": "Section 13.123",
+ "pointer": "CMOS18 §13.123 p843 (scan p865)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ENTRY_TEMPLATES.CONSISTENT"
+ ]
+ },
+ {
+ "section_id": "13.124",
+ "title": "Section 13.124",
+ "pointer": "CMOS18 §13.124 p844 (scan p866)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_SOURCES"
+ ]
+ },
+ {
+ "section_id": "13.125",
+ "title": "Section 13.125",
+ "pointer": "CMOS18 §13.125 p845 (scan p867)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_CITATIONS.ORDER_POLICY"
+ ]
+ },
+ {
+ "section_id": "13.126",
+ "title": "Section 13.126",
+ "pointer": "CMOS18 §13.126 p845 (scan p867)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SORTING_STABLE"
+ ]
+ },
+ {
+ "section_id": "13.127",
+ "title": "Section 13.127",
+ "pointer": "CMOS18 §13.127 p845 (scan p867)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SAME_AUTHOR.ORDER_POLICY"
+ ]
+ },
+ {
+ "section_id": "13.128",
+ "title": "Section 13.128",
+ "pointer": "CMOS18 §13.128 p845 (scan p867)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REPEATED_NAMES.POLICY"
+ ]
+ },
+ {
+ "section_id": "15.12",
+ "title": "Section 15.12",
+ "pointer": "CMOS18 §15.12 p29 (scan p1123)",
+ "status": "covered",
+ "rule_ids": [
+ "CMOS.FIGURES.SOURCE.DATA.CITED"
+ ]
+ }
+ ]
+}
diff --git a/spec/house/HOUSE_CITATIONS_POINTERS.md b/spec/house/HOUSE_CITATIONS_POINTERS.md
new file mode 100644
index 0000000..b627a00
--- /dev/null
+++ b/spec/house/HOUSE_CITATIONS_POINTERS.md
@@ -0,0 +1,11 @@
+# HOUSE citations pointers
+
+House-level pointers for citations lint rules.
+
+- HOUSE §CIT.AUTHOR_DATE.PAREN_YEAR_ONLY p1
+- HOUSE §CIT.AUTHOR_DATE.REFLIST.YEAR_REQUIRED p1
+- HOUSE §CIT.AUTHOR_DATE.REFLIST.REQUIRED p1
+- HOUSE §CIT.NOTES.DEFINITIONS.REQUIRED p1
+- HOUSE §CIT.NOTES.MARKERS.BRACKETED_NUMBERS.AVOID p1
+- HOUSE §CIT.NOTES.BIBLIOGRAPHY.REQUIRED p1
+- HOUSE §CIT.NOTES.IBID.AVOID p1
diff --git a/spec/house/HOUSE_CODE_POINTERS.md b/spec/house/HOUSE_CODE_POINTERS.md
new file mode 100644
index 0000000..036b4dc
--- /dev/null
+++ b/spec/house/HOUSE_CODE_POINTERS.md
@@ -0,0 +1,31 @@
+# HOUSE code pointers
+
+This document defines pointer anchors for the `code` rule category.
+
+It contains no third-party text. Pointers refer to house-maintained guidance used by iftypeset.
+
+Pointer format: `HOUSE §CODE. pN`.
+
+## §CODE.BLOCKS (p1)
+
+General rules for code blocks: structure, elision, determinism, and required context.
+
+## §CODE.EXAMPLES (p1)
+
+Expectations for example quality and reproducibility (tested vs pseudo-code, valid configs).
+
+## §CODE.TYPOGRAPHY (p2)
+
+Typography and formatting for code (monospace, whitespace, smart quotes, line numbers).
+
+## §CODE.SHELL (p2)
+
+Shell-specific conventions (prompts, platform notes, destructive command warnings).
+
+## §CODE.SECURITY (p2)
+
+Redaction, placeholders, and handling of sensitive values in examples.
+
+## §CODE.DIFFS (p2)
+
+Diff formatting expectations (unified format, file headers, context lines).
diff --git a/spec/house/HOUSE_COLOR_POINTERS.md b/spec/house/HOUSE_COLOR_POINTERS.md
new file mode 100644
index 0000000..46c0d4f
--- /dev/null
+++ b/spec/house/HOUSE_COLOR_POINTERS.md
@@ -0,0 +1,25 @@
+# HOUSE color pointers
+
+House-level pointers for color usage in documents and tables.
+
+Pointer format: `HOUSE §COLOR. pN`.
+
+## §COLOR.HIERARCHY (p1)
+
+Use a restrained accent color to aid navigation (headings, section markers) without reducing readability.
+
+## §COLOR.RESTRAINT (p1)
+
+Keep color use limited to navigation, links, and small highlights; body text stays neutral for legibility.
+
+## §COLOR.LINKS (p1)
+
+Link color must remain readable and should not be the only indicator (retain underlines).
+
+## §COLOR.CITATIONS (p1)
+
+Inline citation tokens may be styled subtly to separate evidence markers from narrative text.
+
+## §COLOR.TABLES (p1)
+
+Table accents (rules/stripes) should be subtle, low-contrast, and supportive of scanning.
diff --git a/spec/house/HOUSE_EDITORIAL_POINTERS.md b/spec/house/HOUSE_EDITORIAL_POINTERS.md
new file mode 100644
index 0000000..6c97ca6
--- /dev/null
+++ b/spec/house/HOUSE_EDITORIAL_POINTERS.md
@@ -0,0 +1,63 @@
+# HOUSE editorial pointers
+
+This document defines what `HOUSE §... pN` pointers mean for the `editorial` rule category.
+
+These are **house** rules: they do not reproduce Chicago/Bringhurst text and do not require access to those books.
+
+## Pointer format
+
+Editorial rules cite pointers like:
+
+- `HOUSE §EDITORIAL.PLACEHOLDERS p1`
+- `HOUSE §EDITORIAL.STRUCTURE p1`
+
+Interpretation:
+
+- `HOUSE` means the pointer refers to a house-maintained document in `spec/house/`.
+- `§EDITORIAL.` names the section inside this file.
+- `pN` is a **stable logical page identifier for this pointer doc**, used for schema compatibility and future PDF exports.
+
+For `HOUSE_EDITORIAL_POINTERS.md` v1, all pointers use `p1` because the document is short; use the `§...` section id for the exact location.
+
+## Sections (v1)
+
+### §EDITORIAL.PLACEHOLDERS (p1)
+
+Draft markers and placeholder content that must be removed or resolved before publishing.
+
+### §EDITORIAL.STRUCTURE (p1)
+
+Document structure expectations (title, summary, scope, audience, decisions, action items).
+
+### §EDITORIAL.HEADINGS (p1)
+
+Editorial expectations for headings as text (not typographic styling).
+
+### §EDITORIAL.LISTS (p1)
+
+Editorial expectations for list usage and list content.
+
+### §EDITORIAL.CLARITY (p1)
+
+Clarity guidelines (ambiguity, definitions, brevity, self-contained writing).
+
+### §EDITORIAL.TONE (p1)
+
+Tone and audience fit, including inclusive language guidance.
+
+### §EDITORIAL.CLAIMS (p1)
+
+How to treat claims (evidence, framing, quantification, comparisons).
+
+### §EDITORIAL.CONSISTENCY (p1)
+
+Consistency guidelines (terminology, capitalization, spelling variants, naming, time zones).
+
+### §EDITORIAL.REVIEW (p1)
+
+Review checklist items (spellcheck, fact-check, link verification).
+
+### §EDITORIAL.OPSEC (p1)
+
+Safety checks to avoid publishing secrets or sensitive data.
+
diff --git a/spec/house/HOUSE_FIGURES_TABLES_POINTERS.md b/spec/house/HOUSE_FIGURES_TABLES_POINTERS.md
new file mode 100644
index 0000000..34e5fef
--- /dev/null
+++ b/spec/house/HOUSE_FIGURES_TABLES_POINTERS.md
@@ -0,0 +1,45 @@
+# HOUSE figures/tables pointers
+
+House-level pointers for figures and tables rules.
+
+Pointer format: `HOUSE §FIGURES. pN` or `HOUSE §TABLES. pN`.
+
+## §FIGURES.FORMAT (p1)
+
+Figure file format, vector/raster usage, and resolution expectations.
+
+## §FIGURES.COLOR (p1)
+
+Color and contrast guidance for charts and diagrams.
+
+## §FIGURES.AXES (p1)
+
+Axis labeling and unit disclosure for quantitative figures.
+
+## §FIGURES.CAPTIONS (p1)
+
+Caption content expectations for figures.
+
+## §FIGURES.TEXT (p1)
+
+Figure text legibility and avoidable rasterized text guidance.
+
+## §TABLES.UNITS (p1)
+
+Unit labeling and numeric context in tables.
+
+## §TABLES.ALIGNMENT (p1)
+
+Numeric alignment and precision consistency.
+
+## §TABLES.COLOR (p1)
+
+Subtle shading or striping to improve scanability without heavy gridlines.
+
+## §TABLES.SOURCES (p1)
+
+Data source and notes placement for tables.
+
+## §TABLES.MISSING_DATA (p1)
+
+Missing-data notation and explanatory notes.
diff --git a/spec/house/HOUSE_FRONT_BACK_POINTERS.md b/spec/house/HOUSE_FRONT_BACK_POINTERS.md
new file mode 100644
index 0000000..a401d28
--- /dev/null
+++ b/spec/house/HOUSE_FRONT_BACK_POINTERS.md
@@ -0,0 +1,41 @@
+# HOUSE front/back matter pointers
+
+House-level pointers for frontmatter and backmatter rules.
+
+Pointer format: `HOUSE §FRONTMATTER. pN` or `HOUSE §BACKMATTER. pN`.
+
+## §FRONTMATTER.METADATA (p1)
+
+Document metadata conventions (status, version, owner, dates, distribution labels).
+
+## §FRONTMATTER.TOC (p1)
+
+Table-of-contents generation and consistency expectations.
+
+## §FRONTMATTER.ABSTRACT (p1)
+
+Abstract/summary expectations for long or technical documents.
+
+## §FRONTMATTER.DISTRIBUTION (p1)
+
+Distribution, confidentiality, and contact cues for external sharing.
+
+## §BACKMATTER.REFERENCES (p1)
+
+Reference list ordering, completeness, and deduplication rules.
+
+## §BACKMATTER.GLOSSARY (p1)
+
+Glossary ordering and cross-reference expectations.
+
+## §BACKMATTER.APPENDICES (p1)
+
+Appendix labeling and cross-reference consistency.
+
+## §BACKMATTER.NOTES (p1)
+
+Notes and footnote conventions that affect backmatter layout.
+
+## §BACKMATTER.INDEX (p1)
+
+Index ordering and cross-reference conventions.
diff --git a/spec/house/HOUSE_I18N_POINTERS.md b/spec/house/HOUSE_I18N_POINTERS.md
new file mode 100644
index 0000000..fc39b07
--- /dev/null
+++ b/spec/house/HOUSE_I18N_POINTERS.md
@@ -0,0 +1,37 @@
+# HOUSE i18n pointers
+
+House-level pointers for i18n rules.
+
+Pointer format: `HOUSE §I18N. pN`.
+
+## §I18N.NUMBERS.MIXED_DECIMAL_SEPARATORS (p1)
+
+Avoid mixing decimal separators across the document.
+
+## §I18N.QUOTES.MIXED_STYLES (p1)
+
+Avoid mixing quotation mark styles without a declared language boundary.
+
+## §I18N.NUMBERS.GROUPING (p1)
+
+Use one thousands-grouping style per document based on locale.
+
+## §I18N.NUMBERS.DIGIT_SYSTEM (p1)
+
+Keep digit systems consistent within numeric contexts.
+
+## §I18N.LANGUAGE.SWITCHES (p1)
+
+Mark language switches for non-primary language passages.
+
+## §I18N.CURRENCY.DISAMBIGUATE (p1)
+
+Disambiguate currency symbols in international contexts.
+
+## §I18N.TRANSLATION.LABELS (p1)
+
+Label translated passages and their sources when relevant.
+
+## §I18N.UNITS.SPACING (p1)
+
+Apply locale-appropriate spacing between numbers and units.
diff --git a/spec/house/HOUSE_LAYOUT_TYPO_POINTERS.md b/spec/house/HOUSE_LAYOUT_TYPO_POINTERS.md
new file mode 100644
index 0000000..2d739e4
--- /dev/null
+++ b/spec/house/HOUSE_LAYOUT_TYPO_POINTERS.md
@@ -0,0 +1,45 @@
+# HOUSE layout + typography pointers
+
+House-level pointers for layout and typography rules that are not tied to third-party sources.
+
+Pointer format: `HOUSE §LAYOUT. pN` or `HOUSE §TYPOGRAPHY. pN`.
+
+## §LAYOUT.HTML.MEASURE (p1)
+
+HTML measure and max-width constraints for readable line length.
+
+## §LAYOUT.HTML.GUTTERS (p1)
+
+Minimum side padding and spacing for narrow screens.
+
+## §LAYOUT.HTML.SECTION_SPACING (p1)
+
+Consistent vertical spacing between major sections in HTML output.
+
+## §LAYOUT.MD.BLANK_LINES.SPARING (p1)
+
+Markdown spacing guidance: avoid excessive blank lines unless marking a section break.
+
+## §LAYOUT.MD.HEADINGS.NON_EMPTY_SECTIONS (p1)
+
+Headings should introduce content; avoid empty sections in Markdown sources.
+
+## §LAYOUT.PAGINATION.RUNT_FINAL_PAGE (p1)
+
+Avoid final pages that carry only a few lines; ensure the last page looks intentional.
+
+## §TYPOGRAPHY.HTML.LINE_HEIGHT (p1)
+
+Minimum line-height and readable spacing for body text in HTML output.
+
+## §TYPOGRAPHY.HTML.JUSTIFICATION (p1)
+
+Justification policy for web outputs (avoid full justification unless carefully controlled).
+
+## §TYPOGRAPHY.HTML.LINK_DECORATION (p1)
+
+Link decoration expectations for readable, distinguishable text links.
+
+## §TYPOGRAPHY.MD.EMPHASIS.BALANCE (p1)
+
+Heuristic guidance for emphasis spans in Markdown (avoid long bold/italic runs).
diff --git a/spec/house/HOUSE_RULES.md b/spec/house/HOUSE_RULES.md
index 077e5f5..7737665 100644
--- a/spec/house/HOUSE_RULES.md
+++ b/spec/house/HOUSE_RULES.md
@@ -57,3 +57,53 @@ House baseline accessibility rules for exported HTML/PDF:
- images must have alt text (or an explicit empty alt when decorative),
- link text must be descriptive (avoid “click here”),
- document language must be declared where supported.
+
+## §A11Y.LINKS (p3)
+
+House accessibility guidance for links and navigation:
+
+- link targets should be clear and operable without relying on color alone,
+- icon-only links require accessible text,
+- table of contents entries should be navigable links where supported.
+
+## §A11Y.IMAGES (p3)
+
+House accessibility guidance for images:
+
+- linked images need alt text that describes the destination or purpose,
+- complex figures should include nearby text or captions that explain meaning.
+
+## §A11Y.TABLES (p3)
+
+House accessibility guidance for tables:
+
+- table headers should be identifiable in HTML outputs,
+- avoid layouts that hide structure or merge cells without clear labeling.
+
+## §A11Y.NAVIGATION (p3)
+
+House accessibility guidance for navigation aids:
+
+- provide footnote backlinks when notes are used,
+- generate PDF bookmarks from headings when the engine supports it.
+
+## §QA.CAPTIONS (p2)
+
+House guidance for caption proximity:
+
+- keep figure/table captions with their associated content,
+- flag captions that appear isolated at page edges.
+
+## §QA.LISTS (p2)
+
+House guidance for list pagination:
+
+- keep list introductions with the first list item,
+- avoid lone list items at the top or bottom of a page.
+
+## §QA.HEADINGS (p2)
+
+House guidance for heading proximity:
+
+- avoid back-to-back headings without body text in between,
+- ensure headings are followed by sufficient content on the same page when possible.
diff --git a/spec/indexes/category.json b/spec/indexes/category.json
index a3a2da0..e8617e4 100644
--- a/spec/indexes/category.json
+++ b/spec/indexes/category.json
@@ -1,26 +1,185 @@
{
+ "abbreviations": [
+ "CMOS.ABBREVIATIONS.ACADEMIC.DEGREES.STYLE",
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_IN_HEADINGS",
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_SENTENCE_START",
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_STACKING",
+ "CMOS.ABBREVIATIONS.ACRONYMS.DEFINE_FIRST_USE",
+ "CMOS.ABBREVIATIONS.ACRONYMS.REINTRODUCE_AFTER_GAP",
+ "CMOS.ABBREVIATIONS.AVOID_ONE_OFFS",
+ "CMOS.ABBREVIATIONS.BIBLIOGRAPHY.STANDARDS.FOLLOW",
+ "CMOS.ABBREVIATIONS.CAPS.AVOID_ALL_CAPS_WORDS",
+ "CMOS.ABBREVIATIONS.CAPTIONS.DEFINE_ON_FIRST_USE",
+ "CMOS.ABBREVIATIONS.COMPANIES.INC_LTD.CONSISTENT",
+ "CMOS.ABBREVIATIONS.COUNTRIES.ABBREV_IN_TABLES_ONLY",
+ "CMOS.ABBREVIATIONS.DAYS.ABBREV_IN_TABLES",
+ "CMOS.ABBREVIATIONS.DAYS.SPELL_OUT_IN_TEXT",
+ "CMOS.ABBREVIATIONS.FOOTNOTES.ABBREV_ON_FIRST_USE",
+ "CMOS.ABBREVIATIONS.GENERAL.AVOID_OVERUSE",
+ "CMOS.ABBREVIATIONS.GENERAL.CONSISTENCY",
+ "CMOS.ABBREVIATIONS.GENERAL.GLOSSARY.WHEN_NEEDED",
+ "CMOS.ABBREVIATIONS.GEOGRAPHY.STATE_ABBREVS.CONSISTENT",
+ "CMOS.ABBREVIATIONS.INITIALISMS.NO_PERIODS.DEFAULT",
+ "CMOS.ABBREVIATIONS.LATIN.EG_IE.PUNCTUATION",
+ "CMOS.ABBREVIATIONS.LATIN.ET_AL.USE",
+ "CMOS.ABBREVIATIONS.LATIN.VERSUS_ENGLISH",
+ "CMOS.ABBREVIATIONS.MEASURES.SI.SPACE",
+ "CMOS.ABBREVIATIONS.MONTHS.ABBREV_IN_TABLES",
+ "CMOS.ABBREVIATIONS.MONTHS.SPELL_OUT_IN_TEXT",
+ "CMOS.ABBREVIATIONS.NAMES.INITIALS.SPACING",
+ "CMOS.ABBREVIATIONS.ORGANIZATIONS.SPELL_OUT_FIRST",
+ "CMOS.ABBREVIATIONS.PARENTHETICALS.AVOID_STACKING",
+ "CMOS.ABBREVIATIONS.PLURALS.NO_APOSTROPHE",
+ "CMOS.ABBREVIATIONS.POSSESSIVE.FORM",
+ "CMOS.ABBREVIATIONS.PUNCTUATION.ABBREV_WITH_PERIODS.AVOID_DOUBLE",
+ "CMOS.ABBREVIATIONS.READER_FAMILIARITY",
+ "CMOS.ABBREVIATIONS.STATES.POSTAL_ONLY",
+ "CMOS.ABBREVIATIONS.STATES.SPELL_OUT_IN_TEXT",
+ "CMOS.ABBREVIATIONS.TABLES.ABBREV_KEY",
+ "CMOS.ABBREVIATIONS.TABLES.KEYS.WHEN_DENSE",
+ "CMOS.ABBREVIATIONS.TECH.TERMS.CASE_SENSITIVE",
+ "CMOS.ABBREVIATIONS.TIME.AM_PM.FORM",
+ "CMOS.ABBREVIATIONS.TITLES.COURTESY_PERIODS",
+ "CMOS.ABBREVIATIONS.TITLES.HONORIFICS.CONSISTENT",
+ "CMOS.ABBREVIATIONS.TITLES.JR_SR.CONSISTENT",
+ "CMOS.ABBREVIATIONS.UNITS.ABBREV_WITH_NUMERALS_ONLY",
+ "CMOS.ABBREVIATIONS.UNITS.NO_PERIODS",
+ "CMOS.ABBREVIATIONS.UNITS.NO_PLURAL_SYMBOLS",
+ "CMOS.ABBREVIATIONS.UNITS.SPELL_OUT_WITHOUT_NUMERALS",
+ "CMOS.ABBREVIATIONS.US_USA.CONSISTENT"
+ ],
"accessibility": [
"HOUSE.A11Y.DOCUMENT_LANGUAGE.DECLARE",
"HOUSE.A11Y.HEADINGS.NO_SKIPS",
"HOUSE.A11Y.IMAGES.ALT_REQUIRED",
- "HOUSE.A11Y.LINK_TEXT.DESCRIPTIVE"
+ "HOUSE.A11Y.LINK_TEXT.DESCRIPTIVE",
+ "HOUSE.ACCESSIBILITY.CODE.FENCES.LANGUAGE",
+ "HOUSE.ACCESSIBILITY.COLOR.NOT_SOLE_CONVEYOR",
+ "HOUSE.ACCESSIBILITY.CONTRAST.NON_TEXT",
+ "HOUSE.ACCESSIBILITY.CONTRAST.TEXT_READABLE",
+ "HOUSE.ACCESSIBILITY.EMPHASIS.USE_SPARELY",
+ "HOUSE.ACCESSIBILITY.FIGURES.REFERENCED_IN_TEXT",
+ "HOUSE.ACCESSIBILITY.HEADINGS.HIERARCHY.NO_SKIPS",
+ "HOUSE.ACCESSIBILITY.HEADINGS.NO_DECORATIVE",
+ "HOUSE.ACCESSIBILITY.HEADINGS.NO_EMPTY",
+ "HOUSE.ACCESSIBILITY.HEADINGS.SINGLE_H1",
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_AVOID_DUPLICATE_CAPTION",
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_SUMMARY_FOR_CHARTS",
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_TEXT.QUALITY.NO_FILENAME",
+ "HOUSE.ACCESSIBILITY.IMAGES.CAPTION_FOR_COMPLEX",
+ "HOUSE.ACCESSIBILITY.IMAGES.DECORATIVE.EMPTY_ALT",
+ "HOUSE.ACCESSIBILITY.IMAGES.LINKED.ALT_TARGET",
+ "HOUSE.ACCESSIBILITY.IMAGES.TEXT_IN_IMAGES.AVOID",
+ "HOUSE.ACCESSIBILITY.LANGUAGE.METADATA",
+ "HOUSE.ACCESSIBILITY.LINKS.AVOID_SHORTENERS",
+ "HOUSE.ACCESSIBILITY.LINKS.FOCUS_ORDER",
+ "HOUSE.ACCESSIBILITY.LINKS.FOCUS_VISIBLE",
+ "HOUSE.ACCESSIBILITY.LINKS.ICON_ONLY.TEXT",
+ "HOUSE.ACCESSIBILITY.LINKS.SKIP_TO_CONTENT",
+ "HOUSE.ACCESSIBILITY.LINKS.TARGETS.PUBLIC",
+ "HOUSE.ACCESSIBILITY.LINKS.VISUALLY_DISTINCT",
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.NO_BARE_URLS",
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.SYMBOL_ONLY.AVOID",
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.UNIQUE_TARGETS",
+ "HOUSE.ACCESSIBILITY.LISTS.MARKER_CONSISTENT",
+ "HOUSE.ACCESSIBILITY.LISTS.NO_EMPTY_ITEMS",
+ "HOUSE.ACCESSIBILITY.LISTS.USE_LIST_MARKUP",
+ "HOUSE.ACCESSIBILITY.MEDIA.TRANSCRIPTS",
+ "HOUSE.ACCESSIBILITY.NAVIGATION.FOOTNOTE_BACKLINKS",
+ "HOUSE.ACCESSIBILITY.NAVIGATION.PDF_BOOKMARKS",
+ "HOUSE.ACCESSIBILITY.PDF.TAGS.WHEN_AVAILABLE",
+ "HOUSE.ACCESSIBILITY.TABLES.AVOID_SCREENSHOT",
+ "HOUSE.ACCESSIBILITY.TABLES.CAPTION_SUMMARY",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADERS.SCOPE",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADER_ROW.REQUIRED",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADER_SCOPE",
+ "HOUSE.ACCESSIBILITY.TABLES.NO_LAYOUT",
+ "HOUSE.ACCESSIBILITY.TABLES.ROW_HEADERS_FOR_STUB",
+ "HOUSE.ACCESSIBILITY.TABLES.SIMPLE_STRUCTURE",
+ "HOUSE.ACCESSIBILITY.TOC.LINKED_ENTRIES"
+ ],
+ "backmatter": [
+ "CMOS.BACKMATTER.ABBREVIATIONS.LIST.WHEN_NEEDED",
+ "CMOS.BACKMATTER.ACKNOWLEDGMENTS.PLACEMENT",
+ "CMOS.BACKMATTER.APPENDICES.CROSS_REFERENCES",
+ "CMOS.BACKMATTER.APPENDICES.FORMAT_MATCH",
+ "CMOS.BACKMATTER.APPENDICES.LABELED",
+ "CMOS.BACKMATTER.APPENDICES.SOURCES",
+ "CMOS.BACKMATTER.APPENDIX.NUMBERING.SEQUENTIAL",
+ "CMOS.BACKMATTER.APPENDIX.START_ON_NEW_PAGE",
+ "CMOS.BACKMATTER.APPENDIX.TOC.ENTRIES",
+ "CMOS.BACKMATTER.BIBLIOGRAPHY.CONSISTENT_STYLE",
+ "CMOS.BACKMATTER.BIBLIOGRAPHY.SORTING",
+ "CMOS.BACKMATTER.CONTACT.SUPPORT",
+ "CMOS.BACKMATTER.DATA.AVAILABILITY",
+ "CMOS.BACKMATTER.ENDNOTES.VERSUS_FOOTNOTES.CONSISTENT",
+ "CMOS.BACKMATTER.ERRATA.WHEN_NEEDED",
+ "CMOS.BACKMATTER.GLOSSARY.DEFINITIONS.CONCISE",
+ "CMOS.BACKMATTER.GLOSSARY.SORTING",
+ "CMOS.BACKMATTER.GLOSSARY.TERMS.CONSISTENT_STYLE",
+ "CMOS.BACKMATTER.GLOSSARY.WHEN_TERMS",
+ "CMOS.BACKMATTER.INDEX.ABBREVIATIONS.CONSISTENT",
+ "CMOS.BACKMATTER.INDEX.CROSS_REFERENCES.CONSISTENT",
+ "CMOS.BACKMATTER.INDEX.ENTRIES.CONSISTENT_CASE",
+ "CMOS.BACKMATTER.INDEX.LOCATORS.ACCURATE",
+ "CMOS.BACKMATTER.INDEX.NAMES.SORTING",
+ "CMOS.BACKMATTER.INDEX.PAGE_RANGES.STANDARD",
+ "CMOS.BACKMATTER.INDEX.SEE_ALSO.USE_WHEN_NEEDED",
+ "CMOS.BACKMATTER.INDEX.SUBENTRIES.NESTED",
+ "CMOS.BACKMATTER.INDEX.SUBENTRY.ORDER.LOGICAL",
+ "CMOS.BACKMATTER.INDEX.WHEN_REQUIRED",
+ "CMOS.BACKMATTER.LICENSES.THIRD_PARTY",
+ "CMOS.BACKMATTER.NOTES.BLOCKS.CONSISTENT",
+ "CMOS.BACKMATTER.NOTES.CITATIONS.COMPLETE",
+ "CMOS.BACKMATTER.NOTES.NUMBERING.SEQUENTIAL",
+ "CMOS.BACKMATTER.NOTES.ORDER.FOLLOW_TEXT",
+ "CMOS.BACKMATTER.NOTES.REFERENCE.MATCH",
+ "CMOS.BACKMATTER.REFERENCES.ACCESS_DATES.WHEN_NEEDED",
+ "CMOS.BACKMATTER.REFERENCES.AUTHOR_NAMES.CONSISTENT",
+ "CMOS.BACKMATTER.REFERENCES.DOI.OR_URL",
+ "CMOS.BACKMATTER.REFERENCES.SECTION_PRESENT",
+ "CMOS.BACKMATTER.REFERENCES.URLS.STABLE",
+ "HOUSE.BACKMATTER.APPENDICES.LABELS.MATCH",
+ "HOUSE.BACKMATTER.GLOSSARY.ALPHABETICAL",
+ "HOUSE.BACKMATTER.GLOSSARY.CROSS_REFERENCES",
+ "HOUSE.BACKMATTER.INDEX.CROSS_REFERENCES.CONSISTENT",
+ "HOUSE.BACKMATTER.REFERENCES.DEDUPLICATE",
+ "HOUSE.BACKMATTER.REFERENCES.SORTING.CONSISTENT"
],
"citations": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.CORPORATE_AUTHORS.SHORT_FORM",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.DIRECT_QUOTES",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.EXTRA_INFO",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.LOCATORS",
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_AUTHORS.POLICY",
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_CITATIONS.ORDER_POLICY",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_SOURCES",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.PARENTHETICAL",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.PLACEMENT",
+ "CMOS.CITATIONS.AUTHOR_DATE.NO_AUTHOR.TITLE_KEY",
+ "CMOS.CITATIONS.AUTHOR_DATE.NO_DATE.POLICY",
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ALPHABETICAL",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ENTRY_TEMPLATES.CONSISTENT",
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ORDER_AND_YEAR",
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REPEATED_NAMES",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REPEATED_NAMES.POLICY",
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REQUIRED",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SAME_AUTHOR.ORDER_POLICY",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SORTING_STABLE",
+ "CMOS.CITATIONS.AUTHOR_DATE.SAME_AUTHOR_SAME_YEAR.SUFFIXES",
"CMOS.CITATIONS.BIBLIOGRAPHY.ALT_NAMES.CROSSREF",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_LIST.LENGTH.POLICY",
"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.CONSISTENT_FORM",
"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.INITIALS_PREFERRED",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.PARTICLES.CONSISTENT_FORMAT",
"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.PUBLISHED_FORM",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.SUFFIXES.INCLUDE",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.CONTRIBUTOR_ROLES.LABEL_CLEARLY",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.CORPORATE_AUTHORS.USE_AS_AUTHOR",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.GROUP_AUTHORS.SUBUNITS.CONSISTENT",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.MULTIPLE_CONTRIBUTORS.POLICY_CONSISTENT",
"CMOS.CITATIONS.BIBLIOGRAPHY.MULTI_AUTHORS.ORDER",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.NO_AUTHOR.EDITOR_AS_LEAD_WHEN_APPROPRIATE",
"CMOS.CITATIONS.BIBLIOGRAPHY.NO_AUTHOR.TITLE_LEAD",
"CMOS.CITATIONS.BIBLIOGRAPHY.PSEUDONYMS.CONSISTENT",
"CMOS.CITATIONS.BIBLIOGRAPHY.REPEATED_NAMES.THREE_EM_DASH",
@@ -65,26 +224,475 @@
"CMOS.CITATIONS.ONLINE.VERSION.CITE_RIGHT_VERSION",
"CMOS.CITATIONS.QUOTATIONS.LOCATORS.PAGE_REQUIRED",
"CMOS.CITATIONS.RESEARCH.METADATA.CAPTURE_EARLY",
+ "CMOS.CITATIONS.S13_1.ALL_SOURCE_TYPES",
+ "CMOS.CITATIONS.S13_1.DISCIPLINE_POLICY",
+ "CMOS.CITATIONS.S13_1.PURPOSE.COPYRIGHT",
+ "CMOS.CITATIONS.S13_1.PURPOSE.COURTESY",
+ "CMOS.CITATIONS.S13_1.PURPOSE.ETHICS",
+ "CMOS.CITATIONS.S13_1.SUFFICIENT_INFO",
+ "CMOS.CITATIONS.S13_10.DATABASES.NAME_INSTEAD",
+ "CMOS.CITATIONS.S13_10.DATABASE_IN_CITATION",
+ "CMOS.CITATIONS.S13_10.DOI_PRECEDENCE",
+ "CMOS.CITATIONS.S13_10.TEST_LOGGED_OUT",
+ "CMOS.CITATIONS.S13_100.BIBLIOGRAPHY.ONLINE.SOURCE_STABILITY",
+ "CMOS.CITATIONS.S13_101.BIBLIOGRAPHY.EBOOKS.EDITION_AND_FORMAT",
+ "CMOS.CITATIONS.S13_102.BIBLIOGRAPHY.AUDIOVISUAL.CREDITS",
+ "CMOS.CITATIONS.S13_103.BIBLIOGRAPHY.SOCIAL_MEDIA.ARCHIVE",
+ "CMOS.CITATIONS.S13_104.BIBLIOGRAPHY.PUBLIC_DOCUMENTS.IDENTIFIERS",
+ "CMOS.CITATIONS.S13_105.BIBLIOGRAPHY.REPORTS.ISSUING_BODY_AND_VERSION",
+ "CMOS.CITATIONS.S13_106.BIBLIOGRAPHY.DATASETS.VERSION_AND_PROVENANCE",
+ "CMOS.CITATIONS.S13_107.AUTHOR_DATE.REFERENCE_LIST.MULTI_AUTHOR.ORDERING",
+ "CMOS.CITATIONS.S13_108.BIBLIOGRAPHY.PLATFORMS.PERMALINKS_PREFERRED",
+ "CMOS.CITATIONS.S13_11.NO_SHORTENERS_IN_MS",
+ "CMOS.CITATIONS.S13_11.PUBLISHER_OPTION",
+ "CMOS.CITATIONS.S13_11.SHORTENERS.OBSCURE",
+ "CMOS.CITATIONS.S13_110.AUTHOR_DATE.JOURNAL_ARTICLES.CORE_FIELDS",
+ "CMOS.CITATIONS.S13_111.AUTHOR_DATE.REFERENCE_LIST.REQUIRED",
+ "CMOS.CITATIONS.S13_12.URLS.CASE_SENSITIVE",
+ "CMOS.CITATIONS.S13_12.URLS.NO_SENTENCE_START",
+ "CMOS.CITATIONS.S13_12.URLS.NO_SPACES",
+ "CMOS.CITATIONS.S13_12.URLS.PROTOCOL",
+ "CMOS.CITATIONS.S13_12.URLS.PUNCTUATION_AFTER",
+ "CMOS.CITATIONS.S13_12.URLS.TRAILING_SLASH",
+ "CMOS.CITATIONS.S13_13.BACKUPS",
+ "CMOS.CITATIONS.S13_13.CITATIONS.REVIEW",
+ "CMOS.CITATIONS.S13_13.METADATA.CHECK_FIELDS",
+ "CMOS.CITATIONS.S13_13.METADATA.MISSING",
+ "CMOS.CITATIONS.S13_13.REPAIR_AT_SOURCE",
+ "CMOS.CITATIONS.S13_13.STRIP_CODES",
+ "CMOS.CITATIONS.S13_13.TOOLS.USE_METADATA",
+ "CMOS.CITATIONS.S13_14.CITE_VERSION",
+ "CMOS.CITATIONS.S13_14.DEVICE_SPECIFIC",
+ "CMOS.CITATIONS.S13_14.ONLINE.URL_INDICATOR",
+ "CMOS.CITATIONS.S13_14.SAME_URL.FORMATS",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.NOT_REQUIRED",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.PUBLISHER_POLICY",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.RECORD_ANYWAY",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.UNVERIFIABLE",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.FORMAT",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.PREFERENCE",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.WHEN_ONLY_DATE",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.WIKIS",
+ "CMOS.CITATIONS.S13_17.ARCHIVE_SERVICES",
+ "CMOS.CITATIONS.S13_17.PRESERVE.CRISIS_SOURCES",
+ "CMOS.CITATIONS.S13_17.PRESERVE.FORMAT_OPTIONS",
+ "CMOS.CITATIONS.S13_17.PRESERVE.NONPUBLISHED",
+ "CMOS.CITATIONS.S13_18.BIBLIO.INVERT_FIRST_AUTHOR",
+ "CMOS.CITATIONS.S13_18.BIBLIO.SHORTENED_NOTES",
+ "CMOS.CITATIONS.S13_18.NAMES.NORMAL_ORDER",
+ "CMOS.CITATIONS.S13_18.NOTES.SENTENCE_STYLE",
+ "CMOS.CITATIONS.S13_18.NOTES_BIBLIO.OVERVIEW",
+ "CMOS.CITATIONS.S13_18.NO_BIBLIO.FULL_FIRST_NOTE",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.BIBLIO",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.CONSISTENT",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.NOTES",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.NOUN_FORMS",
+ "CMOS.CITATIONS.S13_2.AUTHOR_DATE_SYSTEM",
+ "CMOS.CITATIONS.S13_2.DEFAULT_SYSTEM",
+ "CMOS.CITATIONS.S13_2.DISCIPLINE_PREFERENCE",
+ "CMOS.CITATIONS.S13_2.JOURNAL_INSTRUCTIONS",
+ "CMOS.CITATIONS.S13_2.NOTES_BIBLIOGRAPHY_OPTIONAL",
+ "CMOS.CITATIONS.S13_2.NOTES_SYSTEM",
+ "CMOS.CITATIONS.S13_2.STYLE_ELEMENTS.SHARED",
+ "CMOS.CITATIONS.S13_2.SYSTEMS.TWO_TYPES",
+ "CMOS.CITATIONS.S13_2.SYSTEM_SWITCHING",
+ "CMOS.CITATIONS.S13_20.BIBLIO.BOOKS.NO_PAGES",
+ "CMOS.CITATIONS.S13_20.BIBLIO.PAGE_RANGE",
+ "CMOS.CITATIONS.S13_20.ELECTRONIC.SHORT_DOCS",
+ "CMOS.CITATIONS.S13_20.LOCATORS.ALTERNATIVES",
+ "CMOS.CITATIONS.S13_20.NOTES.PAGE_SPECIFIC",
+ "CMOS.CITATIONS.S13_20.PAGE_RANGE.EN_DASH",
+ "CMOS.CITATIONS.S13_21.EXAMPLES.BIBLIO_SHORTENED",
+ "CMOS.CITATIONS.S13_21.EXAMPLES.CHAPTER14",
+ "CMOS.CITATIONS.S13_21.EXAMPLES.SHORT_FORMS",
+ "CMOS.CITATIONS.S13_22.BOOK_EDITOR_ONLY",
+ "CMOS.CITATIONS.S13_22.BOOK_EDITOR_ONLY.SHORTENED_NO_ED",
+ "CMOS.CITATIONS.S13_22.BOOK_PLACE_OMIT",
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.NOTE_BIBLIO",
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.PAGE_IN_NOTES",
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.SHORTENED",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.BIBLIO_MORE_THAN_SIX",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.BIBLIO_UP_TO_SIX",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.NOTES_ET_AL",
+ "CMOS.CITATIONS.S13_23.NO_BIBLIO.NOTES_UP_TO_SIX",
+ "CMOS.CITATIONS.S13_23.TWO_AUTHORS.BIBLIO_INVERT_FIRST",
+ "CMOS.CITATIONS.S13_23.TWO_AUTHORS.NOTES_LIST_BOTH",
+ "CMOS.CITATIONS.S13_24.AUTHOR_PLUS_EDITOR.BIBLIO_SPELL_OUT",
+ "CMOS.CITATIONS.S13_24.AUTHOR_PLUS_EDITOR.NOTES_ABBREVIATE",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.BIBLIO_NO_PAGE_RANGE",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.INCLUDE_AUTHOR",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.INCLUDE_EDITOR",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.IN_BEFORE_BOOK",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.NOTES_PAGE_LOCATOR",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.QUOTE_TITLE",
+ "CMOS.CITATIONS.S13_26.JOURNAL.BIBLIO_PAGE_RANGE",
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_ISSUE",
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_VOLUME",
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_YEAR",
+ "CMOS.CITATIONS.S13_26.JOURNAL.NOTES_PAGE_SPECIFIC",
+ "CMOS.CITATIONS.S13_26.JOURNAL.OMIT_MONTH_SEASON",
+ "CMOS.CITATIONS.S13_26.JOURNAL.ONLINE.URL_OR_DOI",
+ "CMOS.CITATIONS.S13_26.JOURNAL.PAGE_COLON",
+ "CMOS.CITATIONS.S13_26.JOURNAL.TITLE_ITALIC",
+ "CMOS.CITATIONS.S13_26.JOURNAL.VOLUME_FORMAT",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.MANUSCRIPT_SUPERSCRIPT_OK",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.NOTES_FULL_SIZE",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.NOTES_PERIOD",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.TEXT_SUPERSCRIPT",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.BASELINE_FALLBACK",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.CONSISTENT_SPACING",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.NOTES_FULL_SIZE",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.NO_PERIOD",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.TEXT_SUPERSCRIPT",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.CONSECUTIVE",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.NO_BOOKWIDE_RUN",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SEPARATE_SYSTEMS",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SYMBOLS_FOR_FEW",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SYMBOL_SEQUENCE_STANDARD",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.TABLE_NOTES_SEPARATE",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AFTER_PUNCTUATION",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AFTER_QUOTE",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AVOID_MIDCLAUSE",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.BEFORE_DASH",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.PLACEMENT_END_SENTENCE",
+ "CMOS.CITATIONS.S13_3.JOURNALS.HOUSE_STYLE",
+ "CMOS.CITATIONS.S13_3.LEGAL.BLUEBOOK",
+ "CMOS.CITATIONS.S13_3.OTHER_SYSTEMS.AMA_CSE",
+ "CMOS.CITATIONS.S13_3.OTHER_SYSTEMS.MLA_APA",
+ "CMOS.CITATIONS.S13_3.SOURCE_MANUALS",
+ "CMOS.CITATIONS.S13_35.SHORT_FORM.DISTINCT_TITLE",
+ "CMOS.CITATIONS.S13_36.SHORT_FORM.DISAMBIGUATE_AUTHOR",
+ "CMOS.CITATIONS.S13_38.IBID.IMMEDIATE_PRECEDENT",
+ "CMOS.CITATIONS.S13_39.IBID.LOCATOR_REQUIRED",
+ "CMOS.CITATIONS.S13_4.CONSISTENCY.REQUIRED",
+ "CMOS.CITATIONS.S13_4.DOCUMENTED_DEVIATIONS",
+ "CMOS.CITATIONS.S13_4.FLEXIBILITY.BY_AGREEMENT",
+ "CMOS.CITATIONS.S13_4.JOURNALS.STRICT",
+ "CMOS.CITATIONS.S13_40.SHORT_FORM.AVOID_OP_CIT",
+ "CMOS.CITATIONS.S13_45.NOTES.CITATION_FIRST",
+ "CMOS.CITATIONS.S13_47.NOTES.SYSTEMS.DONT_MIX",
+ "CMOS.CITATIONS.S13_48.ENDNOTES.GROUP_BY_CHAPTER",
+ "CMOS.CITATIONS.S13_5.ACADEMIC_EXPECTATION",
+ "CMOS.CITATIONS.S13_5.AVOID_TANGENTIAL",
+ "CMOS.CITATIONS.S13_5.CITE_RELEVANT",
+ "CMOS.CITATIONS.S13_5.INFORMAL_SOURCES",
+ "CMOS.CITATIONS.S13_5.NONACADEMIC.MENTIONS_OK",
+ "CMOS.CITATIONS.S13_52.ENDNOTES.NAVIGATION_CUES",
+ "CMOS.CITATIONS.S13_54.AUTHOR_DATE.NOTES.COMMENTARY_ONLY",
+ "CMOS.CITATIONS.S13_56.NOTES.DUAL_STREAMS.DISTINCT_LABELS",
+ "CMOS.CITATIONS.S13_57.NOTES.SEPARATE_SOURCE_VS_COMMENTARY",
+ "CMOS.CITATIONS.S13_59.NOTES.MULTI_EDITIONS.CITE_VERSION_USED",
+ "CMOS.CITATIONS.S13_6.LINK_TITLE_PREFERRED",
+ "CMOS.CITATIONS.S13_6.URL.FINAL_ELEMENT",
+ "CMOS.CITATIONS.S13_6.URLS.EASILY_FOUND",
+ "CMOS.CITATIONS.S13_6.URLS.IN_MANUSCRIPT",
+ "CMOS.CITATIONS.S13_6.URLS.READER_NEEDED",
+ "CMOS.CITATIONS.S13_61.BIBLIOGRAPHY.SCOPE.LABEL_CLEARLY",
+ "CMOS.CITATIONS.S13_62.BIBLIOGRAPHY.ENTRY_COMPLETENESS.MORE_THAN_SHORT_FORM",
+ "CMOS.CITATIONS.S13_63.BIBLIOGRAPHY.CONSISTENT_ELEMENT_ORDER",
+ "CMOS.CITATIONS.S13_64.BIBLIOGRAPHY.SUBSECTIONS.CLEAR_HEADINGS",
+ "CMOS.CITATIONS.S13_66.BIBLIOGRAPHY.INCLUDE_ONLY_PER_SCOPE",
+ "CMOS.CITATIONS.S13_67.BIBLIOGRAPHY.ANNOTATIONS.CONSISTENT_AND_DISTINCT",
+ "CMOS.CITATIONS.S13_68.BIBLIOGRAPHY.ENTRY_TYPES.NOT_MIXED",
+ "CMOS.CITATIONS.S13_7.DOI.NO_PREFIX",
+ "CMOS.CITATIONS.S13_7.DOI.PREFERRED",
+ "CMOS.CITATIONS.S13_7.DOI.RESOLUTION",
+ "CMOS.CITATIONS.S13_7.DOI.URL_FORM",
+ "CMOS.CITATIONS.S13_71.BIBLIOGRAPHY.ALPHABETIZATION.PREFIXES_POLICY",
+ "CMOS.CITATIONS.S13_72.BIBLIOGRAPHY.SORTING.DIACRITICS_AND_TRANSLITERATION",
+ "CMOS.CITATIONS.S13_8.PERMALINK.PREFERRED",
+ "CMOS.CITATIONS.S13_8.PERMALINK.TEST",
+ "CMOS.CITATIONS.S13_8.PREFERRED_ORDER",
+ "CMOS.CITATIONS.S13_8.SUBSCRIPTION_URLS",
+ "CMOS.CITATIONS.S13_9.DATABASE_NAME_OK",
+ "CMOS.CITATIONS.S13_9.SHORTEN_LONG_URLS",
+ "CMOS.CITATIONS.S13_9.SHORT_URLS.ARE_NOT_SHORTENERS",
+ "CMOS.CITATIONS.S13_9.URL_TO_MAIN_PAGE",
+ "CMOS.CITATIONS.S13_90.TITLE_PUNCTUATION.CHANGES.POLICY_LIMITED",
+ "CMOS.CITATIONS.S13_91.TITLE_SUBTITLE.SEPARATOR.COLON",
+ "CMOS.CITATIONS.S13_92.BIBLIOGRAPHY.BOOKS.CORE_ELEMENTS",
+ "CMOS.CITATIONS.S13_93.BIBLIOGRAPHY.EDITED_VOLUMES.ROLE_MARKING",
+ "CMOS.CITATIONS.S13_94.TITLES.TRAILING_PHRASE.PLACEMENT",
+ "CMOS.CITATIONS.S13_95.BIBLIOGRAPHY.CHAPTERS.IN_EDITED_COLLECTIONS",
+ "CMOS.CITATIONS.S13_96.BIBLIOGRAPHY.JOURNAL_ARTICLES.VOLUME_ISSUE_PAGES",
+ "CMOS.CITATIONS.S13_97.BIBLIOGRAPHY.NEWSPAPER_MAGAZINE.DATES",
+ "CMOS.CITATIONS.S13_98.BIBLIOGRAPHY.THESES_DISSERTATIONS.INSTITUTION",
+ "CMOS.CITATIONS.S13_99.LONG_TITLES.TRUNCATION.AVOID",
"CMOS.CITATIONS.SYSTEM.CONSISTENT_CHOICE",
- "CMOS.CITATIONS.TITLES.CAPITALIZATION.CONSISTENT"
+ "CMOS.CITATIONS.TITLES.CAPITALIZATION.CONSISTENT",
+ "HOUSE.CITATIONS.AUTHOR_DATE.PAREN_YEAR_ONLY",
+ "HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.REQUIRED",
+ "HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.YEAR_REQUIRED",
+ "HOUSE.CITATIONS.NOTES.BIBLIOGRAPHY.REQUIRED",
+ "HOUSE.CITATIONS.NOTES.DEFINITIONS.REQUIRED",
+ "HOUSE.CITATIONS.NOTES.IBID.AVOID",
+ "HOUSE.CITATIONS.NOTES.MARKERS.BRACKETED_NUMBERS.AVOID"
],
"code": [
+ "BRING.CODE.MONO_RAGGED_RIGHT",
+ "BRING.CODE.RAG.AVOID_FAKE_JUSTIFY",
+ "BRING.CODE.RAG.FIXED_WORD_SPACES",
+ "BRING.CODE.RAG.NO_AUTO_HYPHENATION",
+ "BRING.CODE.RAG.NO_LETTERSPACING",
+ "BRING.CODE.RAG.NO_MIN_LINE",
+ "HOUSE.CODE.BLOCKS.COMMANDS.PROMPT_FREE_COPY",
+ "HOUSE.CODE.BLOCKS.CONFIG.VALID",
+ "HOUSE.CODE.BLOCKS.DATA.SYNTHETIC_FOR_SENSITIVE",
+ "HOUSE.CODE.BLOCKS.DETERMINISTIC_OUTPUT",
+ "HOUSE.CODE.BLOCKS.ELISION.MARKED",
+ "HOUSE.CODE.BLOCKS.ERROR_OUTPUT.LABELED",
+ "HOUSE.CODE.BLOCKS.INDENTATION.CONSISTENT",
"HOUSE.CODE.BLOCKS.LANGUAGE_TAGS.PREFERRED",
+ "HOUSE.CODE.BLOCKS.LINE_BREAKS.SEMANTIC_SAFE",
+ "HOUSE.CODE.BLOCKS.LONG_LINES.AVOID",
"HOUSE.CODE.BLOCKS.NO_CLIPPING",
+ "HOUSE.CODE.BLOCKS.NO_LINE_NUMBERS",
+ "HOUSE.CODE.BLOCKS.NO_PERSONAL_PATHS",
+ "HOUSE.CODE.BLOCKS.NO_SMART_QUOTES",
+ "HOUSE.CODE.BLOCKS.PLATFORM.NOTED",
+ "HOUSE.CODE.BLOCKS.PRECONDITIONS.STATED",
+ "HOUSE.CODE.BLOCKS.SPLIT_BY_LANGUAGE",
+ "HOUSE.CODE.BLOCKS.TABS.AVOID",
+ "HOUSE.CODE.BLOCKS.TESTED_OR_MARKED",
+ "HOUSE.CODE.BLOCKS.TRAILING_WHITESPACE.AVOID",
+ "HOUSE.CODE.BLOCKS.USE_FOR_MULTILINE",
"HOUSE.CODE.BLOCKS.WRAP_POLICY",
- "HOUSE.CODE.INLINE.MONO_BACKTICKS"
+ "HOUSE.CODE.CAPTIONS.EXPLAIN_SNIPPET",
+ "HOUSE.CODE.COMMENTS.MINIMIZE_NOISE",
+ "HOUSE.CODE.DIFFS.CONTEXT_LINES.PRESENT",
+ "HOUSE.CODE.DIFFS.FILE_HEADERS.PRESENT",
+ "HOUSE.CODE.DIFFS.UNIFIED_FORMAT",
+ "HOUSE.CODE.ERRORS.SHOW_FAILURES",
+ "HOUSE.CODE.EXAMPLES.ENV_VARS.DOCUMENT",
+ "HOUSE.CODE.EXAMPLES.FILE_PATH.LABEL",
+ "HOUSE.CODE.EXAMPLES.MULTI_FILE.SEPARATE",
+ "HOUSE.CODE.EXAMPLES.ORDERED_STEPS",
+ "HOUSE.CODE.FENCES.CLOSE_PROPERLY",
+ "HOUSE.CODE.FENCES.LANGUAGE_INFO.SUGGEST",
+ "HOUSE.CODE.INLINE.MONO_BACKTICKS",
+ "HOUSE.CODE.INLINE.USE_FOR_IDENTIFIERS",
+ "HOUSE.CODE.LANGUAGE.CONSISTENT_FENCES",
+ "HOUSE.CODE.LANGUAGE.NOTATION.CONSISTENT",
+ "HOUSE.CODE.LINE_ENDINGS.NORMALIZE",
+ "HOUSE.CODE.MONO.FONT.PREFERRED",
+ "HOUSE.CODE.OUTPUT.DISTINGUISH_FROM_INPUT",
+ "HOUSE.CODE.OUTPUT.TRUNCATION.LABELED",
+ "HOUSE.CODE.PLACEHOLDERS.CLEAR",
+ "HOUSE.CODE.REFERENCES.VERSION_PIN",
+ "HOUSE.CODE.SECURITY.REDACT_SECRETS",
+ "HOUSE.CODE.SHELL.DESTRUCTIVE.WARN",
+ "HOUSE.CODE.SHELL.PROMPTS.CONSISTENT",
+ "HOUSE.CODE.TABLES.AVOID_FOR_CODE",
+ "HOUSE.CODE.TYPED_VALUES.DISTINGUISH",
+ "HOUSE.CODE.TYPOGRAPHY.UNICODE.MINIMIZE",
+ "HOUSE.CODE.URLS.IN_CODE.AVOID_WRAPPING",
+ "HOUSE.CODE.WRAPPING.NO_SOFT_HYPHENS"
+ ],
+ "editorial": [
+ "HOUSE.EDITORIAL.CLAIMS.AVOID_ABSOLUTES",
+ "HOUSE.EDITORIAL.CLAIMS.BASELINE_FOR_COMPARISONS",
+ "HOUSE.EDITORIAL.CLAIMS.DISTINGUISH_FACT_OPINION",
+ "HOUSE.EDITORIAL.CLAIMS.QUANTIFY_WHEN_POSSIBLE",
+ "HOUSE.EDITORIAL.CLAIMS.SCOPE_TIMEBOUND",
+ "HOUSE.EDITORIAL.CLAIMS.SUPPORT_WITH_SOURCES",
+ "HOUSE.EDITORIAL.CLARITY.ACTIVE_VOICE_INSTRUCTIONS",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_AMBIGUOUS_PRONOUNS",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_DOUBLE_NEGATIVES",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_METACOMMENTARY",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_WEASEL_WORDS",
+ "HOUSE.EDITORIAL.CLARITY.DEFINE_JARGON_ON_FIRST_USE",
+ "HOUSE.EDITORIAL.CLARITY.DEFINE_METRICS",
+ "HOUSE.EDITORIAL.CLARITY.EDIT_FOR_BREVITY",
+ "HOUSE.EDITORIAL.CLARITY.EXAMPLES_WHEN_COMPLEX",
+ "HOUSE.EDITORIAL.CLARITY.ONE_IDEA_PER_PARAGRAPH",
+ "HOUSE.EDITORIAL.CONSISTENCY.CAPITALIZATION.STABLE",
+ "HOUSE.EDITORIAL.CONSISTENCY.DATE_FORMAT.SINGLE",
+ "HOUSE.EDITORIAL.CONSISTENCY.NAMES.SAME_FORM",
+ "HOUSE.EDITORIAL.CONSISTENCY.SPELLING_VARIANT.CHOOSE_ONE",
+ "HOUSE.EDITORIAL.CONSISTENCY.TERMINOLOGY.STABLE",
+ "HOUSE.EDITORIAL.CONSISTENCY.TIMEZONE.EXPLICIT",
+ "HOUSE.EDITORIAL.HEADINGS.AVOID_ALL_CAPS",
+ "HOUSE.EDITORIAL.HEADINGS.AVOID_GENERIC",
+ "HOUSE.EDITORIAL.HEADINGS.CASE.CONSISTENT",
+ "HOUSE.EDITORIAL.HEADINGS.LENGTH.CONCISE",
+ "HOUSE.EDITORIAL.HEADINGS.NO_DUPLICATE",
+ "HOUSE.EDITORIAL.HEADINGS.NO_TRAILING_PUNCTUATION",
+ "HOUSE.EDITORIAL.LISTS.AVOID_DEEP_NESTING",
+ "HOUSE.EDITORIAL.LISTS.AVOID_SINGLE_ITEM",
+ "HOUSE.EDITORIAL.LISTS.ITEMS.ACTIONABLE",
+ "HOUSE.EDITORIAL.LISTS.ORDERED_ONLY_WHEN_ORDERED",
+ "HOUSE.EDITORIAL.LISTS.PARALLEL_STRUCTURE",
+ "HOUSE.EDITORIAL.LISTS.PUNCTUATION.CONSISTENT",
+ "HOUSE.EDITORIAL.LISTS.TASKS.CHECKLIST",
+ "HOUSE.EDITORIAL.OPSEC.REMOVE_PII",
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_LOREM_IPSUM",
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_REVIEW_NOTES_INLINE",
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_TBD_TKTK",
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_TODO_FIXME",
+ "HOUSE.EDITORIAL.REVIEW.CROSS_REFERENCES.VERIFY",
+ "HOUSE.EDITORIAL.REVIEW.FACT_CHECK",
+ "HOUSE.EDITORIAL.REVIEW.LINKS.VERIFY",
+ "HOUSE.EDITORIAL.REVIEW.SENSITIVE_INFO.NO_SECRETS",
+ "HOUSE.EDITORIAL.REVIEW.SPELLCHECK_AND_READTHROUGH",
+ "HOUSE.EDITORIAL.STRUCTURE.ACTION_ITEMS.EXPLICIT",
+ "HOUSE.EDITORIAL.STRUCTURE.ASSUMPTIONS.EXPLICIT",
+ "HOUSE.EDITORIAL.STRUCTURE.AUDIENCE.STATED",
+ "HOUSE.EDITORIAL.STRUCTURE.CHANGELOG.LIVING_DOCS",
+ "HOUSE.EDITORIAL.STRUCTURE.DECISIONS.EXPLICIT",
+ "HOUSE.EDITORIAL.STRUCTURE.GLOSSARY.WHEN_DENSE",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.EARLY",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.PRESENT",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.SINGLE",
+ "HOUSE.EDITORIAL.STRUCTURE.METADATA.OWNER_DATE",
+ "HOUSE.EDITORIAL.STRUCTURE.REFERENCES.WHEN_CITED",
+ "HOUSE.EDITORIAL.STRUCTURE.RISKS.MITIGATIONS",
+ "HOUSE.EDITORIAL.STRUCTURE.SCOPE.STATED",
+ "HOUSE.EDITORIAL.STRUCTURE.SUMMARY.EARLY",
+ "HOUSE.EDITORIAL.TONE.AVOID_EXCESSIVE_EMPHASIS",
+ "HOUSE.EDITORIAL.TONE.CALIBRATE_CERTAINTY",
+ "HOUSE.EDITORIAL.TONE.INCLUSIVE_LANGUAGE",
+ "HOUSE.EDITORIAL.TONE.PROFESSIONAL_AND_RESPECTFUL"
+ ],
+ "figures": [
+ "CMOS.FIGURES.ACCESSIBILITY.ALT_TEXT",
+ "CMOS.FIGURES.ANNOTATIONS.CONSISTENT_STYLE",
+ "CMOS.FIGURES.ASPECT_RATIO.PRESERVE",
+ "CMOS.FIGURES.AXES.UNITS.CONSISTENT",
+ "CMOS.FIGURES.BLEED.ONLY_WHEN_ENABLED",
+ "CMOS.FIGURES.CALL_OUTS.AVOID_OVERLAP",
+ "CMOS.FIGURES.CAPTION.ALIGNMENT.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.CREDITS.INLINE_OR_NOTE",
+ "CMOS.FIGURES.CAPTION.FONT.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.LENGTH.REASONABLE",
+ "CMOS.FIGURES.CAPTION.NUMBER.MATCH_LABEL",
+ "CMOS.FIGURES.CAPTION.PLACEMENT.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.PREFIX.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.PUNCTUATION.CONSISTENT",
+ "CMOS.FIGURES.CAPTIONS.PRESENT",
+ "CMOS.FIGURES.COLOR.NOT_SOLE_SIGNAL",
+ "CMOS.FIGURES.COLOR.PALETTE.CONSISTENT",
+ "CMOS.FIGURES.CONTRAST.SUFFICIENT",
+ "CMOS.FIGURES.CREDIT.SOURCE_WHEN_REQUIRED",
+ "CMOS.FIGURES.CROP.AVOID_LOSS",
+ "CMOS.FIGURES.EMBEDDED_TEXT.MINIMAL",
+ "CMOS.FIGURES.FILENAME.STABLE",
+ "CMOS.FIGURES.FORMAT.VECTOR_WHEN_POSSIBLE",
+ "CMOS.FIGURES.KEY.READABLE",
+ "CMOS.FIGURES.LABELS.AVOID_OVERLAP",
+ "CMOS.FIGURES.LABELS.FONT.CONSISTENT",
+ "CMOS.FIGURES.LEGENDS.EXPLAIN_SYMBOLS",
+ "CMOS.FIGURES.LINE_WEIGHTS.CONSISTENT",
+ "CMOS.FIGURES.LIST_ENTRIES.MATCH_CAPTIONS",
+ "CMOS.FIGURES.LIST_OF_FIGURES.WHEN_NEEDED",
+ "CMOS.FIGURES.MARGINS.AVOID_CLIPPING",
+ "CMOS.FIGURES.MULTIPART.PANEL_LABELS",
+ "CMOS.FIGURES.NUMBERING.SEQUENTIAL",
+ "CMOS.FIGURES.NUMBERING.WITHIN_CHAPTERS",
+ "CMOS.FIGURES.ORIENTATION.CONSISTENT",
+ "CMOS.FIGURES.PANEL_ORDER.LOGICAL",
+ "CMOS.FIGURES.PERMISSIONS.DOCUMENTED",
+ "CMOS.FIGURES.PLACEMENT.AVOID_SPLIT",
+ "CMOS.FIGURES.PLACEMENT.NEAR_MENTION",
+ "CMOS.FIGURES.PLACEMENT.TOP_OR_BOTTOM.CONSISTENT",
+ "CMOS.FIGURES.REFERENCES.IN_TEXT",
+ "CMOS.FIGURES.RESOLUTION.RASTER_SUFFICIENT",
+ "CMOS.FIGURES.SCALE.LEGIBLE",
+ "CMOS.FIGURES.SCALING.UNIFORM",
+ "CMOS.FIGURES.SENSITIVE.DATA.REDACT",
+ "CMOS.FIGURES.SIZE.MATCH_READABILITY",
+ "CMOS.FIGURES.SOURCE.DATA.CITED",
+ "CMOS.FIGURES.SYMBOLS.CONSISTENT",
+ "CMOS.FIGURES.TABLE_VS_FIGURE.CHOOSE",
+ "CMOS.FIGURES.UNITS.LABEL_AXES",
+ "HOUSE.FIGURES.AXES.UNITS.LABELED",
+ "HOUSE.FIGURES.CAPTIONS.TAKEAWAY",
+ "HOUSE.FIGURES.COLOR.CONTRAST_SAFE",
+ "HOUSE.FIGURES.COLOR.LEGEND.REQUIRED",
+ "HOUSE.FIGURES.FORMAT.VECTOR_FOR_LINE_ART",
+ "HOUSE.FIGURES.RESOLUTION.MINIMUM",
+ "HOUSE.FIGURES.TEXT.NOT_RASTERIZED"
+ ],
+ "frontmatter": [
+ "CMOS.FRONTMATTER.ABSTRACT.WHEN_APPROPRIATE",
+ "CMOS.FRONTMATTER.ACCESSIBILITY.NOTES",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.NAMES.CONSISTENT",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.PLACEMENT",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.SCOPE",
+ "CMOS.FRONTMATTER.AUDIENCE.SCOPE.STATED",
+ "CMOS.FRONTMATTER.CHANGELOG.LINKS",
+ "CMOS.FRONTMATTER.CITATION_STYLE.DECLARED",
+ "CMOS.FRONTMATTER.CONTACT.OWNERSHIP",
+ "CMOS.FRONTMATTER.COPYRIGHT.NOTICES.PRESENT",
+ "CMOS.FRONTMATTER.COPYRIGHT.RIGHTS.CONTACT",
+ "CMOS.FRONTMATTER.DISCLAIMERS.WHEN_REQUIRED",
+ "CMOS.FRONTMATTER.EDITION.VERSION_VISIBLE",
+ "CMOS.FRONTMATTER.EPIGRAPH.ATTRIBUTION",
+ "CMOS.FRONTMATTER.EPIGRAPH.PLACEMENT.CONSISTENT",
+ "CMOS.FRONTMATTER.FOREWORD.AUTHOR.ATTRIBUTED",
+ "CMOS.FRONTMATTER.FOREWORD.DATE_IF_PRESENT",
+ "CMOS.FRONTMATTER.INTRODUCTION.SCOPE",
+ "CMOS.FRONTMATTER.LANGUAGE.NOTICE",
+ "CMOS.FRONTMATTER.LICENSE.ATTRIBUTION",
+ "CMOS.FRONTMATTER.LISTS.OF_FIGURES_TABLES.WHEN_NEEDED",
+ "CMOS.FRONTMATTER.LIST_OF_FIGURES.SECTION_TITLE",
+ "CMOS.FRONTMATTER.LIST_OF_TABLES.SECTION_TITLE",
+ "CMOS.FRONTMATTER.NAVIGATION.METADATA",
+ "CMOS.FRONTMATTER.PREFACE.DATE_IF_PRESENT",
+ "CMOS.FRONTMATTER.PREFACE.PURPOSE",
+ "CMOS.FRONTMATTER.READING_TIME.WHEN_HELPFUL",
+ "CMOS.FRONTMATTER.REVISION_HISTORY.WHEN_REQUIRED",
+ "CMOS.FRONTMATTER.SECURITY.CLASSIFICATION",
+ "CMOS.FRONTMATTER.TERMS.DEFINITIONS.EARLY",
+ "CMOS.FRONTMATTER.TITLEPAGE.PRESENT",
+ "CMOS.FRONTMATTER.TOC.ENTRIES.MATCH_HEADINGS",
+ "CMOS.FRONTMATTER.TOC.FRONT_BACK_MATTER.INCLUDED",
+ "CMOS.FRONTMATTER.TOC.INDENTATION.BY_LEVEL",
+ "CMOS.FRONTMATTER.TOC.LEADERS.CONSISTENT",
+ "CMOS.FRONTMATTER.TOC.LEVELS.CONSISTENT",
+ "CMOS.FRONTMATTER.TOC.ORDER.MATCH_BODY",
+ "CMOS.FRONTMATTER.TOC.PAGE_NUMBERS.MATCH",
+ "CMOS.FRONTMATTER.TOC.SHORT_TITLES.CONSISTENT",
+ "CMOS.FRONTMATTER.TOC.WHEN_NEEDED",
+ "HOUSE.FRONTMATTER.ABSTRACT.REQUIRED_FOR_LONG_DOCS",
+ "HOUSE.FRONTMATTER.DISTRIBUTION.CONTACT",
+ "HOUSE.FRONTMATTER.METADATA.CONFIDENTIALITY",
+ "HOUSE.FRONTMATTER.METADATA.DOC_STATUS",
+ "HOUSE.FRONTMATTER.METADATA.LAST_REVIEWED",
+ "HOUSE.FRONTMATTER.METADATA.VERSION",
+ "HOUSE.FRONTMATTER.TOC.AUTO_GENERATED"
],
"headings": [
"BRING.HEADINGS.ALIGNMENT.CONSISTENT_LEVEL",
+ "BRING.HEADINGS.AVOID_ABBREVIATIONS",
+ "BRING.HEADINGS.AVOID_STACKED_LEVELS",
"BRING.HEADINGS.BLOCK_QUOTE.SPACING_AROUND",
+ "BRING.HEADINGS.BREAKS.AT_PHRASE_BOUNDARIES",
"BRING.HEADINGS.CAPITALIZATION.CONSISTENT",
+ "BRING.HEADINGS.CASE.PROPER_NOUNS_PRESERVE",
"BRING.HEADINGS.CONTRAST.CLEAR_HIERARCHY",
"BRING.HEADINGS.DEGRADED.INFER_STRUCTURE",
+ "BRING.HEADINGS.HIERARCHY.MAX_DEPTH",
"BRING.HEADINGS.HIERARCHY.NO_SKIPPED_LEVELS",
+ "BRING.HEADINGS.LEADIN_TEXT.BEFORE_LIST",
+ "BRING.HEADINGS.LENGTH.CONCISE",
"BRING.HEADINGS.MARGIN_HEADS.CLEAR_GUTTER",
+ "BRING.HEADINGS.NO_HYPHENATION",
+ "BRING.HEADINGS.NO_SINGLE_WORD_LINE",
+ "BRING.HEADINGS.NO_TERMINAL_COLON",
+ "BRING.HEADINGS.NO_TERMINAL_PERIOD",
+ "BRING.HEADINGS.NUMBERING.APPENDIX_LABELS",
+ "BRING.HEADINGS.NUMBERING.CONSISTENT_STYLE",
+ "BRING.HEADINGS.NUMBERING.NO_GAPS",
+ "BRING.HEADINGS.NUMBERING.PREFIXES.CONSISTENT",
+ "BRING.HEADINGS.NUMBERING.PUNCTUATION.CONSISTENT",
+ "BRING.HEADINGS.NUMBERING.SUBLEVELS.DECIMAL_STYLE",
"BRING.HEADINGS.PARAGRAPH_INDENT.AFTER_HEAD_NONE",
+ "BRING.HEADINGS.QUESTION_MARK_ONLY_IF_QUESTION",
"BRING.HEADINGS.RELATED_ELEMENTS.COHERENT",
+ "BRING.HEADINGS.RUN_IN.END_PUNCTUATION",
+ "BRING.HEADINGS.RUN_IN.SEPARATION.CONSISTENT",
"BRING.HEADINGS.RUN_IN.STANDALONE.CONSISTENT",
+ "BRING.HEADINGS.SECTION_OPENING.PARAGRAPH_REQUIRED",
"BRING.HEADINGS.SPACING.VERTICAL_RHYTHM",
"BRING.HEADINGS.STRUCTURE.MATCH_TEXT_LOGIC",
"BRING.HEADINGS.STYLE.PALETTE_LIMIT",
@@ -93,9 +701,12 @@
"BRING.HEADINGS.SUBHEADS.MARGIN_HEADS.RUNNING_SHOULDERHEADS",
"BRING.HEADINGS.SUBHEADS.MIXING.HIERARCHY_PLACEMENT",
"BRING.HEADINGS.SUBHEADS.MIXING_SYMM_ASYMM.AVOID_HAPHAZARD",
+ "BRING.HEADINGS.SUBHEADS.PARALLEL_GRAMMAR",
"BRING.HEADINGS.SUBHEADS.RIGHT_SIDEHEADS.VISIBILITY",
"BRING.HEADINGS.SUBHEADS.STYLE_CONTRIBUTES_TO_WHOLE",
+ "BRING.HEADINGS.TOC.MATCH",
"BRING.HEADINGS.WEIGHT_SIZE.HIERARCHY_SCALE",
+ "BRING.HEADINGS.WIDTH.BALANCED",
"CMOS.HEADINGS.DIVISIONS.CHAPTERS.MULTIAUTHOR",
"CMOS.HEADINGS.DIVISIONS.LETTERS_DIARIES.HEADINGS",
"CMOS.HEADINGS.LETTERS_DIARIES.DATELINE_FORMAT",
@@ -106,14 +717,66 @@
"CMOS.HEADINGS.RUNNING_HEADS.DIVISION_MATCH",
"CMOS.HEADINGS.RUNNING_HEADS.LENGTH_SHORT",
"CMOS.HEADINGS.RUNNING_HEADS.NAVIGATION_SCOPE",
- "HOUSE.HEADINGS.KEEPS.AVOID_STRANDED"
+ "HOUSE.HEADINGS.KEEPS.AVOID_STRANDED",
+ "HOUSE.HEADINGS.KEEP_WITH_NEXT"
+ ],
+ "i18n": [
+ "CMOS.I18N.ACRONYMS.LANGUAGE_SPECIFIC",
+ "CMOS.I18N.CAPITALIZATION.TITLES.LANGUAGE_RULES",
+ "CMOS.I18N.CITATIONS.TITLES.ORIGINAL_OR_TRANSLATED",
+ "CMOS.I18N.CURRENCY.CODES.LABEL",
+ "CMOS.I18N.DATES.FORMAT.CONSISTENT",
+ "CMOS.I18N.DIACRITICS.PRESERVE",
+ "CMOS.I18N.GLOSSARY.MULTILINGUAL",
+ "CMOS.I18N.HYPHENATION.LANGUAGE_TAGS",
+ "CMOS.I18N.ITALICS.FOREIGN_WORDS.SPARE",
+ "CMOS.I18N.LANGUAGE.CONSISTENT_SPELLING",
+ "CMOS.I18N.MEANINGFUL_TRANSLATIONS.NOT_LITERAL",
+ "CMOS.I18N.NAMES.SORTING.COLLATION",
+ "CMOS.I18N.NUMBERS.DECIMAL_SEPARATOR.LOCALE",
+ "CMOS.I18N.PARENS.BRACKETS.TRANSLATOR_NOTES",
+ "CMOS.I18N.PUNCTUATION.DASHES.MINUS_SIGN",
+ "CMOS.I18N.PUNCTUATION.ELLIPSIS.STYLE",
+ "CMOS.I18N.PUNCTUATION.SPACING.LANGUAGE_RULES",
+ "CMOS.I18N.QUOTES.NESTING.CONSISTENT",
+ "CMOS.I18N.QUOTES.STYLE.MATCH_LOCALE",
+ "CMOS.I18N.RIGHT_TO_LEFT.MARKUP",
+ "CMOS.I18N.ROMANIZATION.DIACRITICS.KEEP",
+ "CMOS.I18N.SCRIPT_MIXING.AVOID",
+ "CMOS.I18N.SECURITY.HOMOGLYPHS.AWARE",
+ "CMOS.I18N.TRANSLATION.INDICATE",
+ "CMOS.I18N.TRANSLITERATION.SYSTEM.CONSISTENT",
+ "CMOS.I18N.TYPOGRAPHY.FONT_COVERAGE",
+ "CMOS.I18N.UNITS.SYMBOLS.STANDARD",
+ "HOUSE.I18N.CURRENCY.DISAMBIGUATE",
+ "HOUSE.I18N.LANGUAGE.SWITCHES.MARK",
+ "HOUSE.I18N.NUMBERS.DIGIT_SYSTEM.CONSISTENT",
+ "HOUSE.I18N.NUMBERS.GROUPING.CONSISTENT",
+ "HOUSE.I18N.NUMBERS.MIXED_DECIMAL_SEPARATORS",
+ "HOUSE.I18N.QUOTES.MIXED_STYLES",
+ "HOUSE.I18N.TRANSLATION.LABELS",
+ "HOUSE.I18N.UNITS.SPACING.CONSISTENT"
],
"layout": [
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_BLOCK_QUOTES",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_CAPTIONS",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_HEADINGS",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_TABLES",
"BRING.LAYOUT.BLOCK_QUOTES.AVOID_CROWDING",
"BRING.LAYOUT.BLOCK_QUOTES.BEFORE_AFTER_SPACING",
"BRING.LAYOUT.BLOCK_QUOTES.EXTRA_LEAD",
"BRING.LAYOUT.BLOCK_QUOTES.INDENT_OR_NARROW",
+ "BRING.LAYOUT.COLUMNS.ALIGN_BASELINES",
"BRING.LAYOUT.COLUMNS.BALANCE_LENGTHS",
+ "BRING.LAYOUT.COLUMNS.COUNT.MODERATE",
+ "BRING.LAYOUT.COLUMNS.GUTTER.CONSISTENT",
+ "BRING.LAYOUT.COLUMNS.GUTTER.SUFFICIENT",
+ "BRING.LAYOUT.COLUMNS.RAGGED_BOTTOM.AVOID",
+ "BRING.LAYOUT.COLUMNS.SIDEBARS.DISTINCT_MEASURE",
+ "BRING.LAYOUT.COLUMNS.SPAN_POLICY.FIGURES",
+ "BRING.LAYOUT.COLUMNS.SPAN_POLICY.TABLES",
+ "BRING.LAYOUT.COLUMNS.USE_FOR_LONG_LISTS",
+ "BRING.LAYOUT.COLUMNS.WIDTH.CONSISTENT",
"BRING.LAYOUT.DEGRADED.HARD_WRAP_REFLOW",
"BRING.LAYOUT.ELEMENT_RELATIONSHIPS.VISIBLE",
"BRING.LAYOUT.FLOATS.PLACEMENT.NEAR_REFERENCE",
@@ -129,7 +792,17 @@
"BRING.LAYOUT.LEADING.CONSISTENT_BODY",
"BRING.LAYOUT.LEADING.NEGATIVE.AVOID_CONTINUOUS_TEXT",
"BRING.LAYOUT.LINEBREAKS.AVOID_SAME_WORD_START",
+ "BRING.LAYOUT.MARGINS.AVOID_CROWDING",
+ "BRING.LAYOUT.MARGINS.BLEED.ONLY_WHEN_ENABLED",
+ "BRING.LAYOUT.MARGINS.CONSISTENT.ACROSS_SECTIONS",
"BRING.LAYOUT.MARGINS.FACING_PAGES.INNER_OUTER",
+ "BRING.LAYOUT.MARGINS.FOOTNOTE.CLEARANCE",
+ "BRING.LAYOUT.MARGINS.GUTTER.ALLOW_BINDING",
+ "BRING.LAYOUT.MARGINS.NOTES.OUTSIDE_TEXTBLOCK",
+ "BRING.LAYOUT.MARGINS.OUTER_LARGER_THAN_INNER",
+ "BRING.LAYOUT.MARGINS.PROPORTION.BALANCED",
+ "BRING.LAYOUT.MARGINS.RUNNING_HEAD.CLEARANCE",
+ "BRING.LAYOUT.MARGINS.TOP_BOTTOM.BALANCE",
"BRING.LAYOUT.MEASURE.ADJUST_FOR_TYPE_SIZE",
"BRING.LAYOUT.MEASURE.AVOID_TOO_LONG",
"BRING.LAYOUT.MEASURE.AVOID_TOO_SHORT",
@@ -139,28 +812,173 @@
"BRING.LAYOUT.MEASURE.CONSISTENT_WITHIN_SECTION",
"BRING.LAYOUT.MEASURE.MULTICOLUMN_TARGETS",
"BRING.LAYOUT.MEASURE.TARGET_RANGE_CHARS",
+ "BRING.LAYOUT.PAGE.BLANKS.INTENTIONAL",
"BRING.LAYOUT.PAGE.DENSITY.DONT_SUFFOCATE",
+ "BRING.LAYOUT.PAGE.FACING_ELEMENTS.ALIGN",
"BRING.LAYOUT.PAGE.FRAME.TEXTBLOCK_BALANCE",
+ "BRING.LAYOUT.PAGE.HEAD_FOOT_BANDS.CONSISTENT",
+ "BRING.LAYOUT.PAGE.ODD_EVEN.CONSISTENT",
+ "BRING.LAYOUT.PAGE.OPENING_SPREAD.RULE",
+ "BRING.LAYOUT.PAGE.SHAPE.PROPORTIONATE",
+ "BRING.LAYOUT.PAGE.SPREADS.ALIGN_BASELINES",
+ "BRING.LAYOUT.PAGE.SPREADS.BALANCE_CONTENT",
+ "BRING.LAYOUT.PAGE.TEXTBLOCK.POSITION",
+ "BRING.LAYOUT.PAGE.WHITE_SPACE.DISTRIBUTION",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_AFTER_HEADING",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_BEFORE_LAST_LINE",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_IN_BLOCK_QUOTES",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_IN_EQUATIONS",
+ "BRING.LAYOUT.PAGINATION.AVOID_EXCESS_WHITE_SPACE",
+ "BRING.LAYOUT.PAGINATION.AVOID_LONELY_LINE_IN_LISTS",
+ "BRING.LAYOUT.PAGINATION.AVOID_STRANDED_CAPTIONS",
"BRING.LAYOUT.PAGINATION.BALANCE_FACING_PAGES",
+ "BRING.LAYOUT.PAGINATION.BALANCE_FINAL_PAGE",
+ "BRING.LAYOUT.PAGINATION.CLEAR_SECTION_BREAKS",
+ "BRING.LAYOUT.PAGINATION.KEEP_FIGURE_WITH_CAPTION",
+ "BRING.LAYOUT.PAGINATION.KEEP_LIST_WITH_INTRO",
+ "BRING.LAYOUT.PAGINATION.KEEP_TABLE_WITH_HEADER",
"BRING.LAYOUT.PAGINATION.ORPHANS_AVOID",
"BRING.LAYOUT.PAGINATION.WIDOWS_AVOID",
+ "BRING.LAYOUT.PARAGRAPH.AFTER_QUOTE.FLUSH",
+ "BRING.LAYOUT.PARAGRAPH.AVOID_WIDOW_END",
+ "BRING.LAYOUT.PARAGRAPH.AVOID_WIDOW_START",
"BRING.LAYOUT.PARAGRAPH.BLANK_LINES.SPARING",
+ "BRING.LAYOUT.PARAGRAPH.BLOCK_STYLE.CONSISTENT",
+ "BRING.LAYOUT.PARAGRAPH.DROP_CAPS.ALIGN_BASELINE",
+ "BRING.LAYOUT.PARAGRAPH.INDENT.NOT_TOO_DEEP",
+ "BRING.LAYOUT.PARAGRAPH.INDENT.PROPORTIONAL",
+ "BRING.LAYOUT.PARAGRAPH.INDENT.WITHIN_MEASURE",
"BRING.LAYOUT.PARAGRAPH.INDENT_AFTER_FIRST",
"BRING.LAYOUT.PARAGRAPH.INDENT_OR_SPACE_NOT_BOTH",
"BRING.LAYOUT.PARAGRAPH.INDENT_SIZE.CONSISTENT",
+ "BRING.LAYOUT.PARAGRAPH.LISTS.ALIGN_WITH_BODY",
+ "BRING.LAYOUT.PARAGRAPH.LISTS.HANGING_INDENT",
"BRING.LAYOUT.PARAGRAPH.NO_INDENT_AFTER_BLOCKS",
"BRING.LAYOUT.PARAGRAPH.OPENING_FLUSH_LEFT",
+ "BRING.LAYOUT.PARAGRAPH.RUN_IN_HEADS.CONSISTENT",
+ "BRING.LAYOUT.PARAGRAPH.SECTION_BREAKS.CLEAR",
"BRING.LAYOUT.RHYTHM.RULES_SERVE_TEXT",
"BRING.LAYOUT.TEXTBLOCK.CONSISTENT_WIDTH",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.CAPTIONS.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.FIGURES.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.FOOTNOTES.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.HEADINGS.BEFORE_AFTER",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.LISTS.SPACING",
"BRING.LAYOUT.VERTICAL_RHYTHM.MEASURED_INTERVALS.MULTIPLES",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.TABLES.SPACING",
+ "CMOS.LAYOUT.FOOTNOTES.PLACEMENT",
+ "CMOS.LAYOUT.FOOTNOTES.SEQUENCE",
+ "CMOS.LAYOUT.ILLUSTRATIONS.PLACEMENT_NEAR_REF",
+ "CMOS.LAYOUT.MEASURE.LINE_LENGTH.TARGET_RANGE",
+ "CMOS.LAYOUT.MEASURE.MAX_LINE_LENGTH",
+ "CMOS.LAYOUT.MEASURE.MIN_LINE_LENGTH",
+ "CMOS.LAYOUT.PAGINATION.AVOID_SHORT_LAST_LINE",
+ "CMOS.LAYOUT.PAGINATION.AVOID_SINGLE_LINE_ENDING",
+ "CMOS.LAYOUT.PAGINATION.FACING_PAGES.BALANCE",
+ "CMOS.LAYOUT.PAGINATION.FACING_PAGES.BLANKS",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.AVOID_BOTTOM_OF_PAGE",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.AVOID_TOP_OF_PAGE",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.KEEP_WITH_TEXT",
+ "CMOS.LAYOUT.PAGINATION.ORPHANS.AVOID",
+ "CMOS.LAYOUT.PAGINATION.PAGE_BREAKS.BEFORE_PARTS",
+ "CMOS.LAYOUT.PAGINATION.PAGE_NUMBERS.POSITION",
+ "CMOS.LAYOUT.PAGINATION.PAGE_NUMBERS.STYLE",
+ "CMOS.LAYOUT.PAGINATION.PAGE_SEQUENCE.CONTINUITY",
+ "CMOS.LAYOUT.PAGINATION.RUNNING_HEADS.CONSISTENCY",
+ "CMOS.LAYOUT.PAGINATION.RUNNING_HEADS.PLACEMENT",
+ "CMOS.LAYOUT.PAGINATION.WIDOWS.AVOID",
+ "CMOS.LAYOUT.PARAGRAPHS.BLOCK_QUOTE_STYLE",
+ "CMOS.LAYOUT.PARAGRAPHS.INDENT_POLICY",
+ "CMOS.LAYOUT.PARAGRAPHS.SPACING_POLICY",
+ "CMOS.LAYOUT.RUNNING_HEADS.CHAPTER_TITLES",
+ "CMOS.LAYOUT.RUNNING_HEADS.SECTION_TITLES",
+ "CMOS.LAYOUT.SPACING.LEADING.CHOOSE",
+ "CMOS.LAYOUT.SPACING.LINE_SPACING.CONSISTENT",
+ "CMOS.LAYOUT.SPACING.VERTICAL_RHYTHM",
+ "CMOS.LAYOUT.TABLES.PLACEMENT_NEAR_REF",
+ "HOUSE.LAYOUT.HTML.GUTTERS.MIN_PADDING",
+ "HOUSE.LAYOUT.HTML.MEASURE.MAX_WIDTH",
+ "HOUSE.LAYOUT.HTML.SECTION_SPACING.CONSISTENT",
+ "HOUSE.LAYOUT.MD.BLANK_LINES.SPARING",
+ "HOUSE.LAYOUT.MD.HEADINGS.NON_EMPTY_SECTIONS",
"HOUSE.LAYOUT.OVERFLOW.OVERFULL_LINES.REPORT",
- "HOUSE.LAYOUT.PAGINATION.KEEP_WITH_NEXT.HEADINGS"
+ "HOUSE.LAYOUT.PAGINATION.CAPTIONS.KEEP_WITH_CONTENT",
+ "HOUSE.LAYOUT.PAGINATION.HEADINGS.NO_ADJACENT",
+ "HOUSE.LAYOUT.PAGINATION.KEEP_WITH_NEXT.HEADINGS",
+ "HOUSE.LAYOUT.PAGINATION.LISTS.AVOID_LONELY_ITEM",
+ "HOUSE.LAYOUT.PAGINATION.LISTS.KEEP_INTRO",
+ "HOUSE.LAYOUT.PAGINATION.RUNT_FINAL_PAGE"
],
"links": [
+ "CMOS.LINKS.HYPERLINK_EXCLUDES_PUNCTUATION",
+ "CMOS.LINKS.NO_WRAPPERS",
+ "CMOS.LINKS.PUNCTUATE_NORMALLY",
+ "CMOS.LINKS.REPHRASE_IF_URL_ENDS_PUNCT",
+ "CMOS.LINKS.TRAILING_PUNCTUATION_OUTSIDE",
+ "CMOS.LINKS.URL_ONLY_LINE_NO_PUNCT",
+ "HOUSE.LINKS.AUTO.EMBEDDED_CREDENTIALS.AVOID",
+ "HOUSE.LINKS.AUTO.FILETYPE_LABEL.REQUIRED",
+ "HOUSE.LINKS.AUTO.FTP.AVOID",
+ "HOUSE.LINKS.AUTO.HTML_FALLBACK.REQUIRED",
+ "HOUSE.LINKS.AUTO.INTERNAL_HOSTNAMES.AVOID",
+ "HOUSE.LINKS.AUTO.INVITE_LINKS.AVOID",
+ "HOUSE.LINKS.AUTO.LABEL_LENGTH.AVOID_OVERLONG",
+ "HOUSE.LINKS.AUTO.LOGIN_LINKS.AVOID",
+ "HOUSE.LINKS.AUTO.PARTIAL_WORD.AVOID",
+ "HOUSE.LINKS.AUTO.PASSWORD_RESET.AVOID",
+ "HOUSE.LINKS.AUTO.PRIVATE_IPS.AVOID",
+ "HOUSE.LINKS.AUTO.SESSION_PARAMS.AVOID",
+ "HOUSE.LINKS.AUTO.STAGING_HOSTNAMES.AVOID",
+ "HOUSE.LINKS.AUTO.TRACKING_PARAMS.AVOID",
"HOUSE.LINKS.DISALLOW.FILE_URIS",
+ "HOUSE.LINKS.DISALLOW.JAVASCRIPT_URIS",
+ "HOUSE.LINKS.EMAILS.MAILTO_POLICY",
"HOUSE.LINKS.PUNCTUATION.NO_TRAILING_PUNCT",
+ "HOUSE.LINKS.TEXT.ACCESS_RESTRICTIONS.NOTE",
+ "HOUSE.LINKS.TEXT.ARCHIVE_AND_HTML.BOTH",
+ "HOUSE.LINKS.TEXT.AVOID_OVERLONG_LABELS",
"HOUSE.LINKS.TEXT.DESCRIPTIVE",
+ "HOUSE.LINKS.TEXT.DIFFERENTIATE_REPEATED_LINKS",
+ "HOUSE.LINKS.TEXT.FILESIZE.LABEL",
+ "HOUSE.LINKS.TEXT.FILETYPE.LABEL",
+ "HOUSE.LINKS.TEXT.LANGUAGE.LABEL",
+ "HOUSE.LINKS.TEXT.LINK_TARGET_MISMATCH",
+ "HOUSE.LINKS.TEXT.MATCHES_TARGET",
+ "HOUSE.LINKS.TEXT.MIRROR.LABEL",
+ "HOUSE.LINKS.TEXT.NO_CLICK_HERE",
+ "HOUSE.LINKS.TEXT.NO_EMOJIS",
+ "HOUSE.LINKS.TEXT.PARTIAL_WORD.AVOID",
+ "HOUSE.LINKS.TEXT.STABILITY.NOTE",
+ "HOUSE.LINKS.URLS.ANCHORS.STABLE",
+ "HOUSE.LINKS.URLS.AVOID.EXPIRING_SIGNED",
+ "HOUSE.LINKS.URLS.AVOID.INTERNAL_HOSTNAMES",
+ "HOUSE.LINKS.URLS.AVOID.IP_LITERALS",
+ "HOUSE.LINKS.URLS.AVOID.NAKED_URLS_IN_PROSE",
+ "HOUSE.LINKS.URLS.AVOID.ONE_TIME_INVITES",
+ "HOUSE.LINKS.URLS.AVOID.PASSWORD_RESET",
+ "HOUSE.LINKS.URLS.AVOID.STAGING_DOMAINS",
+ "HOUSE.LINKS.URLS.AVOID.TEMP_FILESHARES",
+ "HOUSE.LINKS.URLS.AVOID.TEXT_FRAGMENTS",
+ "HOUSE.LINKS.URLS.AVOID_PRIVATE_IPS",
+ "HOUSE.LINKS.URLS.BARE_DOMAIN.TRAILING_SLASH",
+ "HOUSE.LINKS.URLS.CANONICAL.NO_TRACKING_PARAMS",
+ "HOUSE.LINKS.URLS.CANONICAL_HOST",
+ "HOUSE.LINKS.URLS.DISALLOW.FTP",
+ "HOUSE.LINKS.URLS.DISALLOW.LOCALHOST",
+ "HOUSE.LINKS.URLS.DOIS.PREFER_DOI_ORG",
+ "HOUSE.LINKS.URLS.MAILTO.INTENT",
+ "HOUSE.LINKS.URLS.NO_BACKSLASH",
+ "HOUSE.LINKS.URLS.NO_EMBEDDED_CREDENTIALS",
+ "HOUSE.LINKS.URLS.NO_PROTOCOL_RELATIVE",
+ "HOUSE.LINKS.URLS.NO_QUERY_WHEN_NOT_NEEDED",
+ "HOUSE.LINKS.URLS.NO_SESSION_PARAMS",
+ "HOUSE.LINKS.URLS.NO_TRAILING_PARENS",
+ "HOUSE.LINKS.URLS.NO_WHITESPACE",
+ "HOUSE.LINKS.URLS.NO_ZERO_WIDTH",
"HOUSE.LINKS.URLS.PREFER_HTTPS",
+ "HOUSE.LINKS.URLS.RELATIVE.REPO_LOCAL",
+ "HOUSE.LINKS.URLS.SHORTENERS.AVOID",
+ "HOUSE.LINKS.URLS.STABLE_ANCHORS",
"HOUSE.LINKS.WRAP.SAFE_BREAKS"
],
"numbers": [
@@ -168,40 +986,53 @@
"CMOS.NUMBERS.CENTURIES.SPELLED_OUT",
"CMOS.NUMBERS.CONSISTENCY.MIXED_FORMS.AVOID",
"CMOS.NUMBERS.CONTEXTS.ALWAYS_NUMERALS",
+ "CMOS.NUMBERS.CURRENCY.CODE_POSITION.CONSISTENT",
"CMOS.NUMBERS.CURRENCY.FORMAT.SYMBOL_PLACEMENT",
"CMOS.NUMBERS.CURRENCY.HISTORICAL.YEAR_CONTEXT",
"CMOS.NUMBERS.CURRENCY.ISO_CODES",
"CMOS.NUMBERS.CURRENCY.LARGE_AMOUNTS",
"CMOS.NUMBERS.CURRENCY.NON_US.DISAMBIGUATE",
+ "CMOS.NUMBERS.CURRENCY.RANGES.REPEAT_SYMBOL",
+ "CMOS.NUMBERS.CURRENCY.SYMBOL_ADJACENT",
"CMOS.NUMBERS.CURRENCY.WORDS_VS_SYMBOLS",
"CMOS.NUMBERS.DATES.ABBREVIATED_YEAR",
"CMOS.NUMBERS.DATES.ALL_NUMERAL",
"CMOS.NUMBERS.DATES.CONSISTENT_FORMAT",
+ "CMOS.NUMBERS.DATES.DAY_MONTH_ORDER.CONSISTENT",
"CMOS.NUMBERS.DATES.ISO_8601",
"CMOS.NUMBERS.DATES.MONTH_DAY_STYLE",
+ "CMOS.NUMBERS.DATES.ORDINALS.AVOID",
"CMOS.NUMBERS.DATES.YEAR_NUMERALS",
"CMOS.NUMBERS.DECADES.CONSISTENT_FORM",
"CMOS.NUMBERS.DECIMALS.LEADING_ZERO",
"CMOS.NUMBERS.DECIMALS.NUMERALS",
+ "CMOS.NUMBERS.DECIMALS.TRAILING_ZEROS.AVOID",
"CMOS.NUMBERS.DECIMAL_MARKER.LOCALE",
"CMOS.NUMBERS.DEGRADED.HARD_WRAP_UNITS",
"CMOS.NUMBERS.DEGRADED.NUMERAL_NORMALIZATION",
"CMOS.NUMBERS.DENSE_CONTEXT.USE_NUMERALS",
"CMOS.NUMBERS.DIGIT_GROUPING.SI_SPACE",
"CMOS.NUMBERS.ERAS.BCE_CE",
+ "CMOS.NUMBERS.FRACTIONS.ADJECTIVAL.HYPHENATE",
"CMOS.NUMBERS.FRACTIONS.MATH.NUMERALS",
"CMOS.NUMBERS.FRACTIONS.MIXED.WHOLE_PLUS_FRACTION",
"CMOS.NUMBERS.FRACTIONS.SIMPLE.SPELL_OUT",
+ "CMOS.NUMBERS.FRACTIONS.SLASH_INLINE",
"CMOS.NUMBERS.GROUPING.THOUSANDS_SEPARATOR",
"CMOS.NUMBERS.INCLUSIVE.COMMAS",
+ "CMOS.NUMBERS.INCLUSIVE.SHORTEN_SECOND_NUMBER",
"CMOS.NUMBERS.INCLUSIVE.YEARS",
+ "CMOS.NUMBERS.INCLUSIVE.YEARS.CENTURY_CROSSING",
"CMOS.NUMBERS.INCLUSIVE_RANGES.PAGE_NUMBERS.SHORTEN",
"CMOS.NUMBERS.LARGE_VALUES.MILLIONS_BILLIONS",
"CMOS.NUMBERS.LISTS.OUTLINE.NUMERAL_STYLE",
"CMOS.NUMBERS.NAMES.MONARCHS_POPES",
"CMOS.NUMBERS.NUMERALS.MEASUREMENTS.UNITS",
+ "CMOS.NUMBERS.ORDINALS.CONSISTENT_FORM",
"CMOS.NUMBERS.ORDINALS.SUFFIX.CORRECT",
"CMOS.NUMBERS.PERCENTAGES.NUMERALS",
+ "CMOS.NUMBERS.PERCENTAGES.SYMBOL_NO_SPACE",
+ "CMOS.NUMBERS.PERCENTAGES.SYMBOL_OR_WORD.CONSISTENT",
"CMOS.NUMBERS.PERIODICALS.VOLUME_ISSUE",
"CMOS.NUMBERS.PLACES.BUILDINGS_APTS",
"CMOS.NUMBERS.PLACES.HIGHWAYS",
@@ -209,53 +1040,373 @@
"CMOS.NUMBERS.PLURALS.DECADE.NO_APOSTROPHE",
"CMOS.NUMBERS.PLURALS.SPELLED_OUT",
"CMOS.NUMBERS.RANGES.EN_DASH.USE",
+ "CMOS.NUMBERS.RANGES.NO_MIXED_FROM_BETWEEN",
+ "CMOS.NUMBERS.RANGES.REPEAT_UNIT_IF_AMBIG",
+ "CMOS.NUMBERS.RANGES.UNITS.PLACEMENT_CONSISTENT",
+ "CMOS.NUMBERS.RATIOS.COLON_SPACING",
"CMOS.NUMBERS.RATIOS.FORMAT",
"CMOS.NUMBERS.REFERENCES.PAGE_CHAPTER_FIGURE",
+ "CMOS.NUMBERS.ROMAN_NUMERALS.CASE_CONSISTENT",
"CMOS.NUMBERS.ROMAN_NUMERALS.USE",
"CMOS.NUMBERS.ROUND_NUMBERS.SPELL_OUT",
"CMOS.NUMBERS.RULE_SELECTION.ALTERNATIVE_ZERO_TO_NINE",
"CMOS.NUMBERS.RULE_SELECTION.GENERAL_OR_ALTERNATIVE",
+ "CMOS.NUMBERS.S9_1.GENERAL_WORKS_SCOPE",
+ "CMOS.NUMBERS.S9_1.OVERVIEW.FACTORS",
+ "CMOS.NUMBERS.S9_1.READABILITY_OVER_CONSISTENCY",
+ "CMOS.NUMBERS.S9_10.NEGATIVE_POWERS",
+ "CMOS.NUMBERS.S9_10.POWERS_OF_TEN",
+ "CMOS.NUMBERS.S9_10.SCIENTIFIC_NOTATION.USE",
+ "CMOS.NUMBERS.S9_10.SCI_NOTATION.CONSISTENT",
+ "CMOS.NUMBERS.S9_11.MYR_GYR",
+ "CMOS.NUMBERS.S9_11.PREFIX_SYMBOLS",
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.LARGE",
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.SMALL",
+ "CMOS.NUMBERS.S9_12.BASE_INDICATOR",
+ "CMOS.NUMBERS.S9_12.BASE_PREFIXES",
+ "CMOS.NUMBERS.S9_12.BASE_SUBSCRIPT",
+ "CMOS.NUMBERS.S9_12.BINARY_PREFIXES",
+ "CMOS.NUMBERS.S9_12.DECIMAL_PREFIXES",
+ "CMOS.NUMBERS.S9_12.NO_COMMAS.IN_BASE",
+ "CMOS.NUMBERS.S9_13.DEX.DEFINITION",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.COMMON_NUMERALS",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.CONSISTENCY",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.EXACT_VALUES",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.GENERAL_RULE",
+ "CMOS.NUMBERS.S9_15.DECIMAL_FRACTIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.EMPHASIS_EXCEPTION",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.HYPHENATE",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.FRACTION_SYMBOLS",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.MEASUREMENTS",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.NUMERALS",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.SHORT_SPELLED_OUT",
+ "CMOS.NUMBERS.S9_17.ALGEBRAIC.SLASH",
+ "CMOS.NUMBERS.S9_17.CASE_FRACTIONS.USE_WITH_CARE",
+ "CMOS.NUMBERS.S9_17.DISPLAYED_FRACTIONS.BAR",
+ "CMOS.NUMBERS.S9_17.EXPONENT_FRACTIONS.SLASH",
+ "CMOS.NUMBERS.S9_17.FRACTIONS.IN_NUMERATOR_DENOMINATOR",
+ "CMOS.NUMBERS.S9_17.FRACTIONS.PARENS_BEFORE_SYMBOLS",
+ "CMOS.NUMBERS.S9_17.FRACTIONS.RUNNING_TEXT.SLASH",
+ "CMOS.NUMBERS.S9_17.SLASH_BINDING",
+ "CMOS.NUMBERS.S9_18.ABBREVIATIONS.NUMERALS_ONLY",
+ "CMOS.NUMBERS.S9_18.NO_HYPHEN.NUMERAL_UNIT",
+ "CMOS.NUMBERS.S9_18.NO_SPACE.DEGREE_PERCENT_PRIME",
+ "CMOS.NUMBERS.S9_18.PRIME_SYMBOLS",
+ "CMOS.NUMBERS.S9_18.SCIENTIFIC_CONTEXT.NUMERALS",
+ "CMOS.NUMBERS.S9_18.SPACING.NUMERAL_UNIT",
+ "CMOS.NUMBERS.S9_18.UNIT_WITHOUT_NUMERAL.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_19.REPEAT_UNITS.CLOSED_UP",
+ "CMOS.NUMBERS.S9_19.UNIT_REPETITION.CONSISTENT",
+ "CMOS.NUMBERS.S9_19.UNIT_SPACED.SINGLE",
+ "CMOS.NUMBERS.S9_2.GENERAL_RULE.ZERO_TO_ONE_HUNDRED",
+ "CMOS.NUMBERS.S9_2.NONROUND.ABOVE_ONE_HUNDRED",
+ "CMOS.NUMBERS.S9_2.ROUND_MULTIPLES.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_20.PERCENT.LESS_FREQUENT",
+ "CMOS.NUMBERS.S9_20.PERCENT.NUMERALS",
+ "CMOS.NUMBERS.S9_20.PERCENT.WORD_VS_SYMBOL",
+ "CMOS.NUMBERS.S9_20.PERCENT_RANGES.REPEAT",
+ "CMOS.NUMBERS.S9_20.PERCENT_VS_PERCENTAGE",
+ "CMOS.NUMBERS.S9_21.DECIMALS.NUMERALS",
+ "CMOS.NUMBERS.S9_21.DECIMAL_CONTEXT.CONSISTENT",
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.CALIBERS",
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.CONTEXT",
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.OMIT_PROBABILITIES",
+ "CMOS.NUMBERS.S9_21.UNITS.LESS_THAN_ONE",
+ "CMOS.NUMBERS.S9_22.MONEY.DECIMALS.ONLY_WHEN_MIXED",
+ "CMOS.NUMBERS.S9_22.MONEY.MINIMUM_DECIMALS",
+ "CMOS.NUMBERS.S9_22.MONEY.NUMERALS_EXACT",
+ "CMOS.NUMBERS.S9_22.MONEY.SINGULAR_VERB",
+ "CMOS.NUMBERS.S9_22.MONEY.SPELL_OUT_SMALL",
+ "CMOS.NUMBERS.S9_22.MONEY.SYMBOL_OR_WORD",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.CONTEXT_CLEAR",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.DISAMBIGUATE",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.ISO_CODES",
+ "CMOS.NUMBERS.S9_24.BRITISH.DECIMAL_FORMAT",
+ "CMOS.NUMBERS.S9_24.BRITISH.PENCE_SYMBOL",
+ "CMOS.NUMBERS.S9_24.BRITISH.POUND_SYMBOL",
+ "CMOS.NUMBERS.S9_25.CURRENCY_CODES.CONSISTENT",
+ "CMOS.NUMBERS.S9_25.CURRENCY_CODES.SPACING",
+ "CMOS.NUMBERS.S9_25.ISO_CODES.FORMAL",
+ "CMOS.NUMBERS.S9_25.OTHER_CURRENCIES.DECIMAL",
+ "CMOS.NUMBERS.S9_26.K_THOUSANDS",
+ "CMOS.NUMBERS.S9_26.LARGE_MONEY.MIXED",
+ "CMOS.NUMBERS.S9_26.LARGE_MONEY.NUMERALS",
+ "CMOS.NUMBERS.S9_26.MONEY.COMMAS",
+ "CMOS.NUMBERS.S9_27.CURRENCY_YEAR.CODES_SPACING",
+ "CMOS.NUMBERS.S9_27.CURRENCY_YEAR.PARENS_NO_SPACE",
+ "CMOS.NUMBERS.S9_28.BIBLICAL_REFERENCES",
+ "CMOS.NUMBERS.S9_28.DIVISIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_28.FRONT_MATTER.ROMAN",
+ "CMOS.NUMBERS.S9_29.PERIODICALS.OMIT_WORDS",
+ "CMOS.NUMBERS.S9_29.PERIODICALS.ORDER",
+ "CMOS.NUMBERS.S9_3.ALTERNATIVE_ROUND_MULTIPLES",
+ "CMOS.NUMBERS.S9_3.ALTERNATIVE_RULE.ZERO_TO_NINE",
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.MIXED_LEVELS",
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.PREFER_ARABIC",
+ "CMOS.NUMBERS.S9_31.YEAR_SENTENCE_START_ALLOWED",
+ "CMOS.NUMBERS.S9_31.YEAR_STANDALONE",
+ "CMOS.NUMBERS.S9_32.ABBREVIATED_YEAR.APOSTROPHE",
+ "CMOS.NUMBERS.S9_33.DAY_WITHOUT_MONTH.ORDINAL",
+ "CMOS.NUMBERS.S9_33.MONTH_DAY.CARDINALS",
+ "CMOS.NUMBERS.S9_33.MONTH_DAY_YEAR.COMMA",
+ "CMOS.NUMBERS.S9_34.CENTURIES.NUMERAL_PLURALS",
+ "CMOS.NUMBERS.S9_34.CENTURIES.ORDINAL_LOWERCASE",
+ "CMOS.NUMBERS.S9_34.CENTURY_TURN.AVOID_AMBIGUITY",
+ "CMOS.NUMBERS.S9_35.DECADES.FIRST_DECADE",
+ "CMOS.NUMBERS.S9_35.DECADES.NO_APOSTROPHE",
+ "CMOS.NUMBERS.S9_35.DECADES.SECOND_DECADE",
+ "CMOS.NUMBERS.S9_36.ERAS.ABBREVIATION_PLACEMENT",
+ "CMOS.NUMBERS.S9_36.ERAS.CENTURY_PLACEMENT",
+ "CMOS.NUMBERS.S9_36.ERAS.NO_PERIODS",
+ "CMOS.NUMBERS.S9_4.APPROXIMATIONS.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_4.HUNDREDS_THOUSANDS.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_4.MIXED_LARGE_CONTEXTS",
+ "CMOS.NUMBERS.S9_4.NONROUND.LARGE_NUMERALS",
+ "CMOS.NUMBERS.S9_5.ALPHANUMERIC.MAY_BEGIN",
+ "CMOS.NUMBERS.S9_5.SENTENCE_INITIAL.RECAST",
+ "CMOS.NUMBERS.S9_5.SENTENCE_INITIAL.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_5.TWO_NUMBERS.SAME_CATEGORY",
+ "CMOS.NUMBERS.S9_5.YEARS.MAY_BEGIN",
+ "CMOS.NUMBERS.S9_6.NTH_DEGREE.ITALIC_N",
+ "CMOS.NUMBERS.S9_6.ORDINALS.RULE_PARALLEL",
+ "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.ND_RD",
+ "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.NO_SUPERSCRIPT",
+ "CMOS.NUMBERS.S9_6.ZERO.ORDINAL_TH",
+ "CMOS.NUMBERS.S9_7.AVOID_DENSE_WORDS",
+ "CMOS.NUMBERS.S9_7.CATEGORY_TRIGGER",
+ "CMOS.NUMBERS.S9_7.CONSISTENT_CONTEXT",
+ "CMOS.NUMBERS.S9_7.CROSS_CATEGORY.MIX_OK",
+ "CMOS.NUMBERS.S9_7.DOCUMENT_EXCEPTIONS",
+ "CMOS.NUMBERS.S9_7.SENTENCE_START_EXCEPTION",
+ "CMOS.NUMBERS.S9_8.ABBREVIATED_UNITS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.CLOTHING_SIZES.NUMERALS",
+ "CMOS.NUMBERS.S9_8.DATES.NUMERALS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.ACT_SCENE",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.BOXES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.CHAPTERS_PARTS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.EXAMPLES_QUESTIONS_RULES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.FIGURES_TABLES_EQUATIONS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.NOTES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.PAGES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.SECTIONS_PARAS_LINES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.VOLUMES_ISSUES",
+ "CMOS.NUMBERS.S9_8.GRADES_LEVELS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.PERCENT.NUMERALS",
+ "CMOS.NUMBERS.S9_8.PLACES.STREETS_ROOMS",
+ "CMOS.NUMBERS.S9_8.SCORES_VOTES.NUMERALS",
+ "CMOS.NUMBERS.S9_8.SEVERITY_CLASSIFICATIONS",
+ "CMOS.NUMBERS.S9_8.SYMBOLS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.TITLE_NUMBERS",
+ "CMOS.NUMBERS.S9_9.BILLION_TRILLION.LOCALE_CHECK",
+ "CMOS.NUMBERS.S9_9.CONSISTENCY.WITH_FRACTIONS",
+ "CMOS.NUMBERS.S9_9.MILLIONS_BILLIONS.GENERAL_RULE",
+ "CMOS.NUMBERS.S9_9.MIXED_NUMERAL_WORD.FRACTIONS",
+ "CMOS.NUMBERS.SCIENTIFIC.NOTATION.MANTISSA_RANGE",
+ "CMOS.NUMBERS.SCIENTIFIC.NOTATION.TIMES_SYMBOL",
"CMOS.NUMBERS.SCIENTIFIC.POWERS_OF_TEN",
"CMOS.NUMBERS.SENTENCE_START.AVOID_NUMERAL",
"CMOS.NUMBERS.SI_PREFIXES.NO_HYPHEN",
"CMOS.NUMBERS.SPELLING.ONE_TO_ONE_HUNDRED.DEFAULT",
+ "CMOS.NUMBERS.TELEPHONE.COUNTRY_CODE.WHEN_INTERNATIONAL",
"CMOS.NUMBERS.TELEPHONE.FORMAT",
+ "CMOS.NUMBERS.TELEPHONE.SEPARATORS.CONSISTENT",
+ "CMOS.NUMBERS.TIME.AM_PM.CONSISTENT_SPACING",
"CMOS.NUMBERS.TIME.GENERAL_NUMERALS",
"CMOS.NUMBERS.TIME.ISO_STYLE",
+ "CMOS.NUMBERS.TIME.LEADING_ZERO_MINUTES",
"CMOS.NUMBERS.TIME.NOON_MIDNIGHT",
+ "CMOS.NUMBERS.TIME.RANGES.CONSISTENT_FORMAT",
+ "CMOS.NUMBERS.TIME.SECONDS.INCLUDE_FOR_PRECISION",
+ "CMOS.NUMBERS.TIME.SECONDS.OMIT_IF_NOT_NEEDED",
"CMOS.NUMBERS.TIME.TWENTY_FOUR_HOUR",
+ "CMOS.NUMBERS.TIME.ZONE.INCLUDE_WHEN_AMBIGUOUS",
"CMOS.NUMBERS.UNITS.REPEATED.OMIT_REPEAT",
+ "CMOS.NUMBERS.UNITS.SPACE_BETWEEN_NUMBER_UNIT",
"CMOS.NUMBERS.VEHICLES.VESSELS_NUMBERS"
],
"punctuation": [
+ "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.ELECTRONIC_PREFERS_LOGICAL",
+ "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.PRINT_ONLY",
+ "CMOS.PUNCTUATION.APOSTROPHE.SMART",
+ "CMOS.PUNCTUATION.APOSTROPHE.USE_CASES",
"CMOS.PUNCTUATION.BLOCK_QUOTES.NO_QUOTE_MARKS",
+ "CMOS.PUNCTUATION.BOLD_COLOR.CASE_BY_CASE",
+ "CMOS.PUNCTUATION.BOLD_COLOR.SEMANTIC_OWNERSHIP",
+ "CMOS.PUNCTUATION.BRACKETS.EDITORIAL_INSERTIONS",
"CMOS.PUNCTUATION.BRACKETS.NESTED_PARENS",
"CMOS.PUNCTUATION.BRACKETS.TRANSLATED_TEXT",
+ "CMOS.PUNCTUATION.COLONS.AMPLIFY_OR_ILLUSTRATE",
"CMOS.PUNCTUATION.COLONS.AS_FOLLOWS",
+ "CMOS.PUNCTUATION.COLONS.AVOID_AFTER_PREPOSITION",
+ "CMOS.PUNCTUATION.COLONS.AVOID_INCOMPLETE_LEADIN",
"CMOS.PUNCTUATION.COLONS.CAPITALIZATION",
+ "CMOS.PUNCTUATION.COLONS.COMPLETE_CLAUSE_REQUIRED",
+ "CMOS.PUNCTUATION.COLONS.EMPHASIS_SECOND_CLAUSE",
+ "CMOS.PUNCTUATION.COLONS.FORMAL_GREETINGS",
+ "CMOS.PUNCTUATION.COLONS.INTRODUCE_FORMAL_LISTS",
"CMOS.PUNCTUATION.COLONS.INTRO_QUOTE_QUESTION",
+ "CMOS.PUNCTUATION.COLONS.ONE_SPACE",
+ "CMOS.PUNCTUATION.COLONS.QUOTATIONS",
"CMOS.PUNCTUATION.COLONS.SPACE_AFTER",
"CMOS.PUNCTUATION.COMMAS.ADDRESSES",
+ "CMOS.PUNCTUATION.COMMAS.ADDRESSES.MAILING_SPARING",
+ "CMOS.PUNCTUATION.COMMAS.ADDRESSES.RUN_IN",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL.INTRO_OPTIONAL",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL.MID_END",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_END",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_INTRO_OPTIONAL",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_INVERTED",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_MID",
+ "CMOS.PUNCTUATION.COMMAS.AMPERSAND.NO_SERIAL",
+ "CMOS.PUNCTUATION.COMMAS.AND_THEN",
"CMOS.PUNCTUATION.COMMAS.APPOSITIVES",
+ "CMOS.PUNCTUATION.COMMAS.APPOSITIVES.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.BRACKETS.EDITORIAL",
+ "CMOS.PUNCTUATION.COMMAS.BRACKETS.EDITORIAL_INSERT",
+ "CMOS.PUNCTUATION.COMMAS.COMMA_SPLICE.AVOID_FORMAL",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.CLARITY",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.NO_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.SERIES",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.THEN_SHORTHAND",
"CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATES",
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTION_PLUS_PHRASE.INDEPENDENT",
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTION_PLUS_PHRASE.PREDICATE",
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTIVE_ADVERBS",
+ "CMOS.PUNCTUATION.COMMAS.CONSECUTIVE_CONJUNCTIONS",
+ "CMOS.PUNCTUATION.COMMAS.CONSECUTIVE_CONJUNCTIONS.NO_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.COORDINATE_ADJECTIVES",
+ "CMOS.PUNCTUATION.COMMAS.CORPORATE_SUFFIX",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE.INDEPENDENT_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE.PREDICATE",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE_PHRASES",
"CMOS.PUNCTUATION.COMMAS.DATES",
+ "CMOS.PUNCTUATION.COMMAS.DATES.ALTERNATE_SYSTEMS",
+ "CMOS.PUNCTUATION.COMMAS.DATES.MONTH_DAY_YEAR",
+ "CMOS.PUNCTUATION.COMMAS.DATES.NO_COMMA_OTHER_STYLES",
"CMOS.PUNCTUATION.COMMAS.DEPENDENT_CLAUSE_AFTER",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING.RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING_NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING_RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_INTRO",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_INTRODUCTORY",
+ "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASE",
"CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASES",
+ "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASES.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS",
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS.GREETINGS",
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_QUESTIONS",
+ "CMOS.PUNCTUATION.COMMAS.ELISION",
+ "CMOS.PUNCTUATION.COMMAS.ETC.FINAL_ELEMENT",
+ "CMOS.PUNCTUATION.COMMAS.ETC.FORMAL_LIMIT",
+ "CMOS.PUNCTUATION.COMMAS.ETC.TRAILING",
+ "CMOS.PUNCTUATION.COMMAS.ETC_ETAL.STYLE",
+ "CMOS.PUNCTUATION.COMMAS.ETC_SINGLE_ITEM",
+ "CMOS.PUNCTUATION.COMMAS.EXPLANATORY_ALTERNATIVES",
+ "CMOS.PUNCTUATION.COMMAS.HOMONYMS.CLARITY",
+ "CMOS.PUNCTUATION.COMMAS.IE_EG.PARENS",
+ "CMOS.PUNCTUATION.COMMAS.IMPERATIVE_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.IMPERATIVE_CLAUSES.DEFAULT",
+ "CMOS.PUNCTUATION.COMMAS.INC_LTD.NONE",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.CONJUNCTION",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.SHORT",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.SHORT_OMIT",
+ "CMOS.PUNCTUATION.COMMAS.INDIRECT_QUESTIONS",
"CMOS.PUNCTUATION.COMMAS.INTRODUCTORY_ELEMENTS.CLARITY",
"CMOS.PUNCTUATION.COMMAS.INTRODUCTORY_PHRASES",
+ "CMOS.PUNCTUATION.COMMAS.INTRO_OH_AH",
+ "CMOS.PUNCTUATION.COMMAS.INTRO_PHRASES.GENERAL",
+ "CMOS.PUNCTUATION.COMMAS.INTRO_YES_NO",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.INVERTED",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.NONE",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.RUNNING",
+ "CMOS.PUNCTUATION.COMMAS.LOGIC_OVER_PAUSE",
"CMOS.PUNCTUATION.COMMAS.NONRESTRICTIVE.SET_OFF",
+ "CMOS.PUNCTUATION.COMMAS.NOT_PHRASE",
+ "CMOS.PUNCTUATION.COMMAS.NOT_PHRASES",
+ "CMOS.PUNCTUATION.COMMAS.PAIRS.SECOND_REQUIRED",
+ "CMOS.PUNCTUATION.COMMAS.PAIRS.TITLES_EXCEPTION",
+ "CMOS.PUNCTUATION.COMMAS.PARENS.TRAILING",
+ "CMOS.PUNCTUATION.COMMAS.PARENS_BRACKETS.AFTER_CLOSING",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICALS.SLIGHT_BREAK",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_ELEMENTS",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_HEAVY",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL.LINKING_VERB",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_INTRO",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_LINKING_VERB",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_MID_END",
"CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_PHRASES",
+ "CMOS.PUNCTUATION.COMMAS.PHRASE_PLUS_CONJUNCTION",
"CMOS.PUNCTUATION.COMMAS.QUESTIONS",
+ "CMOS.PUNCTUATION.COMMAS.QUESTIONS.DIRECT_IN_SENTENCE",
+ "CMOS.PUNCTUATION.COMMAS.QUESTIONS.INDIRECT",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.DIALOGUE",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.DIALOGUE_VERB_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.NO_COMMA_CONJUNCTION",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.THAT_WHETHER",
"CMOS.PUNCTUATION.COMMAS.QUOTED_TITLES",
+ "CMOS.PUNCTUATION.COMMAS.QUOTE_ENDING_QM_EXCL",
+ "CMOS.PUNCTUATION.COMMAS.REGISTER.FLEX",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIPS.AVOID_POSSESSIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIPS.UNIQUE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_ALWAYS_USE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_AWKWARD_POSSESSIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_NAMES",
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_THAT_WHICH",
"CMOS.PUNCTUATION.COMMAS.REPEATED_ADJECTIVES",
+ "CMOS.PUNCTUATION.COMMAS.REPEATED_ADJECTIVES.USE_COMMA",
"CMOS.PUNCTUATION.COMMAS.RESTRICTIVE.NO_SET_OFF",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.ALL_CONJUNCTIONS",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.ALL_CONJUNCTIONS_NO_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.AMBIGUITY_REWORD",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.AS_WELL_AS",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.PAIR_LAST_ITEM",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.PAIR_WITH_AND",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.REQUIRED",
"CMOS.PUNCTUATION.COMMAS.SERIAL_COMMA.DEFAULT",
+ "CMOS.PUNCTUATION.COMMAS.SPLICES.AVOID_FORMAL",
+ "CMOS.PUNCTUATION.COMMAS.SPLICES.EDITORIAL_DISCRETION",
+ "CMOS.PUNCTUATION.COMMAS.SUCH_AS_INCLUDING",
+ "CMOS.PUNCTUATION.COMMAS.THAT_IS.TRAILING_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.THAT_IS_NAMELY",
+ "CMOS.PUNCTUATION.COMMAS.THE_MORE_THE_MORE",
+ "CMOS.PUNCTUATION.COMMAS.TITLES.APPOSITIVE_RULE",
+ "CMOS.PUNCTUATION.COMMAS.TITLES_AND_EXPRESSIONS",
+ "CMOS.PUNCTUATION.COMMAS.TOO_EITHER.OMIT",
+ "CMOS.PUNCTUATION.COMMAS.TOO_MID_SENTENCE",
+ "CMOS.PUNCTUATION.DASHES.DISTINCT_TYPES",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.ALTERNATIVE_TO_PARENS",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.AVOID_NESTED",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.DIALOGUE_STYLE",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.LINE_BREAKS_DETAIL",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.LISTS_TABLES",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.PUNCTUATION_BEFORE",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.SPARE_USE",
"CMOS.PUNCTUATION.DASHES.EM_DASH.USE_WITHOUT_SPACES_US",
"CMOS.PUNCTUATION.DASHES.EM_INSTEAD_OF_QUOTES",
"CMOS.PUNCTUATION.DASHES.EM_LINE_BREAKS",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.AVOID_FROM_BETWEEN",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.LINE_BREAKS",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.MINUS_SIGN",
"CMOS.PUNCTUATION.DASHES.EN_DASH.RANGES",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.SPACED_BRITISH",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.WORD_RANGES",
+ "CMOS.PUNCTUATION.DASHES.TWO_EM.OMISSIONS",
"CMOS.PUNCTUATION.DEGRADED.EXTRA_SPACES.AFTER_PUNCT",
"CMOS.PUNCTUATION.ELLIPSIS.FORMAT.CONSISTENT",
+ "CMOS.PUNCTUATION.ELLIPSIS.USE_CASES",
+ "CMOS.PUNCTUATION.EMOJIS.PUNCTUATION",
+ "CMOS.PUNCTUATION.EXCLAMATION.BRACKETED_AVOID",
+ "CMOS.PUNCTUATION.EXCLAMATION.QUOTE_PLACEMENT",
+ "CMOS.PUNCTUATION.EXCLAMATION.RHETORICAL",
+ "CMOS.PUNCTUATION.EXCLAMATION.USE_SPARING",
"CMOS.PUNCTUATION.EXCLAMATION.USE_SPARINGLY",
"CMOS.PUNCTUATION.EXCLAMATION.VS_QUESTION",
"CMOS.PUNCTUATION.HYPHENATION.COMPOUND_DEFINITION",
@@ -265,24 +1416,95 @@
"CMOS.PUNCTUATION.HYPHENATION.TREND_CLOSED",
"CMOS.PUNCTUATION.HYPHENS.ADVERB_LY.NO_HYPHEN",
"CMOS.PUNCTUATION.HYPHENS.COMPOUND_MODIFIERS.BEFORE_NOUN",
+ "CMOS.PUNCTUATION.HYPHENS.NUMERIC_COMPOUNDS",
+ "CMOS.PUNCTUATION.HYPHENS.SEPARATORS",
+ "CMOS.PUNCTUATION.ITALICS.SURROUNDING_STYLE",
+ "CMOS.PUNCTUATION.ITALICS.TITLE_OWNERSHIP",
+ "CMOS.PUNCTUATION.LISTS.AVOID_VERTICAL_FOR_LONG_SENTENCES",
+ "CMOS.PUNCTUATION.LISTS.CONSISTENT_FORMAT",
+ "CMOS.PUNCTUATION.LISTS.MIXED_SENTENCE_TYPES",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.MULTI_DIGIT_ALIGN",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.OUTLINE_MARKERS",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.PUNCTUATION_LEVELS",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.RUNOVER_ALIGN",
+ "CMOS.PUNCTUATION.LISTS.NUMERALS_ONLY_IF_NEEDED",
+ "CMOS.PUNCTUATION.LISTS.PARALLEL_ELEMENTS",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.INTRO_COMPLETE_COLON",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.LETTERS.ITALIC_OPTION",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.MARKERS.PARENS",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SENTENCE_ITEMS_VERTICAL",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SEPARATORS",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SHORT_SIMPLE",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.CAPITALIZATION_CONSISTENT",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.END_PUNCT_SENTENCES",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.INTRO_COLON",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.LONG_OR_MULTI",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.MULTI_COLUMN_SHORT_ITEMS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.ORDERED_MARKERS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.RUNOVER_ALIGN",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_CONJUNCTION",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_LOWERCASE",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_PUNCTUATION",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_USE_ONLY_FOR_EMPHASIS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.UNORDERED_FRAGMENTS",
"CMOS.PUNCTUATION.MULTIPLE_MARKS.AVOID_STACKING",
+ "CMOS.PUNCTUATION.OVERVIEW.CONSISTENT.PRINCIPLES",
+ "CMOS.PUNCTUATION.OVERVIEW.CONTEXT.REGISTER",
+ "CMOS.PUNCTUATION.OVERVIEW.FUNCTION.CLARITY",
+ "CMOS.PUNCTUATION.PARENS.AVOID_MULTIPLE_SENTENCES",
"CMOS.PUNCTUATION.PARENS.GLOSSES_TRANSLATIONS",
"CMOS.PUNCTUATION.PARENS.NESTING",
+ "CMOS.PUNCTUATION.PARENS.PUNCTUATION_PLACEMENT",
"CMOS.PUNCTUATION.PARENS.USE",
"CMOS.PUNCTUATION.PARENS_BRACKETS.BALANCE",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.LINE_ALONE",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.MATCH_SURROUNDING",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.PRINT_HAIR_SPACE",
+ "CMOS.PUNCTUATION.PERIODS.NOT_WITH_QM_EXCL",
+ "CMOS.PUNCTUATION.PERIODS.NO_DOUBLE_AT_SENTENCE_END",
+ "CMOS.PUNCTUATION.PERIODS.OMIT_DISPLAY_LINES",
"CMOS.PUNCTUATION.PERIODS.USE",
"CMOS.PUNCTUATION.PERIODS.WITH_PARENS",
+ "CMOS.PUNCTUATION.QUESTION_EXCLAMATION.DUAL_MARKS",
"CMOS.PUNCTUATION.QUESTION_MARK.DIRECT_VS_INDIRECT",
"CMOS.PUNCTUATION.QUESTION_MARK.USE",
"CMOS.PUNCTUATION.QUESTION_MARK.WITH_PUNCT",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.DIRECT",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.DIRECT_INDIRECT",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.LIST_INTRO",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.QUOTE_PLACEMENT",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.SURROUNDING",
"CMOS.PUNCTUATION.QUOTATION_MARKS.DOUBLE_PRIMARY_US",
"CMOS.PUNCTUATION.QUOTATION_MARKS.PUNCTUATION_PLACEMENT_US",
+ "CMOS.PUNCTUATION.QUOTES.ALT_STYLE.DOCUMENT",
+ "CMOS.PUNCTUATION.QUOTES.APOSTROPHE_NOT_QUOTE",
+ "CMOS.PUNCTUATION.QUOTES.ITALIC_TITLE_EXCEPTION",
+ "CMOS.PUNCTUATION.QUOTES.LINE_ALONE",
+ "CMOS.PUNCTUATION.QUOTES.MATCH_SURROUNDING",
"CMOS.PUNCTUATION.QUOTES.SMART_QUOTES",
+ "CMOS.PUNCTUATION.QUOTES.US_STYLE_PERIODS_COMMAS",
+ "CMOS.PUNCTUATION.SEMICOLONS.AVOID_COMMA_SPLICE",
+ "CMOS.PUNCTUATION.SEMICOLONS.AVOID_DIALOGUE",
"CMOS.PUNCTUATION.SEMICOLONS.BEFORE_CONJUNCTION",
+ "CMOS.PUNCTUATION.SEMICOLONS.COMPLEX_SERIES",
"CMOS.PUNCTUATION.SEMICOLONS.COMPLEX_SERIES.SEPARATE",
+ "CMOS.PUNCTUATION.SEMICOLONS.CONJUNCTIVE_ADVERBS",
"CMOS.PUNCTUATION.SEMICOLONS.CONJUNCTIVE_PHRASES",
+ "CMOS.PUNCTUATION.SEMICOLONS.INDEPENDENT_CLAUSES",
+ "CMOS.PUNCTUATION.SEMICOLONS.THAT_IS_CLAUSE",
"CMOS.PUNCTUATION.SLASHES.ALTERNATIVES",
- "CMOS.PUNCTUATION.SLASHES.TWO_YEAR_SPANS"
+ "CMOS.PUNCTUATION.SLASHES.NO_SPACES",
+ "CMOS.PUNCTUATION.SLASHES.TWO_YEAR_SPANS",
+ "CMOS.PUNCTUATION.SPACING.DESIGN_SPECIFIED",
+ "CMOS.PUNCTUATION.SPACING.FIXED_WIDTHS",
+ "CMOS.PUNCTUATION.SPACING.NONBREAKING",
+ "CMOS.PUNCTUATION.SPACING.ONE_SPACE_AFTER_COLON",
+ "CMOS.PUNCTUATION.SPACING.ONE_SPACE_SENTENCES",
+ "CMOS.PUNCTUATION.SPACING.WORD_SPACE_DEFAULT",
+ "CMOS.PUNCTUATION.URLS.HYPERTEXT_EXCLUDES_PUNCTUATION",
+ "CMOS.PUNCTUATION.URLS.NO_WRAPPERS",
+ "CMOS.PUNCTUATION.URLS.PUNCTUATE_NORMALLY",
+ "CMOS.PUNCTUATION.URLS.TRAILING_PUNCTUATION"
],
"tables": [
"BRING.TABLES.CAPTIONS.CLEAR",
@@ -305,25 +1527,165 @@
"BRING.TABLES.TITLES.CONSISTENT_PLACEMENT",
"BRING.TABLES.TYPE_SIZE.READABLE",
"BRING.TABLES.UNITS.IN_HEADERS",
+ "CMOS.TABLES.ABBREVIATIONS.EXPLAIN",
+ "CMOS.TABLES.ALIGNMENT.NUMERIC_DECIMAL",
+ "CMOS.TABLES.ALIGNMENT.TEXT_LEFT",
+ "CMOS.TABLES.CAPTIONS.BREVITY",
+ "CMOS.TABLES.CAPTIONS.CLARITY",
+ "CMOS.TABLES.CAPTIONS.PRESENT",
+ "CMOS.TABLES.COLUMN_ORDER.LOGICAL",
+ "CMOS.TABLES.COLUMN_SPACING.READABLE",
+ "CMOS.TABLES.DATA_TYPES.NOT_MIXED",
+ "CMOS.TABLES.FOOTNOTES.PLACEMENT",
+ "CMOS.TABLES.GRIDLINES.LIGHT",
+ "CMOS.TABLES.GROUPING.WHITESPACE",
+ "CMOS.TABLES.HEADERS.ALIGNMENT.CONSISTENT",
+ "CMOS.TABLES.HEADERS.CAPITALIZATION.CONSISTENT",
+ "CMOS.TABLES.HEADERS.REQUIRED",
+ "CMOS.TABLES.MISSING_VALUES.EXPLAIN",
+ "CMOS.TABLES.NOTES.ORDERED_MARKERS",
+ "CMOS.TABLES.PRECISION.CONSISTENT",
+ "CMOS.TABLES.REFERENCES.IN_TEXT",
+ "CMOS.TABLES.ROTATION.LANDSCAPE.WHEN_NEEDED",
+ "CMOS.TABLES.ROUNDING.CONSISTENT",
+ "CMOS.TABLES.ROW_ORDER.LOGICAL",
+ "CMOS.TABLES.ROW_SPACING.READABLE",
+ "CMOS.TABLES.RULES.MINIMAL",
+ "CMOS.TABLES.SHADING.SPARING",
+ "CMOS.TABLES.SORTING.LOGICAL",
+ "CMOS.TABLES.SOURCE.NOTES.DISTINCT",
+ "CMOS.TABLES.SPLITS.AVOID_ROW_BREAKS",
+ "CMOS.TABLES.SPLITS.REPEAT_HEADERS",
+ "CMOS.TABLES.STUB_COLUMN.USE",
+ "CMOS.TABLES.SUBTOTALS.CLEAR",
+ "CMOS.TABLES.TITLES.NUMBERING.SEQUENTIAL",
+ "CMOS.TABLES.TITLES.PLACEMENT.CONSISTENT",
+ "CMOS.TABLES.TITLES.SCOPE.CONSISTENT",
+ "CMOS.TABLES.UNITS.CONSISTENT",
+ "CMOS.TABLES.UNITS.IN_HEADERS",
+ "CMOS.TABLES.WIDTH.FIT_PAGE",
"HOUSE.TABLES.ALIGNMENT.DECIMALS",
+ "HOUSE.TABLES.COLUMN_WIDTHS.BALANCED",
"HOUSE.TABLES.HEADERS.REPEAT_ON_PAGEBREAK",
- "HOUSE.TABLES.OVERFLOW.NO_CLIPPING"
+ "HOUSE.TABLES.MISSING_DATA.CONSISTENT_MARK",
+ "HOUSE.TABLES.NUMERIC.ALIGN_DECIMALS",
+ "HOUSE.TABLES.NUMERIC.PRECISION.CONSISTENT",
+ "HOUSE.TABLES.OVERFLOW.NO_CLIPPING",
+ "HOUSE.TABLES.SOURCE.NOTES",
+ "HOUSE.TABLES.UNITS.IN_HEADERS"
],
"typography": [
"BRING.TYPOGRAPHY.ALIGNMENT.DONT_STRETCH_SPACE",
+ "BRING.TYPOGRAPHY.BOLD.AVOID_LONG_PASSAGES",
+ "BRING.TYPOGRAPHY.BOLD.HEADING_HIERARCHY_BALANCE",
+ "BRING.TYPOGRAPHY.BOLD.LABELS_SHORT",
+ "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ALL_CAPS",
+ "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ITALICS_LONG",
+ "BRING.TYPOGRAPHY.BOLD.SPARING_USE",
+ "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_AVOID_LONG_RUNS",
+ "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_SHORT_LABELS_ONLY",
+ "BRING.TYPOGRAPHY.CAPS.AVOID_FOR_EMPHASIS",
+ "BRING.TYPOGRAPHY.CAPS.MIXED_CAPS_CONSISTENT",
+ "BRING.TYPOGRAPHY.CAPS.ROMAN_NUMERALS_SPACING",
+ "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_FOR_ACRONYMS",
+ "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_NOT_FOR_LONG_PASSAGES",
+ "BRING.TYPOGRAPHY.CAPS.TRACKING_REVIEW",
+ "BRING.TYPOGRAPHY.CONTRAST.AVOID_EXTREME_MIX",
+ "BRING.TYPOGRAPHY.CONTRAST.FONT_PAIRING_MATCH",
+ "BRING.TYPOGRAPHY.FAMILY.AVOID_FAUX_BOLD",
+ "BRING.TYPOGRAPHY.FAMILY.BOLD_FOR_STRONG_EMPHASIS",
+ "BRING.TYPOGRAPHY.FAMILY.ITALIC_FOR_SUBTLE_EMPHASIS",
+ "BRING.TYPOGRAPHY.FAMILY.ITALIC_PUNCTUATION_MATCH",
+ "BRING.TYPOGRAPHY.FAMILY.LIMIT_STYLE_VARIANTS",
+ "BRING.TYPOGRAPHY.FAMILY.METRICS_MATCH_WHEN_MIXING",
+ "BRING.TYPOGRAPHY.FAMILY.SINGLE_FAMILY_BODY",
+ "BRING.TYPOGRAPHY.FAMILY.SMALL_CAPS_SPARE",
+ "BRING.TYPOGRAPHY.FAMILY.TRUE_ITALICS",
+ "BRING.TYPOGRAPHY.FAMILY.TRUE_SMALL_CAPS",
+ "BRING.TYPOGRAPHY.FAMILY.USE_DESIGNED_WEIGHTS",
+ "BRING.TYPOGRAPHY.FAMILY.WEIGHT_CONTRAST_CLEAR",
"BRING.TYPOGRAPHY.HYPHENATION.AVOID_AFTER_SHORT_LINE",
"BRING.TYPOGRAPHY.HYPHENATION.AVOID_PROPER_NAMES",
"BRING.TYPOGRAPHY.HYPHENATION.HARD_SPACES.SHORT_EXPRESSIONS",
"BRING.TYPOGRAPHY.HYPHENATION.LANGUAGE_DICTIONARY.MATCH",
"BRING.TYPOGRAPHY.HYPHENATION.MAX_CONSECUTIVE_LINES",
"BRING.TYPOGRAPHY.HYPHENATION.MIN_LEFT_RIGHT",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_IN_ALL_CAPS_HEADINGS",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_NUMERAL_ITALICS",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_STACKED_EMPHASIS",
+ "BRING.TYPOGRAPHY.ITALICS.CONSISTENT_TITLE_TREATMENT",
+ "BRING.TYPOGRAPHY.ITALICS.EMPHASIS_NOT_UNDERLINE",
+ "BRING.TYPOGRAPHY.ITALICS.HEADINGS_AVOID",
+ "BRING.TYPOGRAPHY.ITALICS.LONG_SPANS_AVOID",
+ "BRING.TYPOGRAPHY.ITALICS.PUNCTUATION_FOLLOWS_STYLE",
+ "BRING.TYPOGRAPHY.ITALICS.RUNNING_HEADS_AVOID",
+ "BRING.TYPOGRAPHY.ITALICS.SPARING",
+ "BRING.TYPOGRAPHY.ITALICS.TERMS_INTRODUCED_SPARE",
+ "BRING.TYPOGRAPHY.ITALICS.TITLES_STANDALONE_WORKS",
"BRING.TYPOGRAPHY.KERNING.CONSISTENT_OR_NONE",
"BRING.TYPOGRAPHY.LETTERFORMS.AVOID_DISTORTION",
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ACRONYMS",
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ALL_CAPS",
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_CODE_URLS",
+ "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_IN_DISPLAY",
+ "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_SPARING",
+ "BRING.TYPOGRAPHY.LIGATURES.DO_NOT_USE_IF_AMBIGUOUS",
+ "BRING.TYPOGRAPHY.LIGATURES.FI_FL_COLLISIONS",
+ "BRING.TYPOGRAPHY.LIGATURES.KEEP_CONSISTENT",
+ "BRING.TYPOGRAPHY.LIGATURES.REVIEW_FOR_LANGUAGE",
+ "BRING.TYPOGRAPHY.LIGATURES.STANDARD_ON_BODY",
"BRING.TYPOGRAPHY.NUMBER_STRINGS.SPACE_FOR_READABILITY",
+ "BRING.TYPOGRAPHY.NUMERALS.AVOID_LINING_IN_LOWERCASE",
+ "BRING.TYPOGRAPHY.NUMERALS.CONSISTENT_STYLE_WITHIN_SECTION",
+ "BRING.TYPOGRAPHY.NUMERALS.FIGURE_STYLE_FOR_CAPTIONS",
+ "BRING.TYPOGRAPHY.NUMERALS.FRACTIONS_TRUE_GLYPHS",
+ "BRING.TYPOGRAPHY.NUMERALS.LINING_FOR_CAPS_AND_DISPLAY",
+ "BRING.TYPOGRAPHY.NUMERALS.MIXED_STYLE_AVOID",
+ "BRING.TYPOGRAPHY.NUMERALS.OLDSTYLE_FOR_TEXT",
+ "BRING.TYPOGRAPHY.NUMERALS.PROPORTIONAL_FOR_PROSE",
+ "BRING.TYPOGRAPHY.NUMERALS.SLASHED_ZERO_IF_CONFUSION",
+ "BRING.TYPOGRAPHY.NUMERALS.SMALL_CAPS_AND_FIGURES",
+ "BRING.TYPOGRAPHY.NUMERALS.SUPERIOR_INFERIOR_FOR_NOTES",
+ "BRING.TYPOGRAPHY.NUMERALS.TABULAR_FOR_TABLES",
+ "BRING.TYPOGRAPHY.SERIF.AVOID_MIX_SAME_ROLE",
+ "BRING.TYPOGRAPHY.SERIF.BODY_TEXT_DEFAULT",
+ "BRING.TYPOGRAPHY.SERIF.PAIR_WITH_COMPATIBLE_XHEIGHT",
+ "BRING.TYPOGRAPHY.SERIF.SANS_FOR_DISPLAY",
+ "BRING.TYPOGRAPHY.SERIF.SERIF_SANS_BALANCE",
+ "BRING.TYPOGRAPHY.SERIF.STROKE_CONTRAST_COMPATIBLE",
+ "BRING.TYPOGRAPHY.SIZE.AVOID_TOO_MANY_SIZES",
+ "BRING.TYPOGRAPHY.SIZE.BODY_SIZE_MATCH_MEASURE",
+ "BRING.TYPOGRAPHY.SIZE.DISPLAY_SIZE_BALANCE",
+ "BRING.TYPOGRAPHY.SIZE.LEADING_RELATION",
+ "BRING.TYPOGRAPHY.SIZE.SCALE_CONSISTENT",
+ "BRING.TYPOGRAPHY.SIZE.SMALL_TEXT_MINIMUM",
"BRING.TYPOGRAPHY.SPACING.INITIALS.THIN_SPACE",
"BRING.TYPOGRAPHY.SPACING.SENTENCE_SPACE.SINGLE",
"BRING.TYPOGRAPHY.SPACING.WORD_SPACE.DEFINE",
"BRING.TYPOGRAPHY.TRACKING.CAPS_SMALLCAPS_AND_LONG_DIGITS",
- "BRING.TYPOGRAPHY.TRACKING.LOWERCASE.AVOID"
+ "BRING.TYPOGRAPHY.TRACKING.LOWERCASE.AVOID",
+ "BRING.TYPOGRAPHY.TYPEFACE.CONTRAST_INTENTIONAL",
+ "BRING.TYPOGRAPHY.TYPEFACE.DISPLAY_FACES_FOR_DISPLAY",
+ "BRING.TYPOGRAPHY.TYPEFACE.FALLBACKS_COMPATIBLE_METRICS",
+ "BRING.TYPOGRAPHY.TYPEFACE.FAMILY_WITH_VARIANTS",
+ "BRING.TYPOGRAPHY.TYPEFACE.GLYPH_COVERAGE_REQUIRED",
+ "BRING.TYPOGRAPHY.TYPEFACE.LEGIBILITY_AT_SIZE",
+ "BRING.TYPOGRAPHY.TYPEFACE.LIMIT_NUMBER",
+ "BRING.TYPOGRAPHY.TYPEFACE.MIXING_BY_ROLE_ONLY",
+ "BRING.TYPOGRAPHY.TYPEFACE.OPTICAL_SIZES_USE",
+ "BRING.TYPOGRAPHY.TYPEFACE.PURPOSE_MATCH_CONTENT",
+ "BRING.TYPOGRAPHY.TYPEFACE.SIMILAR_FACES_AVOID",
+ "BRING.TYPOGRAPHY.TYPEFACE.TEXT_FACES_FOR_BODY",
+ "BRING.TYPOGRAPHY.WEIGHT.AVOID_TOO_MANY_WEIGHTS",
+ "BRING.TYPOGRAPHY.WEIGHT.BOLD_IN_LONG_PASSAGES_AVOID",
+ "BRING.TYPOGRAPHY.WEIGHT.HEAVY_WEIGHTS_SHORT_LABELS",
+ "BRING.TYPOGRAPHY.WEIGHT.HIERARCHY_CLEAR",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ALL_CAPS.AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ITALIC_LONG.AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_LONG.AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.ITALIC_LONG.AVOID",
+ "HOUSE.TYPOGRAPHY.HTML.JUSTIFICATION.RAGGED_RIGHT",
+ "HOUSE.TYPOGRAPHY.HTML.LINE_HEIGHT.MINIMUM",
+ "HOUSE.TYPOGRAPHY.HTML.LINK_DECORATION.CONSISTENT"
]
}
diff --git a/spec/indexes/enforcement.json b/spec/indexes/enforcement.json
index 1be2008..30b77e1 100644
--- a/spec/indexes/enforcement.json
+++ b/spec/indexes/enforcement.json
@@ -9,6 +9,8 @@
"BRING.TYPOGRAPHY.ALIGNMENT.DONT_STRETCH_SPACE",
"BRING.TYPOGRAPHY.HYPHENATION.HARD_SPACES.SHORT_EXPRESSIONS",
"BRING.TYPOGRAPHY.SPACING.SENTENCE_SPACE.SINGLE",
+ "CMOS.ABBREVIATIONS.ACRONYMS.DEFINE_FIRST_USE",
+ "CMOS.ABBREVIATIONS.PLURALS.NO_APOSTROPHE",
"CMOS.CITATIONS.DEGRADED.NOTE_MARKERS.REPAIR",
"CMOS.CITATIONS.DEGRADED.URL_LINEBREAKS.NORMALIZE",
"CMOS.CITATIONS.DOI.PREFERRED_OVER_URL",
@@ -16,6 +18,8 @@
"CMOS.CITATIONS.NOTES.NOTE_MARKERS.PLACEMENT_AFTER_PUNCT",
"CMOS.CITATIONS.NOTES.NOTE_MARKERS.SEQUENCE_CONTINUOUS",
"CMOS.CITATIONS.NOTES.NOTE_MARKERS.SUPERSCRIPT_TEXT",
+ "CMOS.LINKS.NO_WRAPPERS",
+ "CMOS.LINKS.URL_ONLY_LINE_NO_PUNCT",
"CMOS.NUMBERS.DECIMALS.LEADING_ZERO",
"CMOS.NUMBERS.DECIMALS.NUMERALS",
"CMOS.NUMBERS.DECIMAL_MARKER.LOCALE",
@@ -27,9 +31,11 @@
"CMOS.NUMBERS.PLURALS.DECADE.NO_APOSTROPHE",
"CMOS.NUMBERS.RANGES.EN_DASH.USE",
"CMOS.NUMBERS.SI_PREFIXES.NO_HYPHEN",
+ "CMOS.PUNCTUATION.APOSTROPHE.SMART",
"CMOS.PUNCTUATION.BLOCK_QUOTES.NO_QUOTE_MARKS",
"CMOS.PUNCTUATION.COLONS.SPACE_AFTER",
"CMOS.PUNCTUATION.COMMAS.SERIAL_COMMA.DEFAULT",
+ "CMOS.PUNCTUATION.COMMAS.SPLICES.AVOID_FORMAL",
"CMOS.PUNCTUATION.DASHES.EM_DASH.USE_WITHOUT_SPACES_US",
"CMOS.PUNCTUATION.DASHES.EN_DASH.RANGES",
"CMOS.PUNCTUATION.DEGRADED.EXTRA_SPACES.AFTER_PUNCT",
@@ -40,25 +46,141 @@
"HOUSE.A11Y.HEADINGS.NO_SKIPS",
"HOUSE.A11Y.IMAGES.ALT_REQUIRED",
"HOUSE.A11Y.LINK_TEXT.DESCRIPTIVE",
+ "HOUSE.ACCESSIBILITY.HEADINGS.NO_EMPTY",
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_TEXT.QUALITY.NO_FILENAME",
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.SYMBOL_ONLY.AVOID",
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.UNIQUE_TARGETS",
+ "HOUSE.ACCESSIBILITY.LISTS.NO_EMPTY_ITEMS",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADER_ROW.REQUIRED",
+ "HOUSE.CITATIONS.AUTHOR_DATE.PAREN_YEAR_ONLY",
+ "HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.REQUIRED",
+ "HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.YEAR_REQUIRED",
+ "HOUSE.CITATIONS.NOTES.BIBLIOGRAPHY.REQUIRED",
+ "HOUSE.CITATIONS.NOTES.DEFINITIONS.REQUIRED",
+ "HOUSE.CITATIONS.NOTES.IBID.AVOID",
+ "HOUSE.CITATIONS.NOTES.MARKERS.BRACKETED_NUMBERS.AVOID",
"HOUSE.CODE.BLOCKS.LANGUAGE_TAGS.PREFERRED",
+ "HOUSE.CODE.BLOCKS.LONG_LINES.AVOID",
+ "HOUSE.CODE.BLOCKS.TABS.AVOID",
+ "HOUSE.CODE.FENCES.LANGUAGE_INFO.SUGGEST",
"HOUSE.CODE.INLINE.MONO_BACKTICKS",
+ "HOUSE.EDITORIAL.HEADINGS.AVOID_ALL_CAPS",
+ "HOUSE.EDITORIAL.HEADINGS.NO_TRAILING_PUNCTUATION",
+ "HOUSE.EDITORIAL.LISTS.AVOID_SINGLE_ITEM",
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_LOREM_IPSUM",
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_TBD_TKTK",
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_TODO_FIXME",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.EARLY",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.PRESENT",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.SINGLE",
+ "HOUSE.I18N.NUMBERS.MIXED_DECIMAL_SEPARATORS",
+ "HOUSE.I18N.QUOTES.MIXED_STYLES",
+ "HOUSE.LAYOUT.MD.BLANK_LINES.SPARING",
+ "HOUSE.LAYOUT.MD.HEADINGS.NON_EMPTY_SECTIONS",
+ "HOUSE.LINKS.AUTO.EMBEDDED_CREDENTIALS.AVOID",
+ "HOUSE.LINKS.AUTO.FILETYPE_LABEL.REQUIRED",
+ "HOUSE.LINKS.AUTO.FTP.AVOID",
+ "HOUSE.LINKS.AUTO.HTML_FALLBACK.REQUIRED",
+ "HOUSE.LINKS.AUTO.INTERNAL_HOSTNAMES.AVOID",
+ "HOUSE.LINKS.AUTO.INVITE_LINKS.AVOID",
+ "HOUSE.LINKS.AUTO.LABEL_LENGTH.AVOID_OVERLONG",
+ "HOUSE.LINKS.AUTO.LOGIN_LINKS.AVOID",
+ "HOUSE.LINKS.AUTO.PARTIAL_WORD.AVOID",
+ "HOUSE.LINKS.AUTO.PASSWORD_RESET.AVOID",
+ "HOUSE.LINKS.AUTO.PRIVATE_IPS.AVOID",
+ "HOUSE.LINKS.AUTO.SESSION_PARAMS.AVOID",
+ "HOUSE.LINKS.AUTO.STAGING_HOSTNAMES.AVOID",
+ "HOUSE.LINKS.AUTO.TRACKING_PARAMS.AVOID",
"HOUSE.LINKS.DISALLOW.FILE_URIS",
+ "HOUSE.LINKS.DISALLOW.JAVASCRIPT_URIS",
"HOUSE.LINKS.PUNCTUATION.NO_TRAILING_PUNCT",
"HOUSE.LINKS.TEXT.DESCRIPTIVE",
- "HOUSE.LINKS.URLS.PREFER_HTTPS"
+ "HOUSE.LINKS.TEXT.NO_CLICK_HERE",
+ "HOUSE.LINKS.URLS.AVOID.NAKED_URLS_IN_PROSE",
+ "HOUSE.LINKS.URLS.DISALLOW.LOCALHOST",
+ "HOUSE.LINKS.URLS.DOIS.PREFER_DOI_ORG",
+ "HOUSE.LINKS.URLS.NO_BACKSLASH",
+ "HOUSE.LINKS.URLS.NO_TRAILING_PARENS",
+ "HOUSE.LINKS.URLS.NO_WHITESPACE",
+ "HOUSE.LINKS.URLS.NO_ZERO_WIDTH",
+ "HOUSE.LINKS.URLS.PREFER_HTTPS",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ALL_CAPS.AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ITALIC_LONG.AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_LONG.AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.ITALIC_LONG.AVOID"
],
"manual": [
+ "BRING.CODE.MONO_RAGGED_RIGHT",
+ "BRING.CODE.RAG.AVOID_FAKE_JUSTIFY",
+ "BRING.CODE.RAG.FIXED_WORD_SPACES",
+ "BRING.CODE.RAG.NO_AUTO_HYPHENATION",
+ "BRING.CODE.RAG.NO_LETTERSPACING",
+ "BRING.CODE.RAG.NO_MIN_LINE",
+ "BRING.HEADINGS.AVOID_ABBREVIATIONS",
+ "BRING.HEADINGS.AVOID_STACKED_LEVELS",
+ "BRING.HEADINGS.BREAKS.AT_PHRASE_BOUNDARIES",
+ "BRING.HEADINGS.CASE.PROPER_NOUNS_PRESERVE",
"BRING.HEADINGS.CONTRAST.CLEAR_HIERARCHY",
+ "BRING.HEADINGS.HIERARCHY.MAX_DEPTH",
+ "BRING.HEADINGS.LEADIN_TEXT.BEFORE_LIST",
+ "BRING.HEADINGS.LENGTH.CONCISE",
+ "BRING.HEADINGS.NO_HYPHENATION",
+ "BRING.HEADINGS.NO_SINGLE_WORD_LINE",
+ "BRING.HEADINGS.NO_TERMINAL_COLON",
+ "BRING.HEADINGS.NO_TERMINAL_PERIOD",
+ "BRING.HEADINGS.NUMBERING.APPENDIX_LABELS",
+ "BRING.HEADINGS.NUMBERING.CONSISTENT_STYLE",
+ "BRING.HEADINGS.NUMBERING.NO_GAPS",
+ "BRING.HEADINGS.NUMBERING.PREFIXES.CONSISTENT",
+ "BRING.HEADINGS.NUMBERING.PUNCTUATION.CONSISTENT",
+ "BRING.HEADINGS.NUMBERING.SUBLEVELS.DECIMAL_STYLE",
+ "BRING.HEADINGS.QUESTION_MARK_ONLY_IF_QUESTION",
"BRING.HEADINGS.RELATED_ELEMENTS.COHERENT",
+ "BRING.HEADINGS.RUN_IN.END_PUNCTUATION",
+ "BRING.HEADINGS.RUN_IN.SEPARATION.CONSISTENT",
"BRING.HEADINGS.RUN_IN.STANDALONE.CONSISTENT",
+ "BRING.HEADINGS.SECTION_OPENING.PARAGRAPH_REQUIRED",
"BRING.HEADINGS.STRUCTURE.MATCH_TEXT_LOGIC",
"BRING.HEADINGS.STYLE.PALETTE_LIMIT",
"BRING.HEADINGS.SUBHEADS.MIXING.HIERARCHY_PLACEMENT",
+ "BRING.HEADINGS.SUBHEADS.PARALLEL_GRAMMAR",
+ "BRING.HEADINGS.TOC.MATCH",
+ "BRING.HEADINGS.WIDTH.BALANCED",
+ "BRING.LAYOUT.COLUMNS.RAGGED_BOTTOM.AVOID",
+ "BRING.LAYOUT.COLUMNS.SPAN_POLICY.FIGURES",
+ "BRING.LAYOUT.COLUMNS.SPAN_POLICY.TABLES",
+ "BRING.LAYOUT.COLUMNS.USE_FOR_LONG_LISTS",
"BRING.LAYOUT.ELEMENT_RELATIONSHIPS.VISIBLE",
"BRING.LAYOUT.FLOATS.PLACEMENT.NEAR_REFERENCE",
+ "BRING.LAYOUT.MARGINS.BLEED.ONLY_WHEN_ENABLED",
+ "BRING.LAYOUT.MARGINS.NOTES.OUTSIDE_TEXTBLOCK",
"BRING.LAYOUT.MEASURE.CODE_BLOCKS.WRAP_POLICY",
+ "BRING.LAYOUT.PAGE.BLANKS.INTENTIONAL",
"BRING.LAYOUT.PAGE.DENSITY.DONT_SUFFOCATE",
+ "BRING.LAYOUT.PAGE.FACING_ELEMENTS.ALIGN",
+ "BRING.LAYOUT.PAGE.ODD_EVEN.CONSISTENT",
+ "BRING.LAYOUT.PAGE.OPENING_SPREAD.RULE",
+ "BRING.LAYOUT.PAGE.SPREADS.BALANCE_CONTENT",
+ "BRING.LAYOUT.PAGE.WHITE_SPACE.DISTRIBUTION",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_AFTER_HEADING",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_BEFORE_LAST_LINE",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_IN_BLOCK_QUOTES",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_IN_EQUATIONS",
+ "BRING.LAYOUT.PAGINATION.AVOID_EXCESS_WHITE_SPACE",
+ "BRING.LAYOUT.PAGINATION.AVOID_LONELY_LINE_IN_LISTS",
+ "BRING.LAYOUT.PAGINATION.AVOID_STRANDED_CAPTIONS",
+ "BRING.LAYOUT.PAGINATION.BALANCE_FINAL_PAGE",
+ "BRING.LAYOUT.PAGINATION.CLEAR_SECTION_BREAKS",
+ "BRING.LAYOUT.PAGINATION.KEEP_FIGURE_WITH_CAPTION",
+ "BRING.LAYOUT.PAGINATION.KEEP_LIST_WITH_INTRO",
+ "BRING.LAYOUT.PAGINATION.KEEP_TABLE_WITH_HEADER",
+ "BRING.LAYOUT.PARAGRAPH.AFTER_QUOTE.FLUSH",
+ "BRING.LAYOUT.PARAGRAPH.AVOID_WIDOW_END",
+ "BRING.LAYOUT.PARAGRAPH.AVOID_WIDOW_START",
"BRING.LAYOUT.PARAGRAPH.BLANK_LINES.SPARING",
+ "BRING.LAYOUT.PARAGRAPH.BLOCK_STYLE.CONSISTENT",
+ "BRING.LAYOUT.PARAGRAPH.RUN_IN_HEADS.CONSISTENT",
+ "BRING.LAYOUT.PARAGRAPH.SECTION_BREAKS.CLEAR",
"BRING.LAYOUT.RHYTHM.RULES_SERVE_TEXT",
"BRING.TABLES.CAPTIONS.CLEAR",
"BRING.TABLES.DATA_TYPES.NOT_MIXED",
@@ -73,25 +195,200 @@
"BRING.TABLES.TEXT_ORIENTATION.HORIZONTAL",
"BRING.TABLES.TITLES.CONSISTENT_PLACEMENT",
"BRING.TABLES.UNITS.IN_HEADERS",
+ "BRING.TYPOGRAPHY.BOLD.AVOID_LONG_PASSAGES",
+ "BRING.TYPOGRAPHY.BOLD.HEADING_HIERARCHY_BALANCE",
+ "BRING.TYPOGRAPHY.BOLD.LABELS_SHORT",
+ "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ALL_CAPS",
+ "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ITALICS_LONG",
+ "BRING.TYPOGRAPHY.BOLD.SPARING_USE",
+ "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_AVOID_LONG_RUNS",
+ "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_SHORT_LABELS_ONLY",
+ "BRING.TYPOGRAPHY.CAPS.AVOID_FOR_EMPHASIS",
+ "BRING.TYPOGRAPHY.CAPS.MIXED_CAPS_CONSISTENT",
+ "BRING.TYPOGRAPHY.CAPS.ROMAN_NUMERALS_SPACING",
+ "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_FOR_ACRONYMS",
+ "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_NOT_FOR_LONG_PASSAGES",
+ "BRING.TYPOGRAPHY.CONTRAST.AVOID_EXTREME_MIX",
+ "BRING.TYPOGRAPHY.CONTRAST.FONT_PAIRING_MATCH",
+ "BRING.TYPOGRAPHY.FAMILY.BOLD_FOR_STRONG_EMPHASIS",
+ "BRING.TYPOGRAPHY.FAMILY.ITALIC_FOR_SUBTLE_EMPHASIS",
+ "BRING.TYPOGRAPHY.FAMILY.ITALIC_PUNCTUATION_MATCH",
+ "BRING.TYPOGRAPHY.FAMILY.LIMIT_STYLE_VARIANTS",
+ "BRING.TYPOGRAPHY.FAMILY.METRICS_MATCH_WHEN_MIXING",
+ "BRING.TYPOGRAPHY.FAMILY.SINGLE_FAMILY_BODY",
+ "BRING.TYPOGRAPHY.FAMILY.SMALL_CAPS_SPARE",
"BRING.TYPOGRAPHY.HYPHENATION.AVOID_PROPER_NAMES",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_IN_ALL_CAPS_HEADINGS",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_NUMERAL_ITALICS",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_STACKED_EMPHASIS",
+ "BRING.TYPOGRAPHY.ITALICS.CONSISTENT_TITLE_TREATMENT",
+ "BRING.TYPOGRAPHY.ITALICS.EMPHASIS_NOT_UNDERLINE",
+ "BRING.TYPOGRAPHY.ITALICS.HEADINGS_AVOID",
+ "BRING.TYPOGRAPHY.ITALICS.LONG_SPANS_AVOID",
+ "BRING.TYPOGRAPHY.ITALICS.PUNCTUATION_FOLLOWS_STYLE",
+ "BRING.TYPOGRAPHY.ITALICS.RUNNING_HEADS_AVOID",
+ "BRING.TYPOGRAPHY.ITALICS.SPARING",
+ "BRING.TYPOGRAPHY.ITALICS.TERMS_INTRODUCED_SPARE",
+ "BRING.TYPOGRAPHY.ITALICS.TITLES_STANDALONE_WORKS",
"BRING.TYPOGRAPHY.KERNING.CONSISTENT_OR_NONE",
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ACRONYMS",
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ALL_CAPS",
+ "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_IN_DISPLAY",
+ "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_SPARING",
+ "BRING.TYPOGRAPHY.LIGATURES.DO_NOT_USE_IF_AMBIGUOUS",
+ "BRING.TYPOGRAPHY.LIGATURES.KEEP_CONSISTENT",
+ "BRING.TYPOGRAPHY.LIGATURES.REVIEW_FOR_LANGUAGE",
"BRING.TYPOGRAPHY.NUMBER_STRINGS.SPACE_FOR_READABILITY",
+ "BRING.TYPOGRAPHY.NUMERALS.AVOID_LINING_IN_LOWERCASE",
+ "BRING.TYPOGRAPHY.NUMERALS.CONSISTENT_STYLE_WITHIN_SECTION",
+ "BRING.TYPOGRAPHY.NUMERALS.FIGURE_STYLE_FOR_CAPTIONS",
+ "BRING.TYPOGRAPHY.NUMERALS.MIXED_STYLE_AVOID",
+ "BRING.TYPOGRAPHY.NUMERALS.SLASHED_ZERO_IF_CONFUSION",
+ "BRING.TYPOGRAPHY.NUMERALS.SMALL_CAPS_AND_FIGURES",
+ "BRING.TYPOGRAPHY.SERIF.AVOID_MIX_SAME_ROLE",
+ "BRING.TYPOGRAPHY.SERIF.BODY_TEXT_DEFAULT",
+ "BRING.TYPOGRAPHY.SERIF.PAIR_WITH_COMPATIBLE_XHEIGHT",
+ "BRING.TYPOGRAPHY.SERIF.SANS_FOR_DISPLAY",
+ "BRING.TYPOGRAPHY.SERIF.SERIF_SANS_BALANCE",
+ "BRING.TYPOGRAPHY.SERIF.STROKE_CONTRAST_COMPATIBLE",
+ "BRING.TYPOGRAPHY.SIZE.AVOID_TOO_MANY_SIZES",
+ "BRING.TYPOGRAPHY.SIZE.BODY_SIZE_MATCH_MEASURE",
+ "BRING.TYPOGRAPHY.SIZE.DISPLAY_SIZE_BALANCE",
+ "BRING.TYPOGRAPHY.SIZE.SCALE_CONSISTENT",
+ "BRING.TYPOGRAPHY.SIZE.SMALL_TEXT_MINIMUM",
"BRING.TYPOGRAPHY.SPACING.INITIALS.THIN_SPACE",
+ "BRING.TYPOGRAPHY.TYPEFACE.CONTRAST_INTENTIONAL",
+ "BRING.TYPOGRAPHY.TYPEFACE.DISPLAY_FACES_FOR_DISPLAY",
+ "BRING.TYPOGRAPHY.TYPEFACE.FAMILY_WITH_VARIANTS",
+ "BRING.TYPOGRAPHY.TYPEFACE.GLYPH_COVERAGE_REQUIRED",
+ "BRING.TYPOGRAPHY.TYPEFACE.LEGIBILITY_AT_SIZE",
+ "BRING.TYPOGRAPHY.TYPEFACE.LIMIT_NUMBER",
+ "BRING.TYPOGRAPHY.TYPEFACE.MIXING_BY_ROLE_ONLY",
+ "BRING.TYPOGRAPHY.TYPEFACE.PURPOSE_MATCH_CONTENT",
+ "BRING.TYPOGRAPHY.TYPEFACE.SIMILAR_FACES_AVOID",
+ "BRING.TYPOGRAPHY.TYPEFACE.TEXT_FACES_FOR_BODY",
+ "BRING.TYPOGRAPHY.WEIGHT.AVOID_TOO_MANY_WEIGHTS",
+ "BRING.TYPOGRAPHY.WEIGHT.BOLD_IN_LONG_PASSAGES_AVOID",
+ "BRING.TYPOGRAPHY.WEIGHT.HEAVY_WEIGHTS_SHORT_LABELS",
+ "BRING.TYPOGRAPHY.WEIGHT.HIERARCHY_CLEAR",
+ "CMOS.ABBREVIATIONS.ACADEMIC.DEGREES.STYLE",
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_IN_HEADINGS",
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_SENTENCE_START",
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_STACKING",
+ "CMOS.ABBREVIATIONS.ACRONYMS.REINTRODUCE_AFTER_GAP",
+ "CMOS.ABBREVIATIONS.AVOID_ONE_OFFS",
+ "CMOS.ABBREVIATIONS.BIBLIOGRAPHY.STANDARDS.FOLLOW",
+ "CMOS.ABBREVIATIONS.CAPS.AVOID_ALL_CAPS_WORDS",
+ "CMOS.ABBREVIATIONS.CAPTIONS.DEFINE_ON_FIRST_USE",
+ "CMOS.ABBREVIATIONS.COMPANIES.INC_LTD.CONSISTENT",
+ "CMOS.ABBREVIATIONS.COUNTRIES.ABBREV_IN_TABLES_ONLY",
+ "CMOS.ABBREVIATIONS.DAYS.ABBREV_IN_TABLES",
+ "CMOS.ABBREVIATIONS.DAYS.SPELL_OUT_IN_TEXT",
+ "CMOS.ABBREVIATIONS.FOOTNOTES.ABBREV_ON_FIRST_USE",
+ "CMOS.ABBREVIATIONS.GENERAL.AVOID_OVERUSE",
+ "CMOS.ABBREVIATIONS.GENERAL.CONSISTENCY",
+ "CMOS.ABBREVIATIONS.GENERAL.GLOSSARY.WHEN_NEEDED",
+ "CMOS.ABBREVIATIONS.GEOGRAPHY.STATE_ABBREVS.CONSISTENT",
+ "CMOS.ABBREVIATIONS.INITIALISMS.NO_PERIODS.DEFAULT",
+ "CMOS.ABBREVIATIONS.LATIN.EG_IE.PUNCTUATION",
+ "CMOS.ABBREVIATIONS.LATIN.ET_AL.USE",
+ "CMOS.ABBREVIATIONS.LATIN.VERSUS_ENGLISH",
+ "CMOS.ABBREVIATIONS.MEASURES.SI.SPACE",
+ "CMOS.ABBREVIATIONS.MONTHS.ABBREV_IN_TABLES",
+ "CMOS.ABBREVIATIONS.MONTHS.SPELL_OUT_IN_TEXT",
+ "CMOS.ABBREVIATIONS.NAMES.INITIALS.SPACING",
+ "CMOS.ABBREVIATIONS.ORGANIZATIONS.SPELL_OUT_FIRST",
+ "CMOS.ABBREVIATIONS.PARENTHETICALS.AVOID_STACKING",
+ "CMOS.ABBREVIATIONS.POSSESSIVE.FORM",
+ "CMOS.ABBREVIATIONS.PUNCTUATION.ABBREV_WITH_PERIODS.AVOID_DOUBLE",
+ "CMOS.ABBREVIATIONS.READER_FAMILIARITY",
+ "CMOS.ABBREVIATIONS.STATES.POSTAL_ONLY",
+ "CMOS.ABBREVIATIONS.STATES.SPELL_OUT_IN_TEXT",
+ "CMOS.ABBREVIATIONS.TABLES.ABBREV_KEY",
+ "CMOS.ABBREVIATIONS.TABLES.KEYS.WHEN_DENSE",
+ "CMOS.ABBREVIATIONS.TECH.TERMS.CASE_SENSITIVE",
+ "CMOS.ABBREVIATIONS.TIME.AM_PM.FORM",
+ "CMOS.ABBREVIATIONS.TITLES.COURTESY_PERIODS",
+ "CMOS.ABBREVIATIONS.TITLES.HONORIFICS.CONSISTENT",
+ "CMOS.ABBREVIATIONS.TITLES.JR_SR.CONSISTENT",
+ "CMOS.ABBREVIATIONS.UNITS.ABBREV_WITH_NUMERALS_ONLY",
+ "CMOS.ABBREVIATIONS.UNITS.NO_PERIODS",
+ "CMOS.ABBREVIATIONS.UNITS.NO_PLURAL_SYMBOLS",
+ "CMOS.ABBREVIATIONS.UNITS.SPELL_OUT_WITHOUT_NUMERALS",
+ "CMOS.ABBREVIATIONS.US_USA.CONSISTENT",
+ "CMOS.BACKMATTER.ABBREVIATIONS.LIST.WHEN_NEEDED",
+ "CMOS.BACKMATTER.ACKNOWLEDGMENTS.PLACEMENT",
+ "CMOS.BACKMATTER.APPENDICES.CROSS_REFERENCES",
+ "CMOS.BACKMATTER.APPENDICES.FORMAT_MATCH",
+ "CMOS.BACKMATTER.APPENDICES.LABELED",
+ "CMOS.BACKMATTER.APPENDICES.SOURCES",
+ "CMOS.BACKMATTER.APPENDIX.NUMBERING.SEQUENTIAL",
+ "CMOS.BACKMATTER.APPENDIX.START_ON_NEW_PAGE",
+ "CMOS.BACKMATTER.APPENDIX.TOC.ENTRIES",
+ "CMOS.BACKMATTER.BIBLIOGRAPHY.CONSISTENT_STYLE",
+ "CMOS.BACKMATTER.BIBLIOGRAPHY.SORTING",
+ "CMOS.BACKMATTER.CONTACT.SUPPORT",
+ "CMOS.BACKMATTER.DATA.AVAILABILITY",
+ "CMOS.BACKMATTER.ENDNOTES.VERSUS_FOOTNOTES.CONSISTENT",
+ "CMOS.BACKMATTER.ERRATA.WHEN_NEEDED",
+ "CMOS.BACKMATTER.GLOSSARY.DEFINITIONS.CONCISE",
+ "CMOS.BACKMATTER.GLOSSARY.SORTING",
+ "CMOS.BACKMATTER.GLOSSARY.TERMS.CONSISTENT_STYLE",
+ "CMOS.BACKMATTER.GLOSSARY.WHEN_TERMS",
+ "CMOS.BACKMATTER.INDEX.ABBREVIATIONS.CONSISTENT",
+ "CMOS.BACKMATTER.INDEX.CROSS_REFERENCES.CONSISTENT",
+ "CMOS.BACKMATTER.INDEX.ENTRIES.CONSISTENT_CASE",
+ "CMOS.BACKMATTER.INDEX.LOCATORS.ACCURATE",
+ "CMOS.BACKMATTER.INDEX.NAMES.SORTING",
+ "CMOS.BACKMATTER.INDEX.PAGE_RANGES.STANDARD",
+ "CMOS.BACKMATTER.INDEX.SEE_ALSO.USE_WHEN_NEEDED",
+ "CMOS.BACKMATTER.INDEX.SUBENTRIES.NESTED",
+ "CMOS.BACKMATTER.INDEX.SUBENTRY.ORDER.LOGICAL",
+ "CMOS.BACKMATTER.INDEX.WHEN_REQUIRED",
+ "CMOS.BACKMATTER.LICENSES.THIRD_PARTY",
+ "CMOS.BACKMATTER.NOTES.BLOCKS.CONSISTENT",
+ "CMOS.BACKMATTER.NOTES.CITATIONS.COMPLETE",
+ "CMOS.BACKMATTER.NOTES.NUMBERING.SEQUENTIAL",
+ "CMOS.BACKMATTER.NOTES.ORDER.FOLLOW_TEXT",
+ "CMOS.BACKMATTER.NOTES.REFERENCE.MATCH",
+ "CMOS.BACKMATTER.REFERENCES.ACCESS_DATES.WHEN_NEEDED",
+ "CMOS.BACKMATTER.REFERENCES.AUTHOR_NAMES.CONSISTENT",
+ "CMOS.BACKMATTER.REFERENCES.DOI.OR_URL",
+ "CMOS.BACKMATTER.REFERENCES.SECTION_PRESENT",
+ "CMOS.BACKMATTER.REFERENCES.URLS.STABLE",
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.CORPORATE_AUTHORS.SHORT_FORM",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.DIRECT_QUOTES",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.EXTRA_INFO",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.LOCATORS",
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_AUTHORS.POLICY",
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_CITATIONS.ORDER_POLICY",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_SOURCES",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.PARENTHETICAL",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.PLACEMENT",
+ "CMOS.CITATIONS.AUTHOR_DATE.NO_AUTHOR.TITLE_KEY",
+ "CMOS.CITATIONS.AUTHOR_DATE.NO_DATE.POLICY",
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ALPHABETICAL",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ENTRY_TEMPLATES.CONSISTENT",
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ORDER_AND_YEAR",
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REPEATED_NAMES",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REPEATED_NAMES.POLICY",
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REQUIRED",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SAME_AUTHOR.ORDER_POLICY",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SORTING_STABLE",
+ "CMOS.CITATIONS.AUTHOR_DATE.SAME_AUTHOR_SAME_YEAR.SUFFIXES",
"CMOS.CITATIONS.BIBLIOGRAPHY.ALT_NAMES.CROSSREF",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_LIST.LENGTH.POLICY",
"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.CONSISTENT_FORM",
"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.INITIALS_PREFERRED",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.PARTICLES.CONSISTENT_FORMAT",
"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.PUBLISHED_FORM",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.SUFFIXES.INCLUDE",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.CONTRIBUTOR_ROLES.LABEL_CLEARLY",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.CORPORATE_AUTHORS.USE_AS_AUTHOR",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.GROUP_AUTHORS.SUBUNITS.CONSISTENT",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.MULTIPLE_CONTRIBUTORS.POLICY_CONSISTENT",
"CMOS.CITATIONS.BIBLIOGRAPHY.MULTI_AUTHORS.ORDER",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.NO_AUTHOR.EDITOR_AS_LEAD_WHEN_APPROPRIATE",
"CMOS.CITATIONS.BIBLIOGRAPHY.NO_AUTHOR.TITLE_LEAD",
"CMOS.CITATIONS.BIBLIOGRAPHY.PSEUDONYMS.CONSISTENT",
"CMOS.CITATIONS.BIBLIOGRAPHY.REPEATED_NAMES.THREE_EM_DASH",
@@ -128,8 +425,292 @@
"CMOS.CITATIONS.ONLINE.VERSION.CITE_RIGHT_VERSION",
"CMOS.CITATIONS.QUOTATIONS.LOCATORS.PAGE_REQUIRED",
"CMOS.CITATIONS.RESEARCH.METADATA.CAPTURE_EARLY",
+ "CMOS.CITATIONS.S13_1.ALL_SOURCE_TYPES",
+ "CMOS.CITATIONS.S13_1.DISCIPLINE_POLICY",
+ "CMOS.CITATIONS.S13_1.PURPOSE.COPYRIGHT",
+ "CMOS.CITATIONS.S13_1.PURPOSE.COURTESY",
+ "CMOS.CITATIONS.S13_1.PURPOSE.ETHICS",
+ "CMOS.CITATIONS.S13_1.SUFFICIENT_INFO",
+ "CMOS.CITATIONS.S13_10.DATABASES.NAME_INSTEAD",
+ "CMOS.CITATIONS.S13_10.DATABASE_IN_CITATION",
+ "CMOS.CITATIONS.S13_10.DOI_PRECEDENCE",
+ "CMOS.CITATIONS.S13_10.TEST_LOGGED_OUT",
+ "CMOS.CITATIONS.S13_100.BIBLIOGRAPHY.ONLINE.SOURCE_STABILITY",
+ "CMOS.CITATIONS.S13_101.BIBLIOGRAPHY.EBOOKS.EDITION_AND_FORMAT",
+ "CMOS.CITATIONS.S13_102.BIBLIOGRAPHY.AUDIOVISUAL.CREDITS",
+ "CMOS.CITATIONS.S13_103.BIBLIOGRAPHY.SOCIAL_MEDIA.ARCHIVE",
+ "CMOS.CITATIONS.S13_104.BIBLIOGRAPHY.PUBLIC_DOCUMENTS.IDENTIFIERS",
+ "CMOS.CITATIONS.S13_105.BIBLIOGRAPHY.REPORTS.ISSUING_BODY_AND_VERSION",
+ "CMOS.CITATIONS.S13_106.BIBLIOGRAPHY.DATASETS.VERSION_AND_PROVENANCE",
+ "CMOS.CITATIONS.S13_107.AUTHOR_DATE.REFERENCE_LIST.MULTI_AUTHOR.ORDERING",
+ "CMOS.CITATIONS.S13_108.BIBLIOGRAPHY.PLATFORMS.PERMALINKS_PREFERRED",
+ "CMOS.CITATIONS.S13_11.NO_SHORTENERS_IN_MS",
+ "CMOS.CITATIONS.S13_11.PUBLISHER_OPTION",
+ "CMOS.CITATIONS.S13_11.SHORTENERS.OBSCURE",
+ "CMOS.CITATIONS.S13_110.AUTHOR_DATE.JOURNAL_ARTICLES.CORE_FIELDS",
+ "CMOS.CITATIONS.S13_111.AUTHOR_DATE.REFERENCE_LIST.REQUIRED",
+ "CMOS.CITATIONS.S13_12.URLS.CASE_SENSITIVE",
+ "CMOS.CITATIONS.S13_12.URLS.NO_SENTENCE_START",
+ "CMOS.CITATIONS.S13_12.URLS.NO_SPACES",
+ "CMOS.CITATIONS.S13_12.URLS.PROTOCOL",
+ "CMOS.CITATIONS.S13_12.URLS.PUNCTUATION_AFTER",
+ "CMOS.CITATIONS.S13_12.URLS.TRAILING_SLASH",
+ "CMOS.CITATIONS.S13_13.BACKUPS",
+ "CMOS.CITATIONS.S13_13.CITATIONS.REVIEW",
+ "CMOS.CITATIONS.S13_13.METADATA.CHECK_FIELDS",
+ "CMOS.CITATIONS.S13_13.METADATA.MISSING",
+ "CMOS.CITATIONS.S13_13.REPAIR_AT_SOURCE",
+ "CMOS.CITATIONS.S13_13.STRIP_CODES",
+ "CMOS.CITATIONS.S13_13.TOOLS.USE_METADATA",
+ "CMOS.CITATIONS.S13_14.CITE_VERSION",
+ "CMOS.CITATIONS.S13_14.DEVICE_SPECIFIC",
+ "CMOS.CITATIONS.S13_14.ONLINE.URL_INDICATOR",
+ "CMOS.CITATIONS.S13_14.SAME_URL.FORMATS",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.NOT_REQUIRED",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.PUBLISHER_POLICY",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.RECORD_ANYWAY",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.UNVERIFIABLE",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.FORMAT",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.PREFERENCE",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.WHEN_ONLY_DATE",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.WIKIS",
+ "CMOS.CITATIONS.S13_17.ARCHIVE_SERVICES",
+ "CMOS.CITATIONS.S13_17.PRESERVE.CRISIS_SOURCES",
+ "CMOS.CITATIONS.S13_17.PRESERVE.FORMAT_OPTIONS",
+ "CMOS.CITATIONS.S13_17.PRESERVE.NONPUBLISHED",
+ "CMOS.CITATIONS.S13_18.BIBLIO.INVERT_FIRST_AUTHOR",
+ "CMOS.CITATIONS.S13_18.BIBLIO.SHORTENED_NOTES",
+ "CMOS.CITATIONS.S13_18.NAMES.NORMAL_ORDER",
+ "CMOS.CITATIONS.S13_18.NOTES.SENTENCE_STYLE",
+ "CMOS.CITATIONS.S13_18.NOTES_BIBLIO.OVERVIEW",
+ "CMOS.CITATIONS.S13_18.NO_BIBLIO.FULL_FIRST_NOTE",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.BIBLIO",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.CONSISTENT",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.NOTES",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.NOUN_FORMS",
+ "CMOS.CITATIONS.S13_2.AUTHOR_DATE_SYSTEM",
+ "CMOS.CITATIONS.S13_2.DEFAULT_SYSTEM",
+ "CMOS.CITATIONS.S13_2.DISCIPLINE_PREFERENCE",
+ "CMOS.CITATIONS.S13_2.JOURNAL_INSTRUCTIONS",
+ "CMOS.CITATIONS.S13_2.NOTES_BIBLIOGRAPHY_OPTIONAL",
+ "CMOS.CITATIONS.S13_2.NOTES_SYSTEM",
+ "CMOS.CITATIONS.S13_2.STYLE_ELEMENTS.SHARED",
+ "CMOS.CITATIONS.S13_2.SYSTEMS.TWO_TYPES",
+ "CMOS.CITATIONS.S13_2.SYSTEM_SWITCHING",
+ "CMOS.CITATIONS.S13_20.BIBLIO.BOOKS.NO_PAGES",
+ "CMOS.CITATIONS.S13_20.BIBLIO.PAGE_RANGE",
+ "CMOS.CITATIONS.S13_20.ELECTRONIC.SHORT_DOCS",
+ "CMOS.CITATIONS.S13_20.LOCATORS.ALTERNATIVES",
+ "CMOS.CITATIONS.S13_20.NOTES.PAGE_SPECIFIC",
+ "CMOS.CITATIONS.S13_20.PAGE_RANGE.EN_DASH",
+ "CMOS.CITATIONS.S13_21.EXAMPLES.BIBLIO_SHORTENED",
+ "CMOS.CITATIONS.S13_21.EXAMPLES.CHAPTER14",
+ "CMOS.CITATIONS.S13_21.EXAMPLES.SHORT_FORMS",
+ "CMOS.CITATIONS.S13_22.BOOK_EDITOR_ONLY",
+ "CMOS.CITATIONS.S13_22.BOOK_EDITOR_ONLY.SHORTENED_NO_ED",
+ "CMOS.CITATIONS.S13_22.BOOK_PLACE_OMIT",
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.NOTE_BIBLIO",
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.PAGE_IN_NOTES",
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.SHORTENED",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.BIBLIO_MORE_THAN_SIX",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.BIBLIO_UP_TO_SIX",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.NOTES_ET_AL",
+ "CMOS.CITATIONS.S13_23.NO_BIBLIO.NOTES_UP_TO_SIX",
+ "CMOS.CITATIONS.S13_23.TWO_AUTHORS.BIBLIO_INVERT_FIRST",
+ "CMOS.CITATIONS.S13_23.TWO_AUTHORS.NOTES_LIST_BOTH",
+ "CMOS.CITATIONS.S13_24.AUTHOR_PLUS_EDITOR.BIBLIO_SPELL_OUT",
+ "CMOS.CITATIONS.S13_24.AUTHOR_PLUS_EDITOR.NOTES_ABBREVIATE",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.BIBLIO_NO_PAGE_RANGE",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.INCLUDE_AUTHOR",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.INCLUDE_EDITOR",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.IN_BEFORE_BOOK",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.NOTES_PAGE_LOCATOR",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.QUOTE_TITLE",
+ "CMOS.CITATIONS.S13_26.JOURNAL.BIBLIO_PAGE_RANGE",
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_ISSUE",
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_VOLUME",
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_YEAR",
+ "CMOS.CITATIONS.S13_26.JOURNAL.NOTES_PAGE_SPECIFIC",
+ "CMOS.CITATIONS.S13_26.JOURNAL.OMIT_MONTH_SEASON",
+ "CMOS.CITATIONS.S13_26.JOURNAL.ONLINE.URL_OR_DOI",
+ "CMOS.CITATIONS.S13_26.JOURNAL.PAGE_COLON",
+ "CMOS.CITATIONS.S13_26.JOURNAL.TITLE_ITALIC",
+ "CMOS.CITATIONS.S13_26.JOURNAL.VOLUME_FORMAT",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.MANUSCRIPT_SUPERSCRIPT_OK",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.NOTES_FULL_SIZE",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.NOTES_PERIOD",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.TEXT_SUPERSCRIPT",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.BASELINE_FALLBACK",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.CONSISTENT_SPACING",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.NOTES_FULL_SIZE",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.NO_PERIOD",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.TEXT_SUPERSCRIPT",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.CONSECUTIVE",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.NO_BOOKWIDE_RUN",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SEPARATE_SYSTEMS",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SYMBOLS_FOR_FEW",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SYMBOL_SEQUENCE_STANDARD",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.TABLE_NOTES_SEPARATE",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AFTER_PUNCTUATION",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AFTER_QUOTE",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AVOID_MIDCLAUSE",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.BEFORE_DASH",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.PLACEMENT_END_SENTENCE",
+ "CMOS.CITATIONS.S13_3.JOURNALS.HOUSE_STYLE",
+ "CMOS.CITATIONS.S13_3.LEGAL.BLUEBOOK",
+ "CMOS.CITATIONS.S13_3.OTHER_SYSTEMS.AMA_CSE",
+ "CMOS.CITATIONS.S13_3.OTHER_SYSTEMS.MLA_APA",
+ "CMOS.CITATIONS.S13_3.SOURCE_MANUALS",
+ "CMOS.CITATIONS.S13_35.SHORT_FORM.DISTINCT_TITLE",
+ "CMOS.CITATIONS.S13_36.SHORT_FORM.DISAMBIGUATE_AUTHOR",
+ "CMOS.CITATIONS.S13_38.IBID.IMMEDIATE_PRECEDENT",
+ "CMOS.CITATIONS.S13_39.IBID.LOCATOR_REQUIRED",
+ "CMOS.CITATIONS.S13_4.CONSISTENCY.REQUIRED",
+ "CMOS.CITATIONS.S13_4.DOCUMENTED_DEVIATIONS",
+ "CMOS.CITATIONS.S13_4.FLEXIBILITY.BY_AGREEMENT",
+ "CMOS.CITATIONS.S13_4.JOURNALS.STRICT",
+ "CMOS.CITATIONS.S13_40.SHORT_FORM.AVOID_OP_CIT",
+ "CMOS.CITATIONS.S13_45.NOTES.CITATION_FIRST",
+ "CMOS.CITATIONS.S13_47.NOTES.SYSTEMS.DONT_MIX",
+ "CMOS.CITATIONS.S13_48.ENDNOTES.GROUP_BY_CHAPTER",
+ "CMOS.CITATIONS.S13_5.ACADEMIC_EXPECTATION",
+ "CMOS.CITATIONS.S13_5.AVOID_TANGENTIAL",
+ "CMOS.CITATIONS.S13_5.CITE_RELEVANT",
+ "CMOS.CITATIONS.S13_5.INFORMAL_SOURCES",
+ "CMOS.CITATIONS.S13_5.NONACADEMIC.MENTIONS_OK",
+ "CMOS.CITATIONS.S13_52.ENDNOTES.NAVIGATION_CUES",
+ "CMOS.CITATIONS.S13_54.AUTHOR_DATE.NOTES.COMMENTARY_ONLY",
+ "CMOS.CITATIONS.S13_56.NOTES.DUAL_STREAMS.DISTINCT_LABELS",
+ "CMOS.CITATIONS.S13_57.NOTES.SEPARATE_SOURCE_VS_COMMENTARY",
+ "CMOS.CITATIONS.S13_59.NOTES.MULTI_EDITIONS.CITE_VERSION_USED",
+ "CMOS.CITATIONS.S13_6.LINK_TITLE_PREFERRED",
+ "CMOS.CITATIONS.S13_6.URL.FINAL_ELEMENT",
+ "CMOS.CITATIONS.S13_6.URLS.EASILY_FOUND",
+ "CMOS.CITATIONS.S13_6.URLS.IN_MANUSCRIPT",
+ "CMOS.CITATIONS.S13_6.URLS.READER_NEEDED",
+ "CMOS.CITATIONS.S13_61.BIBLIOGRAPHY.SCOPE.LABEL_CLEARLY",
+ "CMOS.CITATIONS.S13_62.BIBLIOGRAPHY.ENTRY_COMPLETENESS.MORE_THAN_SHORT_FORM",
+ "CMOS.CITATIONS.S13_63.BIBLIOGRAPHY.CONSISTENT_ELEMENT_ORDER",
+ "CMOS.CITATIONS.S13_64.BIBLIOGRAPHY.SUBSECTIONS.CLEAR_HEADINGS",
+ "CMOS.CITATIONS.S13_66.BIBLIOGRAPHY.INCLUDE_ONLY_PER_SCOPE",
+ "CMOS.CITATIONS.S13_67.BIBLIOGRAPHY.ANNOTATIONS.CONSISTENT_AND_DISTINCT",
+ "CMOS.CITATIONS.S13_68.BIBLIOGRAPHY.ENTRY_TYPES.NOT_MIXED",
+ "CMOS.CITATIONS.S13_7.DOI.NO_PREFIX",
+ "CMOS.CITATIONS.S13_7.DOI.PREFERRED",
+ "CMOS.CITATIONS.S13_7.DOI.RESOLUTION",
+ "CMOS.CITATIONS.S13_7.DOI.URL_FORM",
+ "CMOS.CITATIONS.S13_71.BIBLIOGRAPHY.ALPHABETIZATION.PREFIXES_POLICY",
+ "CMOS.CITATIONS.S13_72.BIBLIOGRAPHY.SORTING.DIACRITICS_AND_TRANSLITERATION",
+ "CMOS.CITATIONS.S13_8.PERMALINK.PREFERRED",
+ "CMOS.CITATIONS.S13_8.PERMALINK.TEST",
+ "CMOS.CITATIONS.S13_8.PREFERRED_ORDER",
+ "CMOS.CITATIONS.S13_8.SUBSCRIPTION_URLS",
+ "CMOS.CITATIONS.S13_9.DATABASE_NAME_OK",
+ "CMOS.CITATIONS.S13_9.SHORTEN_LONG_URLS",
+ "CMOS.CITATIONS.S13_9.SHORT_URLS.ARE_NOT_SHORTENERS",
+ "CMOS.CITATIONS.S13_9.URL_TO_MAIN_PAGE",
+ "CMOS.CITATIONS.S13_90.TITLE_PUNCTUATION.CHANGES.POLICY_LIMITED",
+ "CMOS.CITATIONS.S13_91.TITLE_SUBTITLE.SEPARATOR.COLON",
+ "CMOS.CITATIONS.S13_92.BIBLIOGRAPHY.BOOKS.CORE_ELEMENTS",
+ "CMOS.CITATIONS.S13_93.BIBLIOGRAPHY.EDITED_VOLUMES.ROLE_MARKING",
+ "CMOS.CITATIONS.S13_94.TITLES.TRAILING_PHRASE.PLACEMENT",
+ "CMOS.CITATIONS.S13_95.BIBLIOGRAPHY.CHAPTERS.IN_EDITED_COLLECTIONS",
+ "CMOS.CITATIONS.S13_96.BIBLIOGRAPHY.JOURNAL_ARTICLES.VOLUME_ISSUE_PAGES",
+ "CMOS.CITATIONS.S13_97.BIBLIOGRAPHY.NEWSPAPER_MAGAZINE.DATES",
+ "CMOS.CITATIONS.S13_98.BIBLIOGRAPHY.THESES_DISSERTATIONS.INSTITUTION",
+ "CMOS.CITATIONS.S13_99.LONG_TITLES.TRUNCATION.AVOID",
"CMOS.CITATIONS.SYSTEM.CONSISTENT_CHOICE",
"CMOS.CITATIONS.TITLES.CAPITALIZATION.CONSISTENT",
+ "CMOS.FIGURES.ACCESSIBILITY.ALT_TEXT",
+ "CMOS.FIGURES.ANNOTATIONS.CONSISTENT_STYLE",
+ "CMOS.FIGURES.ASPECT_RATIO.PRESERVE",
+ "CMOS.FIGURES.AXES.UNITS.CONSISTENT",
+ "CMOS.FIGURES.BLEED.ONLY_WHEN_ENABLED",
+ "CMOS.FIGURES.CALL_OUTS.AVOID_OVERLAP",
+ "CMOS.FIGURES.CAPTION.ALIGNMENT.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.CREDITS.INLINE_OR_NOTE",
+ "CMOS.FIGURES.CAPTION.FONT.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.LENGTH.REASONABLE",
+ "CMOS.FIGURES.CAPTION.NUMBER.MATCH_LABEL",
+ "CMOS.FIGURES.CAPTION.PLACEMENT.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.PREFIX.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.PUNCTUATION.CONSISTENT",
+ "CMOS.FIGURES.CAPTIONS.PRESENT",
+ "CMOS.FIGURES.COLOR.NOT_SOLE_SIGNAL",
+ "CMOS.FIGURES.COLOR.PALETTE.CONSISTENT",
+ "CMOS.FIGURES.CONTRAST.SUFFICIENT",
+ "CMOS.FIGURES.CREDIT.SOURCE_WHEN_REQUIRED",
+ "CMOS.FIGURES.CROP.AVOID_LOSS",
+ "CMOS.FIGURES.EMBEDDED_TEXT.MINIMAL",
+ "CMOS.FIGURES.FILENAME.STABLE",
+ "CMOS.FIGURES.FORMAT.VECTOR_WHEN_POSSIBLE",
+ "CMOS.FIGURES.KEY.READABLE",
+ "CMOS.FIGURES.LABELS.AVOID_OVERLAP",
+ "CMOS.FIGURES.LABELS.FONT.CONSISTENT",
+ "CMOS.FIGURES.LEGENDS.EXPLAIN_SYMBOLS",
+ "CMOS.FIGURES.LINE_WEIGHTS.CONSISTENT",
+ "CMOS.FIGURES.LIST_ENTRIES.MATCH_CAPTIONS",
+ "CMOS.FIGURES.LIST_OF_FIGURES.WHEN_NEEDED",
+ "CMOS.FIGURES.MARGINS.AVOID_CLIPPING",
+ "CMOS.FIGURES.MULTIPART.PANEL_LABELS",
+ "CMOS.FIGURES.NUMBERING.SEQUENTIAL",
+ "CMOS.FIGURES.NUMBERING.WITHIN_CHAPTERS",
+ "CMOS.FIGURES.ORIENTATION.CONSISTENT",
+ "CMOS.FIGURES.PANEL_ORDER.LOGICAL",
+ "CMOS.FIGURES.PERMISSIONS.DOCUMENTED",
+ "CMOS.FIGURES.PLACEMENT.AVOID_SPLIT",
+ "CMOS.FIGURES.PLACEMENT.NEAR_MENTION",
+ "CMOS.FIGURES.PLACEMENT.TOP_OR_BOTTOM.CONSISTENT",
+ "CMOS.FIGURES.REFERENCES.IN_TEXT",
+ "CMOS.FIGURES.RESOLUTION.RASTER_SUFFICIENT",
+ "CMOS.FIGURES.SCALE.LEGIBLE",
+ "CMOS.FIGURES.SCALING.UNIFORM",
+ "CMOS.FIGURES.SENSITIVE.DATA.REDACT",
+ "CMOS.FIGURES.SIZE.MATCH_READABILITY",
+ "CMOS.FIGURES.SOURCE.DATA.CITED",
+ "CMOS.FIGURES.SYMBOLS.CONSISTENT",
+ "CMOS.FIGURES.TABLE_VS_FIGURE.CHOOSE",
+ "CMOS.FIGURES.UNITS.LABEL_AXES",
+ "CMOS.FRONTMATTER.ABSTRACT.WHEN_APPROPRIATE",
+ "CMOS.FRONTMATTER.ACCESSIBILITY.NOTES",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.NAMES.CONSISTENT",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.PLACEMENT",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.SCOPE",
+ "CMOS.FRONTMATTER.AUDIENCE.SCOPE.STATED",
+ "CMOS.FRONTMATTER.CHANGELOG.LINKS",
+ "CMOS.FRONTMATTER.CITATION_STYLE.DECLARED",
+ "CMOS.FRONTMATTER.CONTACT.OWNERSHIP",
+ "CMOS.FRONTMATTER.COPYRIGHT.NOTICES.PRESENT",
+ "CMOS.FRONTMATTER.COPYRIGHT.RIGHTS.CONTACT",
+ "CMOS.FRONTMATTER.DISCLAIMERS.WHEN_REQUIRED",
+ "CMOS.FRONTMATTER.EDITION.VERSION_VISIBLE",
+ "CMOS.FRONTMATTER.EPIGRAPH.ATTRIBUTION",
+ "CMOS.FRONTMATTER.EPIGRAPH.PLACEMENT.CONSISTENT",
+ "CMOS.FRONTMATTER.FOREWORD.AUTHOR.ATTRIBUTED",
+ "CMOS.FRONTMATTER.FOREWORD.DATE_IF_PRESENT",
+ "CMOS.FRONTMATTER.INTRODUCTION.SCOPE",
+ "CMOS.FRONTMATTER.LANGUAGE.NOTICE",
+ "CMOS.FRONTMATTER.LICENSE.ATTRIBUTION",
+ "CMOS.FRONTMATTER.LISTS.OF_FIGURES_TABLES.WHEN_NEEDED",
+ "CMOS.FRONTMATTER.LIST_OF_FIGURES.SECTION_TITLE",
+ "CMOS.FRONTMATTER.LIST_OF_TABLES.SECTION_TITLE",
+ "CMOS.FRONTMATTER.NAVIGATION.METADATA",
+ "CMOS.FRONTMATTER.PREFACE.DATE_IF_PRESENT",
+ "CMOS.FRONTMATTER.PREFACE.PURPOSE",
+ "CMOS.FRONTMATTER.READING_TIME.WHEN_HELPFUL",
+ "CMOS.FRONTMATTER.REVISION_HISTORY.WHEN_REQUIRED",
+ "CMOS.FRONTMATTER.SECURITY.CLASSIFICATION",
+ "CMOS.FRONTMATTER.TERMS.DEFINITIONS.EARLY",
+ "CMOS.FRONTMATTER.TITLEPAGE.PRESENT",
+ "CMOS.FRONTMATTER.TOC.ENTRIES.MATCH_HEADINGS",
+ "CMOS.FRONTMATTER.TOC.FRONT_BACK_MATTER.INCLUDED",
+ "CMOS.FRONTMATTER.TOC.INDENTATION.BY_LEVEL",
+ "CMOS.FRONTMATTER.TOC.LEADERS.CONSISTENT",
+ "CMOS.FRONTMATTER.TOC.LEVELS.CONSISTENT",
+ "CMOS.FRONTMATTER.TOC.ORDER.MATCH_BODY",
+ "CMOS.FRONTMATTER.TOC.PAGE_NUMBERS.MATCH",
+ "CMOS.FRONTMATTER.TOC.SHORT_TITLES.CONSISTENT",
+ "CMOS.FRONTMATTER.TOC.WHEN_NEEDED",
"CMOS.HEADINGS.DIVISIONS.CHAPTERS.MULTIAUTHOR",
"CMOS.HEADINGS.DIVISIONS.LETTERS_DIARIES.HEADINGS",
"CMOS.HEADINGS.LETTERS_DIARIES.DATELINE_FORMAT",
@@ -140,76 +721,450 @@
"CMOS.HEADINGS.RUNNING_HEADS.DIVISION_MATCH",
"CMOS.HEADINGS.RUNNING_HEADS.LENGTH_SHORT",
"CMOS.HEADINGS.RUNNING_HEADS.NAVIGATION_SCOPE",
+ "CMOS.I18N.ACRONYMS.LANGUAGE_SPECIFIC",
+ "CMOS.I18N.CAPITALIZATION.TITLES.LANGUAGE_RULES",
+ "CMOS.I18N.CITATIONS.TITLES.ORIGINAL_OR_TRANSLATED",
+ "CMOS.I18N.CURRENCY.CODES.LABEL",
+ "CMOS.I18N.DATES.FORMAT.CONSISTENT",
+ "CMOS.I18N.DIACRITICS.PRESERVE",
+ "CMOS.I18N.GLOSSARY.MULTILINGUAL",
+ "CMOS.I18N.HYPHENATION.LANGUAGE_TAGS",
+ "CMOS.I18N.ITALICS.FOREIGN_WORDS.SPARE",
+ "CMOS.I18N.LANGUAGE.CONSISTENT_SPELLING",
+ "CMOS.I18N.MEANINGFUL_TRANSLATIONS.NOT_LITERAL",
+ "CMOS.I18N.NAMES.SORTING.COLLATION",
+ "CMOS.I18N.NUMBERS.DECIMAL_SEPARATOR.LOCALE",
+ "CMOS.I18N.PARENS.BRACKETS.TRANSLATOR_NOTES",
+ "CMOS.I18N.PUNCTUATION.DASHES.MINUS_SIGN",
+ "CMOS.I18N.PUNCTUATION.ELLIPSIS.STYLE",
+ "CMOS.I18N.PUNCTUATION.SPACING.LANGUAGE_RULES",
+ "CMOS.I18N.QUOTES.NESTING.CONSISTENT",
+ "CMOS.I18N.QUOTES.STYLE.MATCH_LOCALE",
+ "CMOS.I18N.RIGHT_TO_LEFT.MARKUP",
+ "CMOS.I18N.ROMANIZATION.DIACRITICS.KEEP",
+ "CMOS.I18N.SCRIPT_MIXING.AVOID",
+ "CMOS.I18N.SECURITY.HOMOGLYPHS.AWARE",
+ "CMOS.I18N.TRANSLATION.INDICATE",
+ "CMOS.I18N.TRANSLITERATION.SYSTEM.CONSISTENT",
+ "CMOS.I18N.TYPOGRAPHY.FONT_COVERAGE",
+ "CMOS.I18N.UNITS.SYMBOLS.STANDARD",
+ "CMOS.LAYOUT.FOOTNOTES.PLACEMENT",
+ "CMOS.LAYOUT.FOOTNOTES.SEQUENCE",
+ "CMOS.LAYOUT.ILLUSTRATIONS.PLACEMENT_NEAR_REF",
+ "CMOS.LAYOUT.PAGINATION.FACING_PAGES.BALANCE",
+ "CMOS.LAYOUT.PAGINATION.FACING_PAGES.BLANKS",
+ "CMOS.LAYOUT.PAGINATION.PAGE_BREAKS.BEFORE_PARTS",
+ "CMOS.LAYOUT.PAGINATION.PAGE_NUMBERS.POSITION",
+ "CMOS.LAYOUT.PAGINATION.PAGE_NUMBERS.STYLE",
+ "CMOS.LAYOUT.PAGINATION.PAGE_SEQUENCE.CONTINUITY",
+ "CMOS.LAYOUT.PAGINATION.RUNNING_HEADS.CONSISTENCY",
+ "CMOS.LAYOUT.PAGINATION.RUNNING_HEADS.PLACEMENT",
+ "CMOS.LAYOUT.RUNNING_HEADS.CHAPTER_TITLES",
+ "CMOS.LAYOUT.RUNNING_HEADS.SECTION_TITLES",
+ "CMOS.LAYOUT.TABLES.PLACEMENT_NEAR_REF",
+ "CMOS.LINKS.HYPERLINK_EXCLUDES_PUNCTUATION",
+ "CMOS.LINKS.PUNCTUATE_NORMALLY",
+ "CMOS.LINKS.REPHRASE_IF_URL_ENDS_PUNCT",
+ "CMOS.LINKS.TRAILING_PUNCTUATION_OUTSIDE",
"CMOS.NUMBERS.BASES.NON_DECIMAL.NO_GROUPING",
"CMOS.NUMBERS.CENTURIES.SPELLED_OUT",
"CMOS.NUMBERS.CONSISTENCY.MIXED_FORMS.AVOID",
"CMOS.NUMBERS.CONTEXTS.ALWAYS_NUMERALS",
+ "CMOS.NUMBERS.CURRENCY.CODE_POSITION.CONSISTENT",
"CMOS.NUMBERS.CURRENCY.FORMAT.SYMBOL_PLACEMENT",
"CMOS.NUMBERS.CURRENCY.HISTORICAL.YEAR_CONTEXT",
"CMOS.NUMBERS.CURRENCY.ISO_CODES",
"CMOS.NUMBERS.CURRENCY.LARGE_AMOUNTS",
"CMOS.NUMBERS.CURRENCY.NON_US.DISAMBIGUATE",
+ "CMOS.NUMBERS.CURRENCY.RANGES.REPEAT_SYMBOL",
+ "CMOS.NUMBERS.CURRENCY.SYMBOL_ADJACENT",
"CMOS.NUMBERS.CURRENCY.WORDS_VS_SYMBOLS",
"CMOS.NUMBERS.DATES.ABBREVIATED_YEAR",
"CMOS.NUMBERS.DATES.ALL_NUMERAL",
"CMOS.NUMBERS.DATES.CONSISTENT_FORMAT",
+ "CMOS.NUMBERS.DATES.DAY_MONTH_ORDER.CONSISTENT",
"CMOS.NUMBERS.DATES.ISO_8601",
"CMOS.NUMBERS.DATES.MONTH_DAY_STYLE",
+ "CMOS.NUMBERS.DATES.ORDINALS.AVOID",
"CMOS.NUMBERS.DATES.YEAR_NUMERALS",
"CMOS.NUMBERS.DECADES.CONSISTENT_FORM",
+ "CMOS.NUMBERS.DECIMALS.TRAILING_ZEROS.AVOID",
"CMOS.NUMBERS.DENSE_CONTEXT.USE_NUMERALS",
"CMOS.NUMBERS.ERAS.BCE_CE",
+ "CMOS.NUMBERS.FRACTIONS.ADJECTIVAL.HYPHENATE",
"CMOS.NUMBERS.FRACTIONS.MATH.NUMERALS",
"CMOS.NUMBERS.FRACTIONS.MIXED.WHOLE_PLUS_FRACTION",
"CMOS.NUMBERS.FRACTIONS.SIMPLE.SPELL_OUT",
+ "CMOS.NUMBERS.FRACTIONS.SLASH_INLINE",
"CMOS.NUMBERS.INCLUSIVE.COMMAS",
+ "CMOS.NUMBERS.INCLUSIVE.SHORTEN_SECOND_NUMBER",
"CMOS.NUMBERS.INCLUSIVE.YEARS",
+ "CMOS.NUMBERS.INCLUSIVE.YEARS.CENTURY_CROSSING",
"CMOS.NUMBERS.INCLUSIVE_RANGES.PAGE_NUMBERS.SHORTEN",
"CMOS.NUMBERS.LARGE_VALUES.MILLIONS_BILLIONS",
"CMOS.NUMBERS.LISTS.OUTLINE.NUMERAL_STYLE",
"CMOS.NUMBERS.NAMES.MONARCHS_POPES",
"CMOS.NUMBERS.NUMERALS.MEASUREMENTS.UNITS",
+ "CMOS.NUMBERS.ORDINALS.CONSISTENT_FORM",
+ "CMOS.NUMBERS.PERCENTAGES.SYMBOL_NO_SPACE",
+ "CMOS.NUMBERS.PERCENTAGES.SYMBOL_OR_WORD.CONSISTENT",
"CMOS.NUMBERS.PERIODICALS.VOLUME_ISSUE",
"CMOS.NUMBERS.PLACES.BUILDINGS_APTS",
"CMOS.NUMBERS.PLACES.HIGHWAYS",
"CMOS.NUMBERS.PLACES.STREETS",
"CMOS.NUMBERS.PLURALS.SPELLED_OUT",
+ "CMOS.NUMBERS.RANGES.NO_MIXED_FROM_BETWEEN",
+ "CMOS.NUMBERS.RANGES.REPEAT_UNIT_IF_AMBIG",
+ "CMOS.NUMBERS.RANGES.UNITS.PLACEMENT_CONSISTENT",
+ "CMOS.NUMBERS.RATIOS.COLON_SPACING",
"CMOS.NUMBERS.RATIOS.FORMAT",
"CMOS.NUMBERS.REFERENCES.PAGE_CHAPTER_FIGURE",
+ "CMOS.NUMBERS.ROMAN_NUMERALS.CASE_CONSISTENT",
"CMOS.NUMBERS.ROMAN_NUMERALS.USE",
"CMOS.NUMBERS.ROUND_NUMBERS.SPELL_OUT",
"CMOS.NUMBERS.RULE_SELECTION.ALTERNATIVE_ZERO_TO_NINE",
"CMOS.NUMBERS.RULE_SELECTION.GENERAL_OR_ALTERNATIVE",
+ "CMOS.NUMBERS.S9_1.GENERAL_WORKS_SCOPE",
+ "CMOS.NUMBERS.S9_1.OVERVIEW.FACTORS",
+ "CMOS.NUMBERS.S9_1.READABILITY_OVER_CONSISTENCY",
+ "CMOS.NUMBERS.S9_10.NEGATIVE_POWERS",
+ "CMOS.NUMBERS.S9_10.POWERS_OF_TEN",
+ "CMOS.NUMBERS.S9_10.SCIENTIFIC_NOTATION.USE",
+ "CMOS.NUMBERS.S9_10.SCI_NOTATION.CONSISTENT",
+ "CMOS.NUMBERS.S9_11.MYR_GYR",
+ "CMOS.NUMBERS.S9_11.PREFIX_SYMBOLS",
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.LARGE",
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.SMALL",
+ "CMOS.NUMBERS.S9_12.BASE_INDICATOR",
+ "CMOS.NUMBERS.S9_12.BASE_PREFIXES",
+ "CMOS.NUMBERS.S9_12.BASE_SUBSCRIPT",
+ "CMOS.NUMBERS.S9_12.BINARY_PREFIXES",
+ "CMOS.NUMBERS.S9_12.DECIMAL_PREFIXES",
+ "CMOS.NUMBERS.S9_12.NO_COMMAS.IN_BASE",
+ "CMOS.NUMBERS.S9_13.DEX.DEFINITION",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.COMMON_NUMERALS",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.CONSISTENCY",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.EXACT_VALUES",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.GENERAL_RULE",
+ "CMOS.NUMBERS.S9_15.DECIMAL_FRACTIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.EMPHASIS_EXCEPTION",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.HYPHENATE",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.FRACTION_SYMBOLS",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.MEASUREMENTS",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.NUMERALS",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.SHORT_SPELLED_OUT",
+ "CMOS.NUMBERS.S9_17.ALGEBRAIC.SLASH",
+ "CMOS.NUMBERS.S9_17.CASE_FRACTIONS.USE_WITH_CARE",
+ "CMOS.NUMBERS.S9_17.DISPLAYED_FRACTIONS.BAR",
+ "CMOS.NUMBERS.S9_17.EXPONENT_FRACTIONS.SLASH",
+ "CMOS.NUMBERS.S9_17.FRACTIONS.IN_NUMERATOR_DENOMINATOR",
+ "CMOS.NUMBERS.S9_17.FRACTIONS.PARENS_BEFORE_SYMBOLS",
+ "CMOS.NUMBERS.S9_17.FRACTIONS.RUNNING_TEXT.SLASH",
+ "CMOS.NUMBERS.S9_17.SLASH_BINDING",
+ "CMOS.NUMBERS.S9_18.ABBREVIATIONS.NUMERALS_ONLY",
+ "CMOS.NUMBERS.S9_18.NO_HYPHEN.NUMERAL_UNIT",
+ "CMOS.NUMBERS.S9_18.NO_SPACE.DEGREE_PERCENT_PRIME",
+ "CMOS.NUMBERS.S9_18.PRIME_SYMBOLS",
+ "CMOS.NUMBERS.S9_18.SCIENTIFIC_CONTEXT.NUMERALS",
+ "CMOS.NUMBERS.S9_18.SPACING.NUMERAL_UNIT",
+ "CMOS.NUMBERS.S9_18.UNIT_WITHOUT_NUMERAL.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_19.REPEAT_UNITS.CLOSED_UP",
+ "CMOS.NUMBERS.S9_19.UNIT_REPETITION.CONSISTENT",
+ "CMOS.NUMBERS.S9_19.UNIT_SPACED.SINGLE",
+ "CMOS.NUMBERS.S9_2.GENERAL_RULE.ZERO_TO_ONE_HUNDRED",
+ "CMOS.NUMBERS.S9_2.NONROUND.ABOVE_ONE_HUNDRED",
+ "CMOS.NUMBERS.S9_2.ROUND_MULTIPLES.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_20.PERCENT.LESS_FREQUENT",
+ "CMOS.NUMBERS.S9_20.PERCENT.NUMERALS",
+ "CMOS.NUMBERS.S9_20.PERCENT.WORD_VS_SYMBOL",
+ "CMOS.NUMBERS.S9_20.PERCENT_RANGES.REPEAT",
+ "CMOS.NUMBERS.S9_20.PERCENT_VS_PERCENTAGE",
+ "CMOS.NUMBERS.S9_21.DECIMALS.NUMERALS",
+ "CMOS.NUMBERS.S9_21.DECIMAL_CONTEXT.CONSISTENT",
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.CALIBERS",
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.CONTEXT",
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.OMIT_PROBABILITIES",
+ "CMOS.NUMBERS.S9_21.UNITS.LESS_THAN_ONE",
+ "CMOS.NUMBERS.S9_22.MONEY.DECIMALS.ONLY_WHEN_MIXED",
+ "CMOS.NUMBERS.S9_22.MONEY.MINIMUM_DECIMALS",
+ "CMOS.NUMBERS.S9_22.MONEY.NUMERALS_EXACT",
+ "CMOS.NUMBERS.S9_22.MONEY.SINGULAR_VERB",
+ "CMOS.NUMBERS.S9_22.MONEY.SPELL_OUT_SMALL",
+ "CMOS.NUMBERS.S9_22.MONEY.SYMBOL_OR_WORD",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.CONTEXT_CLEAR",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.DISAMBIGUATE",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.ISO_CODES",
+ "CMOS.NUMBERS.S9_24.BRITISH.DECIMAL_FORMAT",
+ "CMOS.NUMBERS.S9_24.BRITISH.PENCE_SYMBOL",
+ "CMOS.NUMBERS.S9_24.BRITISH.POUND_SYMBOL",
+ "CMOS.NUMBERS.S9_25.CURRENCY_CODES.CONSISTENT",
+ "CMOS.NUMBERS.S9_25.CURRENCY_CODES.SPACING",
+ "CMOS.NUMBERS.S9_25.ISO_CODES.FORMAL",
+ "CMOS.NUMBERS.S9_25.OTHER_CURRENCIES.DECIMAL",
+ "CMOS.NUMBERS.S9_26.K_THOUSANDS",
+ "CMOS.NUMBERS.S9_26.LARGE_MONEY.MIXED",
+ "CMOS.NUMBERS.S9_26.LARGE_MONEY.NUMERALS",
+ "CMOS.NUMBERS.S9_26.MONEY.COMMAS",
+ "CMOS.NUMBERS.S9_27.CURRENCY_YEAR.CODES_SPACING",
+ "CMOS.NUMBERS.S9_27.CURRENCY_YEAR.PARENS_NO_SPACE",
+ "CMOS.NUMBERS.S9_28.BIBLICAL_REFERENCES",
+ "CMOS.NUMBERS.S9_28.DIVISIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_28.FRONT_MATTER.ROMAN",
+ "CMOS.NUMBERS.S9_29.PERIODICALS.OMIT_WORDS",
+ "CMOS.NUMBERS.S9_29.PERIODICALS.ORDER",
+ "CMOS.NUMBERS.S9_3.ALTERNATIVE_ROUND_MULTIPLES",
+ "CMOS.NUMBERS.S9_3.ALTERNATIVE_RULE.ZERO_TO_NINE",
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.MIXED_LEVELS",
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.PREFER_ARABIC",
+ "CMOS.NUMBERS.S9_31.YEAR_SENTENCE_START_ALLOWED",
+ "CMOS.NUMBERS.S9_31.YEAR_STANDALONE",
+ "CMOS.NUMBERS.S9_32.ABBREVIATED_YEAR.APOSTROPHE",
+ "CMOS.NUMBERS.S9_33.DAY_WITHOUT_MONTH.ORDINAL",
+ "CMOS.NUMBERS.S9_33.MONTH_DAY.CARDINALS",
+ "CMOS.NUMBERS.S9_33.MONTH_DAY_YEAR.COMMA",
+ "CMOS.NUMBERS.S9_34.CENTURIES.NUMERAL_PLURALS",
+ "CMOS.NUMBERS.S9_34.CENTURIES.ORDINAL_LOWERCASE",
+ "CMOS.NUMBERS.S9_34.CENTURY_TURN.AVOID_AMBIGUITY",
+ "CMOS.NUMBERS.S9_35.DECADES.FIRST_DECADE",
+ "CMOS.NUMBERS.S9_35.DECADES.NO_APOSTROPHE",
+ "CMOS.NUMBERS.S9_35.DECADES.SECOND_DECADE",
+ "CMOS.NUMBERS.S9_36.ERAS.ABBREVIATION_PLACEMENT",
+ "CMOS.NUMBERS.S9_36.ERAS.CENTURY_PLACEMENT",
+ "CMOS.NUMBERS.S9_36.ERAS.NO_PERIODS",
+ "CMOS.NUMBERS.S9_4.APPROXIMATIONS.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_4.HUNDREDS_THOUSANDS.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_4.MIXED_LARGE_CONTEXTS",
+ "CMOS.NUMBERS.S9_4.NONROUND.LARGE_NUMERALS",
+ "CMOS.NUMBERS.S9_5.ALPHANUMERIC.MAY_BEGIN",
+ "CMOS.NUMBERS.S9_5.SENTENCE_INITIAL.RECAST",
+ "CMOS.NUMBERS.S9_5.SENTENCE_INITIAL.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_5.TWO_NUMBERS.SAME_CATEGORY",
+ "CMOS.NUMBERS.S9_5.YEARS.MAY_BEGIN",
+ "CMOS.NUMBERS.S9_6.NTH_DEGREE.ITALIC_N",
+ "CMOS.NUMBERS.S9_6.ORDINALS.RULE_PARALLEL",
+ "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.ND_RD",
+ "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.NO_SUPERSCRIPT",
+ "CMOS.NUMBERS.S9_6.ZERO.ORDINAL_TH",
+ "CMOS.NUMBERS.S9_7.AVOID_DENSE_WORDS",
+ "CMOS.NUMBERS.S9_7.CATEGORY_TRIGGER",
+ "CMOS.NUMBERS.S9_7.CONSISTENT_CONTEXT",
+ "CMOS.NUMBERS.S9_7.CROSS_CATEGORY.MIX_OK",
+ "CMOS.NUMBERS.S9_7.DOCUMENT_EXCEPTIONS",
+ "CMOS.NUMBERS.S9_7.SENTENCE_START_EXCEPTION",
+ "CMOS.NUMBERS.S9_8.ABBREVIATED_UNITS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.CLOTHING_SIZES.NUMERALS",
+ "CMOS.NUMBERS.S9_8.DATES.NUMERALS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.ACT_SCENE",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.BOXES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.CHAPTERS_PARTS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.EXAMPLES_QUESTIONS_RULES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.FIGURES_TABLES_EQUATIONS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.NOTES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.PAGES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.SECTIONS_PARAS_LINES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.VOLUMES_ISSUES",
+ "CMOS.NUMBERS.S9_8.GRADES_LEVELS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.PERCENT.NUMERALS",
+ "CMOS.NUMBERS.S9_8.PLACES.STREETS_ROOMS",
+ "CMOS.NUMBERS.S9_8.SCORES_VOTES.NUMERALS",
+ "CMOS.NUMBERS.S9_8.SEVERITY_CLASSIFICATIONS",
+ "CMOS.NUMBERS.S9_8.SYMBOLS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.TITLE_NUMBERS",
+ "CMOS.NUMBERS.S9_9.BILLION_TRILLION.LOCALE_CHECK",
+ "CMOS.NUMBERS.S9_9.CONSISTENCY.WITH_FRACTIONS",
+ "CMOS.NUMBERS.S9_9.MILLIONS_BILLIONS.GENERAL_RULE",
+ "CMOS.NUMBERS.S9_9.MIXED_NUMERAL_WORD.FRACTIONS",
+ "CMOS.NUMBERS.SCIENTIFIC.NOTATION.MANTISSA_RANGE",
+ "CMOS.NUMBERS.SCIENTIFIC.NOTATION.TIMES_SYMBOL",
"CMOS.NUMBERS.SCIENTIFIC.POWERS_OF_TEN",
"CMOS.NUMBERS.SENTENCE_START.AVOID_NUMERAL",
"CMOS.NUMBERS.SPELLING.ONE_TO_ONE_HUNDRED.DEFAULT",
+ "CMOS.NUMBERS.TELEPHONE.COUNTRY_CODE.WHEN_INTERNATIONAL",
"CMOS.NUMBERS.TELEPHONE.FORMAT",
+ "CMOS.NUMBERS.TELEPHONE.SEPARATORS.CONSISTENT",
+ "CMOS.NUMBERS.TIME.AM_PM.CONSISTENT_SPACING",
"CMOS.NUMBERS.TIME.GENERAL_NUMERALS",
"CMOS.NUMBERS.TIME.ISO_STYLE",
+ "CMOS.NUMBERS.TIME.LEADING_ZERO_MINUTES",
"CMOS.NUMBERS.TIME.NOON_MIDNIGHT",
+ "CMOS.NUMBERS.TIME.RANGES.CONSISTENT_FORMAT",
+ "CMOS.NUMBERS.TIME.SECONDS.INCLUDE_FOR_PRECISION",
+ "CMOS.NUMBERS.TIME.SECONDS.OMIT_IF_NOT_NEEDED",
"CMOS.NUMBERS.TIME.TWENTY_FOUR_HOUR",
+ "CMOS.NUMBERS.TIME.ZONE.INCLUDE_WHEN_AMBIGUOUS",
"CMOS.NUMBERS.UNITS.REPEATED.OMIT_REPEAT",
+ "CMOS.NUMBERS.UNITS.SPACE_BETWEEN_NUMBER_UNIT",
"CMOS.NUMBERS.VEHICLES.VESSELS_NUMBERS",
+ "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.ELECTRONIC_PREFERS_LOGICAL",
+ "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.PRINT_ONLY",
+ "CMOS.PUNCTUATION.APOSTROPHE.USE_CASES",
+ "CMOS.PUNCTUATION.BOLD_COLOR.CASE_BY_CASE",
+ "CMOS.PUNCTUATION.BOLD_COLOR.SEMANTIC_OWNERSHIP",
+ "CMOS.PUNCTUATION.BRACKETS.EDITORIAL_INSERTIONS",
"CMOS.PUNCTUATION.BRACKETS.NESTED_PARENS",
"CMOS.PUNCTUATION.BRACKETS.TRANSLATED_TEXT",
+ "CMOS.PUNCTUATION.COLONS.AMPLIFY_OR_ILLUSTRATE",
"CMOS.PUNCTUATION.COLONS.AS_FOLLOWS",
+ "CMOS.PUNCTUATION.COLONS.AVOID_AFTER_PREPOSITION",
+ "CMOS.PUNCTUATION.COLONS.AVOID_INCOMPLETE_LEADIN",
"CMOS.PUNCTUATION.COLONS.CAPITALIZATION",
+ "CMOS.PUNCTUATION.COLONS.COMPLETE_CLAUSE_REQUIRED",
+ "CMOS.PUNCTUATION.COLONS.EMPHASIS_SECOND_CLAUSE",
+ "CMOS.PUNCTUATION.COLONS.FORMAL_GREETINGS",
+ "CMOS.PUNCTUATION.COLONS.INTRODUCE_FORMAL_LISTS",
"CMOS.PUNCTUATION.COLONS.INTRO_QUOTE_QUESTION",
+ "CMOS.PUNCTUATION.COLONS.ONE_SPACE",
+ "CMOS.PUNCTUATION.COLONS.QUOTATIONS",
"CMOS.PUNCTUATION.COMMAS.ADDRESSES",
+ "CMOS.PUNCTUATION.COMMAS.ADDRESSES.MAILING_SPARING",
+ "CMOS.PUNCTUATION.COMMAS.ADDRESSES.RUN_IN",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL.INTRO_OPTIONAL",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL.MID_END",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_END",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_INTRO_OPTIONAL",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_INVERTED",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_MID",
+ "CMOS.PUNCTUATION.COMMAS.AMPERSAND.NO_SERIAL",
+ "CMOS.PUNCTUATION.COMMAS.AND_THEN",
"CMOS.PUNCTUATION.COMMAS.APPOSITIVES",
+ "CMOS.PUNCTUATION.COMMAS.APPOSITIVES.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.BRACKETS.EDITORIAL",
+ "CMOS.PUNCTUATION.COMMAS.BRACKETS.EDITORIAL_INSERT",
+ "CMOS.PUNCTUATION.COMMAS.COMMA_SPLICE.AVOID_FORMAL",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.CLARITY",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.NO_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.SERIES",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.THEN_SHORTHAND",
"CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATES",
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTION_PLUS_PHRASE.INDEPENDENT",
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTION_PLUS_PHRASE.PREDICATE",
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTIVE_ADVERBS",
+ "CMOS.PUNCTUATION.COMMAS.CONSECUTIVE_CONJUNCTIONS",
+ "CMOS.PUNCTUATION.COMMAS.CONSECUTIVE_CONJUNCTIONS.NO_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.COORDINATE_ADJECTIVES",
+ "CMOS.PUNCTUATION.COMMAS.CORPORATE_SUFFIX",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE.INDEPENDENT_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE.PREDICATE",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE_PHRASES",
"CMOS.PUNCTUATION.COMMAS.DATES",
+ "CMOS.PUNCTUATION.COMMAS.DATES.ALTERNATE_SYSTEMS",
+ "CMOS.PUNCTUATION.COMMAS.DATES.MONTH_DAY_YEAR",
+ "CMOS.PUNCTUATION.COMMAS.DATES.NO_COMMA_OTHER_STYLES",
"CMOS.PUNCTUATION.COMMAS.DEPENDENT_CLAUSE_AFTER",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING.RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING_NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING_RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_INTRO",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_INTRODUCTORY",
+ "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASE",
"CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASES",
+ "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASES.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS",
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS.GREETINGS",
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_QUESTIONS",
+ "CMOS.PUNCTUATION.COMMAS.ELISION",
+ "CMOS.PUNCTUATION.COMMAS.ETC.FINAL_ELEMENT",
+ "CMOS.PUNCTUATION.COMMAS.ETC.FORMAL_LIMIT",
+ "CMOS.PUNCTUATION.COMMAS.ETC.TRAILING",
+ "CMOS.PUNCTUATION.COMMAS.ETC_ETAL.STYLE",
+ "CMOS.PUNCTUATION.COMMAS.ETC_SINGLE_ITEM",
+ "CMOS.PUNCTUATION.COMMAS.EXPLANATORY_ALTERNATIVES",
+ "CMOS.PUNCTUATION.COMMAS.HOMONYMS.CLARITY",
+ "CMOS.PUNCTUATION.COMMAS.IE_EG.PARENS",
+ "CMOS.PUNCTUATION.COMMAS.IMPERATIVE_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.IMPERATIVE_CLAUSES.DEFAULT",
+ "CMOS.PUNCTUATION.COMMAS.INC_LTD.NONE",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.CONJUNCTION",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.SHORT",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.SHORT_OMIT",
+ "CMOS.PUNCTUATION.COMMAS.INDIRECT_QUESTIONS",
"CMOS.PUNCTUATION.COMMAS.INTRODUCTORY_ELEMENTS.CLARITY",
"CMOS.PUNCTUATION.COMMAS.INTRODUCTORY_PHRASES",
+ "CMOS.PUNCTUATION.COMMAS.INTRO_OH_AH",
+ "CMOS.PUNCTUATION.COMMAS.INTRO_PHRASES.GENERAL",
+ "CMOS.PUNCTUATION.COMMAS.INTRO_YES_NO",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.INVERTED",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.NONE",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.RUNNING",
+ "CMOS.PUNCTUATION.COMMAS.LOGIC_OVER_PAUSE",
"CMOS.PUNCTUATION.COMMAS.NONRESTRICTIVE.SET_OFF",
+ "CMOS.PUNCTUATION.COMMAS.NOT_PHRASE",
+ "CMOS.PUNCTUATION.COMMAS.NOT_PHRASES",
+ "CMOS.PUNCTUATION.COMMAS.PAIRS.SECOND_REQUIRED",
+ "CMOS.PUNCTUATION.COMMAS.PAIRS.TITLES_EXCEPTION",
+ "CMOS.PUNCTUATION.COMMAS.PARENS.TRAILING",
+ "CMOS.PUNCTUATION.COMMAS.PARENS_BRACKETS.AFTER_CLOSING",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICALS.SLIGHT_BREAK",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_ELEMENTS",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_HEAVY",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL.LINKING_VERB",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_INTRO",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_LINKING_VERB",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_MID_END",
"CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_PHRASES",
+ "CMOS.PUNCTUATION.COMMAS.PHRASE_PLUS_CONJUNCTION",
"CMOS.PUNCTUATION.COMMAS.QUESTIONS",
+ "CMOS.PUNCTUATION.COMMAS.QUESTIONS.DIRECT_IN_SENTENCE",
+ "CMOS.PUNCTUATION.COMMAS.QUESTIONS.INDIRECT",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.DIALOGUE",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.DIALOGUE_VERB_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.NO_COMMA_CONJUNCTION",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.THAT_WHETHER",
"CMOS.PUNCTUATION.COMMAS.QUOTED_TITLES",
+ "CMOS.PUNCTUATION.COMMAS.QUOTE_ENDING_QM_EXCL",
+ "CMOS.PUNCTUATION.COMMAS.REGISTER.FLEX",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIPS.AVOID_POSSESSIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIPS.UNIQUE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_ALWAYS_USE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_AWKWARD_POSSESSIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_NAMES",
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_THAT_WHICH",
"CMOS.PUNCTUATION.COMMAS.REPEATED_ADJECTIVES",
+ "CMOS.PUNCTUATION.COMMAS.REPEATED_ADJECTIVES.USE_COMMA",
"CMOS.PUNCTUATION.COMMAS.RESTRICTIVE.NO_SET_OFF",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.ALL_CONJUNCTIONS",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.ALL_CONJUNCTIONS_NO_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.AMBIGUITY_REWORD",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.AS_WELL_AS",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.PAIR_LAST_ITEM",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.PAIR_WITH_AND",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.REQUIRED",
+ "CMOS.PUNCTUATION.COMMAS.SPLICES.EDITORIAL_DISCRETION",
+ "CMOS.PUNCTUATION.COMMAS.SUCH_AS_INCLUDING",
+ "CMOS.PUNCTUATION.COMMAS.THAT_IS.TRAILING_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.THAT_IS_NAMELY",
+ "CMOS.PUNCTUATION.COMMAS.THE_MORE_THE_MORE",
+ "CMOS.PUNCTUATION.COMMAS.TITLES.APPOSITIVE_RULE",
+ "CMOS.PUNCTUATION.COMMAS.TITLES_AND_EXPRESSIONS",
+ "CMOS.PUNCTUATION.COMMAS.TOO_EITHER.OMIT",
+ "CMOS.PUNCTUATION.COMMAS.TOO_MID_SENTENCE",
+ "CMOS.PUNCTUATION.DASHES.DISTINCT_TYPES",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.ALTERNATIVE_TO_PARENS",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.AVOID_NESTED",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.DIALOGUE_STYLE",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.LISTS_TABLES",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.PUNCTUATION_BEFORE",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.SPARE_USE",
"CMOS.PUNCTUATION.DASHES.EM_INSTEAD_OF_QUOTES",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.AVOID_FROM_BETWEEN",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.MINUS_SIGN",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.SPACED_BRITISH",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.WORD_RANGES",
+ "CMOS.PUNCTUATION.DASHES.TWO_EM.OMISSIONS",
+ "CMOS.PUNCTUATION.ELLIPSIS.USE_CASES",
+ "CMOS.PUNCTUATION.EMOJIS.PUNCTUATION",
+ "CMOS.PUNCTUATION.EXCLAMATION.BRACKETED_AVOID",
+ "CMOS.PUNCTUATION.EXCLAMATION.QUOTE_PLACEMENT",
+ "CMOS.PUNCTUATION.EXCLAMATION.RHETORICAL",
+ "CMOS.PUNCTUATION.EXCLAMATION.USE_SPARING",
"CMOS.PUNCTUATION.EXCLAMATION.USE_SPARINGLY",
"CMOS.PUNCTUATION.EXCLAMATION.VS_QUESTION",
"CMOS.PUNCTUATION.HYPHENATION.COMPOUND_DEFINITION",
@@ -219,21 +1174,334 @@
"CMOS.PUNCTUATION.HYPHENATION.TREND_CLOSED",
"CMOS.PUNCTUATION.HYPHENS.ADVERB_LY.NO_HYPHEN",
"CMOS.PUNCTUATION.HYPHENS.COMPOUND_MODIFIERS.BEFORE_NOUN",
+ "CMOS.PUNCTUATION.HYPHENS.NUMERIC_COMPOUNDS",
+ "CMOS.PUNCTUATION.HYPHENS.SEPARATORS",
+ "CMOS.PUNCTUATION.ITALICS.SURROUNDING_STYLE",
+ "CMOS.PUNCTUATION.ITALICS.TITLE_OWNERSHIP",
+ "CMOS.PUNCTUATION.LISTS.AVOID_VERTICAL_FOR_LONG_SENTENCES",
+ "CMOS.PUNCTUATION.LISTS.CONSISTENT_FORMAT",
+ "CMOS.PUNCTUATION.LISTS.MIXED_SENTENCE_TYPES",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.MULTI_DIGIT_ALIGN",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.OUTLINE_MARKERS",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.PUNCTUATION_LEVELS",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.RUNOVER_ALIGN",
+ "CMOS.PUNCTUATION.LISTS.NUMERALS_ONLY_IF_NEEDED",
+ "CMOS.PUNCTUATION.LISTS.PARALLEL_ELEMENTS",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.INTRO_COMPLETE_COLON",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.LETTERS.ITALIC_OPTION",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.MARKERS.PARENS",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SENTENCE_ITEMS_VERTICAL",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SEPARATORS",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SHORT_SIMPLE",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.CAPITALIZATION_CONSISTENT",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.END_PUNCT_SENTENCES",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.INTRO_COLON",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.LONG_OR_MULTI",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.MULTI_COLUMN_SHORT_ITEMS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.ORDERED_MARKERS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.RUNOVER_ALIGN",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_CONJUNCTION",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_LOWERCASE",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_PUNCTUATION",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_USE_ONLY_FOR_EMPHASIS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.UNORDERED_FRAGMENTS",
+ "CMOS.PUNCTUATION.OVERVIEW.CONSISTENT.PRINCIPLES",
+ "CMOS.PUNCTUATION.OVERVIEW.CONTEXT.REGISTER",
+ "CMOS.PUNCTUATION.OVERVIEW.FUNCTION.CLARITY",
+ "CMOS.PUNCTUATION.PARENS.AVOID_MULTIPLE_SENTENCES",
"CMOS.PUNCTUATION.PARENS.GLOSSES_TRANSLATIONS",
"CMOS.PUNCTUATION.PARENS.NESTING",
+ "CMOS.PUNCTUATION.PARENS.PUNCTUATION_PLACEMENT",
"CMOS.PUNCTUATION.PARENS.USE",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.LINE_ALONE",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.MATCH_SURROUNDING",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.PRINT_HAIR_SPACE",
+ "CMOS.PUNCTUATION.PERIODS.NOT_WITH_QM_EXCL",
+ "CMOS.PUNCTUATION.PERIODS.NO_DOUBLE_AT_SENTENCE_END",
+ "CMOS.PUNCTUATION.PERIODS.OMIT_DISPLAY_LINES",
"CMOS.PUNCTUATION.PERIODS.USE",
"CMOS.PUNCTUATION.PERIODS.WITH_PARENS",
+ "CMOS.PUNCTUATION.QUESTION_EXCLAMATION.DUAL_MARKS",
"CMOS.PUNCTUATION.QUESTION_MARK.DIRECT_VS_INDIRECT",
"CMOS.PUNCTUATION.QUESTION_MARK.USE",
"CMOS.PUNCTUATION.QUESTION_MARK.WITH_PUNCT",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.DIRECT",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.DIRECT_INDIRECT",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.LIST_INTRO",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.QUOTE_PLACEMENT",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.SURROUNDING",
"CMOS.PUNCTUATION.QUOTATION_MARKS.DOUBLE_PRIMARY_US",
"CMOS.PUNCTUATION.QUOTATION_MARKS.PUNCTUATION_PLACEMENT_US",
+ "CMOS.PUNCTUATION.QUOTES.ALT_STYLE.DOCUMENT",
+ "CMOS.PUNCTUATION.QUOTES.APOSTROPHE_NOT_QUOTE",
+ "CMOS.PUNCTUATION.QUOTES.ITALIC_TITLE_EXCEPTION",
+ "CMOS.PUNCTUATION.QUOTES.LINE_ALONE",
+ "CMOS.PUNCTUATION.QUOTES.MATCH_SURROUNDING",
+ "CMOS.PUNCTUATION.QUOTES.US_STYLE_PERIODS_COMMAS",
+ "CMOS.PUNCTUATION.SEMICOLONS.AVOID_COMMA_SPLICE",
+ "CMOS.PUNCTUATION.SEMICOLONS.AVOID_DIALOGUE",
"CMOS.PUNCTUATION.SEMICOLONS.BEFORE_CONJUNCTION",
+ "CMOS.PUNCTUATION.SEMICOLONS.COMPLEX_SERIES",
"CMOS.PUNCTUATION.SEMICOLONS.COMPLEX_SERIES.SEPARATE",
+ "CMOS.PUNCTUATION.SEMICOLONS.CONJUNCTIVE_ADVERBS",
"CMOS.PUNCTUATION.SEMICOLONS.CONJUNCTIVE_PHRASES",
+ "CMOS.PUNCTUATION.SEMICOLONS.INDEPENDENT_CLAUSES",
+ "CMOS.PUNCTUATION.SEMICOLONS.THAT_IS_CLAUSE",
"CMOS.PUNCTUATION.SLASHES.ALTERNATIVES",
- "CMOS.PUNCTUATION.SLASHES.TWO_YEAR_SPANS"
+ "CMOS.PUNCTUATION.SLASHES.NO_SPACES",
+ "CMOS.PUNCTUATION.SLASHES.TWO_YEAR_SPANS",
+ "CMOS.PUNCTUATION.SPACING.DESIGN_SPECIFIED",
+ "CMOS.PUNCTUATION.SPACING.FIXED_WIDTHS",
+ "CMOS.PUNCTUATION.SPACING.NONBREAKING",
+ "CMOS.PUNCTUATION.SPACING.ONE_SPACE_AFTER_COLON",
+ "CMOS.PUNCTUATION.SPACING.ONE_SPACE_SENTENCES",
+ "CMOS.PUNCTUATION.SPACING.WORD_SPACE_DEFAULT",
+ "CMOS.PUNCTUATION.URLS.HYPERTEXT_EXCLUDES_PUNCTUATION",
+ "CMOS.PUNCTUATION.URLS.NO_WRAPPERS",
+ "CMOS.PUNCTUATION.URLS.PUNCTUATE_NORMALLY",
+ "CMOS.PUNCTUATION.URLS.TRAILING_PUNCTUATION",
+ "CMOS.TABLES.ABBREVIATIONS.EXPLAIN",
+ "CMOS.TABLES.ALIGNMENT.NUMERIC_DECIMAL",
+ "CMOS.TABLES.ALIGNMENT.TEXT_LEFT",
+ "CMOS.TABLES.CAPTIONS.BREVITY",
+ "CMOS.TABLES.CAPTIONS.CLARITY",
+ "CMOS.TABLES.CAPTIONS.PRESENT",
+ "CMOS.TABLES.COLUMN_ORDER.LOGICAL",
+ "CMOS.TABLES.COLUMN_SPACING.READABLE",
+ "CMOS.TABLES.DATA_TYPES.NOT_MIXED",
+ "CMOS.TABLES.FOOTNOTES.PLACEMENT",
+ "CMOS.TABLES.GRIDLINES.LIGHT",
+ "CMOS.TABLES.GROUPING.WHITESPACE",
+ "CMOS.TABLES.HEADERS.ALIGNMENT.CONSISTENT",
+ "CMOS.TABLES.HEADERS.CAPITALIZATION.CONSISTENT",
+ "CMOS.TABLES.HEADERS.REQUIRED",
+ "CMOS.TABLES.MISSING_VALUES.EXPLAIN",
+ "CMOS.TABLES.NOTES.ORDERED_MARKERS",
+ "CMOS.TABLES.PRECISION.CONSISTENT",
+ "CMOS.TABLES.REFERENCES.IN_TEXT",
+ "CMOS.TABLES.ROTATION.LANDSCAPE.WHEN_NEEDED",
+ "CMOS.TABLES.ROUNDING.CONSISTENT",
+ "CMOS.TABLES.ROW_ORDER.LOGICAL",
+ "CMOS.TABLES.ROW_SPACING.READABLE",
+ "CMOS.TABLES.RULES.MINIMAL",
+ "CMOS.TABLES.SHADING.SPARING",
+ "CMOS.TABLES.SORTING.LOGICAL",
+ "CMOS.TABLES.SOURCE.NOTES.DISTINCT",
+ "CMOS.TABLES.SPLITS.AVOID_ROW_BREAKS",
+ "CMOS.TABLES.SPLITS.REPEAT_HEADERS",
+ "CMOS.TABLES.STUB_COLUMN.USE",
+ "CMOS.TABLES.SUBTOTALS.CLEAR",
+ "CMOS.TABLES.TITLES.NUMBERING.SEQUENTIAL",
+ "CMOS.TABLES.TITLES.PLACEMENT.CONSISTENT",
+ "CMOS.TABLES.TITLES.SCOPE.CONSISTENT",
+ "CMOS.TABLES.UNITS.CONSISTENT",
+ "CMOS.TABLES.UNITS.IN_HEADERS",
+ "CMOS.TABLES.WIDTH.FIT_PAGE",
+ "HOUSE.ACCESSIBILITY.CODE.FENCES.LANGUAGE",
+ "HOUSE.ACCESSIBILITY.COLOR.NOT_SOLE_CONVEYOR",
+ "HOUSE.ACCESSIBILITY.CONTRAST.NON_TEXT",
+ "HOUSE.ACCESSIBILITY.CONTRAST.TEXT_READABLE",
+ "HOUSE.ACCESSIBILITY.EMPHASIS.USE_SPARELY",
+ "HOUSE.ACCESSIBILITY.FIGURES.REFERENCED_IN_TEXT",
+ "HOUSE.ACCESSIBILITY.HEADINGS.HIERARCHY.NO_SKIPS",
+ "HOUSE.ACCESSIBILITY.HEADINGS.NO_DECORATIVE",
+ "HOUSE.ACCESSIBILITY.HEADINGS.SINGLE_H1",
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_AVOID_DUPLICATE_CAPTION",
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_SUMMARY_FOR_CHARTS",
+ "HOUSE.ACCESSIBILITY.IMAGES.CAPTION_FOR_COMPLEX",
+ "HOUSE.ACCESSIBILITY.IMAGES.DECORATIVE.EMPTY_ALT",
+ "HOUSE.ACCESSIBILITY.IMAGES.LINKED.ALT_TARGET",
+ "HOUSE.ACCESSIBILITY.IMAGES.TEXT_IN_IMAGES.AVOID",
+ "HOUSE.ACCESSIBILITY.LANGUAGE.METADATA",
+ "HOUSE.ACCESSIBILITY.LINKS.AVOID_SHORTENERS",
+ "HOUSE.ACCESSIBILITY.LINKS.FOCUS_ORDER",
+ "HOUSE.ACCESSIBILITY.LINKS.FOCUS_VISIBLE",
+ "HOUSE.ACCESSIBILITY.LINKS.ICON_ONLY.TEXT",
+ "HOUSE.ACCESSIBILITY.LINKS.SKIP_TO_CONTENT",
+ "HOUSE.ACCESSIBILITY.LINKS.TARGETS.PUBLIC",
+ "HOUSE.ACCESSIBILITY.LINKS.VISUALLY_DISTINCT",
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.NO_BARE_URLS",
+ "HOUSE.ACCESSIBILITY.LISTS.MARKER_CONSISTENT",
+ "HOUSE.ACCESSIBILITY.LISTS.USE_LIST_MARKUP",
+ "HOUSE.ACCESSIBILITY.MEDIA.TRANSCRIPTS",
+ "HOUSE.ACCESSIBILITY.NAVIGATION.FOOTNOTE_BACKLINKS",
+ "HOUSE.ACCESSIBILITY.NAVIGATION.PDF_BOOKMARKS",
+ "HOUSE.ACCESSIBILITY.PDF.TAGS.WHEN_AVAILABLE",
+ "HOUSE.ACCESSIBILITY.TABLES.AVOID_SCREENSHOT",
+ "HOUSE.ACCESSIBILITY.TABLES.CAPTION_SUMMARY",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADERS.SCOPE",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADER_SCOPE",
+ "HOUSE.ACCESSIBILITY.TABLES.NO_LAYOUT",
+ "HOUSE.ACCESSIBILITY.TABLES.ROW_HEADERS_FOR_STUB",
+ "HOUSE.ACCESSIBILITY.TABLES.SIMPLE_STRUCTURE",
+ "HOUSE.ACCESSIBILITY.TOC.LINKED_ENTRIES",
+ "HOUSE.BACKMATTER.APPENDICES.LABELS.MATCH",
+ "HOUSE.BACKMATTER.GLOSSARY.ALPHABETICAL",
+ "HOUSE.BACKMATTER.GLOSSARY.CROSS_REFERENCES",
+ "HOUSE.BACKMATTER.INDEX.CROSS_REFERENCES.CONSISTENT",
+ "HOUSE.BACKMATTER.REFERENCES.DEDUPLICATE",
+ "HOUSE.BACKMATTER.REFERENCES.SORTING.CONSISTENT",
+ "HOUSE.CODE.BLOCKS.COMMANDS.PROMPT_FREE_COPY",
+ "HOUSE.CODE.BLOCKS.CONFIG.VALID",
+ "HOUSE.CODE.BLOCKS.DATA.SYNTHETIC_FOR_SENSITIVE",
+ "HOUSE.CODE.BLOCKS.DETERMINISTIC_OUTPUT",
+ "HOUSE.CODE.BLOCKS.ELISION.MARKED",
+ "HOUSE.CODE.BLOCKS.ERROR_OUTPUT.LABELED",
+ "HOUSE.CODE.BLOCKS.INDENTATION.CONSISTENT",
+ "HOUSE.CODE.BLOCKS.LINE_BREAKS.SEMANTIC_SAFE",
+ "HOUSE.CODE.BLOCKS.NO_LINE_NUMBERS",
+ "HOUSE.CODE.BLOCKS.NO_PERSONAL_PATHS",
+ "HOUSE.CODE.BLOCKS.NO_SMART_QUOTES",
+ "HOUSE.CODE.BLOCKS.PLATFORM.NOTED",
+ "HOUSE.CODE.BLOCKS.PRECONDITIONS.STATED",
+ "HOUSE.CODE.BLOCKS.SPLIT_BY_LANGUAGE",
+ "HOUSE.CODE.BLOCKS.TESTED_OR_MARKED",
+ "HOUSE.CODE.BLOCKS.TRAILING_WHITESPACE.AVOID",
+ "HOUSE.CODE.BLOCKS.USE_FOR_MULTILINE",
+ "HOUSE.CODE.CAPTIONS.EXPLAIN_SNIPPET",
+ "HOUSE.CODE.COMMENTS.MINIMIZE_NOISE",
+ "HOUSE.CODE.DIFFS.CONTEXT_LINES.PRESENT",
+ "HOUSE.CODE.DIFFS.FILE_HEADERS.PRESENT",
+ "HOUSE.CODE.DIFFS.UNIFIED_FORMAT",
+ "HOUSE.CODE.ERRORS.SHOW_FAILURES",
+ "HOUSE.CODE.EXAMPLES.ENV_VARS.DOCUMENT",
+ "HOUSE.CODE.EXAMPLES.FILE_PATH.LABEL",
+ "HOUSE.CODE.EXAMPLES.MULTI_FILE.SEPARATE",
+ "HOUSE.CODE.EXAMPLES.ORDERED_STEPS",
+ "HOUSE.CODE.FENCES.CLOSE_PROPERLY",
+ "HOUSE.CODE.INLINE.USE_FOR_IDENTIFIERS",
+ "HOUSE.CODE.LANGUAGE.CONSISTENT_FENCES",
+ "HOUSE.CODE.LANGUAGE.NOTATION.CONSISTENT",
+ "HOUSE.CODE.LINE_ENDINGS.NORMALIZE",
+ "HOUSE.CODE.MONO.FONT.PREFERRED",
+ "HOUSE.CODE.OUTPUT.DISTINGUISH_FROM_INPUT",
+ "HOUSE.CODE.OUTPUT.TRUNCATION.LABELED",
+ "HOUSE.CODE.PLACEHOLDERS.CLEAR",
+ "HOUSE.CODE.REFERENCES.VERSION_PIN",
+ "HOUSE.CODE.SECURITY.REDACT_SECRETS",
+ "HOUSE.CODE.SHELL.DESTRUCTIVE.WARN",
+ "HOUSE.CODE.SHELL.PROMPTS.CONSISTENT",
+ "HOUSE.CODE.TABLES.AVOID_FOR_CODE",
+ "HOUSE.CODE.TYPED_VALUES.DISTINGUISH",
+ "HOUSE.CODE.TYPOGRAPHY.UNICODE.MINIMIZE",
+ "HOUSE.CODE.URLS.IN_CODE.AVOID_WRAPPING",
+ "HOUSE.CODE.WRAPPING.NO_SOFT_HYPHENS",
+ "HOUSE.EDITORIAL.CLAIMS.AVOID_ABSOLUTES",
+ "HOUSE.EDITORIAL.CLAIMS.BASELINE_FOR_COMPARISONS",
+ "HOUSE.EDITORIAL.CLAIMS.DISTINGUISH_FACT_OPINION",
+ "HOUSE.EDITORIAL.CLAIMS.QUANTIFY_WHEN_POSSIBLE",
+ "HOUSE.EDITORIAL.CLAIMS.SCOPE_TIMEBOUND",
+ "HOUSE.EDITORIAL.CLAIMS.SUPPORT_WITH_SOURCES",
+ "HOUSE.EDITORIAL.CLARITY.ACTIVE_VOICE_INSTRUCTIONS",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_AMBIGUOUS_PRONOUNS",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_DOUBLE_NEGATIVES",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_METACOMMENTARY",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_WEASEL_WORDS",
+ "HOUSE.EDITORIAL.CLARITY.DEFINE_JARGON_ON_FIRST_USE",
+ "HOUSE.EDITORIAL.CLARITY.DEFINE_METRICS",
+ "HOUSE.EDITORIAL.CLARITY.EDIT_FOR_BREVITY",
+ "HOUSE.EDITORIAL.CLARITY.EXAMPLES_WHEN_COMPLEX",
+ "HOUSE.EDITORIAL.CLARITY.ONE_IDEA_PER_PARAGRAPH",
+ "HOUSE.EDITORIAL.CONSISTENCY.CAPITALIZATION.STABLE",
+ "HOUSE.EDITORIAL.CONSISTENCY.DATE_FORMAT.SINGLE",
+ "HOUSE.EDITORIAL.CONSISTENCY.NAMES.SAME_FORM",
+ "HOUSE.EDITORIAL.CONSISTENCY.SPELLING_VARIANT.CHOOSE_ONE",
+ "HOUSE.EDITORIAL.CONSISTENCY.TERMINOLOGY.STABLE",
+ "HOUSE.EDITORIAL.CONSISTENCY.TIMEZONE.EXPLICIT",
+ "HOUSE.EDITORIAL.HEADINGS.AVOID_GENERIC",
+ "HOUSE.EDITORIAL.HEADINGS.CASE.CONSISTENT",
+ "HOUSE.EDITORIAL.HEADINGS.LENGTH.CONCISE",
+ "HOUSE.EDITORIAL.HEADINGS.NO_DUPLICATE",
+ "HOUSE.EDITORIAL.LISTS.AVOID_DEEP_NESTING",
+ "HOUSE.EDITORIAL.LISTS.ITEMS.ACTIONABLE",
+ "HOUSE.EDITORIAL.LISTS.ORDERED_ONLY_WHEN_ORDERED",
+ "HOUSE.EDITORIAL.LISTS.PARALLEL_STRUCTURE",
+ "HOUSE.EDITORIAL.LISTS.PUNCTUATION.CONSISTENT",
+ "HOUSE.EDITORIAL.LISTS.TASKS.CHECKLIST",
+ "HOUSE.EDITORIAL.OPSEC.REMOVE_PII",
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_REVIEW_NOTES_INLINE",
+ "HOUSE.EDITORIAL.REVIEW.CROSS_REFERENCES.VERIFY",
+ "HOUSE.EDITORIAL.REVIEW.FACT_CHECK",
+ "HOUSE.EDITORIAL.REVIEW.LINKS.VERIFY",
+ "HOUSE.EDITORIAL.REVIEW.SENSITIVE_INFO.NO_SECRETS",
+ "HOUSE.EDITORIAL.REVIEW.SPELLCHECK_AND_READTHROUGH",
+ "HOUSE.EDITORIAL.STRUCTURE.ACTION_ITEMS.EXPLICIT",
+ "HOUSE.EDITORIAL.STRUCTURE.ASSUMPTIONS.EXPLICIT",
+ "HOUSE.EDITORIAL.STRUCTURE.AUDIENCE.STATED",
+ "HOUSE.EDITORIAL.STRUCTURE.CHANGELOG.LIVING_DOCS",
+ "HOUSE.EDITORIAL.STRUCTURE.DECISIONS.EXPLICIT",
+ "HOUSE.EDITORIAL.STRUCTURE.GLOSSARY.WHEN_DENSE",
+ "HOUSE.EDITORIAL.STRUCTURE.METADATA.OWNER_DATE",
+ "HOUSE.EDITORIAL.STRUCTURE.REFERENCES.WHEN_CITED",
+ "HOUSE.EDITORIAL.STRUCTURE.RISKS.MITIGATIONS",
+ "HOUSE.EDITORIAL.STRUCTURE.SCOPE.STATED",
+ "HOUSE.EDITORIAL.STRUCTURE.SUMMARY.EARLY",
+ "HOUSE.EDITORIAL.TONE.AVOID_EXCESSIVE_EMPHASIS",
+ "HOUSE.EDITORIAL.TONE.CALIBRATE_CERTAINTY",
+ "HOUSE.EDITORIAL.TONE.INCLUSIVE_LANGUAGE",
+ "HOUSE.EDITORIAL.TONE.PROFESSIONAL_AND_RESPECTFUL",
+ "HOUSE.FIGURES.AXES.UNITS.LABELED",
+ "HOUSE.FIGURES.CAPTIONS.TAKEAWAY",
+ "HOUSE.FIGURES.COLOR.CONTRAST_SAFE",
+ "HOUSE.FIGURES.COLOR.LEGEND.REQUIRED",
+ "HOUSE.FIGURES.FORMAT.VECTOR_FOR_LINE_ART",
+ "HOUSE.FIGURES.RESOLUTION.MINIMUM",
+ "HOUSE.FIGURES.TEXT.NOT_RASTERIZED",
+ "HOUSE.FRONTMATTER.ABSTRACT.REQUIRED_FOR_LONG_DOCS",
+ "HOUSE.FRONTMATTER.DISTRIBUTION.CONTACT",
+ "HOUSE.FRONTMATTER.METADATA.CONFIDENTIALITY",
+ "HOUSE.FRONTMATTER.METADATA.DOC_STATUS",
+ "HOUSE.FRONTMATTER.METADATA.LAST_REVIEWED",
+ "HOUSE.FRONTMATTER.METADATA.VERSION",
+ "HOUSE.FRONTMATTER.TOC.AUTO_GENERATED",
+ "HOUSE.I18N.CURRENCY.DISAMBIGUATE",
+ "HOUSE.I18N.LANGUAGE.SWITCHES.MARK",
+ "HOUSE.I18N.NUMBERS.DIGIT_SYSTEM.CONSISTENT",
+ "HOUSE.I18N.NUMBERS.GROUPING.CONSISTENT",
+ "HOUSE.I18N.TRANSLATION.LABELS",
+ "HOUSE.I18N.UNITS.SPACING.CONSISTENT",
+ "HOUSE.LINKS.EMAILS.MAILTO_POLICY",
+ "HOUSE.LINKS.TEXT.ACCESS_RESTRICTIONS.NOTE",
+ "HOUSE.LINKS.TEXT.ARCHIVE_AND_HTML.BOTH",
+ "HOUSE.LINKS.TEXT.AVOID_OVERLONG_LABELS",
+ "HOUSE.LINKS.TEXT.DIFFERENTIATE_REPEATED_LINKS",
+ "HOUSE.LINKS.TEXT.FILESIZE.LABEL",
+ "HOUSE.LINKS.TEXT.FILETYPE.LABEL",
+ "HOUSE.LINKS.TEXT.LANGUAGE.LABEL",
+ "HOUSE.LINKS.TEXT.LINK_TARGET_MISMATCH",
+ "HOUSE.LINKS.TEXT.MATCHES_TARGET",
+ "HOUSE.LINKS.TEXT.MIRROR.LABEL",
+ "HOUSE.LINKS.TEXT.NO_EMOJIS",
+ "HOUSE.LINKS.TEXT.PARTIAL_WORD.AVOID",
+ "HOUSE.LINKS.TEXT.STABILITY.NOTE",
+ "HOUSE.LINKS.URLS.ANCHORS.STABLE",
+ "HOUSE.LINKS.URLS.AVOID.EXPIRING_SIGNED",
+ "HOUSE.LINKS.URLS.AVOID.INTERNAL_HOSTNAMES",
+ "HOUSE.LINKS.URLS.AVOID.IP_LITERALS",
+ "HOUSE.LINKS.URLS.AVOID.ONE_TIME_INVITES",
+ "HOUSE.LINKS.URLS.AVOID.PASSWORD_RESET",
+ "HOUSE.LINKS.URLS.AVOID.STAGING_DOMAINS",
+ "HOUSE.LINKS.URLS.AVOID.TEMP_FILESHARES",
+ "HOUSE.LINKS.URLS.AVOID.TEXT_FRAGMENTS",
+ "HOUSE.LINKS.URLS.AVOID_PRIVATE_IPS",
+ "HOUSE.LINKS.URLS.BARE_DOMAIN.TRAILING_SLASH",
+ "HOUSE.LINKS.URLS.CANONICAL.NO_TRACKING_PARAMS",
+ "HOUSE.LINKS.URLS.CANONICAL_HOST",
+ "HOUSE.LINKS.URLS.DISALLOW.FTP",
+ "HOUSE.LINKS.URLS.MAILTO.INTENT",
+ "HOUSE.LINKS.URLS.NO_EMBEDDED_CREDENTIALS",
+ "HOUSE.LINKS.URLS.NO_PROTOCOL_RELATIVE",
+ "HOUSE.LINKS.URLS.NO_QUERY_WHEN_NOT_NEEDED",
+ "HOUSE.LINKS.URLS.NO_SESSION_PARAMS",
+ "HOUSE.LINKS.URLS.RELATIVE.REPO_LOCAL",
+ "HOUSE.LINKS.URLS.SHORTENERS.AVOID",
+ "HOUSE.LINKS.URLS.STABLE_ANCHORS",
+ "HOUSE.TABLES.COLUMN_WIDTHS.BALANCED",
+ "HOUSE.TABLES.MISSING_DATA.CONSISTENT_MARK",
+ "HOUSE.TABLES.NUMERIC.ALIGN_DECIMALS",
+ "HOUSE.TABLES.NUMERIC.PRECISION.CONSISTENT",
+ "HOUSE.TABLES.SOURCE.NOTES",
+ "HOUSE.TABLES.UNITS.IN_HEADERS"
],
"postrender": [
"BRING.LAYOUT.COLUMNS.BALANCE_LENGTHS",
@@ -244,10 +1512,22 @@
"BRING.LAYOUT.PAGINATION.WIDOWS_AVOID",
"BRING.TYPOGRAPHY.HYPHENATION.AVOID_AFTER_SHORT_LINE",
"CMOS.CITATIONS.NOTES.FOOTNOTES.PAGE_BREAKS",
+ "CMOS.LAYOUT.PAGINATION.AVOID_SHORT_LAST_LINE",
+ "CMOS.LAYOUT.PAGINATION.AVOID_SINGLE_LINE_ENDING",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.AVOID_BOTTOM_OF_PAGE",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.AVOID_TOP_OF_PAGE",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.KEEP_WITH_TEXT",
+ "CMOS.LAYOUT.PAGINATION.ORPHANS.AVOID",
+ "CMOS.LAYOUT.PAGINATION.WIDOWS.AVOID",
"HOUSE.CODE.BLOCKS.NO_CLIPPING",
"HOUSE.HEADINGS.KEEPS.AVOID_STRANDED",
"HOUSE.LAYOUT.OVERFLOW.OVERFULL_LINES.REPORT",
+ "HOUSE.LAYOUT.PAGINATION.CAPTIONS.KEEP_WITH_CONTENT",
+ "HOUSE.LAYOUT.PAGINATION.HEADINGS.NO_ADJACENT",
"HOUSE.LAYOUT.PAGINATION.KEEP_WITH_NEXT.HEADINGS",
+ "HOUSE.LAYOUT.PAGINATION.LISTS.AVOID_LONELY_ITEM",
+ "HOUSE.LAYOUT.PAGINATION.LISTS.KEEP_INTRO",
+ "HOUSE.LAYOUT.PAGINATION.RUNT_FINAL_PAGE",
"HOUSE.TABLES.OVERFLOW.NO_CLIPPING"
],
"typeset": [
@@ -262,10 +1542,20 @@
"BRING.HEADINGS.SUBHEADS.RIGHT_SIDEHEADS.VISIBILITY",
"BRING.HEADINGS.SUBHEADS.STYLE_CONTRIBUTES_TO_WHOLE",
"BRING.HEADINGS.WEIGHT_SIZE.HIERARCHY_SCALE",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_BLOCK_QUOTES",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_CAPTIONS",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_HEADINGS",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_TABLES",
"BRING.LAYOUT.BLOCK_QUOTES.AVOID_CROWDING",
"BRING.LAYOUT.BLOCK_QUOTES.BEFORE_AFTER_SPACING",
"BRING.LAYOUT.BLOCK_QUOTES.EXTRA_LEAD",
"BRING.LAYOUT.BLOCK_QUOTES.INDENT_OR_NARROW",
+ "BRING.LAYOUT.COLUMNS.ALIGN_BASELINES",
+ "BRING.LAYOUT.COLUMNS.COUNT.MODERATE",
+ "BRING.LAYOUT.COLUMNS.GUTTER.CONSISTENT",
+ "BRING.LAYOUT.COLUMNS.GUTTER.SUFFICIENT",
+ "BRING.LAYOUT.COLUMNS.SIDEBARS.DISTINCT_MEASURE",
+ "BRING.LAYOUT.COLUMNS.WIDTH.CONSISTENT",
"BRING.LAYOUT.GRID.ALIGN_ELEMENTS",
"BRING.LAYOUT.HYPHENATION.STUB_END_AVOID",
"BRING.LAYOUT.JUSTIFICATION.RAGGED_RIGHT_IF_NEEDED",
@@ -276,7 +1566,15 @@
"BRING.LAYOUT.LEADING.CHOOSE_BASE",
"BRING.LAYOUT.LEADING.CONSISTENT_BODY",
"BRING.LAYOUT.LEADING.NEGATIVE.AVOID_CONTINUOUS_TEXT",
+ "BRING.LAYOUT.MARGINS.AVOID_CROWDING",
+ "BRING.LAYOUT.MARGINS.CONSISTENT.ACROSS_SECTIONS",
"BRING.LAYOUT.MARGINS.FACING_PAGES.INNER_OUTER",
+ "BRING.LAYOUT.MARGINS.FOOTNOTE.CLEARANCE",
+ "BRING.LAYOUT.MARGINS.GUTTER.ALLOW_BINDING",
+ "BRING.LAYOUT.MARGINS.OUTER_LARGER_THAN_INNER",
+ "BRING.LAYOUT.MARGINS.PROPORTION.BALANCED",
+ "BRING.LAYOUT.MARGINS.RUNNING_HEAD.CLEARANCE",
+ "BRING.LAYOUT.MARGINS.TOP_BOTTOM.BALANCE",
"BRING.LAYOUT.MEASURE.ADJUST_FOR_TYPE_SIZE",
"BRING.LAYOUT.MEASURE.AVOID_TOO_LONG",
"BRING.LAYOUT.MEASURE.AVOID_TOO_SHORT",
@@ -286,32 +1584,84 @@
"BRING.LAYOUT.MEASURE.MULTICOLUMN_TARGETS",
"BRING.LAYOUT.MEASURE.TARGET_RANGE_CHARS",
"BRING.LAYOUT.PAGE.FRAME.TEXTBLOCK_BALANCE",
+ "BRING.LAYOUT.PAGE.HEAD_FOOT_BANDS.CONSISTENT",
+ "BRING.LAYOUT.PAGE.SHAPE.PROPORTIONATE",
+ "BRING.LAYOUT.PAGE.SPREADS.ALIGN_BASELINES",
+ "BRING.LAYOUT.PAGE.TEXTBLOCK.POSITION",
+ "BRING.LAYOUT.PARAGRAPH.DROP_CAPS.ALIGN_BASELINE",
+ "BRING.LAYOUT.PARAGRAPH.INDENT.NOT_TOO_DEEP",
+ "BRING.LAYOUT.PARAGRAPH.INDENT.PROPORTIONAL",
+ "BRING.LAYOUT.PARAGRAPH.INDENT.WITHIN_MEASURE",
"BRING.LAYOUT.PARAGRAPH.INDENT_AFTER_FIRST",
"BRING.LAYOUT.PARAGRAPH.INDENT_OR_SPACE_NOT_BOTH",
"BRING.LAYOUT.PARAGRAPH.INDENT_SIZE.CONSISTENT",
+ "BRING.LAYOUT.PARAGRAPH.LISTS.ALIGN_WITH_BODY",
+ "BRING.LAYOUT.PARAGRAPH.LISTS.HANGING_INDENT",
"BRING.LAYOUT.PARAGRAPH.NO_INDENT_AFTER_BLOCKS",
"BRING.LAYOUT.PARAGRAPH.OPENING_FLUSH_LEFT",
"BRING.LAYOUT.TEXTBLOCK.CONSISTENT_WIDTH",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.CAPTIONS.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.FIGURES.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.FOOTNOTES.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.HEADINGS.BEFORE_AFTER",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.LISTS.SPACING",
"BRING.LAYOUT.VERTICAL_RHYTHM.MEASURED_INTERVALS.MULTIPLES",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.TABLES.SPACING",
"BRING.TABLES.COLUMN_ALIGNMENT.CONSISTENT",
"BRING.TABLES.FURNITURE.MINIMIZE",
"BRING.TABLES.GROUPING.WHITESPACE",
"BRING.TABLES.HEADERS.ALIGN_WITH_COLUMNS",
"BRING.TABLES.ROW_SPACING.READABLE",
"BRING.TABLES.TYPE_SIZE.READABLE",
+ "BRING.TYPOGRAPHY.CAPS.TRACKING_REVIEW",
+ "BRING.TYPOGRAPHY.FAMILY.AVOID_FAUX_BOLD",
+ "BRING.TYPOGRAPHY.FAMILY.TRUE_ITALICS",
+ "BRING.TYPOGRAPHY.FAMILY.TRUE_SMALL_CAPS",
+ "BRING.TYPOGRAPHY.FAMILY.USE_DESIGNED_WEIGHTS",
+ "BRING.TYPOGRAPHY.FAMILY.WEIGHT_CONTRAST_CLEAR",
"BRING.TYPOGRAPHY.HYPHENATION.LANGUAGE_DICTIONARY.MATCH",
"BRING.TYPOGRAPHY.HYPHENATION.MAX_CONSECUTIVE_LINES",
"BRING.TYPOGRAPHY.HYPHENATION.MIN_LEFT_RIGHT",
"BRING.TYPOGRAPHY.LETTERFORMS.AVOID_DISTORTION",
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_CODE_URLS",
+ "BRING.TYPOGRAPHY.LIGATURES.FI_FL_COLLISIONS",
+ "BRING.TYPOGRAPHY.LIGATURES.STANDARD_ON_BODY",
+ "BRING.TYPOGRAPHY.NUMERALS.FRACTIONS_TRUE_GLYPHS",
+ "BRING.TYPOGRAPHY.NUMERALS.LINING_FOR_CAPS_AND_DISPLAY",
+ "BRING.TYPOGRAPHY.NUMERALS.OLDSTYLE_FOR_TEXT",
+ "BRING.TYPOGRAPHY.NUMERALS.PROPORTIONAL_FOR_PROSE",
+ "BRING.TYPOGRAPHY.NUMERALS.SUPERIOR_INFERIOR_FOR_NOTES",
+ "BRING.TYPOGRAPHY.NUMERALS.TABULAR_FOR_TABLES",
+ "BRING.TYPOGRAPHY.SIZE.LEADING_RELATION",
"BRING.TYPOGRAPHY.SPACING.WORD_SPACE.DEFINE",
"BRING.TYPOGRAPHY.TRACKING.CAPS_SMALLCAPS_AND_LONG_DIGITS",
"BRING.TYPOGRAPHY.TRACKING.LOWERCASE.AVOID",
+ "BRING.TYPOGRAPHY.TYPEFACE.FALLBACKS_COMPATIBLE_METRICS",
+ "BRING.TYPOGRAPHY.TYPEFACE.OPTICAL_SIZES_USE",
+ "CMOS.LAYOUT.MEASURE.LINE_LENGTH.TARGET_RANGE",
+ "CMOS.LAYOUT.MEASURE.MAX_LINE_LENGTH",
+ "CMOS.LAYOUT.MEASURE.MIN_LINE_LENGTH",
+ "CMOS.LAYOUT.PARAGRAPHS.BLOCK_QUOTE_STYLE",
+ "CMOS.LAYOUT.PARAGRAPHS.INDENT_POLICY",
+ "CMOS.LAYOUT.PARAGRAPHS.SPACING_POLICY",
+ "CMOS.LAYOUT.SPACING.LEADING.CHOOSE",
+ "CMOS.LAYOUT.SPACING.LINE_SPACING.CONSISTENT",
+ "CMOS.LAYOUT.SPACING.VERTICAL_RHYTHM",
"CMOS.NUMBERS.DIGIT_GROUPING.SI_SPACE",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.LINE_BREAKS_DETAIL",
"CMOS.PUNCTUATION.DASHES.EM_LINE_BREAKS",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.LINE_BREAKS",
"HOUSE.A11Y.DOCUMENT_LANGUAGE.DECLARE",
"HOUSE.CODE.BLOCKS.WRAP_POLICY",
+ "HOUSE.HEADINGS.KEEP_WITH_NEXT",
+ "HOUSE.LAYOUT.HTML.GUTTERS.MIN_PADDING",
+ "HOUSE.LAYOUT.HTML.MEASURE.MAX_WIDTH",
+ "HOUSE.LAYOUT.HTML.SECTION_SPACING.CONSISTENT",
"HOUSE.LINKS.WRAP.SAFE_BREAKS",
"HOUSE.TABLES.ALIGNMENT.DECIMALS",
- "HOUSE.TABLES.HEADERS.REPEAT_ON_PAGEBREAK"
+ "HOUSE.TABLES.HEADERS.REPEAT_ON_PAGEBREAK",
+ "HOUSE.TYPOGRAPHY.HTML.JUSTIFICATION.RAGGED_RIGHT",
+ "HOUSE.TYPOGRAPHY.HTML.LINE_HEIGHT.MINIMUM",
+ "HOUSE.TYPOGRAPHY.HTML.LINK_DECORATION.CONSISTENT"
]
}
diff --git a/spec/indexes/keywords_all.json b/spec/indexes/keywords_all.json
index 4aa6efe..61663b9 100644
--- a/spec/indexes/keywords_all.json
+++ b/spec/indexes/keywords_all.json
@@ -11,6 +11,9 @@
"1st": [
"CMOS.NUMBERS.ORDINALS.SUFFIX.CORRECT"
],
+ "2-em dash": [
+ "CMOS.PUNCTUATION.DASHES.TWO_EM.OMISSIONS"
+ ],
"24-hour time": [
"CMOS.NUMBERS.TIME.TWENTY_FOUR_HOUR"
],
@@ -18,93 +21,400 @@
"CMOS.NUMBERS.ORDINALS.SUFFIX.CORRECT"
],
"3-em dash": [
- "CMOS.CITATIONS.BIBLIOGRAPHY.REPEATED_NAMES.THREE_EM_DASH"
+ "CMOS.CITATIONS.BIBLIOGRAPHY.REPEATED_NAMES.THREE_EM_DASH",
+ "CMOS.PUNCTUATION.DASHES.TWO_EM.OMISSIONS"
],
"?!": [
"CMOS.PUNCTUATION.MULTIPLE_MARKS.AVOID_STACKING"
],
+ "a.m.": [
+ "CMOS.ABBREVIATIONS.TIME.AM_PM.FORM",
+ "CMOS.NUMBERS.TIME.AM_PM.CONSISTENT_SPACING"
+ ],
"a11y": [
"HOUSE.A11Y.HEADINGS.NO_SKIPS"
],
"abbreviated year": [
"CMOS.NUMBERS.DATES.ABBREVIATED_YEAR"
],
+ "abbreviated years": [
+ "CMOS.NUMBERS.S9_32.ABBREVIATED_YEAR.APOSTROPHE"
+ ],
+ "abbreviation list": [
+ "CMOS.ABBREVIATIONS.GENERAL.GLOSSARY.WHEN_NEEDED"
+ ],
+ "abbreviation periods": [
+ "CMOS.PUNCTUATION.PERIODS.NO_DOUBLE_AT_SENTENCE_END"
+ ],
+ "abbreviations": [
+ "BRING.HEADINGS.AVOID_ABBREVIATIONS",
+ "BRING.TYPOGRAPHY.FAMILY.SMALL_CAPS_SPARE",
+ "CMOS.ABBREVIATIONS.COUNTRIES.ABBREV_IN_TABLES_ONLY",
+ "CMOS.ABBREVIATIONS.DAYS.ABBREV_IN_TABLES",
+ "CMOS.ABBREVIATIONS.GENERAL.CONSISTENCY",
+ "CMOS.ABBREVIATIONS.MONTHS.ABBREV_IN_TABLES",
+ "CMOS.BACKMATTER.INDEX.ABBREVIATIONS.CONSISTENT",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.CONSISTENT",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.NOTES",
+ "CMOS.NUMBERS.S9_18.ABBREVIATIONS.NUMERALS_ONLY",
+ "CMOS.NUMBERS.S9_8.ABBREVIATED_UNITS.NUMERALS",
+ "CMOS.TABLES.ABBREVIATIONS.EXPLAIN"
+ ],
+ "abbreviations list": [
+ "CMOS.BACKMATTER.ABBREVIATIONS.LIST.WHEN_NEEDED"
+ ],
+ "above one hundred": [
+ "CMOS.NUMBERS.S9_2.NONROUND.ABOVE_ONE_HUNDRED"
+ ],
+ "above/below": [
+ "HOUSE.EDITORIAL.CLARITY.AVOID_METACOMMENTARY"
+ ],
+ "absolute claims": [
+ "HOUSE.EDITORIAL.CLAIMS.AVOID_ABSOLUTES"
+ ],
+ "abstract": [
+ "CMOS.FRONTMATTER.ABSTRACT.WHEN_APPROPRIATE",
+ "HOUSE.FRONTMATTER.ABSTRACT.REQUIRED_FOR_LONG_DOCS"
+ ],
+ "academic": [
+ "CMOS.ABBREVIATIONS.ACADEMIC.DEGREES.STYLE",
+ "CMOS.CITATIONS.S13_5.ACADEMIC_EXPECTATION"
+ ],
+ "accents": [
+ "CMOS.I18N.DIACRITICS.PRESERVE"
+ ],
+ "access": [
+ "CMOS.CITATIONS.S13_10.DATABASE_IN_CITATION",
+ "HOUSE.LINKS.AUTO.PRIVATE_IPS.AVOID",
+ "HOUSE.LINKS.TEXT.ACCESS_RESTRICTIONS.NOTE"
+ ],
"access date": [
"CMOS.CITATIONS.ONLINE.ACCESS_DATE.WHEN_NEEDED",
- "CMOS.CITATIONS.ONLINE.REVISION_DATE.DISTINCT"
+ "CMOS.CITATIONS.ONLINE.REVISION_DATE.DISTINCT",
+ "CMOS.CITATIONS.S13_100.BIBLIOGRAPHY.ONLINE.SOURCE_STABILITY",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.NOT_REQUIRED",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.RECORD_ANYWAY"
+ ],
+ "access dates": [
+ "CMOS.BACKMATTER.REFERENCES.ACCESS_DATES.WHEN_NEEDED",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.UNVERIFIABLE"
],
"accessibility": [
- "HOUSE.A11Y.LINK_TEXT.DESCRIPTIVE"
+ "BRING.TYPOGRAPHY.SIZE.SMALL_TEXT_MINIMUM",
+ "CMOS.FIGURES.ACCESSIBILITY.ALT_TEXT",
+ "CMOS.FIGURES.COLOR.NOT_SOLE_SIGNAL",
+ "CMOS.FIGURES.CONTRAST.SUFFICIENT",
+ "CMOS.FRONTMATTER.ACCESSIBILITY.NOTES",
+ "HOUSE.A11Y.LINK_TEXT.DESCRIPTIVE",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADER_ROW.REQUIRED",
+ "HOUSE.EDITORIAL.TONE.INCLUSIVE_LANGUAGE",
+ "HOUSE.LINKS.TEXT.LANGUAGE.LABEL",
+ "HOUSE.LINKS.TEXT.NO_CLICK_HERE",
+ "HOUSE.LINKS.TEXT.NO_EMOJIS",
+ "HOUSE.LINKS.URLS.AVOID_PRIVATE_IPS"
+ ],
+ "accountability": [
+ "HOUSE.EDITORIAL.STRUCTURE.DECISIONS.EXPLICIT"
+ ],
+ "accuracy": [
+ "HOUSE.LINKS.TEXT.MATCHES_TARGET"
],
"acknowledgments": [
- "CMOS.CITATIONS.NOTES.UNNUMBERED.NOT_FOR_SOURCES"
+ "CMOS.BACKMATTER.ACKNOWLEDGMENTS.PLACEMENT",
+ "CMOS.CITATIONS.NOTES.UNNUMBERED.NOT_FOR_SOURCES",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.NAMES.CONSISTENT",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.PLACEMENT",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.SCOPE"
+ ],
+ "acronym": [
+ "CMOS.ABBREVIATIONS.ACRONYMS.DEFINE_FIRST_USE",
+ "CMOS.ABBREVIATIONS.ACRONYMS.REINTRODUCE_AFTER_GAP",
+ "CMOS.ABBREVIATIONS.ORGANIZATIONS.SPELL_OUT_FIRST"
+ ],
+ "acronym stacking": [
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_STACKING"
+ ],
+ "acronyms": [
+ "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_SHORT_LABELS_ONLY",
+ "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_FOR_ACRONYMS",
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ACRONYMS",
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_IN_HEADINGS",
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_SENTENCE_START",
+ "CMOS.I18N.ACRONYMS.LANGUAGE_SPECIFIC"
+ ],
+ "action items": [
+ "HOUSE.EDITORIAL.LISTS.ITEMS.ACTIONABLE",
+ "HOUSE.EDITORIAL.STRUCTURE.ACTION_ITEMS.EXPLICIT"
+ ],
+ "active voice": [
+ "HOUSE.EDITORIAL.CLARITY.ACTIVE_VOICE_INSTRUCTIONS"
+ ],
+ "acts": [
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.ACT_SCENE"
+ ],
+ "ad": [
+ "CMOS.NUMBERS.S9_36.ERAS.ABBREVIATION_PLACEMENT",
+ "CMOS.NUMBERS.S9_36.ERAS.NO_PERIODS"
],
"addresses": [
"CMOS.NUMBERS.PLACES.STREETS",
- "CMOS.PUNCTUATION.COMMAS.ADDRESSES"
+ "CMOS.PUNCTUATION.COMMAS.ADDRESSES",
+ "CMOS.PUNCTUATION.COMMAS.ADDRESSES.RUN_IN"
+ ],
+ "adjectives": [
+ "CMOS.PUNCTUATION.COMMAS.COORDINATE_ADJECTIVES"
],
"adverb": [
"CMOS.PUNCTUATION.HYPHENS.ADVERB_LY.NO_HYPHEN"
],
+ "adverbial phrase": [
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_END",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_INTRO_OPTIONAL",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_INVERTED",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_MID"
+ ],
+ "adverbial phrases": [
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL.INTRO_OPTIONAL",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL.MID_END",
+ "CMOS.PUNCTUATION.COMMAS.PHRASE_PLUS_CONJUNCTION"
+ ],
+ "aesthetic": [
+ "CMOS.PUNCTUATION.BOLD_COLOR.CASE_BY_CASE"
+ ],
+ "aesthetic system": [
+ "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.PRINT_ONLY"
+ ],
+ "after": [
+ "BRING.LAYOUT.PARAGRAPH.AFTER_QUOTE.FLUSH"
+ ],
"after block quote": [
"BRING.LAYOUT.PARAGRAPH.NO_INDENT_AFTER_BLOCKS"
],
"after heading": [
"BRING.HEADINGS.PARAGRAPH_INDENT.AFTER_HEAD_NONE",
- "BRING.LAYOUT.PARAGRAPH.NO_INDENT_AFTER_BLOCKS"
+ "BRING.LAYOUT.PARAGRAPH.NO_INDENT_AFTER_BLOCKS",
+ "CMOS.LAYOUT.PARAGRAPHS.INDENT_POLICY"
+ ],
+ "agreement": [
+ "CMOS.CITATIONS.S13_4.FLEXIBILITY.BY_AGREEMENT"
+ ],
+ "ah": [
+ "CMOS.PUNCTUATION.COMMAS.INTRO_OH_AH"
+ ],
+ "algebraic fractions": [
+ "CMOS.NUMBERS.S9_17.ALGEBRAIC.SLASH"
],
"alignment": [
"BRING.HEADINGS.ALIGNMENT.CONSISTENT_LEVEL",
"BRING.HEADINGS.SUBHEADS.CROSSHEADS_SIDEHEADS.CHOOSE_DELIBERATELY",
"BRING.LAYOUT.LEADING.ALIGN_BASELINE_GRID",
+ "BRING.LAYOUT.MARGINS.NOTES.OUTSIDE_TEXTBLOCK",
+ "BRING.LAYOUT.PAGE.FACING_ELEMENTS.ALIGN",
"BRING.TABLES.COLUMN_ALIGNMENT.CONSISTENT",
"BRING.TABLES.FURNITURE.MINIMIZE",
- "BRING.TYPOGRAPHY.ALIGNMENT.DONT_STRETCH_SPACE"
+ "BRING.TYPOGRAPHY.ALIGNMENT.DONT_STRETCH_SPACE",
+ "BRING.TYPOGRAPHY.NUMERALS.TABULAR_FOR_TABLES",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.MULTI_DIGIT_ALIGN",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.RUNOVER_ALIGN"
+ ],
+ "all caps": [
+ "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ALL_CAPS",
+ "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_AVOID_LONG_RUNS",
+ "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_SHORT_LABELS_ONLY",
+ "BRING.TYPOGRAPHY.CAPS.AVOID_FOR_EMPHASIS",
+ "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_FOR_ACRONYMS",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_IN_ALL_CAPS_HEADINGS",
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ALL_CAPS",
+ "CMOS.ABBREVIATIONS.CAPS.AVOID_ALL_CAPS_WORDS",
+ "HOUSE.EDITORIAL.HEADINGS.AVOID_ALL_CAPS",
+ "HOUSE.EDITORIAL.TONE.AVOID_EXCESSIVE_EMPHASIS",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ALL_CAPS.AVOID"
],
"alphabetical": [
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ALPHABETICAL",
- "CMOS.CITATIONS.NOTES_BIBLIO.BIBLIOGRAPHY.SORT_BY_AUTHOR"
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SORTING_STABLE",
+ "CMOS.CITATIONS.NOTES_BIBLIO.BIBLIOGRAPHY.SORT_BY_AUTHOR",
+ "HOUSE.BACKMATTER.GLOSSARY.ALPHABETICAL"
+ ],
+ "alphabetize": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.CORPORATE_AUTHORS.USE_AS_AUTHOR",
+ "CMOS.CITATIONS.S13_71.BIBLIOGRAPHY.ALPHABETIZATION.PREFIXES_POLICY"
+ ],
+ "alphanumeric": [
+ "CMOS.NUMBERS.S9_5.ALPHANUMERIC.MAY_BEGIN"
],
"alt text": [
- "HOUSE.A11Y.IMAGES.ALT_REQUIRED"
+ "CMOS.FIGURES.ACCESSIBILITY.ALT_TEXT",
+ "HOUSE.A11Y.IMAGES.ALT_REQUIRED",
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_AVOID_DUPLICATE_CAPTION",
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_SUMMARY_FOR_CHARTS",
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_TEXT.QUALITY.NO_FILENAME",
+ "HOUSE.ACCESSIBILITY.IMAGES.DECORATIVE.EMPTY_ALT",
+ "HOUSE.ACCESSIBILITY.IMAGES.LINKED.ALT_TARGET"
],
"alternative rule": [
"CMOS.NUMBERS.RULE_SELECTION.ALTERNATIVE_ZERO_TO_NINE",
- "CMOS.NUMBERS.RULE_SELECTION.GENERAL_OR_ALTERNATIVE"
+ "CMOS.NUMBERS.RULE_SELECTION.GENERAL_OR_ALTERNATIVE",
+ "CMOS.NUMBERS.S9_3.ALTERNATIVE_ROUND_MULTIPLES",
+ "CMOS.NUMBERS.S9_3.ALTERNATIVE_RULE.ZERO_TO_NINE"
],
"alternatives": [
- "CMOS.PUNCTUATION.SLASHES.ALTERNATIVES"
+ "CMOS.PUNCTUATION.SLASHES.ALTERNATIVES",
+ "CMOS.PUNCTUATION.SLASHES.NO_SPACES"
+ ],
+ "always": [
+ "HOUSE.EDITORIAL.CLAIMS.AVOID_ABSOLUTES"
+ ],
+ "ama": [
+ "CMOS.CITATIONS.S13_3.OTHER_SYSTEMS.AMA_CSE"
],
"ambiguity": [
- "CMOS.PUNCTUATION.HYPHENS.COMPOUND_MODIFIERS.BEFORE_NOUN"
+ "CMOS.LINKS.REPHRASE_IF_URL_ENDS_PUNCT",
+ "CMOS.NUMBERS.S9_34.CENTURY_TURN.AVOID_AMBIGUITY",
+ "CMOS.NUMBERS.S9_35.DECADES.FIRST_DECADE",
+ "CMOS.NUMBERS.TIME.ZONE.INCLUDE_WHEN_AMBIGUOUS",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.AMBIGUITY_REWORD",
+ "CMOS.PUNCTUATION.HYPHENS.COMPOUND_MODIFIERS.BEFORE_NOUN",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_AMBIGUOUS_PRONOUNS"
+ ],
+ "ampersand": [
+ "CMOS.PUNCTUATION.COMMAS.AMPERSAND.NO_SERIAL"
+ ],
+ "amplification": [
+ "CMOS.PUNCTUATION.COLONS.AMPLIFY_OR_ILLUSTRATE"
+ ],
+ "anchors": [
+ "HOUSE.EDITORIAL.HEADINGS.NO_DUPLICATE",
+ "HOUSE.LINKS.URLS.ANCHORS.STABLE",
+ "HOUSE.LINKS.URLS.AVOID.TEXT_FRAGMENTS",
+ "HOUSE.LINKS.URLS.STABLE_ANCHORS"
+ ],
+ "angle brackets": [
+ "CMOS.LINKS.NO_WRAPPERS",
+ "CMOS.PUNCTUATION.URLS.NO_WRAPPERS"
+ ],
+ "annotated bibliography": [
+ "CMOS.CITATIONS.S13_67.BIBLIOGRAPHY.ANNOTATIONS.CONSISTENT_AND_DISTINCT"
+ ],
+ "annotations": [
+ "CMOS.CITATIONS.S13_67.BIBLIOGRAPHY.ANNOTATIONS.CONSISTENT_AND_DISTINCT",
+ "CMOS.FIGURES.ANNOTATIONS.CONSISTENT_STYLE"
],
"anonymous works": [
"CMOS.CITATIONS.BIBLIOGRAPHY.NO_AUTHOR.TITLE_LEAD"
],
+ "apa": [
+ "CMOS.CITATIONS.S13_3.OTHER_SYSTEMS.MLA_APA"
+ ],
"apartment numbers": [
"CMOS.NUMBERS.PLACES.BUILDINGS_APTS"
],
"apostrophe": [
- "CMOS.NUMBERS.PLURALS.DECADE.NO_APOSTROPHE"
+ "CMOS.ABBREVIATIONS.PLURALS.NO_APOSTROPHE",
+ "CMOS.ABBREVIATIONS.POSSESSIVE.FORM",
+ "CMOS.NUMBERS.PLURALS.DECADE.NO_APOSTROPHE",
+ "CMOS.NUMBERS.S9_32.ABBREVIATED_YEAR.APOSTROPHE",
+ "CMOS.NUMBERS.S9_35.DECADES.NO_APOSTROPHE",
+ "CMOS.PUNCTUATION.QUOTES.APOSTROPHE_NOT_QUOTE"
],
"apostrophes": [
- "CMOS.NUMBERS.PLURALS.SPELLED_OUT"
+ "CMOS.NUMBERS.PLURALS.SPELLED_OUT",
+ "CMOS.PUNCTUATION.APOSTROPHE.USE_CASES"
+ ],
+ "appendix": [
+ "BRING.HEADINGS.NUMBERING.APPENDIX_LABELS",
+ "BRING.HEADINGS.NUMBERING.PREFIXES.CONSISTENT",
+ "CMOS.BACKMATTER.APPENDICES.CROSS_REFERENCES",
+ "CMOS.BACKMATTER.APPENDICES.FORMAT_MATCH",
+ "CMOS.BACKMATTER.APPENDICES.LABELED",
+ "CMOS.BACKMATTER.APPENDICES.SOURCES",
+ "CMOS.BACKMATTER.APPENDIX.NUMBERING.SEQUENTIAL",
+ "CMOS.BACKMATTER.APPENDIX.START_ON_NEW_PAGE",
+ "CMOS.BACKMATTER.APPENDIX.TOC.ENTRIES",
+ "HOUSE.BACKMATTER.APPENDICES.LABELS.MATCH"
+ ],
+ "appositive": [
+ "CMOS.PUNCTUATION.COMMAS.APPOSITIVES.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.TITLES_AND_EXPRESSIONS"
],
"appositives": [
- "CMOS.PUNCTUATION.COMMAS.APPOSITIVES"
+ "CMOS.PUNCTUATION.COMMAS.APPOSITIVES",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIPS.UNIQUE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_ALWAYS_USE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_NAMES",
+ "CMOS.PUNCTUATION.COMMAS.TITLES.APPOSITIVE_RULE"
+ ],
+ "approximate numbers": [
+ "CMOS.NUMBERS.S9_4.APPROXIMATIONS.SPELLED_OUT"
+ ],
+ "arabic numerals": [
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.PREFER_ARABIC"
+ ],
+ "archive": [
+ "CMOS.CITATIONS.S13_103.BIBLIOGRAPHY.SOCIAL_MEDIA.ARCHIVE"
+ ],
+ "archiving": [
+ "CMOS.CITATIONS.S13_17.ARCHIVE_SERVICES"
+ ],
+ "aria-label": [
+ "HOUSE.ACCESSIBILITY.LINKS.ICON_ONLY.TEXT"
+ ],
+ "articles": [
+ "CMOS.CITATIONS.S13_20.BIBLIO.PAGE_RANGE"
],
"as follows": [
"CMOS.PUNCTUATION.COLONS.AS_FOLLOWS"
],
+ "as well as": [
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.AS_WELL_AS"
+ ],
+ "ascii": [
+ "HOUSE.CODE.TYPOGRAPHY.UNICODE.MINIMIZE"
+ ],
+ "aspect ratio": [
+ "CMOS.FIGURES.ASPECT_RATIO.PRESERVE"
+ ],
+ "assets": [
+ "CMOS.FIGURES.FILENAME.STABLE"
+ ],
+ "assumptions": [
+ "HOUSE.EDITORIAL.STRUCTURE.ASSUMPTIONS.EXPLICIT",
+ "HOUSE.EDITORIAL.STRUCTURE.AUDIENCE.STATED",
+ "HOUSE.EDITORIAL.STRUCTURE.SCOPE.STATED"
+ ],
"asymmetry": [
"BRING.HEADINGS.SUBHEADS.MIXING_SYMM_ASYMM.AVOID_HAPHAZARD"
],
"attribution": [
- "CMOS.HEADINGS.DIVISIONS.CHAPTERS.MULTIAUTHOR"
+ "CMOS.CITATIONS.S13_1.PURPOSE.ETHICS",
+ "CMOS.FRONTMATTER.EPIGRAPH.ATTRIBUTION",
+ "CMOS.FRONTMATTER.LICENSE.ATTRIBUTION",
+ "CMOS.HEADINGS.DIVISIONS.CHAPTERS.MULTIAUTHOR",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.LINE_BREAKS_DETAIL"
+ ],
+ "audience": [
+ "BRING.TYPOGRAPHY.TYPEFACE.PURPOSE_MATCH_CONTENT",
+ "CMOS.ABBREVIATIONS.READER_FAMILIARITY",
+ "CMOS.FRONTMATTER.AUDIENCE.SCOPE.STATED",
+ "HOUSE.EDITORIAL.STRUCTURE.AUDIENCE.STATED",
+ "HOUSE.EDITORIAL.TONE.INCLUSIVE_LANGUAGE"
+ ],
+ "audio": [
+ "CMOS.CITATIONS.S13_102.BIBLIOGRAPHY.AUDIOVISUAL.CREDITS"
+ ],
+ "authentication": [
+ "HOUSE.LINKS.TEXT.ACCESS_RESTRICTIONS.NOTE"
+ ],
+ "author": [
+ "CMOS.FRONTMATTER.FOREWORD.AUTHOR.ATTRIBUTED",
+ "CMOS.FRONTMATTER.TITLEPAGE.PRESENT"
],
"author attribution": [
"CMOS.HEADINGS.MULTIAUTHOR.AUTHOR_ATTRIBUTION_PLACEMENT"
],
+ "author list": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_LIST.LENGTH.POLICY"
+ ],
"author name": [
"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.CONSISTENT_FORM",
"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.INITIALS_PREFERRED",
@@ -114,6 +424,10 @@
"author name order": [
"CMOS.CITATIONS.NOTES_BIBLIO.NAME_ORDER.NOTES_VS_BIBLIO"
],
+ "author names": [
+ "CMOS.BACKMATTER.REFERENCES.AUTHOR_NAMES.CONSISTENT",
+ "CMOS.CITATIONS.S13_18.NAMES.NORMAL_ORDER"
+ ],
"author order": [
"CMOS.CITATIONS.BIBLIOGRAPHY.MULTI_AUTHORS.ORDER"
],
@@ -121,74 +435,286 @@
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.DIRECT_QUOTES",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.EXTRA_INFO",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.LOCATORS",
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_AUTHORS.POLICY",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_SOURCES",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.PARENTHETICAL",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.PLACEMENT",
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ORDER_AND_YEAR",
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REPEATED_NAMES",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REPEATED_NAMES.POLICY",
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REQUIRED",
"CMOS.CITATIONS.NOTES.AUTHOR_DATE_PLUS_NOTES",
- "CMOS.CITATIONS.SYSTEM.CONSISTENT_CHOICE"
+ "CMOS.CITATIONS.S13_107.AUTHOR_DATE.REFERENCE_LIST.MULTI_AUTHOR.ORDERING",
+ "CMOS.CITATIONS.S13_111.AUTHOR_DATE.REFERENCE_LIST.REQUIRED",
+ "CMOS.CITATIONS.S13_2.AUTHOR_DATE_SYSTEM",
+ "CMOS.CITATIONS.S13_2.SYSTEMS.TWO_TYPES",
+ "CMOS.CITATIONS.S13_54.AUTHOR_DATE.NOTES.COMMENTARY_ONLY",
+ "CMOS.CITATIONS.SYSTEM.CONSISTENT_CHOICE",
+ "HOUSE.CITATIONS.AUTHOR_DATE.PAREN_YEAR_ONLY",
+ "HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.REQUIRED"
+ ],
+ "authors": [
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.BIBLIO_UP_TO_SIX"
+ ],
+ "automation": [
+ "HOUSE.FRONTMATTER.TOC.AUTO_GENERATED"
+ ],
+ "averages": [
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.OMIT_PROBABILITIES"
+ ],
+ "awkward": [
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_AWKWARD_POSSESSIVE"
+ ],
+ "axes": [
+ "CMOS.FIGURES.AXES.UNITS.CONSISTENT",
+ "CMOS.FIGURES.UNITS.LABEL_AXES",
+ "HOUSE.FIGURES.AXES.UNITS.LABELED"
+ ],
+ "axis": [
+ "BRING.TYPOGRAPHY.SERIF.STROKE_CONTRAST_COMPATIBLE"
+ ],
+ "backlinks": [
+ "HOUSE.ACCESSIBILITY.NAVIGATION.FOOTNOTE_BACKLINKS"
+ ],
+ "backmatter": [
+ "CMOS.FRONTMATTER.TOC.FRONT_BACK_MATTER.INCLUDED"
],
"backticks": [
"HOUSE.CODE.INLINE.MONO_BACKTICKS"
],
+ "backups": [
+ "CMOS.CITATIONS.S13_13.BACKUPS"
+ ],
"balance": [
+ "BRING.HEADINGS.WIDTH.BALANCED",
"BRING.LAYOUT.COLUMNS.BALANCE_LENGTHS",
+ "BRING.LAYOUT.COLUMNS.RAGGED_BOTTOM.AVOID",
+ "BRING.LAYOUT.PAGE.SPREADS.BALANCE_CONTENT",
"BRING.LAYOUT.PAGINATION.BALANCE_FACING_PAGES",
+ "BRING.LAYOUT.PAGINATION.BALANCE_FINAL_PAGE",
+ "BRING.TYPOGRAPHY.CONTRAST.AVOID_EXTREME_MIX",
+ "BRING.TYPOGRAPHY.SERIF.SERIF_SANS_BALANCE",
+ "BRING.TYPOGRAPHY.SIZE.DISPLAY_SIZE_BALANCE",
+ "CMOS.LAYOUT.PAGINATION.FACING_PAGES.BALANCE",
"CMOS.PUNCTUATION.PARENS_BRACKETS.BALANCE"
],
"bare url": [
- "HOUSE.LINKS.TEXT.DESCRIPTIVE"
+ "HOUSE.LINKS.TEXT.DESCRIPTIVE",
+ "HOUSE.LINKS.URLS.AVOID.NAKED_URLS_IN_PROSE"
+ ],
+ "bare urls": [
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.NO_BARE_URLS"
+ ],
+ "base notation": [
+ "CMOS.NUMBERS.S9_12.BASE_SUBSCRIPT"
],
"baseline": [
- "BRING.LAYOUT.GRID.ALIGN_ELEMENTS"
+ "BRING.LAYOUT.GRID.ALIGN_ELEMENTS",
+ "BRING.LAYOUT.PARAGRAPH.DROP_CAPS.ALIGN_BASELINE",
+ "HOUSE.EDITORIAL.CLAIMS.BASELINE_FOR_COMPARISONS"
],
"baseline grid": [
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_BLOCK_QUOTES",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_CAPTIONS",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_HEADINGS",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_TABLES",
+ "BRING.LAYOUT.COLUMNS.ALIGN_BASELINES",
"BRING.LAYOUT.LEADING.ALIGN_BASELINE_GRID",
- "BRING.LAYOUT.VERTICAL_RHYTHM.MEASURED_INTERVALS.MULTIPLES"
+ "BRING.LAYOUT.PAGE.SPREADS.ALIGN_BASELINES",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.MEASURED_INTERVALS.MULTIPLES",
+ "CMOS.LAYOUT.SPACING.VERTICAL_RHYTHM"
+ ],
+ "bc": [
+ "CMOS.NUMBERS.S9_36.ERAS.ABBREVIATION_PLACEMENT",
+ "CMOS.NUMBERS.S9_36.ERAS.NO_PERIODS"
],
"bce": [
- "CMOS.NUMBERS.ERAS.BCE_CE"
+ "CMOS.NUMBERS.ERAS.BCE_CE",
+ "CMOS.NUMBERS.S9_36.ERAS.NO_PERIODS"
+ ],
+ "between": [
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.AVOID_FROM_BETWEEN"
+ ],
+ "between and": [
+ "CMOS.NUMBERS.RANGES.NO_MIXED_FROM_BETWEEN"
+ ],
+ "biblical references": [
+ "CMOS.NUMBERS.S9_28.BIBLICAL_REFERENCES"
],
"bibliography": [
+ "CMOS.ABBREVIATIONS.BIBLIOGRAPHY.STANDARDS.FOLLOW",
+ "CMOS.BACKMATTER.BIBLIOGRAPHY.CONSISTENT_STYLE",
+ "CMOS.BACKMATTER.BIBLIOGRAPHY.SORTING",
"CMOS.CITATIONS.BIBLIOGRAPHY.REPEATED_NAMES.THREE_EM_DASH",
"CMOS.CITATIONS.BIBLIOGRAPHY.SAME_AUTHOR.ORDER",
"CMOS.CITATIONS.NOTES_BIBLIO.BIBLIOGRAPHY.INCLUDE_WHEN_USED",
- "CMOS.CITATIONS.NOTES_BIBLIO.NAME_ORDER.NOTES_VS_BIBLIO"
+ "CMOS.CITATIONS.NOTES_BIBLIO.NAME_ORDER.NOTES_VS_BIBLIO",
+ "CMOS.CITATIONS.S13_18.BIBLIO.INVERT_FIRST_AUTHOR",
+ "CMOS.CITATIONS.S13_18.BIBLIO.SHORTENED_NOTES",
+ "CMOS.CITATIONS.S13_2.NOTES_BIBLIOGRAPHY_OPTIONAL",
+ "CMOS.CITATIONS.S13_21.EXAMPLES.BIBLIO_SHORTENED",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.BIBLIO_MORE_THAN_SIX",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.BIBLIO_UP_TO_SIX",
+ "CMOS.CITATIONS.S13_23.TWO_AUTHORS.BIBLIO_INVERT_FIRST",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.BIBLIO_NO_PAGE_RANGE",
+ "CMOS.CITATIONS.S13_26.JOURNAL.BIBLIO_PAGE_RANGE",
+ "CMOS.CITATIONS.S13_63.BIBLIOGRAPHY.CONSISTENT_ELEMENT_ORDER",
+ "CMOS.CITATIONS.S13_66.BIBLIOGRAPHY.INCLUDE_ONLY_PER_SCOPE",
+ "HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.REQUIRED",
+ "HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.YEAR_REQUIRED",
+ "HOUSE.CITATIONS.NOTES.BIBLIOGRAPHY.REQUIRED"
],
"bibliography entries": [
"CMOS.CITATIONS.MATCHING.BIBLIO_ENTRY_REQUIRED"
],
+ "bibliography entry": [
+ "CMOS.CITATIONS.S13_62.BIBLIOGRAPHY.ENTRY_COMPLETENESS.MORE_THAN_SHORT_FORM",
+ "CMOS.CITATIONS.S13_92.BIBLIOGRAPHY.BOOKS.CORE_ELEMENTS"
+ ],
"bibliography order": [
"CMOS.CITATIONS.NOTES_BIBLIO.BIBLIOGRAPHY.SORT_BY_AUTHOR"
],
+ "bibliography scope": [
+ "CMOS.CITATIONS.S13_61.BIBLIOGRAPHY.SCOPE.LABEL_CLEARLY"
+ ],
+ "bibliography subsections": [
+ "CMOS.CITATIONS.S13_64.BIBLIOGRAPHY.SUBSECTIONS.CLEAR_HEADINGS"
+ ],
+ "bidirectional": [
+ "CMOS.I18N.RIGHT_TO_LEFT.MARKUP"
+ ],
"billion": [
- "CMOS.NUMBERS.LARGE_VALUES.MILLIONS_BILLIONS"
+ "CMOS.NUMBERS.LARGE_VALUES.MILLIONS_BILLIONS",
+ "CMOS.NUMBERS.S9_26.LARGE_MONEY.MIXED",
+ "CMOS.NUMBERS.S9_9.BILLION_TRILLION.LOCALE_CHECK",
+ "CMOS.NUMBERS.S9_9.MILLIONS_BILLIONS.GENERAL_RULE"
],
"binary": [
- "CMOS.NUMBERS.BASES.NON_DECIMAL.NO_GROUPING"
+ "CMOS.NUMBERS.BASES.NON_DECIMAL.NO_GROUPING",
+ "CMOS.NUMBERS.S9_12.BASE_INDICATOR",
+ "CMOS.NUMBERS.S9_12.BASE_PREFIXES"
+ ],
+ "binding": [
+ "BRING.LAYOUT.MARGINS.GUTTER.ALLOW_BINDING"
],
"blank lines": [
- "BRING.LAYOUT.PARAGRAPH.BLANK_LINES.SPARING"
+ "BRING.LAYOUT.PARAGRAPH.BLANK_LINES.SPARING",
+ "HOUSE.LAYOUT.MD.BLANK_LINES.SPARING"
+ ],
+ "blank page": [
+ "CMOS.LAYOUT.PAGINATION.FACING_PAGES.BLANKS"
+ ],
+ "blank pages": [
+ "BRING.LAYOUT.PAGE.BLANKS.INTENTIONAL"
+ ],
+ "bleed": [
+ "BRING.LAYOUT.MARGINS.BLEED.ONLY_WHEN_ENABLED",
+ "CMOS.FIGURES.BLEED.ONLY_WHEN_ENABLED"
+ ],
+ "block paragraphs": [
+ "BRING.LAYOUT.PARAGRAPH.BLOCK_STYLE.CONSISTENT"
],
"block quotation": [
"CMOS.PUNCTUATION.BLOCK_QUOTES.NO_QUOTE_MARKS"
],
+ "block quote": [
+ "CMOS.LAYOUT.PARAGRAPHS.BLOCK_QUOTE_STYLE"
+ ],
"block quotes": [
"BRING.HEADINGS.BLOCK_QUOTE.SPACING_AROUND",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_BLOCK_QUOTES",
"BRING.LAYOUT.BLOCK_QUOTES.AVOID_CROWDING",
"BRING.LAYOUT.BLOCK_QUOTES.BEFORE_AFTER_SPACING",
"BRING.LAYOUT.BLOCK_QUOTES.EXTRA_LEAD",
- "BRING.LAYOUT.BLOCK_QUOTES.INDENT_OR_NARROW"
+ "BRING.LAYOUT.BLOCK_QUOTES.INDENT_OR_NARROW",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_IN_BLOCK_QUOTES",
+ "BRING.LAYOUT.PARAGRAPH.AFTER_QUOTE.FLUSH"
],
"blockquote": [
"CMOS.PUNCTUATION.BLOCK_QUOTES.NO_QUOTE_MARKS"
],
+ "bluebook": [
+ "CMOS.CITATIONS.S13_3.LEGAL.BLUEBOOK"
+ ],
+ "body": [
+ "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_AVOID_LONG_RUNS",
+ "BRING.TYPOGRAPHY.TYPEFACE.DISPLAY_FACES_FOR_DISPLAY",
+ "BRING.TYPOGRAPHY.TYPEFACE.MIXING_BY_ROLE_ONLY",
+ "BRING.TYPOGRAPHY.TYPEFACE.TEXT_FACES_FOR_BODY"
+ ],
+ "body size": [
+ "BRING.TYPOGRAPHY.SIZE.BODY_SIZE_MATCH_MEASURE"
+ ],
+ "body text": [
+ "BRING.TYPOGRAPHY.FAMILY.ITALIC_FOR_SUBTLE_EMPHASIS",
+ "BRING.TYPOGRAPHY.SERIF.BODY_TEXT_DEFAULT",
+ "BRING.TYPOGRAPHY.SIZE.SMALL_TEXT_MINIMUM",
+ "CMOS.LAYOUT.MEASURE.LINE_LENGTH.TARGET_RANGE"
+ ],
+ "bold": [
+ "BRING.TYPOGRAPHY.BOLD.AVOID_LONG_PASSAGES",
+ "BRING.TYPOGRAPHY.BOLD.LABELS_SHORT",
+ "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ALL_CAPS",
+ "BRING.TYPOGRAPHY.BOLD.SPARING_USE",
+ "BRING.TYPOGRAPHY.FAMILY.AVOID_FAUX_BOLD",
+ "BRING.TYPOGRAPHY.FAMILY.BOLD_FOR_STRONG_EMPHASIS",
+ "BRING.TYPOGRAPHY.FAMILY.SINGLE_FAMILY_BODY",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_STACKED_EMPHASIS",
+ "BRING.TYPOGRAPHY.TYPEFACE.FAMILY_WITH_VARIANTS",
+ "BRING.TYPOGRAPHY.WEIGHT.BOLD_IN_LONG_PASSAGES_AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ALL_CAPS.AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_LONG.AVOID"
+ ],
+ "bold contrast": [
+ "BRING.TYPOGRAPHY.FAMILY.WEIGHT_CONTRAST_CLEAR"
+ ],
+ "bold italic": [
+ "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ITALICS_LONG"
+ ],
+ "bold italics": [
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ITALIC_LONG.AVOID"
+ ],
+ "boldface": [
+ "CMOS.PUNCTUATION.BOLD_COLOR.CASE_BY_CASE",
+ "CMOS.PUNCTUATION.BOLD_COLOR.SEMANTIC_OWNERSHIP"
+ ],
+ "books": [
+ "BRING.TYPOGRAPHY.ITALICS.TITLES_STANDALONE_WORKS",
+ "CMOS.CITATIONS.S13_20.BIBLIO.BOOKS.NO_PAGES",
+ "CMOS.CITATIONS.S13_92.BIBLIOGRAPHY.BOOKS.CORE_ELEMENTS"
+ ],
+ "bottom margin": [
+ "BRING.LAYOUT.MARGINS.FOOTNOTE.CLEARANCE",
+ "BRING.LAYOUT.MARGINS.TOP_BOTTOM.BALANCE"
+ ],
+ "boxes": [
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.BOXES"
+ ],
+ "bracketed exclamation": [
+ "CMOS.PUNCTUATION.EXCLAMATION.BRACKETED_AVOID"
+ ],
+ "bracketed numbers": [
+ "HOUSE.CITATIONS.NOTES.MARKERS.BRACKETED_NUMBERS.AVOID"
+ ],
"brackets": [
+ "CMOS.I18N.PARENS.BRACKETS.TRANSLATOR_NOTES",
+ "CMOS.PUNCTUATION.BRACKETS.EDITORIAL_INSERTIONS",
"CMOS.PUNCTUATION.BRACKETS.NESTED_PARENS",
+ "CMOS.PUNCTUATION.COMMAS.BRACKETS.EDITORIAL_INSERT",
+ "CMOS.PUNCTUATION.COMMAS.PARENS.TRAILING",
+ "CMOS.PUNCTUATION.COMMAS.PARENS_BRACKETS.AFTER_CLOSING",
"CMOS.PUNCTUATION.PARENS.NESTING",
- "CMOS.PUNCTUATION.PARENS_BRACKETS.BALANCE"
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.BALANCE",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.LINE_ALONE",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.MATCH_SURROUNDING"
+ ],
+ "brevity": [
+ "CMOS.TABLES.CAPTIONS.BREVITY",
+ "HOUSE.EDITORIAL.CLARITY.EDIT_FOR_BREVITY"
+ ],
+ "british style": [
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.SPACED_BRITISH",
+ "CMOS.PUNCTUATION.QUOTES.ALT_STYLE.DOCUMENT"
],
"broken urls": [
"CMOS.CITATIONS.DEGRADED.URL_LINEBREAKS.NORMALIZE"
@@ -196,21 +722,138 @@
"building numbers": [
"CMOS.NUMBERS.PLACES.BUILDINGS_APTS"
],
+ "caliber": [
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.CALIBERS"
+ ],
+ "callouts": [
+ "CMOS.BACKMATTER.NOTES.REFERENCE.MATCH",
+ "CMOS.FIGURES.ANNOTATIONS.CONSISTENT_STYLE",
+ "CMOS.FIGURES.CALL_OUTS.AVOID_OVERLAP",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.BOXES"
+ ],
+ "canonical": [
+ "HOUSE.LINKS.URLS.BARE_DOMAIN.TRAILING_SLASH",
+ "HOUSE.LINKS.URLS.CANONICAL_HOST",
+ "HOUSE.LINKS.URLS.NO_QUERY_WHEN_NOT_NEEDED"
+ ],
+ "canonical url": [
+ "CMOS.CITATIONS.S13_108.BIBLIOGRAPHY.PLATFORMS.PERMALINKS_PREFERRED",
+ "HOUSE.LINKS.URLS.CANONICAL.NO_TRACKING_PARAMS"
+ ],
+ "cap height": [
+ "BRING.TYPOGRAPHY.NUMERALS.SMALL_CAPS_AND_FIGURES"
+ ],
"capitalization": [
"BRING.HEADINGS.CAPITALIZATION.CONSISTENT",
- "CMOS.CITATIONS.TITLES.CAPITALIZATION.CONSISTENT"
+ "BRING.HEADINGS.CASE.PROPER_NOUNS_PRESERVE",
+ "BRING.TYPOGRAPHY.CAPS.MIXED_CAPS_CONSISTENT",
+ "CMOS.BACKMATTER.INDEX.ENTRIES.CONSISTENT_CASE",
+ "CMOS.CITATIONS.S13_2.STYLE_ELEMENTS.SHARED",
+ "CMOS.CITATIONS.TITLES.CAPITALIZATION.CONSISTENT",
+ "CMOS.I18N.CAPITALIZATION.TITLES.LANGUAGE_RULES",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.CAPITALIZATION_CONSISTENT",
+ "CMOS.TABLES.HEADERS.CAPITALIZATION.CONSISTENT",
+ "HOUSE.EDITORIAL.CONSISTENCY.CAPITALIZATION.STABLE"
],
"caps": [
+ "BRING.TYPOGRAPHY.CAPS.ROMAN_NUMERALS_SPACING",
+ "BRING.TYPOGRAPHY.CAPS.TRACKING_REVIEW",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_STACKED_EMPHASIS",
+ "BRING.TYPOGRAPHY.NUMERALS.LINING_FOR_CAPS_AND_DISPLAY",
"BRING.TYPOGRAPHY.TRACKING.CAPS_SMALLCAPS_AND_LONG_DIGITS"
],
+ "caption alignment": [
+ "CMOS.FIGURES.CAPTION.ALIGNMENT.CONSISTENT"
+ ],
+ "caption placement": [
+ "CMOS.FIGURES.CAPTION.PLACEMENT.CONSISTENT"
+ ],
+ "caption typography": [
+ "CMOS.FIGURES.CAPTION.FONT.CONSISTENT"
+ ],
+ "captions": [
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_CAPTIONS",
+ "BRING.LAYOUT.PAGINATION.AVOID_STRANDED_CAPTIONS",
+ "BRING.LAYOUT.PAGINATION.KEEP_FIGURE_WITH_CAPTION",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.CAPTIONS.SPACING",
+ "BRING.TYPOGRAPHY.LIGATURES.KEEP_CONSISTENT",
+ "BRING.TYPOGRAPHY.NUMERALS.FIGURE_STYLE_FOR_CAPTIONS",
+ "CMOS.ABBREVIATIONS.CAPTIONS.DEFINE_ON_FIRST_USE",
+ "CMOS.FIGURES.CAPTION.LENGTH.REASONABLE",
+ "CMOS.FIGURES.CAPTION.NUMBER.MATCH_LABEL",
+ "CMOS.FIGURES.CAPTION.PUNCTUATION.CONSISTENT",
+ "CMOS.FIGURES.CAPTIONS.PRESENT",
+ "CMOS.FIGURES.LIST_ENTRIES.MATCH_CAPTIONS",
+ "CMOS.FIGURES.NUMBERING.SEQUENTIAL",
+ "CMOS.TABLES.CAPTIONS.BREVITY",
+ "CMOS.TABLES.CAPTIONS.CLARITY",
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_AVOID_DUPLICATE_CAPTION",
+ "HOUSE.ACCESSIBILITY.IMAGES.CAPTION_FOR_COMPLEX",
+ "HOUSE.ACCESSIBILITY.MEDIA.TRANSCRIPTS",
+ "HOUSE.ACCESSIBILITY.TABLES.CAPTION_SUMMARY",
+ "HOUSE.FIGURES.CAPTIONS.TAKEAWAY",
+ "HOUSE.LAYOUT.PAGINATION.CAPTIONS.KEEP_WITH_CONTENT"
+ ],
+ "cardinals": [
+ "CMOS.NUMBERS.S9_33.MONTH_DAY.CARDINALS"
+ ],
+ "case": [
+ "CMOS.ABBREVIATIONS.TECH.TERMS.CASE_SENSITIVE",
+ "CMOS.NUMBERS.ROMAN_NUMERALS.CASE_CONSISTENT"
+ ],
+ "case fractions": [
+ "CMOS.NUMBERS.S9_17.CASE_FRACTIONS.USE_WITH_CARE"
+ ],
+ "case sensitivity": [
+ "CMOS.CITATIONS.S13_12.URLS.CASE_SENSITIVE"
+ ],
+ "categories": [
+ "CMOS.NUMBERS.S9_7.CONSISTENT_CONTEXT"
+ ],
+ "category": [
+ "CMOS.NUMBERS.S9_7.CATEGORY_TRIGGER",
+ "CMOS.NUMBERS.S9_8.SEVERITY_CLASSIFICATIONS"
+ ],
"ce": [
- "CMOS.NUMBERS.ERAS.BCE_CE"
+ "CMOS.NUMBERS.ERAS.BCE_CE",
+ "CMOS.NUMBERS.S9_36.ERAS.NO_PERIODS"
+ ],
+ "cells": [
+ "CMOS.TABLES.ALIGNMENT.TEXT_LEFT"
],
"centered": [
"BRING.HEADINGS.SUBHEADS.CROSSHEADS_SIDEHEADS.CHOOSE_DELIBERATELY"
],
+ "cents": [
+ "CMOS.NUMBERS.S9_22.MONEY.DECIMALS.ONLY_WHEN_MIXED",
+ "CMOS.NUMBERS.S9_22.MONEY.MINIMUM_DECIMALS"
+ ],
"centuries": [
- "CMOS.NUMBERS.CENTURIES.SPELLED_OUT"
+ "CMOS.NUMBERS.CENTURIES.SPELLED_OUT",
+ "CMOS.NUMBERS.INCLUSIVE.YEARS.CENTURY_CROSSING",
+ "CMOS.NUMBERS.S9_34.CENTURIES.NUMERAL_PLURALS",
+ "CMOS.NUMBERS.S9_34.CENTURIES.ORDINAL_LOWERCASE",
+ "CMOS.NUMBERS.S9_36.ERAS.CENTURY_PLACEMENT"
+ ],
+ "certainty": [
+ "HOUSE.EDITORIAL.CLARITY.AVOID_WEASEL_WORDS",
+ "HOUSE.EDITORIAL.TONE.CALIBRATE_CERTAINTY"
+ ],
+ "changelog": [
+ "CMOS.FRONTMATTER.CHANGELOG.LINKS",
+ "HOUSE.EDITORIAL.STRUCTURE.CHANGELOG.LIVING_DOCS"
+ ],
+ "changes": [
+ "CMOS.CITATIONS.S13_17.PRESERVE.CRISIS_SOURCES"
+ ],
+ "chapter": [
+ "CMOS.CITATIONS.S13_95.BIBLIOGRAPHY.CHAPTERS.IN_EDITED_COLLECTIONS"
+ ],
+ "chapter 14": [
+ "CMOS.CITATIONS.S13_21.EXAMPLES.CHAPTER14"
+ ],
+ "chapter author": [
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.INCLUDE_AUTHOR"
],
"chapter citation": [
"CMOS.CITATIONS.NOTES.CHAPTER_IN_EDITED_BOOK"
@@ -221,35 +864,121 @@
"chapter headings": [
"CMOS.HEADINGS.MULTIAUTHOR.AUTHOR_ATTRIBUTION_PLACEMENT"
],
+ "chapter notes": [
+ "CMOS.CITATIONS.S13_48.ENDNOTES.GROUP_BY_CHAPTER"
+ ],
"chapter numbering": [
- "CMOS.HEADINGS.MULTIAUTHOR.CHAPTER_NUMBERING"
+ "CMOS.CITATIONS.S13_52.ENDNOTES.NAVIGATION_CUES",
+ "CMOS.FIGURES.NUMBERING.WITHIN_CHAPTERS",
+ "CMOS.HEADINGS.MULTIAUTHOR.CHAPTER_NUMBERING",
+ "CMOS.TABLES.TITLES.SCOPE.CONSISTENT"
],
"chapter numbers": [
"CMOS.NUMBERS.REFERENCES.PAGE_CHAPTER_FIGURE"
],
+ "chapter restart": [
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.NO_BOOKWIDE_RUN"
+ ],
+ "chapter start": [
+ "CMOS.LAYOUT.PAGINATION.PAGE_BREAKS.BEFORE_PARTS"
+ ],
+ "chapter title": [
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.QUOTE_TITLE",
+ "CMOS.LAYOUT.RUNNING_HEADS.CHAPTER_TITLES"
+ ],
"chapters": [
- "CMOS.HEADINGS.DIVISIONS.CHAPTERS.MULTIAUTHOR"
+ "CMOS.HEADINGS.DIVISIONS.CHAPTERS.MULTIAUTHOR",
+ "CMOS.NUMBERS.S9_28.DIVISIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.CHAPTERS_PARTS"
],
"characters per line": [
"BRING.LAYOUT.MEASURE.COMFORTABLE_RANGE"
],
+ "charts": [
+ "HOUSE.ACCESSIBILITY.CONTRAST.NON_TEXT",
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_SUMMARY_FOR_CHARTS",
+ "HOUSE.FIGURES.AXES.UNITS.LABELED"
+ ],
+ "checklists": [
+ "HOUSE.EDITORIAL.LISTS.TASKS.CHECKLIST"
+ ],
+ "citation": [
+ "CMOS.FIGURES.SOURCE.DATA.CITED"
+ ],
+ "citation database": [
+ "CMOS.CITATIONS.S13_13.REPAIR_AT_SOURCE"
+ ],
"citation management": [
"CMOS.CITATIONS.RESEARCH.METADATA.CAPTURE_EARLY"
],
+ "citation markers": [
+ "HOUSE.CITATIONS.NOTES.MARKERS.BRACKETED_NUMBERS.AVOID"
+ ],
+ "citation order": [
+ "CMOS.CITATIONS.S13_45.NOTES.CITATION_FIRST"
+ ],
"citation placement": [
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.PLACEMENT"
],
+ "citation style": [
+ "CMOS.FRONTMATTER.CITATION_STYLE.DECLARED"
+ ],
"citation system": [
"CMOS.CITATIONS.SYSTEM.CONSISTENT_CHOICE"
],
+ "citation tools": [
+ "CMOS.CITATIONS.S13_13.TOOLS.USE_METADATA"
+ ],
+ "citations": [
+ "CMOS.ABBREVIATIONS.LATIN.ET_AL.USE",
+ "CMOS.BACKMATTER.APPENDICES.SOURCES",
+ "CMOS.BACKMATTER.NOTES.CITATIONS.COMPLETE",
+ "CMOS.BACKMATTER.REFERENCES.SECTION_PRESENT",
+ "CMOS.I18N.CITATIONS.TITLES.ORIGINAL_OR_TRANSLATED",
+ "CMOS.I18N.TRANSLATION.INDICATE",
+ "CMOS.NUMBERS.S9_29.PERIODICALS.OMIT_WORDS",
+ "HOUSE.EDITORIAL.CLAIMS.SUPPORT_WITH_SOURCES",
+ "HOUSE.EDITORIAL.STRUCTURE.REFERENCES.WHEN_CITED"
+ ],
+ "claims": [
+ "HOUSE.EDITORIAL.CLAIMS.SCOPE_TIMEBOUND",
+ "HOUSE.EDITORIAL.CLAIMS.SUPPORT_WITH_SOURCES"
+ ],
+ "clarification": [
+ "CMOS.PUNCTUATION.COMMAS.NOT_PHRASE",
+ "CMOS.PUNCTUATION.COMMAS.NOT_PHRASES"
+ ],
"clarity": [
"BRING.TABLES.CAPTIONS.CLEAR",
- "CMOS.PUNCTUATION.HYPHENATION.READABILITY"
+ "CMOS.ABBREVIATIONS.AVOID_ONE_OFFS",
+ "CMOS.ABBREVIATIONS.LATIN.VERSUS_ENGLISH",
+ "CMOS.NUMBERS.S9_7.CROSS_CATEGORY.MIX_OK",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.CLARITY",
+ "CMOS.PUNCTUATION.COMMAS.HOMONYMS.CLARITY",
+ "CMOS.PUNCTUATION.COMMAS.TOO_MID_SENTENCE",
+ "CMOS.PUNCTUATION.HYPHENATION.READABILITY",
+ "CMOS.PUNCTUATION.OVERVIEW.FUNCTION.CLARITY",
+ "CMOS.PUNCTUATION.PARENS.AVOID_MULTIPLE_SENTENCES",
+ "CMOS.TABLES.CAPTIONS.CLARITY",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_AMBIGUOUS_PRONOUNS",
+ "HOUSE.EDITORIAL.CLARITY.EXAMPLES_WHEN_COMPLEX"
+ ],
+ "classification": [
+ "CMOS.FRONTMATTER.NAVIGATION.METADATA",
+ "CMOS.FRONTMATTER.SECURITY.CLASSIFICATION"
+ ],
+ "clearance": [
+ "BRING.LAYOUT.MARGINS.RUNNING_HEAD.CLEARANCE"
+ ],
+ "cli": [
+ "HOUSE.CODE.OUTPUT.DISTINGUISH_FROM_INPUT"
],
"click here": [
- "HOUSE.LINKS.TEXT.DESCRIPTIVE"
+ "HOUSE.LINKS.TEXT.DESCRIPTIVE",
+ "HOUSE.LINKS.TEXT.NO_CLICK_HERE"
],
"clipping": [
+ "CMOS.FIGURES.MARGINS.AVOID_CLIPPING",
"HOUSE.CODE.BLOCKS.NO_CLIPPING",
"HOUSE.LAYOUT.OVERFLOW.OVERFULL_LINES.REPORT",
"HOUSE.TABLES.OVERFLOW.NO_CLIPPING"
@@ -258,34 +987,116 @@
"CMOS.PUNCTUATION.HYPHENATION.COMPOUND_DEFINITION",
"CMOS.PUNCTUATION.HYPHENATION.TREND_CLOSED"
],
+ "clothing sizes": [
+ "CMOS.NUMBERS.S9_8.CLOTHING_SIZES.NUMERALS"
+ ],
+ "clusters": [
+ "CMOS.NUMBERS.S9_4.MIXED_LARGE_CONTEXTS",
+ "CMOS.NUMBERS.S9_7.AVOID_DENSE_WORDS"
+ ],
+ "code": [
+ "BRING.CODE.RAG.AVOID_FAKE_JUSTIFY",
+ "BRING.CODE.RAG.NO_AUTO_HYPHENATION",
+ "BRING.CODE.RAG.NO_LETTERSPACING",
+ "BRING.CODE.RAG.NO_MIN_LINE",
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_CODE_URLS",
+ "HOUSE.CODE.BLOCKS.TRAILING_WHITESPACE.AVOID",
+ "HOUSE.CODE.TABLES.AVOID_FOR_CODE",
+ "HOUSE.CODE.URLS.IN_CODE.AVOID_WRAPPING",
+ "HOUSE.CODE.WRAPPING.NO_SOFT_HYPHENS"
+ ],
+ "code alignment": [
+ "BRING.CODE.RAG.FIXED_WORD_SPACES"
+ ],
"code blocks": [
- "BRING.LAYOUT.MEASURE.CODE_BLOCKS.WRAP_POLICY"
+ "BRING.CODE.MONO_RAGGED_RIGHT",
+ "BRING.LAYOUT.MEASURE.CODE_BLOCKS.WRAP_POLICY",
+ "HOUSE.CODE.BLOCKS.NO_LINE_NUMBERS",
+ "HOUSE.CODE.BLOCKS.SPLIT_BY_LANGUAGE",
+ "HOUSE.CODE.BLOCKS.USE_FOR_MULTILINE",
+ "HOUSE.CODE.EXAMPLES.MULTI_FILE.SEPARATE"
],
"code fence": [
"HOUSE.CODE.BLOCKS.LANGUAGE_TAGS.PREFERRED"
],
+ "code fences": [
+ "HOUSE.ACCESSIBILITY.CODE.FENCES.LANGUAGE",
+ "HOUSE.CODE.FENCES.LANGUAGE_INFO.SUGGEST",
+ "HOUSE.CODE.LANGUAGE.CONSISTENT_FENCES"
+ ],
+ "code line length": [
+ "HOUSE.CODE.BLOCKS.LONG_LINES.AVOID"
+ ],
"code overflow": [
"HOUSE.CODE.BLOCKS.NO_CLIPPING"
],
"code wrapping": [
"HOUSE.CODE.BLOCKS.WRAP_POLICY"
],
+ "codes": [
+ "BRING.TYPOGRAPHY.NUMERALS.SLASHED_ZERO_IF_CONFUSION"
+ ],
"coherence": [
"BRING.HEADINGS.RELATED_ELEMENTS.COHERENT"
],
+ "collation": [
+ "CMOS.I18N.NAMES.SORTING.COLLATION"
+ ],
+ "collisions": [
+ "BRING.TYPOGRAPHY.LIGATURES.FI_FL_COLLISIONS"
+ ],
+ "colon": [
+ "CMOS.CITATIONS.S13_26.JOURNAL.PAGE_COLON",
+ "CMOS.CITATIONS.S13_91.TITLE_SUBTITLE.SEPARATOR.COLON",
+ "CMOS.NUMBERS.S9_28.BIBLICAL_REFERENCES",
+ "CMOS.PUNCTUATION.COLONS.AVOID_AFTER_PREPOSITION",
+ "CMOS.PUNCTUATION.COLONS.FORMAL_GREETINGS",
+ "CMOS.PUNCTUATION.COLONS.INTRODUCE_FORMAL_LISTS",
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS.GREETINGS",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.INTRO_COMPLETE_COLON",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.INTRO_COLON",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.LIST_INTRO"
+ ],
"colon capitalization": [
"CMOS.PUNCTUATION.COLONS.CAPITALIZATION"
],
+ "colon misuse": [
+ "CMOS.PUNCTUATION.COLONS.AVOID_INCOMPLETE_LEADIN"
+ ],
"colon notation": [
"CMOS.NUMBERS.RATIOS.FORMAT"
],
"colon spacing": [
- "CMOS.PUNCTUATION.COLONS.SPACE_AFTER"
+ "CMOS.PUNCTUATION.COLONS.SPACE_AFTER",
+ "CMOS.PUNCTUATION.SPACING.ONE_SPACE_AFTER_COLON"
],
"colon usage": [
"CMOS.PUNCTUATION.COLONS.AS_FOLLOWS",
+ "CMOS.PUNCTUATION.COLONS.COMPLETE_CLAUSE_REQUIRED",
"CMOS.PUNCTUATION.COLONS.INTRO_QUOTE_QUESTION"
],
+ "colons": [
+ "BRING.HEADINGS.NO_TERMINAL_COLON",
+ "CMOS.PUNCTUATION.COLONS.AMPLIFY_OR_ILLUSTRATE",
+ "CMOS.PUNCTUATION.COLONS.EMPHASIS_SECOND_CLAUSE",
+ "CMOS.PUNCTUATION.COLONS.ONE_SPACE",
+ "CMOS.PUNCTUATION.COLONS.QUOTATIONS"
+ ],
+ "color": [
+ "BRING.TYPOGRAPHY.FAMILY.METRICS_MATCH_WHEN_MIXING",
+ "CMOS.FIGURES.COLOR.NOT_SOLE_SIGNAL",
+ "CMOS.FIGURES.COLOR.PALETTE.CONSISTENT",
+ "CMOS.PUNCTUATION.BOLD_COLOR.CASE_BY_CASE",
+ "CMOS.PUNCTUATION.BOLD_COLOR.SEMANTIC_OWNERSHIP",
+ "HOUSE.ACCESSIBILITY.COLOR.NOT_SOLE_CONVEYOR",
+ "HOUSE.ACCESSIBILITY.LINKS.VISUALLY_DISTINCT"
+ ],
+ "color encoding": [
+ "HOUSE.FIGURES.COLOR.LEGEND.REQUIRED"
+ ],
+ "colorblind": [
+ "HOUSE.FIGURES.COLOR.CONTRAST_SAFE"
+ ],
"column consistency": [
"BRING.TABLES.DATA_TYPES.NOT_MIXED"
],
@@ -293,22 +1104,64 @@
"BRING.TABLES.HEADERS.CONCISE",
"BRING.TABLES.TEXT_ORIENTATION.HORIZONTAL"
],
+ "column order": [
+ "CMOS.TABLES.COLUMN_ORDER.LOGICAL"
+ ],
+ "column spacing": [
+ "CMOS.TABLES.COLUMN_SPACING.READABLE"
+ ],
+ "column width": [
+ "BRING.LAYOUT.COLUMNS.WIDTH.CONSISTENT"
+ ],
+ "column widths": [
+ "HOUSE.TABLES.COLUMN_WIDTHS.BALANCED"
+ ],
"columns": [
+ "BRING.LAYOUT.COLUMNS.ALIGN_BASELINES",
"BRING.LAYOUT.COLUMNS.BALANCE_LENGTHS",
+ "BRING.LAYOUT.COLUMNS.COUNT.MODERATE",
+ "BRING.LAYOUT.COLUMNS.USE_FOR_LONG_LISTS",
"BRING.LAYOUT.MEASURE.AVOID_TOO_SHORT",
"BRING.LAYOUT.MEASURE.COMFORTABLE_RANGE",
"BRING.LAYOUT.MEASURE.MULTICOLUMN_TARGETS",
"BRING.LAYOUT.PAGE.DENSITY.DONT_SUFFOCATE",
- "BRING.TABLES.HEADERS.ALIGN_WITH_COLUMNS"
+ "BRING.TABLES.HEADERS.ALIGN_WITH_COLUMNS",
+ "CMOS.LAYOUT.MEASURE.MAX_LINE_LENGTH",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.MULTI_COLUMN_SHORT_ITEMS",
+ "CMOS.TABLES.DATA_TYPES.NOT_MIXED",
+ "CMOS.TABLES.HEADERS.ALIGNMENT.CONSISTENT"
+ ],
+ "comma": [
+ "CMOS.PUNCTUATION.COMMAS.AND_THEN",
+ "CMOS.PUNCTUATION.COMMAS.CONSECUTIVE_CONJUNCTIONS",
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS.GREETINGS",
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_QUESTIONS",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_ELEMENTS",
+ "CMOS.PUNCTUATION.COMMAS.REPEATED_ADJECTIVES.USE_COMMA",
+ "CMOS.PUNCTUATION.QUOTES.ITALIC_TITLE_EXCEPTION"
+ ],
+ "comma choice": [
+ "CMOS.PUNCTUATION.COMMAS.INTRO_PHRASES.GENERAL"
],
"comma grouping": [
"CMOS.NUMBERS.INCLUSIVE.COMMAS"
],
+ "comma omission": [
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.NO_COMMA"
+ ],
"comma placement": [
"CMOS.PUNCTUATION.COMMAS.DATES",
"CMOS.PUNCTUATION.COMMAS.DEPENDENT_CLAUSE_AFTER",
+ "CMOS.PUNCTUATION.COMMAS.PARENS.TRAILING",
+ "CMOS.PUNCTUATION.COMMAS.PARENS_BRACKETS.AFTER_CLOSING",
"CMOS.PUNCTUATION.COMMAS.QUOTED_TITLES"
],
+ "comma splice": [
+ "CMOS.PUNCTUATION.COMMAS.COMMA_SPLICE.AVOID_FORMAL",
+ "CMOS.PUNCTUATION.COMMAS.SPLICES.AVOID_FORMAL",
+ "CMOS.PUNCTUATION.COMMAS.SPLICES.EDITORIAL_DISCRETION",
+ "CMOS.PUNCTUATION.SEMICOLONS.AVOID_COMMA_SPLICE"
+ ],
"comma use": [
"CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASES",
"CMOS.PUNCTUATION.COMMAS.INTRODUCTORY_PHRASES",
@@ -316,40 +1169,127 @@
"CMOS.PUNCTUATION.COMMAS.QUESTIONS",
"CMOS.PUNCTUATION.COMMAS.REPEATED_ADJECTIVES"
],
+ "commands": [
+ "HOUSE.CODE.BLOCKS.PLATFORM.NOTED"
+ ],
"commas": [
+ "CMOS.NUMBERS.S9_12.NO_COMMAS.IN_BASE",
+ "CMOS.NUMBERS.S9_26.MONEY.COMMAS",
+ "CMOS.NUMBERS.S9_33.MONTH_DAY_YEAR.COMMA",
"CMOS.PUNCTUATION.COMMAS.ADDRESSES",
- "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATES"
+ "CMOS.PUNCTUATION.COMMAS.BRACKETS.EDITORIAL",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATES",
+ "CMOS.PUNCTUATION.COMMAS.EXPLANATORY_ALTERNATIVES",
+ "CMOS.PUNCTUATION.COMMAS.IMPERATIVE_CLAUSES.DEFAULT",
+ "CMOS.PUNCTUATION.COMMAS.LOGIC_OVER_PAUSE",
+ "CMOS.PUNCTUATION.COMMAS.PAIRS.TITLES_EXCEPTION",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICALS.SLIGHT_BREAK",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.QUESTIONS.DIRECT_IN_SENTENCE",
+ "CMOS.PUNCTUATION.COMMAS.QUOTE_ENDING_QM_EXCL",
+ "CMOS.PUNCTUATION.COMMAS.REGISTER.FLEX",
+ "CMOS.PUNCTUATION.COMMAS.THAT_IS.TRAILING_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.TOO_EITHER.OMIT",
+ "CMOS.PUNCTUATION.COMMAS.TOO_MID_SENTENCE",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SEPARATORS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_PUNCTUATION",
+ "CMOS.PUNCTUATION.QUOTES.US_STYLE_PERIODS_COMMAS"
],
"commas in quotes": [
"CMOS.PUNCTUATION.QUOTATION_MARKS.PUNCTUATION_PLACEMENT_US"
],
"commentary": [
- "CMOS.CITATIONS.NOTES.SUBSTANTIVE.SEPARATE_FROM_SOURCE"
+ "CMOS.CITATIONS.NOTES.SUBSTANTIVE.SEPARATE_FROM_SOURCE",
+ "CMOS.CITATIONS.S13_54.AUTHOR_DATE.NOTES.COMMENTARY_ONLY",
+ "CMOS.CITATIONS.S13_57.NOTES.SEPARATE_SOURCE_VS_COMMENTARY"
],
"commentary notes": [
- "CMOS.CITATIONS.NOTES.AUTHOR_DATE_PLUS_NOTES"
+ "CMOS.CITATIONS.NOTES.AUTHOR_DATE_PLUS_NOTES",
+ "CMOS.CITATIONS.S13_45.NOTES.CITATION_FIRST"
+ ],
+ "comments": [
+ "HOUSE.CODE.COMMENTS.MINIMIZE_NOISE",
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_REVIEW_NOTES_INLINE"
+ ],
+ "company names": [
+ "CMOS.PUNCTUATION.COMMAS.CORPORATE_SUFFIX",
+ "CMOS.PUNCTUATION.COMMAS.INC_LTD.NONE"
+ ],
+ "comparisons": [
+ "CMOS.FIGURES.SCALING.UNIFORM",
+ "HOUSE.EDITORIAL.CLAIMS.BASELINE_FOR_COMPARISONS"
+ ],
+ "complete clause": [
+ "CMOS.PUNCTUATION.COLONS.AVOID_INCOMPLETE_LEADIN",
+ "CMOS.PUNCTUATION.COLONS.COMPLETE_CLAUSE_REQUIRED"
+ ],
+ "completeness": [
+ "CMOS.CITATIONS.S13_1.SUFFICIENT_INFO"
],
"complex series": [
"CMOS.PUNCTUATION.SEMICOLONS.COMPLEX_SERIES.SEPARATE"
],
+ "compliance": [
+ "CMOS.CITATIONS.S13_1.PURPOSE.COPYRIGHT"
+ ],
"compound modifier": [
"CMOS.PUNCTUATION.HYPHENS.COMPOUND_MODIFIERS.BEFORE_NOUN"
],
+ "compound modifiers": [
+ "CMOS.NUMBERS.FRACTIONS.ADJECTIVAL.HYPHENATE"
+ ],
"compound predicate": [
- "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATES"
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.CLARITY",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.NO_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.SERIES",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.THEN_SHORTHAND",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATES",
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTION_PLUS_PHRASE.PREDICATE",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE.PREDICATE",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE_PHRASES"
+ ],
+ "compound surnames": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.PARTICLES.CONSISTENT_FORMAT"
],
"compounds": [
"CMOS.PUNCTUATION.HYPHENATION.GENERAL_CHOICE"
],
"concise": [
- "BRING.TABLES.HEADERS.CONCISE"
+ "BRING.TABLES.HEADERS.CONCISE",
+ "CMOS.FIGURES.CAPTION.LENGTH.REASONABLE",
+ "HOUSE.EDITORIAL.HEADINGS.LENGTH.CONCISE"
+ ],
+ "concise headings": [
+ "BRING.HEADINGS.LENGTH.CONCISE"
],
"condense": [
"BRING.TYPOGRAPHY.LETTERFORMS.AVOID_DISTORTION"
],
+ "confidential": [
+ "HOUSE.FRONTMATTER.METADATA.CONFIDENTIALITY"
+ ],
+ "config": [
+ "HOUSE.CODE.BLOCKS.CONFIG.VALID"
+ ],
+ "conjunction": [
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTION_PLUS_PHRASE.INDEPENDENT",
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTION_PLUS_PHRASE.PREDICATE"
+ ],
"conjunctions": [
+ "CMOS.PUNCTUATION.COMMAS.CONSECUTIVE_CONJUNCTIONS",
+ "CMOS.PUNCTUATION.COMMAS.CONSECUTIVE_CONJUNCTIONS.NO_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.CONJUNCTION",
+ "CMOS.PUNCTUATION.COMMAS.PHRASE_PLUS_CONJUNCTION",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.NO_COMMA_CONJUNCTION",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.ALL_CONJUNCTIONS",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.ALL_CONJUNCTIONS_NO_COMMA",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_CONJUNCTION",
"CMOS.PUNCTUATION.SEMICOLONS.BEFORE_CONJUNCTION"
],
+ "conjunctive adverbs": [
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTIVE_ADVERBS",
+ "CMOS.PUNCTUATION.SEMICOLONS.CONJUNCTIVE_ADVERBS"
+ ],
"conjunctive phrases": [
"CMOS.PUNCTUATION.SEMICOLONS.CONJUNCTIVE_PHRASES"
],
@@ -357,54 +1297,284 @@
"BRING.LAYOUT.LINEBREAKS.AVOID_SAME_WORD_START",
"BRING.TYPOGRAPHY.HYPHENATION.MAX_CONSECUTIVE_LINES"
],
+ "consecutive numbering": [
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.CONSECUTIVE"
+ ],
"consistency": [
+ "BRING.HEADINGS.NUMBERING.CONSISTENT_STYLE",
"BRING.HEADINGS.SUBHEADS.MIXING_SYMM_ASYMM.AVOID_HAPHAZARD",
"BRING.HEADINGS.SUBHEADS.STYLE_CONTRIBUTES_TO_WHOLE",
+ "BRING.HEADINGS.TOC.MATCH",
+ "BRING.LAYOUT.COLUMNS.WIDTH.CONSISTENT",
"BRING.LAYOUT.LEADING.CONSISTENT_BODY",
"BRING.LAYOUT.PARAGRAPH.INDENT_SIZE.CONSISTENT",
+ "BRING.LAYOUT.PARAGRAPH.RUN_IN_HEADS.CONSISTENT",
+ "BRING.TYPOGRAPHY.CAPS.MIXED_CAPS_CONSISTENT",
+ "BRING.TYPOGRAPHY.FAMILY.ITALIC_PUNCTUATION_MATCH",
+ "BRING.TYPOGRAPHY.ITALICS.CONSISTENT_TITLE_TREATMENT",
+ "BRING.TYPOGRAPHY.ITALICS.PUNCTUATION_FOLLOWS_STYLE",
"BRING.TYPOGRAPHY.KERNING.CONSISTENT_OR_NONE",
+ "BRING.TYPOGRAPHY.LIGATURES.KEEP_CONSISTENT",
+ "BRING.TYPOGRAPHY.NUMERALS.CONSISTENT_STYLE_WITHIN_SECTION",
+ "BRING.TYPOGRAPHY.SIZE.AVOID_TOO_MANY_SIZES",
+ "BRING.TYPOGRAPHY.TYPEFACE.LIMIT_NUMBER",
+ "BRING.TYPOGRAPHY.WEIGHT.AVOID_TOO_MANY_WEIGHTS",
+ "CMOS.ABBREVIATIONS.GENERAL.CONSISTENCY",
+ "CMOS.BACKMATTER.BIBLIOGRAPHY.CONSISTENT_STYLE",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ENTRY_TEMPLATES.CONSISTENT",
"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.CONSISTENT_FORM",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.MULTIPLE_CONTRIBUTORS.POLICY_CONSISTENT",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.CONSISTENT",
+ "CMOS.CITATIONS.S13_4.CONSISTENCY.REQUIRED",
+ "CMOS.CITATIONS.S13_63.BIBLIOGRAPHY.CONSISTENT_ELEMENT_ORDER",
+ "CMOS.CITATIONS.S13_68.BIBLIOGRAPHY.ENTRY_TYPES.NOT_MIXED",
+ "CMOS.FIGURES.CAPTION.FONT.CONSISTENT",
+ "CMOS.I18N.PUNCTUATION.ELLIPSIS.STYLE",
+ "CMOS.I18N.TRANSLITERATION.SYSTEM.CONSISTENT",
+ "CMOS.LAYOUT.PAGINATION.RUNNING_HEADS.CONSISTENCY",
+ "CMOS.LAYOUT.PARAGRAPHS.SPACING_POLICY",
+ "CMOS.LAYOUT.RUNNING_HEADS.CHAPTER_TITLES",
+ "CMOS.LAYOUT.SPACING.LINE_SPACING.CONSISTENT",
"CMOS.NUMBERS.CONSISTENCY.MIXED_FORMS.AVOID",
- "CMOS.NUMBERS.DECADES.CONSISTENT_FORM"
+ "CMOS.NUMBERS.DATES.DAY_MONTH_ORDER.CONSISTENT",
+ "CMOS.NUMBERS.DECADES.CONSISTENT_FORM",
+ "CMOS.NUMBERS.ORDINALS.CONSISTENT_FORM",
+ "CMOS.NUMBERS.PERCENTAGES.SYMBOL_OR_WORD.CONSISTENT",
+ "CMOS.NUMBERS.S9_1.READABILITY_OVER_CONSISTENCY",
+ "CMOS.NUMBERS.S9_10.SCI_NOTATION.CONSISTENT",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.CONSISTENCY",
+ "CMOS.NUMBERS.S9_19.UNIT_REPETITION.CONSISTENT",
+ "CMOS.NUMBERS.S9_21.DECIMAL_CONTEXT.CONSISTENT",
+ "CMOS.NUMBERS.S9_22.MONEY.SYMBOL_OR_WORD",
+ "CMOS.NUMBERS.S9_25.CURRENCY_CODES.CONSISTENT",
+ "CMOS.NUMBERS.S9_7.CONSISTENT_CONTEXT",
+ "CMOS.NUMBERS.S9_9.CONSISTENCY.WITH_FRACTIONS",
+ "CMOS.NUMBERS.TIME.RANGES.CONSISTENT_FORMAT",
+ "CMOS.PUNCTUATION.LISTS.CONSISTENT_FORMAT",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.CAPITALIZATION_CONSISTENT",
+ "CMOS.PUNCTUATION.OVERVIEW.CONSISTENT.PRINCIPLES",
+ "CMOS.PUNCTUATION.QUOTES.ALT_STYLE.DOCUMENT",
+ "CMOS.TABLES.SORTING.LOGICAL",
+ "CMOS.TABLES.UNITS.CONSISTENT",
+ "HOUSE.ACCESSIBILITY.LISTS.MARKER_CONSISTENT",
+ "HOUSE.CODE.LANGUAGE.CONSISTENT_FENCES",
+ "HOUSE.CODE.LANGUAGE.NOTATION.CONSISTENT",
+ "HOUSE.CODE.LINE_ENDINGS.NORMALIZE",
+ "HOUSE.EDITORIAL.CONSISTENCY.CAPITALIZATION.STABLE",
+ "HOUSE.EDITORIAL.CONSISTENCY.DATE_FORMAT.SINGLE",
+ "HOUSE.EDITORIAL.CONSISTENCY.NAMES.SAME_FORM",
+ "HOUSE.EDITORIAL.CONSISTENCY.TERMINOLOGY.STABLE",
+ "HOUSE.EDITORIAL.HEADINGS.CASE.CONSISTENT",
+ "HOUSE.EDITORIAL.LISTS.PUNCTUATION.CONSISTENT",
+ "HOUSE.LINKS.TEXT.DIFFERENTIATE_REPEATED_LINKS"
+ ],
+ "constraints": [
+ "CMOS.FRONTMATTER.ACCESSIBILITY.NOTES"
+ ],
+ "contact": [
+ "CMOS.BACKMATTER.CONTACT.SUPPORT",
+ "CMOS.FRONTMATTER.CONTACT.OWNERSHIP",
+ "HOUSE.FRONTMATTER.DISTRIBUTION.CONTACT",
+ "HOUSE.LINKS.URLS.MAILTO.INTENT"
+ ],
+ "container": [
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.IN_BEFORE_BOOK"
+ ],
+ "context": [
+ "CMOS.FIGURES.CROP.AVOID_LOSS",
+ "CMOS.NUMBERS.S9_1.OVERVIEW.FACTORS",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.CONTEXT_CLEAR",
+ "CMOS.PUNCTUATION.OVERVIEW.CONTEXT.REGISTER",
+ "CMOS.TABLES.CAPTIONS.PRESENT",
+ "HOUSE.CODE.DIFFS.CONTEXT_LINES.PRESENT",
+ "HOUSE.CODE.EXAMPLES.FILE_PATH.LABEL",
+ "HOUSE.EDITORIAL.CLAIMS.BASELINE_FOR_COMPARISONS"
+ ],
+ "continuation": [
+ "HOUSE.CODE.BLOCKS.LINE_BREAKS.SEMANTIC_SAFE"
+ ],
+ "continued tables": [
+ "CMOS.TABLES.SPLITS.REPEAT_HEADERS"
],
"continuous text": [
"BRING.LAYOUT.PARAGRAPH.INDENT_AFTER_FIRST"
],
+ "contractions": [
+ "CMOS.PUNCTUATION.APOSTROPHE.USE_CASES"
+ ],
"contrast": [
"BRING.HEADINGS.CONTRAST.CLEAR_HIERARCHY",
- "BRING.HEADINGS.SUBHEADS.MIXING.HIERARCHY_PLACEMENT"
+ "BRING.HEADINGS.SUBHEADS.MIXING.HIERARCHY_PLACEMENT",
+ "BRING.TYPOGRAPHY.CONTRAST.AVOID_EXTREME_MIX",
+ "BRING.TYPOGRAPHY.CONTRAST.FONT_PAIRING_MATCH",
+ "BRING.TYPOGRAPHY.SERIF.SANS_FOR_DISPLAY",
+ "BRING.TYPOGRAPHY.TYPEFACE.CONTRAST_INTENTIONAL",
+ "BRING.TYPOGRAPHY.TYPEFACE.SIMILAR_FACES_AVOID",
+ "BRING.TYPOGRAPHY.WEIGHT.HIERARCHY_CLEAR",
+ "CMOS.FIGURES.CONTRAST.SUFFICIENT",
+ "HOUSE.ACCESSIBILITY.CONTRAST.NON_TEXT",
+ "HOUSE.ACCESSIBILITY.CONTRAST.TEXT_READABLE",
+ "HOUSE.FIGURES.COLOR.CONTRAST_SAFE"
],
"conventional use": [
"CMOS.NUMBERS.ROMAN_NUMERALS.USE"
],
+ "coordinate": [
+ "CMOS.PUNCTUATION.COMMAS.COORDINATE_ADJECTIVES"
+ ],
"coordinate adjectives": [
"CMOS.PUNCTUATION.COMMAS.REPEATED_ADJECTIVES"
],
+ "coordinating conjunction": [
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES"
+ ],
+ "coordination": [
+ "CMOS.PUNCTUATION.COMMAS.IMPERATIVE_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.SHORT"
+ ],
"copy paste": [
+ "HOUSE.CODE.BLOCKS.COMMANDS.PROMPT_FREE_COPY",
+ "HOUSE.CODE.BLOCKS.NO_SMART_QUOTES",
"HOUSE.LINKS.WRAP.SAFE_BREAKS"
],
+ "copyedit": [
+ "HOUSE.EDITORIAL.REVIEW.SPELLCHECK_AND_READTHROUGH"
+ ],
+ "copyfitting": [
+ "HOUSE.LAYOUT.PAGINATION.RUNT_FINAL_PAGE"
+ ],
+ "copyright": [
+ "CMOS.CITATIONS.S13_1.PURPOSE.COPYRIGHT",
+ "CMOS.FRONTMATTER.COPYRIGHT.NOTICES.PRESENT",
+ "CMOS.FRONTMATTER.COPYRIGHT.RIGHTS.CONTACT"
+ ],
+ "corporate author": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.CORPORATE_AUTHORS.SHORT_FORM",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.CORPORATE_AUTHORS.USE_AS_AUTHOR"
+ ],
+ "corrections": [
+ "CMOS.BACKMATTER.ERRATA.WHEN_NEEDED"
+ ],
+ "correlative conjunctions": [
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE.INDEPENDENT_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE.PREDICATE",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE_PHRASES"
+ ],
+ "countries": [
+ "CMOS.ABBREVIATIONS.COUNTRIES.ABBREV_IN_TABLES_ONLY"
+ ],
+ "country code": [
+ "CMOS.NUMBERS.TELEPHONE.COUNTRY_CODE.WHEN_INTERNATIONAL"
+ ],
+ "courtesy titles": [
+ "CMOS.ABBREVIATIONS.TITLES.COURTESY_PERIODS"
+ ],
+ "cramped margins": [
+ "BRING.LAYOUT.MARGINS.AVOID_CROWDING"
+ ],
+ "credentials": [
+ "HOUSE.LINKS.AUTO.EMBEDDED_CREDENTIALS.AVOID",
+ "HOUSE.LINKS.URLS.NO_EMBEDDED_CREDENTIALS"
+ ],
+ "credits": [
+ "CMOS.CITATIONS.S13_102.BIBLIOGRAPHY.AUDIOVISUAL.CREDITS",
+ "CMOS.FIGURES.CAPTION.CREDITS.INLINE_OR_NOTE",
+ "CMOS.FIGURES.CREDIT.SOURCE_WHEN_REQUIRED"
+ ],
+ "cropping": [
+ "CMOS.FIGURES.CROP.AVOID_LOSS"
+ ],
+ "cross reference": [
+ "CMOS.FIGURES.REFERENCES.IN_TEXT",
+ "CMOS.TABLES.REFERENCES.IN_TEXT"
+ ],
+ "cross references": [
+ "CMOS.BACKMATTER.INDEX.CROSS_REFERENCES.CONSISTENT"
+ ],
"cross-reference": [
+ "CMOS.BACKMATTER.APPENDICES.CROSS_REFERENCES",
"CMOS.CITATIONS.BIBLIOGRAPHY.ALT_NAMES.CROSSREF",
- "CMOS.CITATIONS.NOTES.SHORT_FORM.CROSS_REFERENCE"
+ "CMOS.CITATIONS.NOTES.SHORT_FORM.CROSS_REFERENCE",
+ "CMOS.LAYOUT.TABLES.PLACEMENT_NEAR_REF"
+ ],
+ "cross-references": [
+ "HOUSE.EDITORIAL.REVIEW.CROSS_REFERENCES.VERIFY"
],
"crossheads": [
"BRING.HEADINGS.SUBHEADS.CROSSHEADS_SIDEHEADS.CHOOSE_DELIBERATELY"
],
+ "cse": [
+ "CMOS.CITATIONS.S13_3.OTHER_SYSTEMS.AMA_CSE"
+ ],
+ "css": [
+ "HOUSE.TYPOGRAPHY.HTML.LINK_DECORATION.CONSISTENT"
+ ],
"currency": [
+ "CMOS.I18N.CURRENCY.CODES.LABEL",
"CMOS.NUMBERS.CURRENCY.FORMAT.SYMBOL_PLACEMENT",
- "CMOS.NUMBERS.CURRENCY.ISO_CODES"
+ "CMOS.NUMBERS.CURRENCY.ISO_CODES",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.DISAMBIGUATE",
+ "HOUSE.I18N.CURRENCY.DISAMBIGUATE"
],
"currency code": [
"CMOS.NUMBERS.CURRENCY.NON_US.DISAMBIGUATE"
],
+ "currency codes": [
+ "CMOS.NUMBERS.CURRENCY.CODE_POSITION.CONSISTENT",
+ "CMOS.NUMBERS.S9_25.CURRENCY_CODES.CONSISTENT",
+ "CMOS.NUMBERS.S9_25.CURRENCY_CODES.SPACING",
+ "CMOS.NUMBERS.S9_27.CURRENCY_YEAR.CODES_SPACING"
+ ],
+ "currency ranges": [
+ "CMOS.NUMBERS.CURRENCY.RANGES.REPEAT_SYMBOL"
+ ],
"currency symbols": [
- "CMOS.NUMBERS.CURRENCY.WORDS_VS_SYMBOLS"
+ "CMOS.NUMBERS.CURRENCY.SYMBOL_ADJACENT",
+ "CMOS.NUMBERS.CURRENCY.WORDS_VS_SYMBOLS",
+ "CMOS.NUMBERS.S9_22.MONEY.NUMERALS_EXACT"
+ ],
+ "currency year": [
+ "CMOS.NUMBERS.S9_27.CURRENCY_YEAR.PARENS_NO_SPACE"
+ ],
+ "dash": [
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.BEFORE_DASH"
],
"dash spacing": [
"CMOS.PUNCTUATION.DASHES.EM_DASH.USE_WITHOUT_SPACES_US"
],
+ "dashes": [
+ "CMOS.I18N.PUNCTUATION.DASHES.MINUS_SIGN"
+ ],
+ "data": [
+ "CMOS.FIGURES.CALL_OUTS.AVOID_OVERLAP"
+ ],
+ "data availability": [
+ "CMOS.BACKMATTER.DATA.AVAILABILITY"
+ ],
+ "data source": [
+ "CMOS.FIGURES.SOURCE.DATA.CITED"
+ ],
"data types": [
- "BRING.TABLES.DATA_TYPES.NOT_MIXED"
+ "BRING.TABLES.DATA_TYPES.NOT_MIXED",
+ "CMOS.TABLES.DATA_TYPES.NOT_MIXED"
+ ],
+ "database": [
+ "CMOS.CITATIONS.S13_10.DATABASES.NAME_INSTEAD",
+ "CMOS.CITATIONS.S13_10.DOI_PRECEDENCE"
+ ],
+ "database name": [
+ "CMOS.CITATIONS.S13_10.DATABASE_IN_CITATION",
+ "CMOS.CITATIONS.S13_9.DATABASE_NAME_OK"
+ ],
+ "dataset": [
+ "CMOS.CITATIONS.S13_106.BIBLIOGRAPHY.DATASETS.VERSION_AND_PROVENANCE"
+ ],
+ "date": [
+ "CMOS.CITATIONS.S13_97.BIBLIOGRAPHY.NEWSPAPER_MAGAZINE.DATES",
+ "CMOS.FRONTMATTER.FOREWORD.DATE_IF_PRESENT",
+ "CMOS.FRONTMATTER.PREFACE.DATE_IF_PRESENT",
+ "HOUSE.EDITORIAL.STRUCTURE.METADATA.OWNER_DATE"
],
"date format": [
"CMOS.NUMBERS.DATES.CONSISTENT_FORMAT",
@@ -412,7 +1582,8 @@
"CMOS.NUMBERS.DATES.MONTH_DAY_STYLE"
],
"date order": [
- "CMOS.NUMBERS.DATES.ALL_NUMERAL"
+ "CMOS.NUMBERS.DATES.ALL_NUMERAL",
+ "CMOS.NUMBERS.DATES.DAY_MONTH_ORDER.CONSISTENT"
],
"date range": [
"CMOS.PUNCTUATION.DASHES.EN_DASH.RANGES"
@@ -422,42 +1593,179 @@
],
"dates": [
"CMOS.HEADINGS.DIVISIONS.LETTERS_DIARIES.HEADINGS",
+ "CMOS.I18N.DATES.FORMAT.CONSISTENT",
"CMOS.NUMBERS.DATES.ABBREVIATED_YEAR",
"CMOS.NUMBERS.DATES.YEAR_NUMERALS",
- "CMOS.PUNCTUATION.COMMAS.DATES"
+ "CMOS.NUMBERS.S9_8.DATES.NUMERALS",
+ "CMOS.PUNCTUATION.COMMAS.DATES",
+ "CMOS.PUNCTUATION.COMMAS.DATES.ALTERNATE_SYSTEMS",
+ "CMOS.PUNCTUATION.COMMAS.DATES.MONTH_DAY_YEAR",
+ "CMOS.PUNCTUATION.COMMAS.DATES.NO_COMMA_OTHER_STYLES",
+ "HOUSE.EDITORIAL.CONSISTENCY.DATE_FORMAT.SINGLE",
+ "HOUSE.EDITORIAL.REVIEW.FACT_CHECK"
+ ],
+ "day references": [
+ "CMOS.NUMBERS.S9_33.DAY_WITHOUT_MONTH.ORDINAL"
+ ],
+ "day-month-year": [
+ "CMOS.PUNCTUATION.COMMAS.DATES.ALTERNATE_SYSTEMS",
+ "CMOS.PUNCTUATION.COMMAS.DATES.NO_COMMA_OTHER_STYLES"
+ ],
+ "days": [
+ "CMOS.ABBREVIATIONS.DAYS.SPELL_OUT_IN_TEXT"
+ ],
+ "days of week": [
+ "CMOS.ABBREVIATIONS.DAYS.ABBREV_IN_TABLES"
+ ],
+ "deadlines": [
+ "HOUSE.EDITORIAL.STRUCTURE.ACTION_ITEMS.EXPLICIT"
],
"decade plural": [
"CMOS.NUMBERS.PLURALS.DECADE.NO_APOSTROPHE"
],
"decades": [
- "CMOS.NUMBERS.DECADES.CONSISTENT_FORM"
+ "CMOS.NUMBERS.DECADES.CONSISTENT_FORM",
+ "CMOS.NUMBERS.S9_35.DECADES.NO_APOSTROPHE"
],
"decimal": [
"CMOS.NUMBERS.DECIMALS.LEADING_ZERO",
"CMOS.NUMBERS.DECIMALS.NUMERALS",
- "CMOS.NUMBERS.NUMERALS.MEASUREMENTS.UNITS"
+ "CMOS.NUMBERS.NUMERALS.MEASUREMENTS.UNITS",
+ "CMOS.NUMBERS.S9_12.DECIMAL_PREFIXES",
+ "CMOS.TABLES.ALIGNMENT.NUMERIC_DECIMAL"
],
"decimal alignment": [
"HOUSE.TABLES.ALIGNMENT.DECIMALS"
],
+ "decimal currency": [
+ "CMOS.NUMBERS.S9_24.BRITISH.DECIMAL_FORMAT",
+ "CMOS.NUMBERS.S9_25.OTHER_CURRENCIES.DECIMAL"
+ ],
"decimal marker": [
"CMOS.NUMBERS.DECIMAL_MARKER.LOCALE"
],
+ "decimal separator": [
+ "CMOS.I18N.NUMBERS.DECIMAL_SEPARATOR.LOCALE",
+ "HOUSE.I18N.NUMBERS.MIXED_DECIMAL_SEPARATORS"
+ ],
"decimals": [
- "CMOS.NUMBERS.CONTEXTS.ALWAYS_NUMERALS"
+ "CMOS.NUMBERS.CONTEXTS.ALWAYS_NUMERALS",
+ "CMOS.NUMBERS.S9_15.DECIMAL_FRACTIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_21.DECIMALS.NUMERALS",
+ "CMOS.NUMBERS.S9_22.MONEY.DECIMALS.ONLY_WHEN_MIXED",
+ "HOUSE.TABLES.NUMERIC.ALIGN_DECIMALS",
+ "HOUSE.TABLES.NUMERIC.PRECISION.CONSISTENT"
+ ],
+ "decisions": [
+ "HOUSE.EDITORIAL.STRUCTURE.DECISIONS.EXPLICIT",
+ "HOUSE.EDITORIAL.STRUCTURE.SUMMARY.EARLY"
+ ],
+ "decorative": [
+ "HOUSE.ACCESSIBILITY.HEADINGS.NO_EMPTY",
+ "HOUSE.ACCESSIBILITY.IMAGES.DECORATIVE.EMPTY_ALT"
+ ],
+ "dedupe": [
+ "HOUSE.BACKMATTER.REFERENCES.DEDUPLICATE"
+ ],
+ "default system": [
+ "CMOS.CITATIONS.S13_2.DEFAULT_SYSTEM"
+ ],
+ "defaults": [
+ "HOUSE.CODE.EXAMPLES.ENV_VARS.DOCUMENT"
+ ],
+ "define on first use": [
+ "CMOS.ABBREVIATIONS.ACRONYMS.DEFINE_FIRST_USE"
+ ],
+ "defined terms": [
+ "HOUSE.EDITORIAL.CONSISTENCY.CAPITALIZATION.STABLE"
+ ],
+ "definitions": [
+ "BRING.TYPOGRAPHY.ITALICS.TERMS_INTRODUCED_SPARE",
+ "CMOS.ABBREVIATIONS.CAPTIONS.DEFINE_ON_FIRST_USE",
+ "CMOS.BACKMATTER.GLOSSARY.DEFINITIONS.CONCISE",
+ "CMOS.BACKMATTER.GLOSSARY.WHEN_TERMS",
+ "CMOS.FRONTMATTER.TERMS.DEFINITIONS.EARLY",
+ "HOUSE.EDITORIAL.CLARITY.DEFINE_JARGON_ON_FIRST_USE",
+ "HOUSE.EDITORIAL.CONSISTENCY.TERMINOLOGY.STABLE",
+ "HOUSE.EDITORIAL.STRUCTURE.GLOSSARY.WHEN_DENSE"
+ ],
+ "degree": [
+ "CMOS.NUMBERS.S9_18.NO_SPACE.DEGREE_PERCENT_PRIME"
+ ],
+ "degrees": [
+ "CMOS.ABBREVIATIONS.ACADEMIC.DEGREES.STYLE"
],
"dense data": [
"CMOS.NUMBERS.DENSE_CONTEXT.USE_NUMERALS"
],
"dependent clause": [
- "CMOS.PUNCTUATION.COMMAS.DEPENDENT_CLAUSE_AFTER"
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_CLAUSE_AFTER",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING.RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING_NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING_RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_INTRO",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_INTRODUCTORY"
+ ],
+ "dependent clauses": [
+ "CMOS.PUNCTUATION.COMMAS.CONSECUTIVE_CONJUNCTIONS.NO_COMMA"
+ ],
+ "deprecated": [
+ "CMOS.CITATIONS.S13_7.DOI.NO_PREFIX"
+ ],
+ "depth": [
+ "BRING.LAYOUT.PARAGRAPH.INDENT.NOT_TOO_DEEP"
],
"descriptive phrases": [
- "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASES"
+ "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASE",
+ "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASES",
+ "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASES.NONRESTRICTIVE"
+ ],
+ "design": [
+ "CMOS.PUNCTUATION.SPACING.DESIGN_SPECIFIED"
],
"designations": [
"CMOS.NUMBERS.VEHICLES.VESSELS_NUMBERS"
],
+ "destructive commands": [
+ "HOUSE.CODE.SHELL.DESTRUCTIVE.WARN"
+ ],
+ "deterministic": [
+ "HOUSE.CODE.BLOCKS.DETERMINISTIC_OUTPUT"
+ ],
+ "dev": [
+ "HOUSE.LINKS.AUTO.STAGING_HOSTNAMES.AVOID",
+ "HOUSE.LINKS.URLS.AVOID.STAGING_DOMAINS"
+ ],
+ "deviations": [
+ "CMOS.CITATIONS.S13_4.DOCUMENTED_DEVIATIONS"
+ ],
+ "device": [
+ "CMOS.CITATIONS.S13_14.DEVICE_SPECIFIC"
+ ],
+ "dex": [
+ "CMOS.NUMBERS.S9_13.DEX.DEFINITION"
+ ],
+ "diacritics": [
+ "BRING.TYPOGRAPHY.TYPEFACE.GLYPH_COVERAGE_REQUIRED",
+ "CMOS.CITATIONS.S13_72.BIBLIOGRAPHY.SORTING.DIACRITICS_AND_TRANSLITERATION",
+ "CMOS.I18N.DIACRITICS.PRESERVE",
+ "CMOS.I18N.ROMANIZATION.DIACRITICS.KEEP"
+ ],
+ "diagrams": [
+ "HOUSE.FIGURES.FORMAT.VECTOR_FOR_LINE_ART"
+ ],
+ "dialogue": [
+ "CMOS.PUNCTUATION.COLONS.QUOTATIONS",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.DIALOGUE_STYLE",
+ "CMOS.PUNCTUATION.SEMICOLONS.AVOID_DIALOGUE"
+ ],
+ "dialogue verb": [
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.DIALOGUE"
+ ],
+ "dialogue verbs": [
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.DIALOGUE_VERB_COMMA"
+ ],
"diaries": [
"CMOS.HEADINGS.DIVISIONS.LETTERS_DIARIES.HEADINGS",
"CMOS.HEADINGS.LETTERS_DIARIES.DATELINE_FORMAT",
@@ -469,125 +1777,619 @@
"dictionary usage": [
"CMOS.PUNCTUATION.HYPHENATION.TREND_CLOSED"
],
+ "diff": [
+ "HOUSE.CODE.DIFFS.UNIFIED_FORMAT"
+ ],
+ "diffs": [
+ "HOUSE.CODE.DIFFS.CONTEXT_LINES.PRESENT",
+ "HOUSE.CODE.DIFFS.FILE_HEADERS.PRESENT"
+ ],
"digit grouping": [
- "CMOS.NUMBERS.BASES.NON_DECIMAL.NO_GROUPING"
+ "CMOS.NUMBERS.BASES.NON_DECIMAL.NO_GROUPING",
+ "CMOS.NUMBERS.S9_26.MONEY.COMMAS"
+ ],
+ "digit systems": [
+ "HOUSE.I18N.NUMBERS.DIGIT_SYSTEM.CONSISTENT"
],
"digits": [
"BRING.TYPOGRAPHY.TRACKING.CAPS_SMALLCAPS_AND_LONG_DIGITS"
],
+ "direct address": [
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS"
+ ],
+ "direct question": [
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_QUESTIONS"
+ ],
"direct questions": [
- "CMOS.PUNCTUATION.QUESTION_MARK.USE"
+ "CMOS.PUNCTUATION.COMMAS.QUESTIONS.DIRECT_IN_SENTENCE",
+ "CMOS.PUNCTUATION.QUESTION_MARK.USE",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.DIRECT",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.DIRECT_INDIRECT"
],
"direct quote": [
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.DIRECT_QUOTES"
],
"disambiguation": [
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.EXTRA_INFO",
- "CMOS.CITATIONS.BIBLIOGRAPHY.SAME_SURNAME.DISAMBIGUATE"
+ "CMOS.CITATIONS.AUTHOR_DATE.SAME_AUTHOR_SAME_YEAR.SUFFIXES",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.SAME_SURNAME.DISAMBIGUATE",
+ "CMOS.CITATIONS.S13_36.SHORT_FORM.DISAMBIGUATE_AUTHOR"
+ ],
+ "discipline": [
+ "CMOS.CITATIONS.S13_1.DISCIPLINE_POLICY",
+ "CMOS.CITATIONS.S13_2.DISCIPLINE_PREFERENCE"
+ ],
+ "disclaimer": [
+ "CMOS.FRONTMATTER.DISCLAIMERS.WHEN_REQUIRED"
+ ],
+ "discretionary": [
+ "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_IN_DISPLAY"
+ ],
+ "discretionary ligatures": [
+ "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_SPARING"
],
"discursive notes": [
- "CMOS.CITATIONS.NOTES.AVOID_OVERLONG"
+ "CMOS.CITATIONS.NOTES.AVOID_OVERLONG",
+ "CMOS.CITATIONS.S13_57.NOTES.SEPARATE_SOURCE_VS_COMMENTARY"
+ ],
+ "display": [
+ "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_IN_DISPLAY",
+ "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_SPARING",
+ "BRING.TYPOGRAPHY.NUMERALS.LINING_FOR_CAPS_AND_DISPLAY",
+ "BRING.TYPOGRAPHY.TYPEFACE.MIXING_BY_ROLE_ONLY"
+ ],
+ "display face": [
+ "BRING.TYPOGRAPHY.TYPEFACE.DISPLAY_FACES_FOR_DISPLAY"
+ ],
+ "display lines": [
+ "CMOS.PUNCTUATION.PERIODS.OMIT_DISPLAY_LINES"
+ ],
+ "display size": [
+ "BRING.TYPOGRAPHY.SIZE.DISPLAY_SIZE_BALANCE"
+ ],
+ "displayed equations": [
+ "CMOS.NUMBERS.S9_17.DISPLAYED_FRACTIONS.BAR"
+ ],
+ "dissertation": [
+ "CMOS.CITATIONS.S13_98.BIBLIOGRAPHY.THESES_DISSERTATIONS.INSTITUTION"
+ ],
+ "distance": [
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.GENERAL_RULE"
],
"distort": [
"BRING.TYPOGRAPHY.LETTERFORMS.AVOID_DISTORTION"
],
+ "distribution": [
+ "HOUSE.FRONTMATTER.METADATA.CONFIDENTIALITY"
+ ],
"divisions": [
"CMOS.HEADINGS.DIVISIONS.CHAPTERS.MULTIAUTHOR"
],
+ "docs": [
+ "HOUSE.CODE.ERRORS.SHOW_FAILURES",
+ "HOUSE.CODE.TYPED_VALUES.DISTINGUISH"
+ ],
+ "document title": [
+ "HOUSE.ACCESSIBILITY.HEADINGS.SINGLE_H1"
+ ],
"doi": [
- "CMOS.CITATIONS.DOI.PREFERRED_OVER_URL"
+ "CMOS.BACKMATTER.REFERENCES.DOI.OR_URL",
+ "CMOS.BACKMATTER.REFERENCES.URLS.STABLE",
+ "CMOS.CITATIONS.DOI.PREFERRED_OVER_URL",
+ "CMOS.CITATIONS.S13_10.DOI_PRECEDENCE",
+ "CMOS.CITATIONS.S13_26.JOURNAL.ONLINE.URL_OR_DOI",
+ "CMOS.CITATIONS.S13_7.DOI.NO_PREFIX",
+ "CMOS.CITATIONS.S13_7.DOI.URL_FORM",
+ "CMOS.CITATIONS.S13_8.PREFERRED_ORDER",
+ "CMOS.CITATIONS.S13_96.BIBLIOGRAPHY.JOURNAL_ARTICLES.VOLUME_ISSUE_PAGES",
+ "HOUSE.LINKS.URLS.DOIS.PREFER_DOI_ORG"
],
"doi.org": [
- "CMOS.CITATIONS.DOI.PREFERRED_OVER_URL"
+ "CMOS.CITATIONS.DOI.PREFERRED_OVER_URL",
+ "HOUSE.LINKS.URLS.DOIS.PREFER_DOI_ORG"
],
"dollar": [
"CMOS.NUMBERS.CURRENCY.FORMAT.SYMBOL_PLACEMENT"
],
+ "dollar sign": [
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.CONTEXT_CLEAR",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.DISAMBIGUATE"
+ ],
+ "domains": [
+ "HOUSE.LINKS.URLS.AVOID.IP_LITERALS"
+ ],
"dot leaders": [
"BRING.TYPOGRAPHY.ALIGNMENT.DONT_STRETCH_SPACE"
],
"double hyphen": [
"CMOS.PUNCTUATION.DASHES.EM_DASH.USE_WITHOUT_SPACES_US"
],
+ "double negatives": [
+ "HOUSE.EDITORIAL.CLARITY.AVOID_DOUBLE_NEGATIVES"
+ ],
+ "double prime": [
+ "CMOS.NUMBERS.S9_18.PRIME_SYMBOLS"
+ ],
"double quotes": [
"CMOS.PUNCTUATION.QUOTATION_MARKS.DOUBLE_PRIMARY_US"
],
"double space": [
"BRING.TYPOGRAPHY.SPACING.SENTENCE_SPACE.SINGLE"
],
+ "downloads": [
+ "HOUSE.LINKS.AUTO.FILETYPE_LABEL.REQUIRED",
+ "HOUSE.LINKS.AUTO.HTML_FALLBACK.REQUIRED",
+ "HOUSE.LINKS.TEXT.ARCHIVE_AND_HTML.BOTH",
+ "HOUSE.LINKS.TEXT.FILESIZE.LABEL",
+ "HOUSE.LINKS.TEXT.FILETYPE.LABEL"
+ ],
+ "draft": [
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_REVIEW_NOTES_INLINE",
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_TODO_FIXME",
+ "HOUSE.FRONTMATTER.METADATA.DOC_STATUS"
+ ],
+ "drop caps": [
+ "BRING.LAYOUT.PARAGRAPH.DROP_CAPS.ALIGN_BASELINE"
+ ],
+ "dual marks": [
+ "CMOS.PUNCTUATION.QUESTION_EXCLAMATION.DUAL_MARKS"
+ ],
+ "dual notes": [
+ "CMOS.CITATIONS.S13_56.NOTES.DUAL_STREAMS.DISTINCT_LABELS"
+ ],
+ "duplicate headings": [
+ "HOUSE.EDITORIAL.HEADINGS.NO_DUPLICATE"
+ ],
+ "durability": [
+ "HOUSE.EDITORIAL.REVIEW.LINKS.VERIFY",
+ "HOUSE.LINKS.URLS.NO_SESSION_PARAMS",
+ "HOUSE.LINKS.URLS.SHORTENERS.AVOID"
+ ],
+ "e-book": [
+ "CMOS.CITATIONS.S13_101.BIBLIOGRAPHY.EBOOKS.EDITION_AND_FORMAT"
+ ],
+ "e.g.": [
+ "CMOS.ABBREVIATIONS.LATIN.EG_IE.PUNCTUATION",
+ "CMOS.PUNCTUATION.COMMAS.IE_EG.PARENS"
+ ],
"edited book": [
- "CMOS.CITATIONS.NOTES.CHAPTER_IN_EDITED_BOOK"
+ "CMOS.CITATIONS.NOTES.CHAPTER_IN_EDITED_BOOK",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.INCLUDE_EDITOR"
+ ],
+ "edited by": [
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.BIBLIO",
+ "CMOS.CITATIONS.S13_24.AUTHOR_PLUS_EDITOR.BIBLIO_SPELL_OUT"
+ ],
+ "edited collection": [
+ "CMOS.CITATIONS.S13_95.BIBLIOGRAPHY.CHAPTERS.IN_EDITED_COLLECTIONS"
+ ],
+ "editing": [
+ "HOUSE.EDITORIAL.CLARITY.EDIT_FOR_BREVITY"
+ ],
+ "edition": [
+ "CMOS.CITATIONS.S13_101.BIBLIOGRAPHY.EBOOKS.EDITION_AND_FORMAT",
+ "CMOS.CITATIONS.S13_59.NOTES.MULTI_EDITIONS.CITE_VERSION_USED",
+ "CMOS.FRONTMATTER.EDITION.VERSION_VISIBLE",
+ "HOUSE.FRONTMATTER.METADATA.VERSION"
+ ],
+ "editor": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.CONTRIBUTOR_ROLES.LABEL_CLEARLY",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.NO_AUTHOR.EDITOR_AS_LEAD_WHEN_APPROPRIATE",
+ "CMOS.CITATIONS.S13_22.BOOK_EDITOR_ONLY",
+ "CMOS.CITATIONS.S13_22.BOOK_EDITOR_ONLY.SHORTENED_NO_ED",
+ "CMOS.CITATIONS.S13_24.AUTHOR_PLUS_EDITOR.NOTES_ABBREVIATE",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.INCLUDE_EDITOR"
],
"editorial": [
"BRING.TABLES.EDIT_AS_TEXT.READABILITY"
],
+ "editorial brackets": [
+ "CMOS.PUNCTUATION.COMMAS.BRACKETS.EDITORIAL"
+ ],
+ "editorial insert": [
+ "CMOS.PUNCTUATION.COMMAS.BRACKETS.EDITORIAL_INSERT"
+ ],
"editorial insertions": [
+ "CMOS.PUNCTUATION.BRACKETS.EDITORIAL_INSERTIONS",
"CMOS.PUNCTUATION.BRACKETS.TRANSLATED_TEXT"
],
+ "editors": [
+ "CMOS.CITATIONS.S13_93.BIBLIOGRAPHY.EDITED_VOLUMES.ROLE_MARKING"
+ ],
+ "eds.": [
+ "CMOS.CITATIONS.S13_22.BOOK_EDITOR_ONLY"
+ ],
+ "either": [
+ "CMOS.PUNCTUATION.COMMAS.TOO_EITHER.OMIT"
+ ],
+ "electronic formats": [
+ "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.ELECTRONIC_PREFERS_LOGICAL"
+ ],
+ "electronic sources": [
+ "CMOS.CITATIONS.S13_20.LOCATORS.ALTERNATIVES"
+ ],
"element relationships": [
"BRING.LAYOUT.ELEMENT_RELATIONSHIPS.VISIBLE"
],
+ "elision": [
+ "CMOS.PUNCTUATION.COMMAS.ELISION",
+ "HOUSE.CODE.BLOCKS.ELISION.MARKED"
+ ],
"ellipsis": [
- "CMOS.PUNCTUATION.ELLIPSIS.FORMAT.CONSISTENT"
+ "CMOS.CITATIONS.S13_99.LONG_TITLES.TRUNCATION.AVOID",
+ "CMOS.I18N.PUNCTUATION.ELLIPSIS.STYLE",
+ "CMOS.PUNCTUATION.ELLIPSIS.FORMAT.CONSISTENT",
+ "CMOS.PUNCTUATION.ELLIPSIS.USE_CASES"
+ ],
+ "ellipsis comma": [
+ "CMOS.PUNCTUATION.COMMAS.ELISION"
],
"em dash": [
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_HEAVY",
+ "CMOS.PUNCTUATION.DASHES.DISTINCT_TYPES",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.ALTERNATIVE_TO_PARENS",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.AVOID_NESTED",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.DIALOGUE_STYLE",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.LINE_BREAKS_DETAIL",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.LISTS_TABLES",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.PUNCTUATION_BEFORE",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.SPARE_USE",
"CMOS.PUNCTUATION.DASHES.EM_DASH.USE_WITHOUT_SPACES_US",
"CMOS.PUNCTUATION.DASHES.EM_INSTEAD_OF_QUOTES",
"CMOS.PUNCTUATION.DASHES.EM_LINE_BREAKS"
],
+ "email": [
+ "CMOS.PUNCTUATION.URLS.PUNCTUATE_NORMALLY",
+ "CMOS.PUNCTUATION.URLS.TRAILING_PUNCTUATION",
+ "HOUSE.LINKS.EMAILS.MAILTO_POLICY"
+ ],
+ "emails": [
+ "CMOS.LINKS.PUNCTUATE_NORMALLY"
+ ],
"embedded questions": [
"CMOS.PUNCTUATION.COMMAS.QUESTIONS"
],
+ "embedded text": [
+ "CMOS.FIGURES.EMBEDDED_TEXT.MINIMAL"
+ ],
+ "embolden": [
+ "BRING.TYPOGRAPHY.FAMILY.AVOID_FAUX_BOLD"
+ ],
+ "emoji": [
+ "HOUSE.LINKS.TEXT.NO_EMOJIS"
+ ],
+ "emojis": [
+ "CMOS.PUNCTUATION.EMOJIS.PUNCTUATION"
+ ],
+ "emphasis": [
+ "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ALL_CAPS",
+ "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ITALICS_LONG",
+ "BRING.TYPOGRAPHY.BOLD.SPARING_USE",
+ "BRING.TYPOGRAPHY.CAPS.AVOID_FOR_EMPHASIS",
+ "BRING.TYPOGRAPHY.FAMILY.BOLD_FOR_STRONG_EMPHASIS",
+ "BRING.TYPOGRAPHY.FAMILY.ITALIC_FOR_SUBTLE_EMPHASIS",
+ "BRING.TYPOGRAPHY.ITALICS.EMPHASIS_NOT_UNDERLINE",
+ "BRING.TYPOGRAPHY.ITALICS.SPARING",
+ "BRING.TYPOGRAPHY.ITALICS.TERMS_INTRODUCED_SPARE",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.EMPHASIS_EXCEPTION",
+ "CMOS.PUNCTUATION.COLONS.EMPHASIS_SECOND_CLAUSE",
+ "CMOS.PUNCTUATION.EXCLAMATION.USE_SPARING",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.LONG_OR_MULTI",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_USE_ONLY_FOR_EMPHASIS",
+ "CMOS.TABLES.SHADING.SPARING",
+ "HOUSE.ACCESSIBILITY.EMPHASIS.USE_SPARELY",
+ "HOUSE.EDITORIAL.TONE.AVOID_EXCESSIVE_EMPHASIS",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ALL_CAPS.AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ITALIC_LONG.AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_LONG.AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.ITALIC_LONG.AVOID"
+ ],
+ "empty headings": [
+ "HOUSE.ACCESSIBILITY.HEADINGS.NO_EMPTY"
+ ],
+ "empty items": [
+ "HOUSE.ACCESSIBILITY.LISTS.NO_EMPTY_ITEMS"
+ ],
+ "empty sections": [
+ "HOUSE.LAYOUT.MD.HEADINGS.NON_EMPTY_SECTIONS"
+ ],
"en dash": [
+ "CMOS.CITATIONS.S13_20.PAGE_RANGE.EN_DASH",
"CMOS.NUMBERS.RANGES.EN_DASH.USE",
- "CMOS.PUNCTUATION.DASHES.EN_DASH.RANGES"
+ "CMOS.PUNCTUATION.DASHES.DISTINCT_TYPES",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.AVOID_FROM_BETWEEN",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.LINE_BREAKS",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.MINUS_SIGN",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.RANGES",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.SPACED_BRITISH",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.WORD_RANGES"
+ ],
+ "end of sentence": [
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.PLACEMENT_END_SENTENCE"
+ ],
+ "end punctuation": [
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.END_PUNCT_SENTENCES"
],
"endnote placement": [
"CMOS.CITATIONS.NOTES.ENDNOTES.PLACEMENT"
],
"endnotes": [
+ "CMOS.ABBREVIATIONS.FOOTNOTES.ABBREV_ON_FIRST_USE",
+ "CMOS.BACKMATTER.ENDNOTES.VERSUS_FOOTNOTES.CONSISTENT",
"CMOS.CITATIONS.NOTES.ENDNOTES.AVOID_IBID",
"CMOS.CITATIONS.NOTES.ENDNOTES.RUNNING_HEADS",
- "CMOS.CITATIONS.NOTES.FOOTNOTES_VS_ENDNOTES.CHOOSE"
+ "CMOS.CITATIONS.NOTES.FOOTNOTES_VS_ENDNOTES.CHOOSE",
+ "CMOS.CITATIONS.S13_2.NOTES_SYSTEM",
+ "CMOS.CITATIONS.S13_47.NOTES.SYSTEMS.DONT_MIX",
+ "CMOS.CITATIONS.S13_48.ENDNOTES.GROUP_BY_CHAPTER",
+ "CMOS.CITATIONS.S13_52.ENDNOTES.NAVIGATION_CUES"
+ ],
+ "entry template": [
+ "CMOS.CITATIONS.S13_63.BIBLIOGRAPHY.CONSISTENT_ELEMENT_ORDER"
+ ],
+ "entry types": [
+ "CMOS.CITATIONS.S13_68.BIBLIOGRAPHY.ENTRY_TYPES.NOT_MIXED"
+ ],
+ "environment": [
+ "HOUSE.CODE.BLOCKS.PRECONDITIONS.STATED"
+ ],
+ "environment variables": [
+ "HOUSE.CODE.EXAMPLES.ENV_VARS.DOCUMENT"
+ ],
+ "epigraph": [
+ "CMOS.FRONTMATTER.EPIGRAPH.ATTRIBUTION",
+ "CMOS.FRONTMATTER.EPIGRAPH.PLACEMENT.CONSISTENT"
+ ],
+ "equations": [
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_IN_EQUATIONS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.FIGURES_TABLES_EQUATIONS"
+ ],
+ "era abbreviations": [
+ "CMOS.NUMBERS.S9_36.ERAS.CENTURY_PLACEMENT"
],
"era designations": [
"CMOS.NUMBERS.ERAS.BCE_CE"
],
+ "errata": [
+ "CMOS.BACKMATTER.ERRATA.WHEN_NEEDED"
+ ],
+ "errors": [
+ "HOUSE.CODE.BLOCKS.ERROR_OUTPUT.LABELED",
+ "HOUSE.CODE.ERRORS.SHOW_FAILURES"
+ ],
"essential clause": [
"CMOS.PUNCTUATION.COMMAS.RESTRICTIVE.NO_SET_OFF"
],
+ "et al": [
+ "CMOS.ABBREVIATIONS.LATIN.ET_AL.USE",
+ "CMOS.PUNCTUATION.COMMAS.ETC_ETAL.STYLE"
+ ],
+ "et al.": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_AUTHORS.POLICY",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_LIST.LENGTH.POLICY",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.BIBLIO_MORE_THAN_SIX",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.NOTES_ET_AL",
+ "CMOS.PUNCTUATION.COMMAS.ETC_SINGLE_ITEM"
+ ],
+ "etc": [
+ "CMOS.PUNCTUATION.COMMAS.ETC.FINAL_ELEMENT",
+ "CMOS.PUNCTUATION.COMMAS.ETC_ETAL.STYLE"
+ ],
+ "etc.": [
+ "CMOS.PUNCTUATION.COMMAS.ETC.FORMAL_LIMIT",
+ "CMOS.PUNCTUATION.COMMAS.ETC.TRAILING",
+ "CMOS.PUNCTUATION.COMMAS.ETC_SINGLE_ITEM"
+ ],
+ "ethics": [
+ "CMOS.CITATIONS.S13_1.PURPOSE.ETHICS"
+ ],
"eur": [
"CMOS.NUMBERS.CURRENCY.FORMAT.SYMBOL_PLACEMENT"
],
+ "even page": [
+ "BRING.LAYOUT.PAGE.ODD_EVEN.CONSISTENT"
+ ],
+ "evidence": [
+ "HOUSE.EDITORIAL.CLAIMS.SUPPORT_WITH_SOURCES",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_WEASEL_WORDS"
+ ],
+ "exact amounts": [
+ "CMOS.NUMBERS.S9_22.MONEY.NUMERALS_EXACT"
+ ],
+ "exact values": [
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.EXACT_VALUES"
+ ],
+ "examples": [
+ "CMOS.CITATIONS.S13_21.EXAMPLES.CHAPTER14",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.EXAMPLES_QUESTIONS_RULES",
+ "HOUSE.CODE.BLOCKS.DETERMINISTIC_OUTPUT",
+ "HOUSE.CODE.BLOCKS.ELISION.MARKED",
+ "HOUSE.CODE.BLOCKS.TESTED_OR_MARKED",
+ "HOUSE.CODE.CAPTIONS.EXPLAIN_SNIPPET",
+ "HOUSE.CODE.OUTPUT.DISTINGUISH_FROM_INPUT",
+ "HOUSE.EDITORIAL.CLARITY.EXAMPLES_WHEN_COMPLEX"
+ ],
"exceptions": [
- "BRING.LAYOUT.RHYTHM.RULES_SERVE_TEXT"
+ "BRING.LAYOUT.RHYTHM.RULES_SERVE_TEXT",
+ "CMOS.NUMBERS.S9_7.DOCUMENT_EXCEPTIONS",
+ "CMOS.NUMBERS.S9_7.SENTENCE_START_EXCEPTION"
+ ],
+ "exclamation": [
+ "HOUSE.EDITORIAL.TONE.AVOID_EXCESSIVE_EMPHASIS"
+ ],
+ "exclamation point": [
+ "CMOS.PUNCTUATION.COMMAS.QUOTE_ENDING_QM_EXCL",
+ "CMOS.PUNCTUATION.EXCLAMATION.QUOTE_PLACEMENT",
+ "CMOS.PUNCTUATION.PERIODS.NOT_WITH_QM_EXCL",
+ "CMOS.PUNCTUATION.QUESTION_EXCLAMATION.DUAL_MARKS"
],
"exclamation points": [
+ "CMOS.PUNCTUATION.EXCLAMATION.RHETORICAL",
+ "CMOS.PUNCTUATION.EXCLAMATION.USE_SPARING",
"CMOS.PUNCTUATION.EXCLAMATION.USE_SPARINGLY",
"CMOS.PUNCTUATION.EXCLAMATION.VS_QUESTION"
],
+ "executive summary": [
+ "CMOS.FRONTMATTER.ABSTRACT.WHEN_APPROPRIATE",
+ "HOUSE.EDITORIAL.STRUCTURE.SUMMARY.EARLY"
+ ],
"expand": [
"BRING.TYPOGRAPHY.LETTERFORMS.AVOID_DISTORTION"
],
+ "expires": [
+ "HOUSE.LINKS.URLS.AVOID.EXPIRING_SIGNED"
+ ],
+ "explanation": [
+ "HOUSE.CODE.CAPTIONS.EXPLAIN_SNIPPET"
+ ],
+ "explanatory alternatives": [
+ "CMOS.PUNCTUATION.COMMAS.EXPLANATORY_ALTERNATIVES"
+ ],
+ "exponent": [
+ "CMOS.NUMBERS.S9_13.DEX.DEFINITION"
+ ],
+ "exponents": [
+ "CMOS.NUMBERS.S9_17.EXPONENT_FRACTIONS.SLASH"
+ ],
+ "external": [
+ "HOUSE.FRONTMATTER.DISTRIBUTION.CONTACT"
+ ],
"extra spaces": [
"CMOS.PUNCTUATION.DEGRADED.EXTRA_SPACES.AFTER_PUNCT"
],
+ "extremes": [
+ "BRING.TYPOGRAPHY.FAMILY.USE_DESIGNED_WEIGHTS"
+ ],
"facing pages": [
"BRING.LAYOUT.MARGINS.FACING_PAGES.INNER_OUTER",
- "BRING.LAYOUT.PAGINATION.BALANCE_FACING_PAGES"
+ "BRING.LAYOUT.MARGINS.OUTER_LARGER_THAN_INNER",
+ "BRING.LAYOUT.PAGE.SPREADS.ALIGN_BASELINES",
+ "BRING.LAYOUT.PAGINATION.BALANCE_FACING_PAGES",
+ "CMOS.LAYOUT.PAGINATION.FACING_PAGES.BALANCE"
+ ],
+ "fact-check": [
+ "HOUSE.EDITORIAL.REVIEW.FACT_CHECK"
+ ],
+ "facts": [
+ "HOUSE.EDITORIAL.CLAIMS.DISTINGUISH_FACT_OPINION"
+ ],
+ "fallback": [
+ "BRING.TYPOGRAPHY.TYPEFACE.FALLBACKS_COMPATIBLE_METRICS"
+ ],
+ "familiarity": [
+ "CMOS.ABBREVIATIONS.READER_FAMILIARITY"
+ ],
+ "family": [
+ "BRING.TYPOGRAPHY.FAMILY.SINGLE_FAMILY_BODY",
+ "BRING.TYPOGRAPHY.TYPEFACE.FAMILY_WITH_VARIANTS"
+ ],
+ "fences": [
+ "HOUSE.CODE.BLOCKS.USE_FOR_MULTILINE",
+ "HOUSE.CODE.FENCES.CLOSE_PROPERLY"
+ ],
+ "few notes": [
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SYMBOLS_FOR_FEW"
+ ],
+ "fewer": [
+ "CMOS.NUMBERS.S9_20.PERCENT.LESS_FREQUENT"
+ ],
+ "fi": [
+ "BRING.TYPOGRAPHY.LIGATURES.FI_FL_COLLISIONS",
+ "BRING.TYPOGRAPHY.LIGATURES.STANDARD_ON_BODY"
+ ],
+ "field codes": [
+ "CMOS.CITATIONS.S13_13.STRIP_CODES"
+ ],
+ "figure": [
+ "CMOS.LAYOUT.ILLUSTRATIONS.PLACEMENT_NEAR_REF"
+ ],
+ "figure 1": [
+ "CMOS.FIGURES.REFERENCES.IN_TEXT"
+ ],
+ "figure label": [
+ "CMOS.FIGURES.CAPTION.PREFIX.CONSISTENT"
],
"figure numbers": [
"CMOS.NUMBERS.REFERENCES.PAGE_CHAPTER_FIGURE"
],
"figures": [
- "BRING.LAYOUT.FLOATS.PLACEMENT.NEAR_REFERENCE"
+ "BRING.LAYOUT.COLUMNS.SPAN_POLICY.FIGURES",
+ "BRING.LAYOUT.FLOATS.PLACEMENT.NEAR_REFERENCE",
+ "BRING.LAYOUT.PAGINATION.KEEP_FIGURE_WITH_CAPTION",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.FIGURES.SPACING",
+ "BRING.TYPOGRAPHY.NUMERALS.FIGURE_STYLE_FOR_CAPTIONS",
+ "BRING.TYPOGRAPHY.NUMERALS.SMALL_CAPS_AND_FIGURES",
+ "CMOS.FIGURES.CAPTIONS.PRESENT",
+ "CMOS.FIGURES.NUMBERING.SEQUENTIAL",
+ "CMOS.FIGURES.NUMBERING.WITHIN_CHAPTERS",
+ "CMOS.FIGURES.TABLE_VS_FIGURE.CHOOSE",
+ "CMOS.NUMBERS.S9_28.DIVISIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.FIGURES_TABLES_EQUATIONS",
+ "HOUSE.ACCESSIBILITY.FIGURES.REFERENCED_IN_TEXT",
+ "HOUSE.EDITORIAL.REVIEW.CROSS_REFERENCES.VERIFY",
+ "HOUSE.LAYOUT.PAGINATION.CAPTIONS.KEEP_WITH_CONTENT"
+ ],
+ "file headers": [
+ "HOUSE.CODE.DIFFS.FILE_HEADERS.PRESENT"
+ ],
+ "file paths": [
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_CODE_URLS"
+ ],
+ "file sharing": [
+ "HOUSE.LINKS.URLS.AVOID.TEMP_FILESHARES"
+ ],
+ "file size": [
+ "HOUSE.LINKS.TEXT.FILESIZE.LABEL"
+ ],
+ "file type": [
+ "HOUSE.LINKS.AUTO.FILETYPE_LABEL.REQUIRED",
+ "HOUSE.LINKS.TEXT.FILETYPE.LABEL"
],
"file uri": [
"HOUSE.LINKS.DISALLOW.FILE_URIS"
],
+ "filename": [
+ "HOUSE.CODE.EXAMPLES.FILE_PATH.LABEL"
+ ],
+ "filenames": [
+ "CMOS.FIGURES.FILENAME.STABLE",
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_TEXT.QUALITY.NO_FILENAME"
+ ],
+ "filler": [
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_LOREM_IPSUM"
+ ],
+ "film": [
+ "CMOS.CITATIONS.S13_102.BIBLIOGRAPHY.AUDIOVISUAL.CREDITS"
+ ],
+ "final": [
+ "HOUSE.FRONTMATTER.METADATA.DOC_STATUS"
+ ],
+ "final page": [
+ "BRING.LAYOUT.PAGINATION.BALANCE_FINAL_PAGE",
+ "HOUSE.LAYOUT.PAGINATION.RUNT_FINAL_PAGE"
+ ],
+ "first decade": [
+ "CMOS.NUMBERS.S9_35.DECADES.FIRST_DECADE"
+ ],
+ "first line": [
+ "CMOS.LAYOUT.PARAGRAPHS.INDENT_POLICY"
+ ],
"first note": [
"CMOS.CITATIONS.NOTES_BIBLIO.FIRST_NOTE.FULL_REFERENCE"
],
+ "fixed spaces": [
+ "BRING.CODE.RAG.FIXED_WORD_SPACES"
+ ],
+ "fixed-width space": [
+ "CMOS.PUNCTUATION.SPACING.FIXED_WIDTHS"
+ ],
+ "fixme": [
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_TODO_FIXME"
+ ],
+ "fl": [
+ "BRING.TYPOGRAPHY.LIGATURES.FI_FL_COLLISIONS",
+ "BRING.TYPOGRAPHY.LIGATURES.STANDARD_ON_BODY"
+ ],
"floats": [
"BRING.LAYOUT.FLOATS.PLACEMENT.NEAR_REFERENCE"
],
@@ -595,54 +2397,244 @@
"BRING.HEADINGS.SUBHEADS.CROSSHEADS_SIDEHEADS.CHOOSE_DELIBERATELY",
"BRING.LAYOUT.PARAGRAPH.OPENING_FLUSH_LEFT"
],
+ "focus": [
+ "HOUSE.ACCESSIBILITY.LINKS.FOCUS_VISIBLE",
+ "HOUSE.EDITORIAL.CLARITY.ONE_IDEA_PER_PARAGRAPH"
+ ],
"font stretch": [
"BRING.TYPOGRAPHY.LETTERFORMS.AVOID_DISTORTION"
],
+ "fonts": [
+ "CMOS.I18N.TYPOGRAPHY.FONT_COVERAGE",
+ "HOUSE.CODE.MONO.FONT.PREFERRED"
+ ],
+ "footer band": [
+ "BRING.LAYOUT.PAGE.HEAD_FOOT_BANDS.CONSISTENT"
+ ],
+ "footnote": [
+ "CMOS.LAYOUT.FOOTNOTES.PLACEMENT",
+ "CMOS.LAYOUT.FOOTNOTES.SEQUENCE"
+ ],
"footnote continuation": [
"CMOS.CITATIONS.NOTES.FOOTNOTES.PAGE_BREAKS"
],
+ "footnote definitions": [
+ "HOUSE.CITATIONS.NOTES.DEFINITIONS.REQUIRED"
+ ],
"footnote position": [
"CMOS.CITATIONS.NOTES.NOTE_MARKERS.PLACEMENT_AFTER_PUNCT"
],
"footnotes": [
+ "BRING.LAYOUT.MARGINS.FOOTNOTE.CLEARANCE",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.FOOTNOTES.SPACING",
+ "BRING.TYPOGRAPHY.NUMERALS.SUPERIOR_INFERIOR_FOR_NOTES",
+ "CMOS.ABBREVIATIONS.FOOTNOTES.ABBREV_ON_FIRST_USE",
+ "CMOS.BACKMATTER.ENDNOTES.VERSUS_FOOTNOTES.CONSISTENT",
"CMOS.CITATIONS.NOTES.FOOTNOTES_VS_ENDNOTES.CHOOSE",
"CMOS.CITATIONS.NOTES.NOTE_MARKERS.SEQUENCE_CONTINUOUS",
- "CMOS.CITATIONS.NOTES.NOTE_MARKERS.SUPERSCRIPT_TEXT"
+ "CMOS.CITATIONS.NOTES.NOTE_MARKERS.SUPERSCRIPT_TEXT",
+ "CMOS.CITATIONS.S13_2.NOTES_SYSTEM",
+ "CMOS.CITATIONS.S13_47.NOTES.SYSTEMS.DONT_MIX",
+ "HOUSE.ACCESSIBILITY.NAVIGATION.FOOTNOTE_BACKLINKS"
+ ],
+ "for example": [
+ "CMOS.PUNCTUATION.COMMAS.THAT_IS_NAMELY",
+ "CMOS.PUNCTUATION.SEMICOLONS.THAT_IS_CLAUSE"
+ ],
+ "foreign terms": [
+ "CMOS.I18N.ITALICS.FOREIGN_WORDS.SPARE"
+ ],
+ "foreword": [
+ "CMOS.FRONTMATTER.FOREWORD.AUTHOR.ATTRIBUTED",
+ "CMOS.FRONTMATTER.FOREWORD.DATE_IF_PRESENT"
+ ],
+ "formal citations": [
+ "CMOS.CITATIONS.S13_5.ACADEMIC_EXPECTATION"
+ ],
+ "formal greetings": [
+ "CMOS.PUNCTUATION.COLONS.FORMAL_GREETINGS"
+ ],
+ "formal prose": [
+ "CMOS.PUNCTUATION.COMMAS.ETC.FORMAL_LIMIT"
+ ],
+ "format": [
+ "BRING.LAYOUT.PAGE.SHAPE.PROPORTIONATE",
+ "CMOS.CITATIONS.S13_14.CITE_VERSION",
+ "CMOS.CITATIONS.S13_14.DEVICE_SPECIFIC",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.FORMAT",
+ "CMOS.CITATIONS.S13_67.BIBLIOGRAPHY.ANNOTATIONS.CONSISTENT_AND_DISTINCT",
+ "HOUSE.EDITORIAL.CONSISTENCY.DATE_FORMAT.SINGLE",
+ "HOUSE.FIGURES.FORMAT.VECTOR_FOR_LINE_ART"
],
"format choice": [
"CMOS.CITATIONS.NOTES.FOOTNOTES_VS_ENDNOTES.CHOOSE"
],
+ "formats": [
+ "CMOS.CITATIONS.S13_1.ALL_SOURCE_TYPES"
+ ],
+ "formatting": [
+ "CMOS.BACKMATTER.APPENDICES.FORMAT_MATCH",
+ "CMOS.CITATIONS.S13_13.CITATIONS.REVIEW",
+ "CMOS.LAYOUT.PAGINATION.PAGE_NUMBERS.STYLE"
+ ],
+ "fraction bar": [
+ "CMOS.NUMBERS.S9_17.DISPLAYED_FRACTIONS.BAR"
+ ],
+ "fraction symbols": [
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.FRACTION_SYMBOLS"
+ ],
+ "fractional": [
+ "CMOS.NUMBERS.S9_9.MIXED_NUMERAL_WORD.FRACTIONS"
+ ],
+ "fractions": [
+ "BRING.TYPOGRAPHY.NUMERALS.FRACTIONS_TRUE_GLYPHS",
+ "CMOS.NUMBERS.FRACTIONS.ADJECTIVAL.HYPHENATE",
+ "CMOS.NUMBERS.FRACTIONS.SLASH_INLINE",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.EMPHASIS_EXCEPTION",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.HYPHENATE",
+ "CMOS.NUMBERS.S9_17.EXPONENT_FRACTIONS.SLASH",
+ "CMOS.NUMBERS.S9_17.FRACTIONS.RUNNING_TEXT.SLASH"
+ ],
"fragment": [
"BRING.LAYOUT.HYPHENATION.STUB_END_AVOID"
],
+ "fragments": [
+ "CMOS.PUNCTUATION.LISTS.MIXED_SENTENCE_TYPES",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.UNORDERED_FRAGMENTS"
+ ],
+ "from": [
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.AVOID_FROM_BETWEEN"
+ ],
"from to": [
- "CMOS.NUMBERS.RANGES.EN_DASH.USE"
+ "CMOS.NUMBERS.RANGES.EN_DASH.USE",
+ "CMOS.NUMBERS.RANGES.NO_MIXED_FROM_BETWEEN"
+ ],
+ "front matter": [
+ "CMOS.FRONTMATTER.TITLEPAGE.PRESENT",
+ "CMOS.LAYOUT.PAGINATION.PAGE_SEQUENCE.CONTINUITY",
+ "CMOS.NUMBERS.S9_28.FRONT_MATTER.ROMAN"
+ ],
+ "frontmatter": [
+ "CMOS.FRONTMATTER.TOC.FRONT_BACK_MATTER.INCLUDED",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.EARLY"
+ ],
+ "ftp": [
+ "HOUSE.LINKS.AUTO.FTP.AVOID",
+ "HOUSE.LINKS.URLS.DISALLOW.FTP"
],
"full citation": [
"CMOS.CITATIONS.NOTES_BIBLIO.FIRST_NOTE.FULL_REFERENCE"
],
+ "full note": [
+ "CMOS.CITATIONS.S13_18.NO_BIBLIO.FULL_FIRST_NOTE",
+ "CMOS.CITATIONS.S13_23.NO_BIBLIO.NOTES_UP_TO_SIX"
+ ],
+ "full size": [
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.NOTES_FULL_SIZE"
+ ],
"general rule": [
"CMOS.NUMBERS.RULE_SELECTION.GENERAL_OR_ALTERNATIVE"
],
+ "generic headings": [
+ "HOUSE.EDITORIAL.HEADINGS.AVOID_GENERIC"
+ ],
+ "genre": [
+ "CMOS.NUMBERS.S9_1.GENERAL_WORKS_SCOPE"
+ ],
+ "geography": [
+ "CMOS.ABBREVIATIONS.GEOGRAPHY.STATE_ABBREVS.CONSISTENT"
+ ],
+ "gibi": [
+ "CMOS.NUMBERS.S9_12.BINARY_PREFIXES"
+ ],
+ "giga": [
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.LARGE"
+ ],
+ "glossary": [
+ "CMOS.ABBREVIATIONS.GENERAL.GLOSSARY.WHEN_NEEDED",
+ "CMOS.BACKMATTER.ABBREVIATIONS.LIST.WHEN_NEEDED",
+ "CMOS.BACKMATTER.GLOSSARY.DEFINITIONS.CONCISE",
+ "CMOS.BACKMATTER.GLOSSARY.SORTING",
+ "CMOS.BACKMATTER.GLOSSARY.TERMS.CONSISTENT_STYLE",
+ "CMOS.BACKMATTER.GLOSSARY.WHEN_TERMS",
+ "CMOS.I18N.GLOSSARY.MULTILINGUAL",
+ "HOUSE.BACKMATTER.GLOSSARY.ALPHABETICAL",
+ "HOUSE.BACKMATTER.GLOSSARY.CROSS_REFERENCES",
+ "HOUSE.EDITORIAL.CLARITY.DEFINE_JARGON_ON_FIRST_USE",
+ "HOUSE.EDITORIAL.STRUCTURE.GLOSSARY.WHEN_DENSE"
+ ],
"glosses": [
"CMOS.PUNCTUATION.PARENS.GLOSSES_TRANSLATIONS"
],
+ "glyph coverage": [
+ "BRING.TYPOGRAPHY.TYPEFACE.GLYPH_COVERAGE_REQUIRED",
+ "CMOS.I18N.TYPOGRAPHY.FONT_COVERAGE"
+ ],
+ "glyphs": [
+ "BRING.TYPOGRAPHY.NUMERALS.FRACTIONS_TRUE_GLYPHS"
+ ],
+ "grades": [
+ "CMOS.NUMBERS.S9_8.GRADES_LEVELS.NUMERALS"
+ ],
+ "grammar": [
+ "CMOS.PUNCTUATION.COMMAS.LOGIC_OVER_PAUSE"
+ ],
+ "greetings": [
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS.GREETINGS"
+ ],
"grid": [
"BRING.LAYOUT.GRID.ALIGN_ELEMENTS"
],
"gridlines": [
- "BRING.TABLES.FURNITURE.MINIMIZE"
+ "BRING.TABLES.FURNITURE.MINIMIZE",
+ "CMOS.TABLES.GRIDLINES.LIGHT",
+ "CMOS.TABLES.RULES.MINIMAL"
+ ],
+ "group author": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.GROUP_AUTHORS.SUBUNITS.CONSISTENT"
],
"grouping": [
"BRING.TABLES.GROUPING.WHITESPACE",
"BRING.TYPOGRAPHY.NUMBER_STRINGS.SPACE_FOR_READABILITY",
- "CMOS.NUMBERS.TELEPHONE.FORMAT"
+ "CMOS.BACKMATTER.NOTES.BLOCKS.CONSISTENT",
+ "CMOS.CITATIONS.S13_48.ENDNOTES.GROUP_BY_CHAPTER",
+ "CMOS.NUMBERS.S9_12.NO_COMMAS.IN_BASE",
+ "CMOS.NUMBERS.S9_17.SLASH_BINDING",
+ "CMOS.NUMBERS.TELEPHONE.FORMAT",
+ "CMOS.TABLES.GROUPING.WHITESPACE",
+ "HOUSE.I18N.NUMBERS.GROUPING.CONSISTENT"
+ ],
+ "guarantees": [
+ "HOUSE.EDITORIAL.TONE.CALIBRATE_CERTAINTY"
+ ],
+ "guillemets": [
+ "HOUSE.I18N.QUOTES.MIXED_STYLES"
+ ],
+ "gutter": [
+ "BRING.LAYOUT.COLUMNS.GUTTER.CONSISTENT",
+ "BRING.LAYOUT.COLUMNS.GUTTER.SUFFICIENT",
+ "BRING.LAYOUT.MARGINS.GUTTER.ALLOW_BINDING"
],
"gutters": [
"BRING.LAYOUT.MARGINS.FACING_PAGES.INNER_OUTER"
],
+ "gyr": [
+ "CMOS.NUMBERS.S9_11.MYR_GYR"
+ ],
+ "h1": [
+ "HOUSE.ACCESSIBILITY.HEADINGS.SINGLE_H1",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.EARLY",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.PRESENT"
+ ],
"hair space": [
- "BRING.TYPOGRAPHY.SPACING.INITIALS.THIN_SPACE"
+ "BRING.TYPOGRAPHY.SPACING.INITIALS.THIN_SPACE",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.PRINT_HAIR_SPACE"
+ ],
+ "hanging indent": [
+ "BRING.LAYOUT.PARAGRAPH.LISTS.HANGING_INDENT"
+ ],
+ "hard to locate": [
+ "CMOS.CITATIONS.S13_6.URLS.READER_NEEDED"
],
"hard wrap": [
"CMOS.CITATIONS.DEGRADED.NOTE_MARKERS.REPAIR"
@@ -651,16 +2643,41 @@
"BRING.LAYOUT.DEGRADED.HARD_WRAP_REFLOW",
"CMOS.NUMBERS.DEGRADED.HARD_WRAP_UNITS"
],
+ "header": [
+ "CMOS.LAYOUT.PAGINATION.RUNNING_HEADS.PLACEMENT"
+ ],
"header alignment": [
- "BRING.TABLES.HEADERS.ALIGN_WITH_COLUMNS"
+ "BRING.TABLES.HEADERS.ALIGN_WITH_COLUMNS",
+ "CMOS.TABLES.HEADERS.ALIGNMENT.CONSISTENT"
+ ],
+ "header band": [
+ "BRING.LAYOUT.PAGE.HEAD_FOOT_BANDS.CONSISTENT"
],
"headers": [
- "BRING.TABLES.UNITS.IN_HEADERS"
+ "BRING.LAYOUT.PAGE.ODD_EVEN.CONSISTENT",
+ "BRING.LAYOUT.PAGINATION.KEEP_TABLE_WITH_HEADER",
+ "BRING.TABLES.UNITS.IN_HEADERS",
+ "BRING.TYPOGRAPHY.ITALICS.RUNNING_HEADS_AVOID",
+ "CMOS.TABLES.HEADERS.CAPITALIZATION.CONSISTENT",
+ "CMOS.TABLES.HEADERS.REQUIRED",
+ "CMOS.TABLES.SPLITS.REPEAT_HEADERS",
+ "CMOS.TABLES.UNITS.IN_HEADERS",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADER_ROW.REQUIRED",
+ "HOUSE.TABLES.UNITS.IN_HEADERS"
+ ],
+ "heading": [
+ "BRING.TYPOGRAPHY.TYPEFACE.DISPLAY_FACES_FOR_DISPLAY",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.AVOID_BOTTOM_OF_PAGE",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.AVOID_TOP_OF_PAGE",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.KEEP_WITH_TEXT",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.PRESENT"
],
"heading case": [
- "BRING.HEADINGS.CAPITALIZATION.CONSISTENT"
+ "BRING.HEADINGS.CAPITALIZATION.CONSISTENT",
+ "HOUSE.EDITORIAL.HEADINGS.CASE.CONSISTENT"
],
"heading depth": [
+ "BRING.HEADINGS.HIERARCHY.MAX_DEPTH",
"BRING.HEADINGS.HIERARCHY.NO_SKIPPED_LEVELS"
],
"heading hierarchy": [
@@ -674,32 +2691,96 @@
"heading levels": [
"BRING.HEADINGS.SUBHEADS.LEVELS.AS_MANY_AS_NEEDED"
],
+ "heading line breaks": [
+ "BRING.HEADINGS.NO_HYPHENATION",
+ "BRING.HEADINGS.NO_SINGLE_WORD_LINE"
+ ],
"heading notes": [
"CMOS.CITATIONS.NOTES.NOTE_MARKERS.HEADINGS_END"
],
+ "heading numbers": [
+ "BRING.HEADINGS.NUMBERING.CONSISTENT_STYLE"
+ ],
+ "heading punctuation": [
+ "BRING.HEADINGS.NO_TERMINAL_COLON",
+ "BRING.HEADINGS.NO_TERMINAL_PERIOD"
+ ],
"heading styles": [
"BRING.HEADINGS.STYLE.PALETTE_LIMIT"
],
"heading visibility": [
"BRING.HEADINGS.SUBHEADS.RIGHT_SIDEHEADS.VISIBILITY"
],
+ "heading wrap": [
+ "BRING.HEADINGS.BREAKS.AT_PHRASE_BOUNDARIES"
+ ],
"headings": [
"BRING.HEADINGS.ALIGNMENT.CONSISTENT_LEVEL",
+ "BRING.HEADINGS.AVOID_ABBREVIATIONS",
+ "BRING.HEADINGS.NUMBERING.NO_GAPS",
+ "BRING.HEADINGS.NUMBERING.PUNCTUATION.CONSISTENT",
+ "BRING.HEADINGS.QUESTION_MARK_ONLY_IF_QUESTION",
+ "BRING.HEADINGS.SUBHEADS.PARALLEL_GRAMMAR",
"BRING.HEADINGS.SUBHEADS.STYLE_CONTRIBUTES_TO_WHOLE",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_HEADINGS",
"BRING.LAYOUT.BLOCK_QUOTES.AVOID_CROWDING",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_AFTER_HEADING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.HEADINGS.BEFORE_AFTER",
"BRING.LAYOUT.VERTICAL_RHYTHM.MEASURED_INTERVALS.MULTIPLES",
- "CMOS.HEADINGS.DIVISIONS.LETTERS_DIARIES.HEADINGS"
+ "BRING.TYPOGRAPHY.BOLD.HEADING_HIERARCHY_BALANCE",
+ "BRING.TYPOGRAPHY.CAPS.MIXED_CAPS_CONSISTENT",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_IN_ALL_CAPS_HEADINGS",
+ "BRING.TYPOGRAPHY.ITALICS.HEADINGS_AVOID",
+ "BRING.TYPOGRAPHY.SERIF.SANS_FOR_DISPLAY",
+ "BRING.TYPOGRAPHY.SIZE.SCALE_CONSISTENT",
+ "BRING.TYPOGRAPHY.WEIGHT.HEAVY_WEIGHTS_SHORT_LABELS",
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_IN_HEADINGS",
+ "CMOS.CITATIONS.S13_64.BIBLIOGRAPHY.SUBSECTIONS.CLEAR_HEADINGS",
+ "CMOS.FRONTMATTER.TOC.ENTRIES.MATCH_HEADINGS",
+ "CMOS.FRONTMATTER.TOC.WHEN_NEEDED",
+ "CMOS.HEADINGS.DIVISIONS.LETTERS_DIARIES.HEADINGS",
+ "CMOS.PUNCTUATION.PERIODS.OMIT_DISPLAY_LINES",
+ "HOUSE.ACCESSIBILITY.HEADINGS.HIERARCHY.NO_SKIPS",
+ "HOUSE.ACCESSIBILITY.HEADINGS.NO_DECORATIVE",
+ "HOUSE.ACCESSIBILITY.NAVIGATION.PDF_BOOKMARKS",
+ "HOUSE.EDITORIAL.HEADINGS.AVOID_ALL_CAPS",
+ "HOUSE.EDITORIAL.HEADINGS.LENGTH.CONCISE",
+ "HOUSE.EDITORIAL.HEADINGS.NO_TRAILING_PUNCTUATION",
+ "HOUSE.LAYOUT.MD.HEADINGS.NON_EMPTY_SECTIONS",
+ "HOUSE.LAYOUT.PAGINATION.HEADINGS.NO_ADJACENT"
],
"headline style": [
"CMOS.CITATIONS.TITLES.CAPITALIZATION.CONSISTENT"
],
+ "heavy weight": [
+ "BRING.TYPOGRAPHY.WEIGHT.HEAVY_WEIGHTS_SHORT_LABELS"
+ ],
+ "hex": [
+ "CMOS.NUMBERS.S9_12.BASE_INDICATOR",
+ "CMOS.NUMBERS.S9_12.BASE_PREFIXES"
+ ],
"hexadecimal": [
"CMOS.NUMBERS.BASES.NON_DECIMAL.NO_GROUPING"
],
"hierarchy": [
+ "BRING.HEADINGS.AVOID_STACKED_LEVELS",
"BRING.HEADINGS.CONTRAST.CLEAR_HIERARCHY",
+ "BRING.HEADINGS.HIERARCHY.MAX_DEPTH",
+ "BRING.HEADINGS.NUMBERING.SUBLEVELS.DECIMAL_STYLE",
"BRING.HEADINGS.SUBHEADS.STYLE_CONTRIBUTES_TO_WHOLE",
- "BRING.HEADINGS.WEIGHT_SIZE.HIERARCHY_SCALE"
+ "BRING.HEADINGS.WEIGHT_SIZE.HIERARCHY_SCALE",
+ "BRING.TYPOGRAPHY.BOLD.HEADING_HIERARCHY_BALANCE",
+ "BRING.TYPOGRAPHY.FAMILY.LIMIT_STYLE_VARIANTS",
+ "BRING.TYPOGRAPHY.FAMILY.WEIGHT_CONTRAST_CLEAR",
+ "BRING.TYPOGRAPHY.ITALICS.HEADINGS_AVOID",
+ "BRING.TYPOGRAPHY.SIZE.DISPLAY_SIZE_BALANCE",
+ "BRING.TYPOGRAPHY.SIZE.SCALE_CONSISTENT",
+ "BRING.TYPOGRAPHY.TYPEFACE.LIMIT_NUMBER",
+ "BRING.TYPOGRAPHY.WEIGHT.AVOID_TOO_MANY_WEIGHTS",
+ "BRING.TYPOGRAPHY.WEIGHT.HIERARCHY_CLEAR",
+ "CMOS.LAYOUT.RUNNING_HEADS.SECTION_TITLES",
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.MIXED_LEVELS",
+ "HOUSE.ACCESSIBILITY.HEADINGS.HIERARCHY.NO_SKIPS"
],
"hierarchy depth": [
"BRING.HEADINGS.SUBHEADS.LEVELS.AS_MANY_AS_NEEDED"
@@ -710,16 +2791,71 @@
"historical currency": [
"CMOS.NUMBERS.CURRENCY.HISTORICAL.YEAR_CONTEXT"
],
+ "homoglyph": [
+ "CMOS.I18N.SECURITY.HOMOGLYPHS.AWARE"
+ ],
+ "homoglyphs": [
+ "CMOS.I18N.SCRIPT_MIXING.AVOID"
+ ],
+ "homonyms": [
+ "CMOS.PUNCTUATION.COMMAS.HOMONYMS.CLARITY"
+ ],
+ "honorifics": [
+ "CMOS.ABBREVIATIONS.TITLES.HONORIFICS.CONSISTENT"
+ ],
+ "hostnames": [
+ "HOUSE.LINKS.URLS.AVOID.STAGING_DOMAINS",
+ "HOUSE.LINKS.URLS.CANONICAL_HOST"
+ ],
+ "house style": [
+ "CMOS.CITATIONS.S13_3.JOURNALS.HOUSE_STYLE"
+ ],
+ "however": [
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTIVE_ADVERBS"
+ ],
+ "html": [
+ "CMOS.CITATIONS.S13_14.SAME_URL.FORMATS",
+ "HOUSE.LAYOUT.HTML.GUTTERS.MIN_PADDING",
+ "HOUSE.LAYOUT.HTML.MEASURE.MAX_WIDTH",
+ "HOUSE.LAYOUT.HTML.SECTION_SPACING.CONSISTENT",
+ "HOUSE.TYPOGRAPHY.HTML.JUSTIFICATION.RAGGED_RIGHT",
+ "HOUSE.TYPOGRAPHY.HTML.LINE_HEIGHT.MINIMUM"
+ ],
+ "html fallback": [
+ "HOUSE.LINKS.AUTO.HTML_FALLBACK.REQUIRED",
+ "HOUSE.LINKS.TEXT.ARCHIVE_AND_HTML.BOTH"
+ ],
+ "http": [
+ "CMOS.CITATIONS.S13_12.URLS.PROTOCOL"
+ ],
"https": [
+ "CMOS.CITATIONS.S13_12.URLS.PROTOCOL",
+ "HOUSE.LINKS.URLS.NO_PROTOCOL_RELATIVE",
"HOUSE.LINKS.URLS.PREFER_HTTPS"
],
+ "humanities": [
+ "CMOS.CITATIONS.S13_2.DISCIPLINE_PREFERENCE"
+ ],
+ "hundred": [
+ "CMOS.NUMBERS.S9_4.HUNDREDS_THOUSANDS.SPELLED_OUT"
+ ],
"hundreds": [
"CMOS.NUMBERS.ROUND_NUMBERS.SPELL_OUT"
],
"hybrid system": [
- "CMOS.CITATIONS.NOTES.AUTHOR_DATE_PLUS_NOTES"
+ "CMOS.CITATIONS.NOTES.AUTHOR_DATE_PLUS_NOTES",
+ "CMOS.CITATIONS.S13_2.SYSTEM_SWITCHING"
+ ],
+ "hyperlink": [
+ "CMOS.LINKS.HYPERLINK_EXCLUDES_PUNCTUATION",
+ "CMOS.PUNCTUATION.URLS.HYPERTEXT_EXCLUDES_PUNCTUATION"
+ ],
+ "hyphen": [
+ "CMOS.PUNCTUATION.DASHES.DISTINCT_TYPES"
],
"hyphenation": [
+ "BRING.CODE.RAG.NO_AUTO_HYPHENATION",
+ "BRING.HEADINGS.NO_HYPHENATION",
"BRING.LAYOUT.HYPHENATION.AVOID_NEAR_INTERRUPTION",
"BRING.LAYOUT.HYPHENATION.STUB_END_AVOID",
"BRING.TYPOGRAPHY.HYPHENATION.AVOID_AFTER_SHORT_LINE",
@@ -727,27 +2863,101 @@
"BRING.TYPOGRAPHY.HYPHENATION.LANGUAGE_DICTIONARY.MATCH",
"BRING.TYPOGRAPHY.HYPHENATION.MAX_CONSECUTIVE_LINES",
"BRING.TYPOGRAPHY.HYPHENATION.MIN_LEFT_RIGHT",
+ "CMOS.I18N.HYPHENATION.LANGUAGE_TAGS",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.HYPHENATE",
+ "CMOS.NUMBERS.S9_18.NO_HYPHEN.NUMERAL_UNIT",
"CMOS.NUMBERS.SI_PREFIXES.NO_HYPHEN",
"CMOS.PUNCTUATION.HYPHENATION.GENERAL_CHOICE",
"CMOS.PUNCTUATION.HYPHENATION.READABILITY",
"CMOS.PUNCTUATION.HYPHENS.ADVERB_LY.NO_HYPHEN",
"CMOS.PUNCTUATION.HYPHENS.COMPOUND_MODIFIERS.BEFORE_NOUN",
+ "CMOS.PUNCTUATION.HYPHENS.NUMERIC_COMPOUNDS",
"HOUSE.A11Y.DOCUMENT_LANGUAGE.DECLARE"
],
+ "hyphens": [
+ "CMOS.PUNCTUATION.HYPHENS.SEPARATORS"
+ ],
+ "i.e.": [
+ "CMOS.ABBREVIATIONS.LATIN.EG_IE.PUNCTUATION",
+ "CMOS.PUNCTUATION.COMMAS.IE_EG.PARENS"
+ ],
+ "i18n": [
+ "BRING.TYPOGRAPHY.LIGATURES.REVIEW_FOR_LANGUAGE"
+ ],
"ibid": [
"CMOS.CITATIONS.IBID.MINIMIZE_OR_AVOID",
- "CMOS.CITATIONS.NOTES.ENDNOTES.AVOID_IBID"
+ "CMOS.CITATIONS.NOTES.ENDNOTES.AVOID_IBID",
+ "CMOS.CITATIONS.S13_38.IBID.IMMEDIATE_PRECEDENT",
+ "CMOS.CITATIONS.S13_39.IBID.LOCATOR_REQUIRED",
+ "HOUSE.CITATIONS.NOTES.IBID.AVOID"
+ ],
+ "icon links": [
+ "HOUSE.ACCESSIBILITY.LINKS.ICON_ONLY.TEXT"
+ ],
+ "icons": [
+ "CMOS.FIGURES.SYMBOLS.CONSISTENT",
+ "HOUSE.ACCESSIBILITY.CONTRAST.NON_TEXT"
+ ],
+ "identification": [
+ "CMOS.CITATIONS.S13_1.SUFFICIENT_INFO"
+ ],
+ "identifier": [
+ "CMOS.CITATIONS.S13_104.BIBLIOGRAPHY.PUBLIC_DOCUMENTS.IDENTIFIERS"
+ ],
+ "identifiers": [
+ "HOUSE.CODE.INLINE.USE_FOR_IDENTIFIERS",
+ "HOUSE.EDITORIAL.CONSISTENCY.NAMES.SAME_FORM"
+ ],
+ "ids": [
+ "BRING.TYPOGRAPHY.NUMERALS.SLASHED_ZERO_IF_CONFUSION"
+ ],
+ "illustration": [
+ "CMOS.LAYOUT.ILLUSTRATIONS.PLACEMENT_NEAR_REF",
+ "CMOS.PUNCTUATION.COLONS.AMPLIFY_OR_ILLUSTRATE"
],
"images": [
- "HOUSE.A11Y.IMAGES.ALT_REQUIRED"
+ "CMOS.FIGURES.RESOLUTION.RASTER_SUFFICIENT",
+ "HOUSE.A11Y.IMAGES.ALT_REQUIRED",
+ "HOUSE.ACCESSIBILITY.IMAGES.CAPTION_FOR_COMPLEX",
+ "HOUSE.ACCESSIBILITY.IMAGES.TEXT_IN_IMAGES.AVOID",
+ "HOUSE.ACCESSIBILITY.TABLES.AVOID_SCREENSHOT"
+ ],
+ "immediate precedent": [
+ "CMOS.CITATIONS.S13_38.IBID.IMMEDIATE_PRECEDENT"
+ ],
+ "imperative": [
+ "CMOS.PUNCTUATION.COMMAS.IMPERATIVE_CLAUSES"
+ ],
+ "imperatives": [
+ "CMOS.PUNCTUATION.COMMAS.IMPERATIVE_CLAUSES.DEFAULT"
+ ],
+ "in": [
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.IN_BEFORE_BOOK"
],
"in-text citation": [
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.PARENTHETICAL"
],
+ "inc": [
+ "CMOS.ABBREVIATIONS.COMPANIES.INC_LTD.CONSISTENT",
+ "CMOS.PUNCTUATION.COMMAS.INC_LTD.NONE"
+ ],
+ "inc.": [
+ "CMOS.PUNCTUATION.COMMAS.CORPORATE_SUFFIX"
+ ],
"incidental material": [
"CMOS.PUNCTUATION.PARENS.USE"
],
+ "including": [
+ "CMOS.PUNCTUATION.COMMAS.SUCH_AS_INCLUDING"
+ ],
+ "inclusion criteria": [
+ "CMOS.CITATIONS.S13_66.BIBLIOGRAPHY.INCLUDE_ONLY_PER_SCOPE"
+ ],
+ "inclusive language": [
+ "HOUSE.EDITORIAL.TONE.INCLUSIVE_LANGUAGE"
+ ],
"inclusive numbers": [
+ "CMOS.NUMBERS.INCLUSIVE.SHORTEN_SECOND_NUMBER",
"CMOS.NUMBERS.INCLUSIVE_RANGES.PAGE_NUMBERS.SHORTEN"
],
"inclusive range": [
@@ -764,67 +2974,269 @@
],
"indentation": [
"BRING.HEADINGS.PARAGRAPH_INDENT.AFTER_HEAD_NONE",
- "BRING.LAYOUT.BLOCK_QUOTES.INDENT_OR_NARROW"
+ "BRING.LAYOUT.BLOCK_QUOTES.INDENT_OR_NARROW",
+ "CMOS.FRONTMATTER.TOC.INDENTATION.BY_LEVEL",
+ "CMOS.LAYOUT.PARAGRAPHS.BLOCK_QUOTE_STYLE",
+ "CMOS.LAYOUT.PARAGRAPHS.SPACING_POLICY",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.RUNOVER_ALIGN",
+ "HOUSE.CODE.BLOCKS.INDENTATION.CONSISTENT",
+ "HOUSE.CODE.BLOCKS.TABS.AVOID"
],
"indents": [
+ "BRING.LAYOUT.PARAGRAPH.INDENT.NOT_TOO_DEEP",
+ "BRING.LAYOUT.PARAGRAPH.INDENT.PROPORTIONAL",
+ "BRING.LAYOUT.PARAGRAPH.INDENT.WITHIN_MEASURE",
"BRING.LAYOUT.PARAGRAPH.INDENT_OR_SPACE_NOT_BOTH"
],
+ "independent clauses": [
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTION_PLUS_PHRASE.INDEPENDENT",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE.INDEPENDENT_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.CONJUNCTION",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.SHORT_OMIT",
+ "CMOS.PUNCTUATION.SEMICOLONS.AVOID_COMMA_SPLICE",
+ "CMOS.PUNCTUATION.SEMICOLONS.INDEPENDENT_CLAUSES"
+ ],
+ "index": [
+ "CMOS.BACKMATTER.INDEX.ABBREVIATIONS.CONSISTENT",
+ "CMOS.BACKMATTER.INDEX.CROSS_REFERENCES.CONSISTENT",
+ "CMOS.BACKMATTER.INDEX.ENTRIES.CONSISTENT_CASE",
+ "CMOS.BACKMATTER.INDEX.LOCATORS.ACCURATE",
+ "CMOS.BACKMATTER.INDEX.NAMES.SORTING",
+ "CMOS.BACKMATTER.INDEX.PAGE_RANGES.STANDARD",
+ "CMOS.BACKMATTER.INDEX.SEE_ALSO.USE_WHEN_NEEDED",
+ "CMOS.BACKMATTER.INDEX.SUBENTRIES.NESTED",
+ "CMOS.BACKMATTER.INDEX.SUBENTRY.ORDER.LOGICAL",
+ "CMOS.BACKMATTER.INDEX.WHEN_REQUIRED",
+ "CMOS.I18N.NAMES.SORTING.COLLATION",
+ "HOUSE.BACKMATTER.INDEX.CROSS_REFERENCES.CONSISTENT"
+ ],
+ "indirect question": [
+ "CMOS.PUNCTUATION.COMMAS.INDIRECT_QUESTIONS"
+ ],
"indirect questions": [
- "CMOS.PUNCTUATION.QUESTION_MARK.DIRECT_VS_INDIRECT"
+ "CMOS.PUNCTUATION.COMMAS.QUESTIONS.INDIRECT",
+ "CMOS.PUNCTUATION.QUESTION_MARK.DIRECT_VS_INDIRECT",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.DIRECT_INDIRECT"
+ ],
+ "inferior": [
+ "BRING.TYPOGRAPHY.NUMERALS.SUPERIOR_INFERIOR_FOR_NOTES"
+ ],
+ "informal sources": [
+ "CMOS.CITATIONS.S13_5.INFORMAL_SOURCES"
+ ],
+ "initialism": [
+ "CMOS.ABBREVIATIONS.ACRONYMS.DEFINE_FIRST_USE",
+ "CMOS.ABBREVIATIONS.INITIALISMS.NO_PERIODS.DEFAULT",
+ "CMOS.ABBREVIATIONS.PLURALS.NO_APOSTROPHE"
+ ],
+ "initialisms": [
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ACRONYMS"
],
"initials": [
"BRING.TYPOGRAPHY.SPACING.INITIALS.THIN_SPACE",
+ "CMOS.ABBREVIATIONS.NAMES.INITIALS.SPACING",
"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.INITIALS_PREFERRED"
],
"inline code": [
- "HOUSE.CODE.INLINE.MONO_BACKTICKS"
+ "HOUSE.CODE.INLINE.MONO_BACKTICKS",
+ "HOUSE.CODE.INLINE.USE_FOR_IDENTIFIERS"
+ ],
+ "inner margin": [
+ "BRING.LAYOUT.MARGINS.OUTER_LARGER_THAN_INNER"
+ ],
+ "institution": [
+ "CMOS.CITATIONS.S13_98.BIBLIOGRAPHY.THESES_DISSERTATIONS.INSTITUTION"
+ ],
+ "instructions": [
+ "CMOS.CITATIONS.S13_2.JOURNAL_INSTRUCTIONS",
+ "HOUSE.EDITORIAL.CLARITY.ACTIVE_VOICE_INSTRUCTIONS",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_DOUBLE_NEGATIVES"
+ ],
+ "interjection": [
+ "CMOS.PUNCTUATION.COMMAS.INTRO_OH_AH"
+ ],
+ "internal hostname": [
+ "HOUSE.LINKS.URLS.AVOID.INTERNAL_HOSTNAMES"
+ ],
+ "internal hostnames": [
+ "HOUSE.LINKS.AUTO.INTERNAL_HOSTNAMES.AVOID"
+ ],
+ "internal links": [
+ "HOUSE.LINKS.URLS.ANCHORS.STABLE"
],
"interruption": [
"BRING.LAYOUT.HYPHENATION.AVOID_NEAR_INTERRUPTION"
],
+ "intro": [
+ "BRING.LAYOUT.PAGINATION.KEEP_LIST_WITH_INTRO",
+ "HOUSE.LAYOUT.PAGINATION.LISTS.KEEP_INTRO"
+ ],
+ "intro sentence": [
+ "CMOS.PUNCTUATION.LISTS.RUNIN.INTRO_COMPLETE_COLON"
+ ],
+ "introduction": [
+ "CMOS.FRONTMATTER.INTRODUCTION.SCOPE",
+ "CMOS.FRONTMATTER.PREFACE.PURPOSE"
+ ],
+ "introductory": [
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL.INTRO_OPTIONAL",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_INTRO_OPTIONAL",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_INTRO",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_INTRODUCTORY",
+ "CMOS.PUNCTUATION.COMMAS.INTRO_YES_NO",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_INTRO"
+ ],
"introductory clause": [
"CMOS.PUNCTUATION.COMMAS.INTRODUCTORY_ELEMENTS.CLARITY"
],
"introductory comma": [
"CMOS.PUNCTUATION.COMMAS.INTRODUCTORY_ELEMENTS.CLARITY"
],
+ "introductory phrase": [
+ "CMOS.PUNCTUATION.COMMAS.INTRO_PHRASES.GENERAL"
+ ],
"introductory phrases": [
"CMOS.PUNCTUATION.COMMAS.INTRODUCTORY_PHRASES"
],
+ "inversion": [
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.NOTE_BIBLIO",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_INVERTED"
+ ],
"inverted name": [
- "CMOS.CITATIONS.NOTES_BIBLIO.NAME_ORDER.NOTES_VS_BIBLIO"
+ "CMOS.CITATIONS.NOTES_BIBLIO.NAME_ORDER.NOTES_VS_BIBLIO",
+ "CMOS.CITATIONS.S13_23.TWO_AUTHORS.BIBLIO_INVERT_FIRST"
+ ],
+ "inverted names": [
+ "CMOS.CITATIONS.S13_18.BIBLIO.INVERT_FIRST_AUTHOR",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.INVERTED"
+ ],
+ "invite links": [
+ "HOUSE.LINKS.AUTO.INVITE_LINKS.AVOID",
+ "HOUSE.LINKS.URLS.AVOID.ONE_TIME_INVITES"
+ ],
+ "ip addresses": [
+ "HOUSE.LINKS.URLS.AVOID.IP_LITERALS"
+ ],
+ "iso": [
+ "CMOS.NUMBERS.CURRENCY.CODE_POSITION.CONSISTENT"
],
"iso 8601": [
+ "CMOS.I18N.DATES.FORMAT.CONSISTENT",
"CMOS.NUMBERS.DATES.CONSISTENT_FORMAT",
"CMOS.NUMBERS.DATES.ISO_8601"
],
+ "iso code": [
+ "CMOS.I18N.CURRENCY.CODES.LABEL"
+ ],
"iso codes": [
- "CMOS.NUMBERS.CURRENCY.ISO_CODES"
+ "CMOS.NUMBERS.CURRENCY.ISO_CODES",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.ISO_CODES",
+ "CMOS.NUMBERS.S9_25.ISO_CODES.FORMAL",
+ "HOUSE.I18N.CURRENCY.DISAMBIGUATE"
],
"iso time": [
"CMOS.NUMBERS.TIME.ISO_STYLE"
],
"issue": [
"CMOS.CITATIONS.NOTES.JOURNAL.ARTICLE_ELEMENTS",
- "CMOS.NUMBERS.PERIODICALS.VOLUME_ISSUE"
+ "CMOS.CITATIONS.S13_110.AUTHOR_DATE.JOURNAL_ARTICLES.CORE_FIELDS",
+ "CMOS.NUMBERS.PERIODICALS.VOLUME_ISSUE",
+ "CMOS.NUMBERS.S9_29.PERIODICALS.ORDER",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.VOLUMES_ISSUES"
+ ],
+ "issue number": [
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_ISSUE"
+ ],
+ "issuing body": [
+ "CMOS.CITATIONS.S13_104.BIBLIOGRAPHY.PUBLIC_DOCUMENTS.IDENTIFIERS",
+ "CMOS.CITATIONS.S13_105.BIBLIOGRAPHY.REPORTS.ISSUING_BODY_AND_VERSION"
+ ],
+ "italic": [
+ "BRING.TYPOGRAPHY.FAMILY.SINGLE_FAMILY_BODY",
+ "BRING.TYPOGRAPHY.TYPEFACE.FAMILY_WITH_VARIANTS"
+ ],
+ "italic title": [
+ "CMOS.PUNCTUATION.QUOTES.ITALIC_TITLE_EXCEPTION"
+ ],
+ "italics": [
+ "BRING.TYPOGRAPHY.FAMILY.ITALIC_FOR_SUBTLE_EMPHASIS",
+ "BRING.TYPOGRAPHY.FAMILY.ITALIC_PUNCTUATION_MATCH",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_IN_ALL_CAPS_HEADINGS",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_NUMERAL_ITALICS",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_STACKED_EMPHASIS",
+ "BRING.TYPOGRAPHY.ITALICS.HEADINGS_AVOID",
+ "BRING.TYPOGRAPHY.ITALICS.LONG_SPANS_AVOID",
+ "BRING.TYPOGRAPHY.ITALICS.PUNCTUATION_FOLLOWS_STYLE",
+ "BRING.TYPOGRAPHY.ITALICS.SPARING",
+ "CMOS.CITATIONS.S13_26.JOURNAL.TITLE_ITALIC",
+ "CMOS.I18N.ITALICS.FOREIGN_WORDS.SPARE",
+ "CMOS.NUMBERS.S9_6.NTH_DEGREE.ITALIC_N",
+ "CMOS.PUNCTUATION.COMMAS.ETC_ETAL.STYLE",
+ "CMOS.PUNCTUATION.ITALICS.SURROUNDING_STYLE",
+ "CMOS.PUNCTUATION.ITALICS.TITLE_OWNERSHIP",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.LETTERS.ITALIC_OPTION",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.ITALIC_LONG.AVOID"
],
"j.c.l.": [
"BRING.TYPOGRAPHY.SPACING.INITIALS.THIN_SPACE"
],
+ "jargon": [
+ "HOUSE.EDITORIAL.CLARITY.DEFINE_JARGON_ON_FIRST_USE"
+ ],
+ "javascript:": [
+ "HOUSE.LINKS.DISALLOW.JAVASCRIPT_URIS"
+ ],
+ "journal abbreviations": [
+ "CMOS.ABBREVIATIONS.BIBLIOGRAPHY.STANDARDS.FOLLOW"
+ ],
"journal article": [
- "CMOS.CITATIONS.NOTES.JOURNAL.ARTICLE_ELEMENTS"
+ "CMOS.CITATIONS.NOTES.JOURNAL.ARTICLE_ELEMENTS",
+ "CMOS.CITATIONS.S13_96.BIBLIOGRAPHY.JOURNAL_ARTICLES.VOLUME_ISSUE_PAGES"
+ ],
+ "journal articles": [
+ "CMOS.CITATIONS.S13_110.AUTHOR_DATE.JOURNAL_ARTICLES.CORE_FIELDS"
+ ],
+ "journal title": [
+ "CMOS.CITATIONS.S13_26.JOURNAL.TITLE_ITALIC"
+ ],
+ "journals": [
+ "BRING.TYPOGRAPHY.ITALICS.TITLES_STANDALONE_WORKS",
+ "CMOS.CITATIONS.S13_2.JOURNAL_INSTRUCTIONS",
+ "CMOS.CITATIONS.S13_3.JOURNALS.HOUSE_STYLE",
+ "CMOS.CITATIONS.S13_4.JOURNALS.STRICT"
+ ],
+ "jr": [
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.NONE"
+ ],
+ "jr.": [
+ "CMOS.ABBREVIATIONS.TITLES.JR_SR.CONSISTENT",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.SUFFIXES.INCLUDE",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.RUNNING"
+ ],
+ "json": [
+ "HOUSE.CODE.BLOCKS.CONFIG.VALID"
],
"jurisdiction": [
"CMOS.CITATIONS.LEGAL_PUBLIC_DOCS.USE_JURISDICTIONAL_FORMAT"
],
"justification": [
- "BRING.TYPOGRAPHY.SPACING.WORD_SPACE.DEFINE"
+ "BRING.CODE.RAG.AVOID_FAKE_JUSTIFY",
+ "BRING.TYPOGRAPHY.SPACING.WORD_SPACE.DEFINE",
+ "HOUSE.TYPOGRAPHY.HTML.JUSTIFICATION.RAGGED_RIGHT"
],
"justified text": [
"BRING.LAYOUT.JUSTIFICATION.RAGGED_RIGHT_IF_NEEDED"
],
+ "k notation": [
+ "CMOS.NUMBERS.S9_26.K_THOUSANDS"
+ ],
"keep with next": [
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.AVOID_BOTTOM_OF_PAGE",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.KEEP_WITH_TEXT",
"HOUSE.HEADINGS.KEEPS.AVOID_STRANDED",
+ "HOUSE.HEADINGS.KEEP_WITH_NEXT",
"HOUSE.LAYOUT.PAGINATION.KEEP_WITH_NEXT.HEADINGS"
],
"kerning": [
@@ -833,155 +3245,583 @@
"kerning tables": [
"BRING.TYPOGRAPHY.KERNING.CONSISTENT_OR_NONE"
],
+ "keyboard": [
+ "HOUSE.ACCESSIBILITY.LINKS.FOCUS_VISIBLE"
+ ],
+ "keys": [
+ "CMOS.FIGURES.KEY.READABLE"
+ ],
+ "kibi": [
+ "CMOS.NUMBERS.S9_12.BINARY_PREFIXES"
+ ],
+ "labeling": [
+ "CMOS.BACKMATTER.APPENDICES.LABELED"
+ ],
+ "labels": [
+ "BRING.HEADINGS.NUMBERING.APPENDIX_LABELS",
+ "BRING.TYPOGRAPHY.BOLD.LABELS_SHORT",
+ "BRING.TYPOGRAPHY.BOLD.SPARING_USE",
+ "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_SHORT_LABELS_ONLY",
+ "BRING.TYPOGRAPHY.FAMILY.BOLD_FOR_STRONG_EMPHASIS",
+ "BRING.TYPOGRAPHY.FAMILY.SMALL_CAPS_SPARE",
+ "BRING.TYPOGRAPHY.WEIGHT.HEAVY_WEIGHTS_SHORT_LABELS",
+ "CMOS.FIGURES.LABELS.AVOID_OVERLAP",
+ "CMOS.FIGURES.LABELS.FONT.CONSISTENT",
+ "CMOS.NUMBERS.S9_5.ALPHANUMERIC.MAY_BEGIN",
+ "CMOS.TABLES.HEADERS.REQUIRED",
+ "HOUSE.ACCESSIBILITY.LINKS.ICON_ONLY.TEXT",
+ "HOUSE.BACKMATTER.APPENDICES.LABELS.MATCH",
+ "HOUSE.LINKS.AUTO.FILETYPE_LABEL.REQUIRED",
+ "HOUSE.LINKS.TEXT.FILETYPE.LABEL"
+ ],
+ "landscape": [
+ "CMOS.TABLES.ROTATION.LANDSCAPE.WHEN_NEEDED"
+ ],
"lang attribute": [
"HOUSE.A11Y.DOCUMENT_LANGUAGE.DECLARE"
],
"language": [
- "BRING.TYPOGRAPHY.HYPHENATION.LANGUAGE_DICTIONARY.MATCH"
+ "BRING.TYPOGRAPHY.HYPHENATION.LANGUAGE_DICTIONARY.MATCH",
+ "BRING.TYPOGRAPHY.LIGATURES.REVIEW_FOR_LANGUAGE",
+ "CMOS.FRONTMATTER.LANGUAGE.NOTICE",
+ "CMOS.I18N.HYPHENATION.LANGUAGE_TAGS",
+ "HOUSE.ACCESSIBILITY.CODE.FENCES.LANGUAGE",
+ "HOUSE.ACCESSIBILITY.LANGUAGE.METADATA",
+ "HOUSE.CODE.BLOCKS.SPLIT_BY_LANGUAGE",
+ "HOUSE.CODE.FENCES.LANGUAGE_INFO.SUGGEST",
+ "HOUSE.LINKS.TEXT.LANGUAGE.LABEL"
],
"language tag": [
"HOUSE.CODE.BLOCKS.LANGUAGE_TAGS.PREFERRED"
],
+ "language tags": [
+ "HOUSE.I18N.LANGUAGE.SWITCHES.MARK"
+ ],
"large amounts": [
- "CMOS.NUMBERS.CURRENCY.LARGE_AMOUNTS"
+ "CMOS.NUMBERS.CURRENCY.LARGE_AMOUNTS",
+ "CMOS.NUMBERS.S9_26.LARGE_MONEY.NUMERALS"
],
"large numbers": [
- "CMOS.NUMBERS.LARGE_VALUES.MILLIONS_BILLIONS"
+ "CMOS.NUMBERS.LARGE_VALUES.MILLIONS_BILLIONS",
+ "CMOS.NUMBERS.S9_4.MIXED_LARGE_CONTEXTS",
+ "CMOS.NUMBERS.S9_9.CONSISTENCY.WITH_FRACTIONS"
+ ],
+ "last reviewed": [
+ "HOUSE.FRONTMATTER.METADATA.LAST_REVIEWED"
+ ],
+ "latin": [
+ "CMOS.ABBREVIATIONS.LATIN.VERSUS_ENGLISH"
+ ],
+ "latin abbreviations": [
+ "CMOS.ABBREVIATIONS.LATIN.EG_IE.PUNCTUATION"
+ ],
+ "layout": [
+ "CMOS.FIGURES.CAPTION.ALIGNMENT.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.PLACEMENT.CONSISTENT",
+ "CMOS.FIGURES.ORIENTATION.CONSISTENT",
+ "CMOS.FIGURES.PLACEMENT.NEAR_MENTION",
+ "CMOS.FIGURES.PLACEMENT.TOP_OR_BOTTOM.CONSISTENT",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.MULTI_COLUMN_SHORT_ITEMS",
+ "HOUSE.TABLES.COLUMN_WIDTHS.BALANCED"
],
"layout clarity": [
"BRING.LAYOUT.ELEMENT_RELATIONSHIPS.VISIBLE"
],
+ "layout tables": [
+ "HOUSE.ACCESSIBILITY.TABLES.NO_LAYOUT"
+ ],
+ "lead-in": [
+ "BRING.HEADINGS.LEADIN_TEXT.BEFORE_LIST",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.INTRO_COLON"
+ ],
+ "leaders": [
+ "CMOS.FRONTMATTER.TOC.LEADERS.CONSISTENT"
+ ],
"leading": [
"BRING.LAYOUT.LEADING.ADJUST_FOR_SIZE_CHANGES",
"BRING.LAYOUT.LEADING.CHOOSE_BASE",
"BRING.LAYOUT.LEADING.CONSISTENT_BODY",
"BRING.LAYOUT.LEADING.NEGATIVE.AVOID_CONTINUOUS_TEXT",
"BRING.LAYOUT.PAGE.DENSITY.DONT_SUFFOCATE",
- "BRING.LAYOUT.VERTICAL_RHYTHM.MEASURED_INTERVALS.MULTIPLES"
+ "BRING.LAYOUT.VERTICAL_RHYTHM.MEASURED_INTERVALS.MULTIPLES",
+ "BRING.TYPOGRAPHY.SIZE.LEADING_RELATION",
+ "CMOS.LAYOUT.SPACING.LEADING.CHOOSE",
+ "CMOS.LAYOUT.SPACING.LINE_SPACING.CONSISTENT",
+ "HOUSE.TYPOGRAPHY.HTML.LINE_HEIGHT.MINIMUM"
],
"leading zero": [
- "CMOS.NUMBERS.DECIMALS.LEADING_ZERO"
+ "CMOS.NUMBERS.DECIMALS.LEADING_ZERO",
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.CONTEXT",
+ "CMOS.NUMBERS.TIME.LEADING_ZERO_MINUTES"
],
"leading zeros": [
"CMOS.NUMBERS.TIME.ISO_STYLE"
],
+ "legal": [
+ "CMOS.CITATIONS.S13_3.LEGAL.BLUEBOOK",
+ "CMOS.FRONTMATTER.DISCLAIMERS.WHEN_REQUIRED",
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.MIXED_LEVELS"
+ ],
"legal citation": [
"CMOS.CITATIONS.LEGAL_PUBLIC_DOCS.USE_JURISDICTIONAL_FORMAT"
],
+ "legal instruments": [
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.NUMERALS"
+ ],
+ "legal references": [
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.PREFER_ARABIC",
+ "CMOS.NUMBERS.S9_8.TITLE_NUMBERS"
+ ],
+ "legend": [
+ "CMOS.ABBREVIATIONS.TABLES.ABBREV_KEY",
+ "CMOS.ABBREVIATIONS.TABLES.KEYS.WHEN_DENSE",
+ "CMOS.FIGURES.KEY.READABLE",
+ "CMOS.FIGURES.LEGENDS.EXPLAIN_SYMBOLS",
+ "CMOS.TABLES.ABBREVIATIONS.EXPLAIN",
+ "HOUSE.FIGURES.COLOR.LEGEND.REQUIRED"
+ ],
"legibility": [
"BRING.LAYOUT.LEADING.NEGATIVE.AVOID_CONTINUOUS_TEXT",
"BRING.TABLES.TYPE_SIZE.READABLE",
- "BRING.TYPOGRAPHY.TRACKING.LOWERCASE.AVOID"
+ "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ITALICS_LONG",
+ "BRING.TYPOGRAPHY.TRACKING.LOWERCASE.AVOID",
+ "BRING.TYPOGRAPHY.TYPEFACE.LEGIBILITY_AT_SIZE",
+ "BRING.TYPOGRAPHY.TYPEFACE.OPTICAL_SIZES_USE",
+ "BRING.TYPOGRAPHY.TYPEFACE.TEXT_FACES_FOR_BODY",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.BASELINE_FALLBACK",
+ "CMOS.FIGURES.SCALE.LEGIBLE",
+ "CMOS.TABLES.COLUMN_SPACING.READABLE",
+ "CMOS.TABLES.ROW_SPACING.READABLE"
],
"length": [
+ "CMOS.FRONTMATTER.READING_TIME.WHEN_HELPFUL",
"CMOS.HEADINGS.RUNNING_HEADS.LENGTH_SHORT"
],
+ "less": [
+ "CMOS.NUMBERS.S9_20.PERCENT.LESS_FREQUENT"
+ ],
"letters": [
"CMOS.HEADINGS.DIVISIONS.LETTERS_DIARIES.HEADINGS",
"CMOS.HEADINGS.LETTERS_DIARIES.DATELINE_FORMAT",
- "CMOS.HEADINGS.LETTERS_DIARIES.SIGNATURE_FORMAT"
+ "CMOS.HEADINGS.LETTERS_DIARIES.SIGNATURE_FORMAT",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.LETTERS.ITALIC_OPTION",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.ORDERED_MARKERS"
],
"letterspacing": [
+ "BRING.CODE.RAG.NO_LETTERSPACING",
"BRING.TYPOGRAPHY.TRACKING.CAPS_SMALLCAPS_AND_LONG_DIGITS",
"BRING.TYPOGRAPHY.TRACKING.LOWERCASE.AVOID"
],
+ "levels": [
+ "CMOS.FRONTMATTER.TOC.LEVELS.CONSISTENT",
+ "CMOS.NUMBERS.S9_8.GRADES_LEVELS.NUMERALS"
+ ],
+ "license": [
+ "CMOS.FRONTMATTER.LICENSE.ATTRIBUTION"
+ ],
+ "licenses": [
+ "CMOS.BACKMATTER.LICENSES.THIRD_PARTY",
+ "CMOS.FIGURES.PERMISSIONS.DOCUMENTED"
+ ],
+ "ligatures": [
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ACRONYMS",
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ALL_CAPS",
+ "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_IN_DISPLAY",
+ "BRING.TYPOGRAPHY.LIGATURES.DO_NOT_USE_IF_AMBIGUOUS",
+ "BRING.TYPOGRAPHY.LIGATURES.KEEP_CONSISTENT",
+ "BRING.TYPOGRAPHY.LIGATURES.REVIEW_FOR_LANGUAGE",
+ "BRING.TYPOGRAPHY.LIGATURES.STANDARD_ON_BODY"
+ ],
+ "line": [
+ "CMOS.LINKS.URL_ONLY_LINE_NO_PUNCT"
+ ],
+ "line balance": [
+ "CMOS.LAYOUT.PAGINATION.AVOID_SHORT_LAST_LINE"
+ ],
"line break": [
"BRING.LAYOUT.LINEBREAKS.AVOID_SAME_WORD_START",
"BRING.TYPOGRAPHY.HYPHENATION.HARD_SPACES.SHORT_EXPRESSIONS"
],
"line breaks": [
"CMOS.CITATIONS.DEGRADED.URL_LINEBREAKS.NORMALIZE",
+ "CMOS.CITATIONS.S13_12.URLS.NO_SPACES",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.LINE_BREAKS_DETAIL",
"CMOS.PUNCTUATION.DASHES.EM_LINE_BREAKS",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.LINE_BREAKS",
+ "CMOS.PUNCTUATION.SPACING.NONBREAKING",
+ "HOUSE.CODE.BLOCKS.LINE_BREAKS.SEMANTIC_SAFE",
"HOUSE.LINKS.WRAP.SAFE_BREAKS"
],
+ "line endings": [
+ "HOUSE.CODE.LINE_ENDINGS.NORMALIZE"
+ ],
+ "line height": [
+ "HOUSE.TYPOGRAPHY.HTML.LINE_HEIGHT.MINIMUM"
+ ],
"line length": [
+ "BRING.CODE.RAG.NO_MIN_LINE",
+ "BRING.HEADINGS.WIDTH.BALANCED",
"BRING.LAYOUT.MEASURE.COMFORTABLE_RANGE",
- "BRING.LAYOUT.MEASURE.TARGET_RANGE_CHARS"
+ "BRING.LAYOUT.MEASURE.TARGET_RANGE_CHARS",
+ "BRING.TYPOGRAPHY.SIZE.BODY_SIZE_MATCH_MEASURE",
+ "BRING.TYPOGRAPHY.TYPEFACE.LEGIBILITY_AT_SIZE",
+ "CMOS.LAYOUT.MEASURE.LINE_LENGTH.TARGET_RANGE",
+ "HOUSE.LAYOUT.HTML.MEASURE.MAX_WIDTH"
+ ],
+ "line numbers": [
+ "HOUSE.CODE.BLOCKS.NO_LINE_NUMBERS"
],
"line spacing": [
"BRING.LAYOUT.LEADING.CHOOSE_BASE",
- "BRING.LAYOUT.LEADING.NEGATIVE.AVOID_CONTINUOUS_TEXT"
+ "BRING.LAYOUT.LEADING.NEGATIVE.AVOID_CONTINUOUS_TEXT",
+ "BRING.TYPOGRAPHY.SIZE.LEADING_RELATION",
+ "CMOS.LAYOUT.SPACING.LEADING.CHOOSE",
+ "CMOS.LAYOUT.SPACING.LINE_SPACING.CONSISTENT"
+ ],
+ "line weights": [
+ "CMOS.FIGURES.LINE_WEIGHTS.CONSISTENT"
+ ],
+ "lines": [
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.SECTIONS_PARAS_LINES"
+ ],
+ "lining": [
+ "BRING.TYPOGRAPHY.NUMERALS.MIXED_STYLE_AVOID"
+ ],
+ "lining figures": [
+ "BRING.TYPOGRAPHY.NUMERALS.AVOID_LINING_IN_LOWERCASE",
+ "BRING.TYPOGRAPHY.NUMERALS.LINING_FOR_CAPS_AND_DISPLAY"
+ ],
+ "link labels": [
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.NO_BARE_URLS",
+ "HOUSE.LINKS.AUTO.LABEL_LENGTH.AVOID_OVERLONG",
+ "HOUSE.LINKS.TEXT.AVOID_OVERLONG_LABELS"
],
"link rot": [
"CMOS.CITATIONS.ONLINE.URLS.STABLE"
],
+ "link shorteners": [
+ "HOUSE.ACCESSIBILITY.LINKS.AVOID_SHORTENERS"
+ ],
"link text": [
+ "CMOS.CITATIONS.S13_6.LINK_TITLE_PREFERRED",
"HOUSE.A11Y.LINK_TEXT.DESCRIPTIVE",
- "HOUSE.LINKS.TEXT.DESCRIPTIVE"
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.SYMBOL_ONLY.AVOID",
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.UNIQUE_TARGETS",
+ "HOUSE.LINKS.AUTO.PARTIAL_WORD.AVOID",
+ "HOUSE.LINKS.TEXT.DESCRIPTIVE",
+ "HOUSE.LINKS.TEXT.MATCHES_TARGET",
+ "HOUSE.LINKS.TEXT.PARTIAL_WORD.AVOID"
+ ],
+ "linked images": [
+ "HOUSE.ACCESSIBILITY.IMAGES.LINKED.ALT_TARGET"
+ ],
+ "linking verb": [
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_LINKING_VERB"
+ ],
+ "linking verbs": [
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL.LINKING_VERB"
],
"links": [
+ "HOUSE.ACCESSIBILITY.LINKS.TARGETS.PUBLIC",
+ "HOUSE.ACCESSIBILITY.LINKS.VISUALLY_DISTINCT",
+ "HOUSE.ACCESSIBILITY.TOC.LINKED_ENTRIES",
+ "HOUSE.EDITORIAL.REVIEW.LINKS.VERIFY",
"HOUSE.LINKS.DISALLOW.FILE_URIS",
- "HOUSE.LINKS.PUNCTUATION.NO_TRAILING_PUNCT"
+ "HOUSE.LINKS.DISALLOW.JAVASCRIPT_URIS",
+ "HOUSE.LINKS.PUNCTUATION.NO_TRAILING_PUNCT",
+ "HOUSE.LINKS.URLS.DISALLOW.LOCALHOST",
+ "HOUSE.TYPOGRAPHY.HTML.LINK_DECORATION.CONSISTENT"
+ ],
+ "list introduction": [
+ "CMOS.PUNCTUATION.COLONS.INTRODUCE_FORMAL_LISTS"
],
"list items": [
"CMOS.PUNCTUATION.SEMICOLONS.COMPLEX_SERIES.SEPARATE"
],
+ "list markers": [
+ "HOUSE.ACCESSIBILITY.LISTS.MARKER_CONSISTENT"
+ ],
+ "list of figures": [
+ "CMOS.FIGURES.LIST_ENTRIES.MATCH_CAPTIONS",
+ "CMOS.FIGURES.LIST_OF_FIGURES.WHEN_NEEDED",
+ "CMOS.FRONTMATTER.LISTS.OF_FIGURES_TABLES.WHEN_NEEDED",
+ "CMOS.FRONTMATTER.LIST_OF_FIGURES.SECTION_TITLE"
+ ],
+ "list of tables": [
+ "CMOS.FRONTMATTER.LISTS.OF_FIGURES_TABLES.WHEN_NEEDED",
+ "CMOS.FRONTMATTER.LIST_OF_TABLES.SECTION_TITLE"
+ ],
"list punctuation": [
- "CMOS.PUNCTUATION.COMMAS.SERIAL_COMMA.DEFAULT"
+ "CMOS.PUNCTUATION.COMMAS.SERIAL_COMMA.DEFAULT",
+ "HOUSE.EDITORIAL.LISTS.PUNCTUATION.CONSISTENT"
],
"lists": [
+ "BRING.HEADINGS.LEADIN_TEXT.BEFORE_LIST",
+ "BRING.LAYOUT.COLUMNS.USE_FOR_LONG_LISTS",
"BRING.LAYOUT.MEASURE.CHANGE_FOR_LISTS",
- "BRING.TABLES.GUIDES.READING_DIRECTION"
+ "BRING.LAYOUT.PAGINATION.AVOID_LONELY_LINE_IN_LISTS",
+ "BRING.LAYOUT.PAGINATION.KEEP_LIST_WITH_INTRO",
+ "BRING.LAYOUT.PARAGRAPH.LISTS.ALIGN_WITH_BODY",
+ "BRING.LAYOUT.PARAGRAPH.LISTS.HANGING_INDENT",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.LISTS.SPACING",
+ "BRING.TABLES.GUIDES.READING_DIRECTION",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.LISTS_TABLES",
+ "CMOS.PUNCTUATION.LISTS.AVOID_VERTICAL_FOR_LONG_SENTENCES",
+ "CMOS.PUNCTUATION.LISTS.CONSISTENT_FORMAT",
+ "CMOS.PUNCTUATION.LISTS.MIXED_SENTENCE_TYPES",
+ "CMOS.PUNCTUATION.LISTS.NUMERALS_ONLY_IF_NEEDED",
+ "CMOS.PUNCTUATION.LISTS.PARALLEL_ELEMENTS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.CAPITALIZATION_CONSISTENT",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.END_PUNCT_SENTENCES",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.MULTI_COLUMN_SHORT_ITEMS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.RUNOVER_ALIGN",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.LIST_INTRO",
+ "HOUSE.ACCESSIBILITY.LISTS.NO_EMPTY_ITEMS",
+ "HOUSE.ACCESSIBILITY.LISTS.USE_LIST_MARKUP",
+ "HOUSE.EDITORIAL.LISTS.AVOID_SINGLE_ITEM",
+ "HOUSE.EDITORIAL.LISTS.PARALLEL_STRUCTURE",
+ "HOUSE.LAYOUT.PAGINATION.LISTS.AVOID_LONELY_ITEM",
+ "HOUSE.LAYOUT.PAGINATION.LISTS.KEEP_INTRO"
+ ],
+ "llc": [
+ "CMOS.ABBREVIATIONS.COMPANIES.INC_LTD.CONSISTENT"
+ ],
+ "loanwords": [
+ "CMOS.I18N.ITALICS.FOREIGN_WORDS.SPARE"
+ ],
+ "loc. cit.": [
+ "CMOS.CITATIONS.S13_40.SHORT_FORM.AVOID_OP_CIT"
],
"locale": [
+ "CMOS.I18N.LANGUAGE.CONSISTENT_SPELLING",
+ "CMOS.I18N.QUOTES.STYLE.MATCH_LOCALE",
"CMOS.NUMBERS.DECIMAL_MARKER.LOCALE",
- "CMOS.NUMBERS.GROUPING.THOUSANDS_SEPARATOR"
+ "CMOS.NUMBERS.GROUPING.THOUSANDS_SEPARATOR",
+ "CMOS.NUMBERS.S9_9.BILLION_TRILLION.LOCALE_CHECK",
+ "HOUSE.EDITORIAL.CONSISTENCY.SPELLING_VARIANT.CHOOSE_ONE",
+ "HOUSE.I18N.NUMBERS.MIXED_DECIMAL_SEPARATORS"
+ ],
+ "localhost": [
+ "HOUSE.LINKS.URLS.DISALLOW.LOCALHOST"
],
"locator": [
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.DIRECT_QUOTES",
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.LOCATORS",
"CMOS.CITATIONS.NOTES.QUOTE_IN_NOTE.LOCATOR",
"CMOS.CITATIONS.NOTES.SHORT_FORM.BASIC_ELEMENTS",
- "CMOS.CITATIONS.QUOTATIONS.LOCATORS.PAGE_REQUIRED"
+ "CMOS.CITATIONS.QUOTATIONS.LOCATORS.PAGE_REQUIRED",
+ "CMOS.CITATIONS.S13_39.IBID.LOCATOR_REQUIRED",
+ "CMOS.CITATIONS.S13_9.URL_TO_MAIN_PAGE"
+ ],
+ "locators": [
+ "CMOS.BACKMATTER.INDEX.LOCATORS.ACCURATE",
+ "CMOS.CITATIONS.S13_20.ELECTRONIC.SHORT_DOCS",
+ "CMOS.CITATIONS.S13_20.LOCATORS.ALTERNATIVES"
+ ],
+ "logged out": [
+ "CMOS.CITATIONS.S13_10.TEST_LOGGED_OUT"
+ ],
+ "logic": [
+ "CMOS.PUNCTUATION.COMMAS.LOGIC_OVER_PAUSE",
+ "CMOS.TABLES.COLUMN_ORDER.LOGICAL",
+ "CMOS.TABLES.ROW_ORDER.LOGICAL"
+ ],
+ "logical system": [
+ "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.ELECTRONIC_PREFERS_LOGICAL"
+ ],
+ "login": [
+ "HOUSE.LINKS.AUTO.LOGIN_LINKS.AVOID",
+ "HOUSE.LINKS.URLS.AVOID.PASSWORD_RESET"
],
"long lines": [
- "BRING.LAYOUT.MEASURE.AVOID_TOO_LONG"
+ "BRING.LAYOUT.MEASURE.AVOID_TOO_LONG",
+ "CMOS.LAYOUT.MEASURE.MAX_LINE_LENGTH"
],
"long notes": [
"CMOS.CITATIONS.NOTES.LONG_NOTES.PARAGRAPHING"
],
+ "long passages": [
+ "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_NOT_FOR_LONG_PASSAGES"
+ ],
+ "long sentences": [
+ "CMOS.PUNCTUATION.LISTS.AVOID_VERTICAL_FOR_LONG_SENTENCES"
+ ],
+ "long url": [
+ "CMOS.CITATIONS.S13_9.SHORTEN_LONG_URLS"
+ ],
"loose leading": [
"BRING.LAYOUT.LEADING.AVOID_TOO_LOOSE"
],
+ "lorem ipsum": [
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_LOREM_IPSUM"
+ ],
"lowercase": [
- "BRING.TYPOGRAPHY.TRACKING.LOWERCASE.AVOID"
+ "BRING.TYPOGRAPHY.NUMERALS.AVOID_LINING_IN_LOWERCASE",
+ "BRING.TYPOGRAPHY.TRACKING.LOWERCASE.AVOID",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_LOWERCASE",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.UNORDERED_FRAGMENTS"
+ ],
+ "ltd": [
+ "CMOS.PUNCTUATION.COMMAS.INC_LTD.NONE"
+ ],
+ "ltd.": [
+ "CMOS.PUNCTUATION.COMMAS.CORPORATE_SUFFIX"
+ ],
+ "magazine": [
+ "CMOS.CITATIONS.S13_97.BIBLIOGRAPHY.NEWSPAPER_MAGAZINE.DATES"
+ ],
+ "mailing addresses": [
+ "CMOS.PUNCTUATION.COMMAS.ADDRESSES.MAILING_SPARING"
+ ],
+ "mailto": [
+ "HOUSE.LINKS.EMAILS.MAILTO_POLICY",
+ "HOUSE.LINKS.URLS.MAILTO.INTENT"
+ ],
+ "main page": [
+ "CMOS.CITATIONS.S13_9.URL_TO_MAIN_PAGE"
+ ],
+ "mantissa": [
+ "CMOS.NUMBERS.SCIENTIFIC.NOTATION.MANTISSA_RANGE"
+ ],
+ "manuals": [
+ "CMOS.CITATIONS.S13_3.SOURCE_MANUALS"
+ ],
+ "manuscript": [
+ "CMOS.CITATIONS.S13_6.URLS.IN_MANUSCRIPT"
+ ],
+ "manuscripts": [
+ "CMOS.CITATIONS.S13_11.NO_SHORTENERS_IN_MS",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.MANUSCRIPT_SUPERSCRIPT_OK"
+ ],
+ "many authors": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_LIST.LENGTH.POLICY"
+ ],
+ "march 3rd": [
+ "CMOS.NUMBERS.DATES.ORDINALS.AVOID"
+ ],
+ "margin consistency": [
+ "BRING.LAYOUT.MARGINS.CONSISTENT.ACROSS_SECTIONS"
],
"margin heads": [
"BRING.HEADINGS.MARGIN_HEADS.CLEAR_GUTTER",
"BRING.HEADINGS.SUBHEADS.MARGIN_HEADS.RUNNING_SHOULDERHEADS"
],
+ "marginal notes": [
+ "BRING.LAYOUT.MARGINS.NOTES.OUTSIDE_TEXTBLOCK"
+ ],
"margins": [
- "BRING.LAYOUT.PAGE.FRAME.TEXTBLOCK_BALANCE"
+ "BRING.LAYOUT.MARGINS.PROPORTION.BALANCED",
+ "BRING.LAYOUT.PAGE.FRAME.TEXTBLOCK_BALANCE",
+ "CMOS.FIGURES.MARGINS.AVOID_CLIPPING",
+ "CMOS.TABLES.WIDTH.FIT_PAGE"
+ ],
+ "markdown": [
+ "HOUSE.CODE.FENCES.CLOSE_PROPERLY"
+ ],
+ "markers": [
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.PUNCTUATION_LEVELS",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.MARKERS.PARENS",
+ "CMOS.TABLES.NOTES.ORDERED_MARKERS",
+ "HOUSE.TABLES.MISSING_DATA.CONSISTENT_MARK"
+ ],
+ "markup": [
+ "HOUSE.ACCESSIBILITY.LISTS.USE_LIST_MARKUP"
+ ],
+ "math": [
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.MINUS_SIGN"
],
"math fractions": [
"CMOS.NUMBERS.FRACTIONS.MATH.NUMERALS"
],
+ "math symbols": [
+ "CMOS.NUMBERS.S9_17.FRACTIONS.PARENS_BEFORE_SYMBOLS"
+ ],
+ "meaning": [
+ "CMOS.I18N.MEANINGFUL_TRANSLATIONS.NOT_LITERAL",
+ "HOUSE.ACCESSIBILITY.COLOR.NOT_SOLE_CONVEYOR"
+ ],
"measure": [
+ "BRING.LAYOUT.COLUMNS.COUNT.MODERATE",
+ "BRING.LAYOUT.COLUMNS.SIDEBARS.DISTINCT_MEASURE",
"BRING.LAYOUT.MEASURE.ADJUST_FOR_TYPE_SIZE",
"BRING.LAYOUT.MEASURE.CHANGE_FOR_LISTS",
"BRING.LAYOUT.MEASURE.COMFORTABLE_RANGE",
"BRING.LAYOUT.MEASURE.MULTICOLUMN_TARGETS",
"BRING.LAYOUT.MEASURE.TARGET_RANGE_CHARS",
"BRING.LAYOUT.PAGE.DENSITY.DONT_SUFFOCATE",
- "BRING.LAYOUT.TEXTBLOCK.CONSISTENT_WIDTH"
+ "BRING.LAYOUT.PARAGRAPH.INDENT.WITHIN_MEASURE",
+ "BRING.LAYOUT.PARAGRAPH.LISTS.ALIGN_WITH_BODY",
+ "BRING.LAYOUT.TEXTBLOCK.CONSISTENT_WIDTH",
+ "BRING.TYPOGRAPHY.SIZE.BODY_SIZE_MATCH_MEASURE",
+ "CMOS.LAYOUT.MEASURE.LINE_LENGTH.TARGET_RANGE",
+ "CMOS.LAYOUT.MEASURE.MAX_LINE_LENGTH",
+ "CMOS.LAYOUT.MEASURE.MIN_LINE_LENGTH",
+ "CMOS.PUNCTUATION.SPACING.DESIGN_SPECIFIED",
+ "HOUSE.LAYOUT.HTML.MEASURE.MAX_WIDTH"
],
"measure consistency": [
"BRING.LAYOUT.MEASURE.CONSISTENT_WITHIN_SECTION"
],
"measurement": [
- "CMOS.NUMBERS.UNITS.REPEATED.OMIT_REPEAT"
+ "CMOS.NUMBERS.UNITS.REPEATED.OMIT_REPEAT",
+ "HOUSE.EDITORIAL.CLARITY.DEFINE_METRICS"
],
"measurements": [
- "CMOS.NUMBERS.CONTEXTS.ALWAYS_NUMERALS"
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_NUMERAL_ITALICS",
+ "CMOS.NUMBERS.CONTEXTS.ALWAYS_NUMERALS",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.COMMON_NUMERALS",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.CONSISTENCY",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.MEASUREMENTS",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.NUMERALS"
+ ],
+ "mebi": [
+ "CMOS.NUMBERS.S9_12.BINARY_PREFIXES"
+ ],
+ "mega": [
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.LARGE"
+ ],
+ "mentions": [
+ "CMOS.CITATIONS.S13_5.NONACADEMIC.MENTIONS_OK"
+ ],
+ "metacommentary": [
+ "HOUSE.EDITORIAL.CLARITY.AVOID_METACOMMENTARY"
],
"metadata": [
- "CMOS.CITATIONS.RESEARCH.METADATA.CAPTURE_EARLY"
+ "CMOS.CITATIONS.RESEARCH.METADATA.CAPTURE_EARLY",
+ "CMOS.CITATIONS.S13_13.METADATA.CHECK_FIELDS",
+ "CMOS.CITATIONS.S13_13.TOOLS.USE_METADATA",
+ "CMOS.FRONTMATTER.NAVIGATION.METADATA",
+ "HOUSE.ACCESSIBILITY.LANGUAGE.METADATA",
+ "HOUSE.ACCESSIBILITY.PDF.TAGS.WHEN_AVAILABLE",
+ "HOUSE.EDITORIAL.STRUCTURE.METADATA.OWNER_DATE"
+ ],
+ "metrics": [
+ "BRING.TYPOGRAPHY.FAMILY.METRICS_MATCH_WHEN_MIXING",
+ "BRING.TYPOGRAPHY.SERIF.PAIR_WITH_COMPATIBLE_XHEIGHT",
+ "BRING.TYPOGRAPHY.TYPEFACE.FALLBACKS_COMPATIBLE_METRICS",
+ "HOUSE.EDITORIAL.CLAIMS.QUANTIFY_WHEN_POSSIBLE",
+ "HOUSE.EDITORIAL.CLARITY.DEFINE_METRICS"
+ ],
+ "micro": [
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.SMALL"
+ ],
+ "mid-clause": [
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AVOID_MIDCLAUSE"
+ ],
+ "mid-sentence": [
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_MID"
],
"midnight": [
"CMOS.NUMBERS.TIME.NOON_MIDNIGHT"
],
+ "milli": [
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.SMALL"
+ ],
"million": [
- "CMOS.NUMBERS.LARGE_VALUES.MILLIONS_BILLIONS"
+ "CMOS.NUMBERS.LARGE_VALUES.MILLIONS_BILLIONS",
+ "CMOS.NUMBERS.S9_26.LARGE_MONEY.MIXED",
+ "CMOS.NUMBERS.S9_9.MILLIONS_BILLIONS.GENERAL_RULE",
+ "CMOS.NUMBERS.S9_9.MIXED_NUMERAL_WORD.FRACTIONS"
],
"minimum left": [
"BRING.TYPOGRAPHY.HYPHENATION.MIN_LEFT_RIGHT"
@@ -989,58 +3829,197 @@
"minimum right": [
"BRING.TYPOGRAPHY.HYPHENATION.MIN_LEFT_RIGHT"
],
+ "minimum size": [
+ "BRING.TYPOGRAPHY.SIZE.SMALL_TEXT_MINIMUM"
+ ],
+ "minus": [
+ "CMOS.I18N.PUNCTUATION.DASHES.MINUS_SIGN"
+ ],
+ "minus sign": [
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.MINUS_SIGN"
+ ],
+ "mirrors": [
+ "HOUSE.LINKS.TEXT.MIRROR.LABEL"
+ ],
+ "misleading": [
+ "HOUSE.LINKS.TEXT.LINK_TARGET_MISMATCH"
+ ],
+ "misread": [
+ "CMOS.PUNCTUATION.QUOTES.APOSTROPHE_NOT_QUOTE"
+ ],
+ "missing data": [
+ "CMOS.CITATIONS.S13_13.METADATA.MISSING",
+ "HOUSE.TABLES.MISSING_DATA.CONSISTENT_MARK"
+ ],
+ "missing notes": [
+ "HOUSE.CITATIONS.NOTES.DEFINITIONS.REQUIRED"
+ ],
+ "missing values": [
+ "CMOS.TABLES.MISSING_VALUES.EXPLAIN"
+ ],
+ "mitigations": [
+ "HOUSE.EDITORIAL.STRUCTURE.RISKS.MITIGATIONS"
+ ],
+ "mixed categories": [
+ "CMOS.NUMBERS.S9_7.CROSS_CATEGORY.MIX_OK"
+ ],
+ "mixed forms": [
+ "CMOS.NUMBERS.S9_5.TWO_NUMBERS.SAME_CATEGORY"
+ ],
"mixed fractions": [
"CMOS.NUMBERS.FRACTIONS.MIXED.WHOLE_PLUS_FRACTION"
],
+ "mixed numbers": [
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.MEASUREMENTS",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.NUMERALS",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.SHORT_SPELLED_OUT"
+ ],
+ "mla": [
+ "CMOS.CITATIONS.S13_3.OTHER_SYSTEMS.MLA_APA"
+ ],
"monarchs": [
"CMOS.NUMBERS.NAMES.MONARCHS_POPES"
],
"money": [
"CMOS.NUMBERS.CURRENCY.LARGE_AMOUNTS",
- "CMOS.NUMBERS.CURRENCY.WORDS_VS_SYMBOLS"
+ "CMOS.NUMBERS.CURRENCY.WORDS_VS_SYMBOLS",
+ "CMOS.NUMBERS.S9_22.MONEY.SPELL_OUT_SMALL"
+ ],
+ "money format": [
+ "CMOS.NUMBERS.S9_22.MONEY.SYMBOL_OR_WORD"
],
"monospace": [
- "HOUSE.CODE.INLINE.MONO_BACKTICKS"
+ "HOUSE.CODE.INLINE.MONO_BACKTICKS",
+ "HOUSE.CODE.MONO.FONT.PREFERRED"
+ ],
+ "monospaced": [
+ "BRING.CODE.MONO_RAGGED_RIGHT",
+ "BRING.CODE.RAG.AVOID_FAKE_JUSTIFY"
+ ],
+ "month": [
+ "CMOS.CITATIONS.S13_26.JOURNAL.OMIT_MONTH_SEASON"
],
"month day year": [
"CMOS.NUMBERS.DATES.CONSISTENT_FORMAT"
],
"month-day": [
- "CMOS.NUMBERS.DATES.MONTH_DAY_STYLE"
+ "CMOS.NUMBERS.DATES.MONTH_DAY_STYLE",
+ "CMOS.NUMBERS.S9_33.MONTH_DAY.CARDINALS"
+ ],
+ "month-day-year": [
+ "CMOS.NUMBERS.S9_33.MONTH_DAY_YEAR.COMMA",
+ "CMOS.PUNCTUATION.COMMAS.DATES.MONTH_DAY_YEAR"
+ ],
+ "months": [
+ "CMOS.ABBREVIATIONS.MONTHS.ABBREV_IN_TABLES",
+ "CMOS.ABBREVIATIONS.MONTHS.SPELL_OUT_IN_TEXT"
+ ],
+ "moving targets": [
+ "HOUSE.LINKS.TEXT.STABILITY.NOTE"
],
"multi-author": [
"CMOS.HEADINGS.DIVISIONS.CHAPTERS.MULTIAUTHOR",
"CMOS.HEADINGS.MULTIAUTHOR.CHAPTER_NUMBERING"
],
+ "multi-file": [
+ "HOUSE.CODE.EXAMPLES.MULTI_FILE.SEPARATE"
+ ],
"multi-line headers": [
"BRING.TABLES.MULTI_LINE_HEADERS.AVOID"
],
"multi-page tables": [
"HOUSE.TABLES.HEADERS.REPEAT_ON_PAGEBREAK"
],
+ "multilevel lists": [
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.OUTLINE_MARKERS",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.RUNOVER_ALIGN"
+ ],
+ "multilingual": [
+ "CMOS.FRONTMATTER.LANGUAGE.NOTICE",
+ "CMOS.I18N.GLOSSARY.MULTILINGUAL",
+ "HOUSE.I18N.LANGUAGE.SWITCHES.MARK"
+ ],
+ "multipart": [
+ "CMOS.FIGURES.MULTIPART.PANEL_LABELS",
+ "CMOS.FIGURES.PANEL_ORDER.LOGICAL"
+ ],
"multiple authors": [
- "CMOS.CITATIONS.BIBLIOGRAPHY.MULTI_AUTHORS.ORDER"
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_AUTHORS.POLICY",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.MULTI_AUTHORS.ORDER",
+ "CMOS.CITATIONS.S13_107.AUTHOR_DATE.REFERENCE_LIST.MULTI_AUTHOR.ORDERING"
],
"multiple citations": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_CITATIONS.ORDER_POLICY",
"CMOS.CITATIONS.NOTES.MULTIPLE_CITATIONS.SINGLE_NOTE"
],
+ "multiple h1": [
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.SINGLE"
+ ],
"multiple punctuation": [
"CMOS.PUNCTUATION.MULTIPLE_MARKS.AVOID_STACKING"
],
+ "multiple roles": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.MULTIPLE_CONTRIBUTORS.POLICY_CONSISTENT"
+ ],
"multiple sources": [
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_SOURCES"
],
+ "multiples": [
+ "CMOS.NUMBERS.S9_2.ROUND_MULTIPLES.SPELLED_OUT"
+ ],
+ "myr": [
+ "CMOS.NUMBERS.S9_11.MYR_GYR"
+ ],
+ "n.d.": [
+ "CMOS.CITATIONS.AUTHOR_DATE.NO_DATE.POLICY"
+ ],
+ "name disambiguation": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.SUFFIXES.INCLUDE"
+ ],
"name variants": [
"CMOS.CITATIONS.BIBLIOGRAPHY.ALT_NAMES.CROSSREF"
],
+ "namely": [
+ "CMOS.PUNCTUATION.COMMAS.THAT_IS.TRAILING_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.THAT_IS_NAMELY"
+ ],
+ "names": [
+ "CMOS.ABBREVIATIONS.NAMES.INITIALS.SPACING",
+ "CMOS.BACKMATTER.INDEX.NAMES.SORTING",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.NAMES.CONSISTENT",
+ "CMOS.I18N.DIACRITICS.PRESERVE",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.NONE",
+ "HOUSE.EDITORIAL.CONSISTENCY.NAMES.SAME_FORM"
+ ],
+ "nano": [
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.SMALL"
+ ],
"navigation": [
+ "BRING.LAYOUT.PAGINATION.CLEAR_SECTION_BREAKS",
+ "CMOS.CITATIONS.S13_52.ENDNOTES.NAVIGATION_CUES",
+ "CMOS.FIGURES.LIST_OF_FIGURES.WHEN_NEEDED",
"CMOS.HEADINGS.RUNNING_HEADS.DEFINITION",
"CMOS.HEADINGS.RUNNING_HEADS.DIVISION_MATCH",
- "CMOS.HEADINGS.RUNNING_HEADS.NAVIGATION_SCOPE"
+ "CMOS.HEADINGS.RUNNING_HEADS.NAVIGATION_SCOPE",
+ "CMOS.LAYOUT.PAGINATION.RUNNING_HEADS.CONSISTENCY",
+ "HOUSE.ACCESSIBILITY.LINKS.SKIP_TO_CONTENT",
+ "HOUSE.ACCESSIBILITY.TOC.LINKED_ENTRIES"
+ ],
+ "nd": [
+ "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.ND_RD"
+ ],
+ "negative exponent": [
+ "CMOS.NUMBERS.S9_10.NEGATIVE_POWERS"
],
"negative leading": [
"BRING.LAYOUT.LEADING.NEGATIVE.AVOID_CONTINUOUS_TEXT"
],
+ "nested fractions": [
+ "CMOS.NUMBERS.S9_17.FRACTIONS.IN_NUMERATOR_DENOMINATOR"
+ ],
+ "nested lists": [
+ "HOUSE.EDITORIAL.LISTS.AVOID_DEEP_NESTING"
+ ],
"nested parentheses": [
"CMOS.PUNCTUATION.PARENS.NESTING"
],
@@ -1048,23 +4027,82 @@
"CMOS.PUNCTUATION.BRACKETS.NESTED_PARENS"
],
"nested quotes": [
+ "CMOS.I18N.QUOTES.NESTING.CONSISTENT",
"CMOS.PUNCTUATION.QUOTATION_MARKS.DOUBLE_PRIMARY_US"
],
+ "nesting": [
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.AVOID_NESTED"
+ ],
+ "never": [
+ "HOUSE.EDITORIAL.CLAIMS.AVOID_ABSOLUTES"
+ ],
+ "newspaper": [
+ "CMOS.CITATIONS.S13_97.BIBLIOGRAPHY.NEWSPAPER_MAGAZINE.DATES"
+ ],
+ "no": [
+ "CMOS.PUNCTUATION.COMMAS.INTRO_YES_NO"
+ ],
+ "no author": [
+ "CMOS.CITATIONS.AUTHOR_DATE.NO_AUTHOR.TITLE_KEY",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.NO_AUTHOR.EDITOR_AS_LEAD_WHEN_APPROPRIATE"
+ ],
+ "no bibliography": [
+ "CMOS.CITATIONS.S13_18.NO_BIBLIO.FULL_FIRST_NOTE",
+ "CMOS.CITATIONS.S13_23.NO_BIBLIO.NOTES_UP_TO_SIX"
+ ],
+ "no date": [
+ "CMOS.CITATIONS.AUTHOR_DATE.NO_DATE.POLICY"
+ ],
"non-breaking space": [
"BRING.TYPOGRAPHY.HYPHENATION.HARD_SPACES.SHORT_EXPRESSIONS"
],
+ "non-english": [
+ "CMOS.I18N.TRANSLATION.INDICATE"
+ ],
+ "non-goals": [
+ "HOUSE.EDITORIAL.STRUCTURE.SCOPE.STATED"
+ ],
"non-us dollar": [
"CMOS.NUMBERS.CURRENCY.NON_US.DISAMBIGUATE"
],
+ "nonacademic": [
+ "CMOS.CITATIONS.S13_5.NONACADEMIC.MENTIONS_OK"
+ ],
"nonbreaking space": [
"CMOS.NUMBERS.DEGRADED.HARD_WRAP_UNITS"
],
+ "nonbreaking spaces": [
+ "CMOS.PUNCTUATION.SPACING.NONBREAKING"
+ ],
+ "nonrestrictive": [
+ "CMOS.PUNCTUATION.COMMAS.APPOSITIVES.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING_NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_MID_END",
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_NONRESTRICTIVE"
+ ],
"nonrestrictive clause": [
"CMOS.PUNCTUATION.COMMAS.NONRESTRICTIVE.SET_OFF"
],
+ "nonround numbers": [
+ "CMOS.NUMBERS.S9_2.NONROUND.ABOVE_ONE_HUNDRED",
+ "CMOS.NUMBERS.S9_4.NONROUND.LARGE_NUMERALS"
+ ],
"noon": [
"CMOS.NUMBERS.TIME.NOON_MIDNIGHT"
],
+ "normalization": [
+ "CMOS.CITATIONS.S13_90.TITLE_PUNCTUATION.CHANGES.POLICY_LIMITED"
+ ],
+ "not phrase": [
+ "CMOS.PUNCTUATION.COMMAS.NOT_PHRASES"
+ ],
+ "not phrases": [
+ "CMOS.PUNCTUATION.COMMAS.NOT_PHRASE"
+ ],
+ "notation": [
+ "HOUSE.CODE.LANGUAGE.NOTATION.CONSISTENT"
+ ],
"note consolidation": [
"CMOS.CITATIONS.NOTES.MULTIPLE_CITATIONS.SINGLE_NOTE"
],
@@ -1076,18 +4114,66 @@
"CMOS.CITATIONS.NOTES.NOTE_MARKERS.SUPERSCRIPT_TEXT"
],
"note numbers": [
- "CMOS.CITATIONS.NOTES.NOTE_MARKERS.SEQUENCE_CONTINUOUS"
+ "CMOS.CITATIONS.NOTES.NOTE_MARKERS.SEQUENCE_CONTINUOUS",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.TEXT_SUPERSCRIPT"
+ ],
+ "note order": [
+ "HOUSE.CITATIONS.NOTES.IBID.AVOID"
],
"note processing": [
"CMOS.CITATIONS.IBID.MINIMIZE_OR_AVOID"
],
+ "note streams": [
+ "CMOS.CITATIONS.S13_56.NOTES.DUAL_STREAMS.DISTINCT_LABELS"
+ ],
"notes": [
- "CMOS.CITATIONS.NOTES_BIBLIO.BIBLIOGRAPHY.INCLUDE_WHEN_USED"
+ "CMOS.BACKMATTER.NOTES.BLOCKS.CONSISTENT",
+ "CMOS.BACKMATTER.NOTES.CITATIONS.COMPLETE",
+ "CMOS.BACKMATTER.NOTES.NUMBERING.SEQUENTIAL",
+ "CMOS.BACKMATTER.NOTES.ORDER.FOLLOW_TEXT",
+ "CMOS.BACKMATTER.NOTES.REFERENCE.MATCH",
+ "CMOS.CITATIONS.NOTES_BIBLIO.BIBLIOGRAPHY.INCLUDE_WHEN_USED",
+ "CMOS.CITATIONS.S13_18.NAMES.NORMAL_ORDER",
+ "CMOS.CITATIONS.S13_18.NOTES.SENTENCE_STYLE",
+ "CMOS.CITATIONS.S13_18.NOTES_BIBLIO.OVERVIEW",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.NOTES",
+ "CMOS.CITATIONS.S13_2.NOTES_SYSTEM",
+ "CMOS.CITATIONS.S13_20.NOTES.PAGE_SPECIFIC",
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.PAGE_IN_NOTES",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.NOTES_ET_AL",
+ "CMOS.CITATIONS.S13_23.TWO_AUTHORS.NOTES_LIST_BOTH",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.NOTES_PAGE_LOCATOR",
+ "CMOS.CITATIONS.S13_26.JOURNAL.NOTES_PAGE_SPECIFIC",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.NOTES_FULL_SIZE",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.NOTES_PERIOD",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.NOTES_FULL_SIZE",
+ "CMOS.CITATIONS.S13_54.AUTHOR_DATE.NOTES.COMMENTARY_ONLY",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.NOTES",
+ "CMOS.TABLES.MISSING_VALUES.EXPLAIN",
+ "HOUSE.TABLES.SOURCE.NOTES"
],
"notes and bibliography": [
"CMOS.CITATIONS.NOTES_BIBLIO.FIRST_NOTE.FULL_REFERENCE",
"CMOS.CITATIONS.SYSTEM.CONSISTENT_CHOICE"
],
+ "notes-biblio": [
+ "CMOS.FRONTMATTER.CITATION_STYLE.DECLARED"
+ ],
+ "notes-bibliography": [
+ "CMOS.CITATIONS.S13_2.SYSTEMS.TWO_TYPES"
+ ],
+ "notices": [
+ "CMOS.FRONTMATTER.COPYRIGHT.NOTICES.PRESENT"
+ ],
+ "noun abbreviations": [
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.NOUN_FORMS"
+ ],
+ "nth degree": [
+ "CMOS.NUMBERS.S9_6.NTH_DEGREE.ITALIC_N"
+ ],
+ "number": [
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.VOLUMES_ISSUES"
+ ],
"number grouping": [
"CMOS.NUMBERS.GROUPING.THOUSANDS_SEPARATOR"
],
@@ -1095,13 +4181,33 @@
"CMOS.NUMBERS.RULE_SELECTION.GENERAL_OR_ALTERNATIVE"
],
"number unit": [
- "BRING.TYPOGRAPHY.HYPHENATION.HARD_SPACES.SHORT_EXPRESSIONS"
+ "BRING.TYPOGRAPHY.HYPHENATION.HARD_SPACES.SHORT_EXPRESSIONS",
+ "CMOS.NUMBERS.UNITS.SPACE_BETWEEN_NUMBER_UNIT"
],
"numbered lists": [
"CMOS.NUMBERS.LISTS.OUTLINE.NUMERAL_STYLE"
],
+ "numbering": [
+ "CMOS.BACKMATTER.APPENDIX.NUMBERING.SEQUENTIAL",
+ "CMOS.BACKMATTER.NOTES.NUMBERING.SEQUENTIAL",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SEPARATE_SYSTEMS",
+ "CMOS.CITATIONS.S13_47.NOTES.SYSTEMS.DONT_MIX",
+ "CMOS.CITATIONS.S13_56.NOTES.DUAL_STREAMS.DISTINCT_LABELS",
+ "CMOS.FIGURES.CAPTION.NUMBER.MATCH_LABEL",
+ "CMOS.FIGURES.NUMBERING.SEQUENTIAL",
+ "CMOS.LAYOUT.FOOTNOTES.SEQUENCE",
+ "CMOS.LAYOUT.PAGINATION.PAGE_SEQUENCE.CONTINUITY",
+ "CMOS.PUNCTUATION.LISTS.NUMERALS_ONLY_IF_NEEDED"
+ ],
+ "numbering gaps": [
+ "BRING.HEADINGS.NUMBERING.NO_GAPS"
+ ],
+ "numbering punctuation": [
+ "BRING.HEADINGS.NUMBERING.PUNCTUATION.CONSISTENT"
+ ],
"numbers": [
- "BRING.TYPOGRAPHY.NUMBER_STRINGS.SPACE_FOR_READABILITY"
+ "BRING.TYPOGRAPHY.NUMBER_STRINGS.SPACE_FOR_READABILITY",
+ "HOUSE.EDITORIAL.REVIEW.FACT_CHECK"
],
"numeral": [
"CMOS.NUMBERS.SENTENCE_START.AVOID_NUMERAL"
@@ -1109,18 +4215,43 @@
"numeral normalization": [
"CMOS.NUMBERS.DEGRADED.NUMERAL_NORMALIZATION"
],
+ "numeral style": [
+ "BRING.TYPOGRAPHY.NUMERALS.CONSISTENT_STYLE_WITHIN_SECTION"
+ ],
"numerals": [
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_NUMERAL_ITALICS",
+ "BRING.TYPOGRAPHY.NUMERALS.OLDSTYLE_FOR_TEXT",
"CMOS.NUMBERS.CONSISTENCY.MIXED_FORMS.AVOID",
"CMOS.NUMBERS.DECIMALS.NUMERALS",
"CMOS.NUMBERS.DENSE_CONTEXT.USE_NUMERALS",
+ "CMOS.NUMBERS.S9_1.OVERVIEW.FACTORS",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.COMMON_NUMERALS",
+ "CMOS.NUMBERS.S9_18.SCIENTIFIC_CONTEXT.NUMERALS",
+ "CMOS.NUMBERS.S9_20.PERCENT.NUMERALS",
+ "CMOS.NUMBERS.S9_21.DECIMALS.NUMERALS",
+ "CMOS.NUMBERS.S9_31.YEAR_STANDALONE",
+ "CMOS.NUMBERS.S9_7.CATEGORY_TRIGGER",
+ "CMOS.NUMBERS.S9_8.DATES.NUMERALS",
+ "CMOS.NUMBERS.S9_8.PERCENT.NUMERALS",
+ "CMOS.NUMBERS.S9_8.SYMBOLS.NUMERALS",
"CMOS.NUMBERS.SPELLING.ONE_TO_ONE_HUNDRED.DEFAULT",
- "CMOS.NUMBERS.TIME.GENERAL_NUMERALS"
+ "CMOS.NUMBERS.TIME.GENERAL_NUMERALS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.ORDERED_MARKERS",
+ "HOUSE.I18N.NUMBERS.DIGIT_SYSTEM.CONSISTENT"
+ ],
+ "numeric alignment": [
+ "CMOS.TABLES.ALIGNMENT.NUMERIC_DECIMAL",
+ "HOUSE.TABLES.NUMERIC.ALIGN_DECIMALS"
],
"numeric columns": [
"BRING.TABLES.COLUMN_ALIGNMENT.CONSISTENT",
"BRING.TABLES.NUMERIC_PRECISION.CONSISTENT",
+ "CMOS.TABLES.PRECISION.CONSISTENT",
"HOUSE.TABLES.ALIGNMENT.DECIMALS"
],
+ "numeric compounds": [
+ "CMOS.PUNCTUATION.HYPHENS.NUMERIC_COMPOUNDS"
+ ],
"numeric dates": [
"CMOS.NUMBERS.DATES.ALL_NUMERAL"
],
@@ -1130,6 +4261,9 @@
"numeric range": [
"CMOS.NUMBERS.RANGES.EN_DASH.USE"
],
+ "oblique": [
+ "BRING.TYPOGRAPHY.FAMILY.TRUE_ITALICS"
+ ],
"ocr": [
"BRING.HEADINGS.DEGRADED.INFER_STRUCTURE",
"BRING.TABLES.DEGRADED.REBUILD_COLUMNS",
@@ -1137,18 +4271,64 @@
"CMOS.NUMBERS.DEGRADED.NUMERAL_NORMALIZATION",
"CMOS.PUNCTUATION.DEGRADED.EXTRA_SPACES.AFTER_PUNCT"
],
+ "octal": [
+ "CMOS.NUMBERS.S9_12.BASE_INDICATOR",
+ "CMOS.NUMBERS.S9_12.BASE_PREFIXES"
+ ],
+ "odd page": [
+ "BRING.LAYOUT.PAGE.ODD_EVEN.CONSISTENT"
+ ],
+ "oh": [
+ "CMOS.PUNCTUATION.COMMAS.INTRO_OH_AH"
+ ],
+ "oldstyle": [
+ "BRING.TYPOGRAPHY.NUMERALS.MIXED_STYLE_AVOID"
+ ],
+ "oldstyle figures": [
+ "BRING.TYPOGRAPHY.NUMERALS.OLDSTYLE_FOR_TEXT"
+ ],
"omission": [
- "CMOS.PUNCTUATION.ELLIPSIS.FORMAT.CONSISTENT"
+ "CMOS.PUNCTUATION.ELLIPSIS.FORMAT.CONSISTENT",
+ "CMOS.PUNCTUATION.ELLIPSIS.USE_CASES"
+ ],
+ "omissions": [
+ "CMOS.PUNCTUATION.DASHES.TWO_EM.OMISSIONS",
+ "HOUSE.CODE.BLOCKS.ELISION.MARKED"
+ ],
+ "onboarding": [
+ "HOUSE.LINKS.AUTO.INVITE_LINKS.AVOID",
+ "HOUSE.LINKS.URLS.AVOID.ONE_TIME_INVITES"
+ ],
+ "one hundred": [
+ "CMOS.NUMBERS.S9_2.GENERAL_RULE.ZERO_TO_ONE_HUNDRED"
+ ],
+ "one space": [
+ "CMOS.PUNCTUATION.SPACING.ONE_SPACE_AFTER_COLON",
+ "CMOS.PUNCTUATION.SPACING.ONE_SPACE_SENTENCES"
],
"one through one hundred": [
"CMOS.NUMBERS.SPELLING.ONE_TO_ONE_HUNDRED.DEFAULT"
],
+ "one-off abbreviations": [
+ "CMOS.ABBREVIATIONS.AVOID_ONE_OFFS"
+ ],
+ "ongoing events": [
+ "CMOS.CITATIONS.S13_17.PRESERVE.CRISIS_SOURCES"
+ ],
+ "online": [
+ "CMOS.CITATIONS.S13_14.ONLINE.URL_INDICATOR"
+ ],
"online source": [
"CMOS.CITATIONS.ONLINE.ACCESS_DATE.WHEN_NEEDED"
],
"online sources": [
+ "CMOS.BACKMATTER.REFERENCES.ACCESS_DATES.WHEN_NEEDED",
"CMOS.CITATIONS.ONLINE.URLS.STABLE",
- "CMOS.CITATIONS.ONLINE.VERSION.CITE_RIGHT_VERSION"
+ "CMOS.CITATIONS.ONLINE.VERSION.CITE_RIGHT_VERSION",
+ "CMOS.CITATIONS.S13_100.BIBLIOGRAPHY.ONLINE.SOURCE_STABILITY"
+ ],
+ "op. cit.": [
+ "CMOS.CITATIONS.S13_40.SHORT_FORM.AVOID_OP_CIT"
],
"open compounds": [
"CMOS.PUNCTUATION.HYPHENATION.COMPOUND_DEFINITION"
@@ -1156,33 +4336,105 @@
"opening paragraph": [
"BRING.LAYOUT.PARAGRAPH.OPENING_FLUSH_LEFT"
],
+ "opening spread": [
+ "BRING.LAYOUT.PAGE.OPENING_SPREAD.RULE"
+ ],
+ "opinions": [
+ "HOUSE.EDITORIAL.CLAIMS.DISTINGUISH_FACT_OPINION"
+ ],
"opsec": [
- "HOUSE.LINKS.DISALLOW.FILE_URIS"
+ "HOUSE.LINKS.AUTO.INTERNAL_HOSTNAMES.AVOID",
+ "HOUSE.LINKS.DISALLOW.FILE_URIS",
+ "HOUSE.LINKS.URLS.AVOID.INTERNAL_HOSTNAMES"
+ ],
+ "optical size": [
+ "BRING.TYPOGRAPHY.TYPEFACE.OPTICAL_SIZES_USE"
+ ],
+ "or": [
+ "CMOS.PUNCTUATION.COMMAS.EXPLANATORY_ALTERNATIVES"
+ ],
+ "order": [
+ "CMOS.FRONTMATTER.TOC.ORDER.MATCH_BODY",
+ "CMOS.LAYOUT.FOOTNOTES.SEQUENCE"
+ ],
+ "ordered lists": [
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.ORDERED_MARKERS",
+ "HOUSE.EDITORIAL.LISTS.ORDERED_ONLY_WHEN_ORDERED"
],
"ordering": [
"BRING.TABLES.ORDER.LOGICAL",
- "CMOS.CITATIONS.BIBLIOGRAPHY.SAME_AUTHOR.ORDER"
+ "CMOS.BACKMATTER.NOTES.ORDER.FOLLOW_TEXT",
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_CITATIONS.ORDER_POLICY",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SAME_AUTHOR.ORDER_POLICY",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.MULTIPLE_CONTRIBUTORS.POLICY_CONSISTENT",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.SAME_AUTHOR.ORDER",
+ "CMOS.CITATIONS.S13_64.BIBLIOGRAPHY.SUBSECTIONS.CLEAR_HEADINGS"
],
"ordinal": [
"CMOS.NUMBERS.ORDINALS.SUFFIX.CORRECT"
],
+ "ordinal dates": [
+ "CMOS.NUMBERS.DATES.ORDINALS.AVOID"
+ ],
+ "ordinal suffix": [
+ "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.ND_RD"
+ ],
"ordinal titles": [
"CMOS.NUMBERS.NAMES.MONARCHS_POPES"
],
"ordinals": [
- "CMOS.NUMBERS.CENTURIES.SPELLED_OUT"
+ "CMOS.NUMBERS.CENTURIES.SPELLED_OUT",
+ "CMOS.NUMBERS.ORDINALS.CONSISTENT_FORM",
+ "CMOS.NUMBERS.S9_33.DAY_WITHOUT_MONTH.ORDINAL",
+ "CMOS.NUMBERS.S9_34.CENTURIES.ORDINAL_LOWERCASE",
+ "CMOS.NUMBERS.S9_6.ORDINALS.RULE_PARALLEL",
+ "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.NO_SUPERSCRIPT"
+ ],
+ "organization": [
+ "CMOS.ABBREVIATIONS.ORGANIZATIONS.SPELL_OUT_FIRST",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.CORPORATE_AUTHORS.USE_AS_AUTHOR"
+ ],
+ "orientation": [
+ "BRING.HEADINGS.SECTION_OPENING.PARAGRAPH_REQUIRED",
+ "CMOS.FIGURES.ORIENTATION.CONSISTENT"
],
"original publication": [
"CMOS.CITATIONS.NOTES.SOURCE_NOTES.REPRINTS"
],
"orphan": [
- "BRING.LAYOUT.PAGINATION.ORPHANS_AVOID"
+ "BRING.LAYOUT.PAGINATION.ORPHANS_AVOID",
+ "BRING.LAYOUT.PARAGRAPH.AVOID_WIDOW_START",
+ "CMOS.LAYOUT.PAGINATION.ORPHANS.AVOID"
+ ],
+ "orphans": [
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_BEFORE_LAST_LINE",
+ "HOUSE.LAYOUT.PAGINATION.LISTS.AVOID_LONELY_ITEM"
+ ],
+ "outer margin": [
+ "BRING.LAYOUT.MARGINS.OUTER_LARGER_THAN_INNER"
],
"outline": [
- "CMOS.NUMBERS.LISTS.OUTLINE.NUMERAL_STYLE"
+ "CMOS.NUMBERS.LISTS.OUTLINE.NUMERAL_STYLE",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.LONG_OR_MULTI"
+ ],
+ "outline levels": [
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.PUNCTUATION_LEVELS"
+ ],
+ "outline markers": [
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.OUTLINE_MARKERS"
+ ],
+ "outline numerals": [
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.MULTI_DIGIT_ALIGN"
+ ],
+ "output": [
+ "HOUSE.CODE.BLOCKS.DETERMINISTIC_OUTPUT",
+ "HOUSE.CODE.BLOCKS.ERROR_OUTPUT.LABELED",
+ "HOUSE.CODE.OUTPUT.TRUNCATION.LABELED"
],
"overflow": [
"BRING.LAYOUT.MEASURE.CODE_BLOCKS.WRAP_POLICY",
+ "CMOS.TABLES.WIDTH.FIT_PAGE",
+ "HOUSE.CODE.BLOCKS.LONG_LINES.AVOID",
"HOUSE.LAYOUT.OVERFLOW.OVERFULL_LINES.REPORT"
],
"overflow policy": [
@@ -1191,49 +4443,175 @@
"overfull": [
"HOUSE.LAYOUT.OVERFLOW.OVERFULL_LINES.REPORT"
],
+ "overlap": [
+ "CMOS.FIGURES.LABELS.AVOID_OVERLAP"
+ ],
"overlong notes": [
"CMOS.CITATIONS.NOTES.AVOID_OVERLONG"
],
+ "owner": [
+ "CMOS.FRONTMATTER.CONTACT.OWNERSHIP",
+ "HOUSE.EDITORIAL.STRUCTURE.METADATA.OWNER_DATE"
+ ],
+ "owners": [
+ "HOUSE.EDITORIAL.STRUCTURE.ACTION_ITEMS.EXPLICIT"
+ ],
"oxford comma": [
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.REQUIRED",
"CMOS.PUNCTUATION.COMMAS.SERIAL_COMMA.DEFAULT"
],
+ "p.m.": [
+ "CMOS.ABBREVIATIONS.TIME.AM_PM.FORM",
+ "CMOS.NUMBERS.TIME.AM_PM.CONSISTENT_SPACING"
+ ],
+ "padding": [
+ "HOUSE.LAYOUT.HTML.GUTTERS.MIN_PADDING"
+ ],
+ "page": [
+ "CMOS.CITATIONS.S13_110.AUTHOR_DATE.JOURNAL_ARTICLES.CORE_FIELDS",
+ "CMOS.NUMBERS.S9_29.PERIODICALS.OMIT_WORDS"
+ ],
+ "page balance": [
+ "BRING.LAYOUT.PAGE.WHITE_SPACE.DISTRIBUTION"
+ ],
+ "page bottom": [
+ "CMOS.LAYOUT.FOOTNOTES.PLACEMENT",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.AVOID_BOTTOM_OF_PAGE"
+ ],
"page break": [
"BRING.LAYOUT.HYPHENATION.AVOID_NEAR_INTERRUPTION",
"BRING.LAYOUT.PAGINATION.ORPHANS_AVOID",
"BRING.LAYOUT.PAGINATION.WIDOWS_AVOID",
- "CMOS.CITATIONS.NOTES.FOOTNOTES.PAGE_BREAKS"
+ "CMOS.CITATIONS.NOTES.FOOTNOTES.PAGE_BREAKS",
+ "CMOS.LAYOUT.PAGINATION.ORPHANS.AVOID",
+ "CMOS.LAYOUT.PAGINATION.PAGE_BREAKS.BEFORE_PARTS",
+ "CMOS.LAYOUT.PAGINATION.WIDOWS.AVOID"
+ ],
+ "page breaks": [
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_AFTER_HEADING",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_IN_BLOCK_QUOTES",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_IN_EQUATIONS",
+ "BRING.LAYOUT.PAGINATION.AVOID_EXCESS_WHITE_SPACE",
+ "BRING.LAYOUT.PAGINATION.AVOID_LONELY_LINE_IN_LISTS",
+ "BRING.LAYOUT.PAGINATION.AVOID_STRANDED_CAPTIONS",
+ "CMOS.BACKMATTER.APPENDIX.START_ON_NEW_PAGE",
+ "CMOS.FIGURES.PLACEMENT.AVOID_SPLIT",
+ "CMOS.TABLES.SPLITS.AVOID_ROW_BREAKS"
],
"page density": [
"BRING.LAYOUT.PAGE.DENSITY.DONT_SUFFOCATE"
],
+ "page edge": [
+ "BRING.LAYOUT.MARGINS.AVOID_CROWDING"
+ ],
+ "page end": [
+ "BRING.LAYOUT.PARAGRAPH.AVOID_WIDOW_END",
+ "CMOS.LAYOUT.PAGINATION.AVOID_SINGLE_LINE_ENDING"
+ ],
"page headers": [
"CMOS.HEADINGS.RUNNING_HEADS.DEFINITION"
],
+ "page locator": [
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.NOTES_PAGE_LOCATOR"
+ ],
"page number": [
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.PARENTHETICAL",
"CMOS.CITATIONS.NOTES.QUOTE_IN_NOTE.LOCATOR",
- "CMOS.CITATIONS.QUOTATIONS.LOCATORS.PAGE_REQUIRED"
+ "CMOS.CITATIONS.QUOTATIONS.LOCATORS.PAGE_REQUIRED",
+ "CMOS.CITATIONS.S13_39.IBID.LOCATOR_REQUIRED"
],
"page numbers": [
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.LOCATORS",
+ "CMOS.CITATIONS.S13_20.BIBLIO.BOOKS.NO_PAGES",
+ "CMOS.CITATIONS.S13_20.NOTES.PAGE_SPECIFIC",
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.PAGE_IN_NOTES",
+ "CMOS.CITATIONS.S13_26.JOURNAL.NOTES_PAGE_SPECIFIC",
+ "CMOS.CITATIONS.S13_26.JOURNAL.PAGE_COLON",
+ "CMOS.FRONTMATTER.TOC.PAGE_NUMBERS.MATCH",
+ "CMOS.LAYOUT.PAGINATION.PAGE_NUMBERS.POSITION",
+ "CMOS.LAYOUT.PAGINATION.PAGE_NUMBERS.STYLE",
"CMOS.NUMBERS.PERIODICALS.VOLUME_ISSUE",
"CMOS.NUMBERS.REFERENCES.PAGE_CHAPTER_FIGURE"
],
+ "page proportion": [
+ "BRING.LAYOUT.PAGE.SHAPE.PROPORTIONATE"
+ ],
"page range": [
"CMOS.CITATIONS.NOTES.CHAPTER_IN_EDITED_BOOK",
"CMOS.CITATIONS.NOTES.JOURNAL.ARTICLE_ELEMENTS",
+ "CMOS.CITATIONS.S13_20.BIBLIO.PAGE_RANGE",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.BIBLIO_NO_PAGE_RANGE",
+ "CMOS.CITATIONS.S13_26.JOURNAL.BIBLIO_PAGE_RANGE",
+ "CMOS.CITATIONS.S13_95.BIBLIOGRAPHY.CHAPTERS.IN_EDITED_COLLECTIONS",
"CMOS.NUMBERS.INCLUSIVE_RANGES.PAGE_NUMBERS.SHORTEN",
"CMOS.PUNCTUATION.DASHES.EN_DASH.RANGES"
],
+ "page ranges": [
+ "CMOS.BACKMATTER.INDEX.PAGE_RANGES.STANDARD",
+ "CMOS.CITATIONS.S13_20.PAGE_RANGE.EN_DASH"
+ ],
+ "page sequence": [
+ "CMOS.LAYOUT.PAGINATION.PAGE_SEQUENCE.CONTINUITY"
+ ],
+ "page start": [
+ "BRING.LAYOUT.PARAGRAPH.AVOID_WIDOW_START"
+ ],
+ "page top": [
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.AVOID_TOP_OF_PAGE"
+ ],
+ "pages": [
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.PAGES"
+ ],
"pagination": [
+ "BRING.LAYOUT.PAGE.BLANKS.INTENTIONAL",
+ "CMOS.LAYOUT.PAGINATION.FACING_PAGES.BLANKS",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.KEEP_WITH_TEXT",
+ "CMOS.LAYOUT.PAGINATION.PAGE_NUMBERS.POSITION",
"HOUSE.HEADINGS.KEEPS.AVOID_STRANDED",
- "HOUSE.LAYOUT.PAGINATION.KEEP_WITH_NEXT.HEADINGS"
+ "HOUSE.LAYOUT.PAGINATION.CAPTIONS.KEEP_WITH_CONTENT",
+ "HOUSE.LAYOUT.PAGINATION.HEADINGS.NO_ADJACENT",
+ "HOUSE.LAYOUT.PAGINATION.KEEP_WITH_NEXT.HEADINGS",
+ "HOUSE.LAYOUT.PAGINATION.LISTS.AVOID_LONELY_ITEM",
+ "HOUSE.LAYOUT.PAGINATION.LISTS.KEEP_INTRO",
+ "HOUSE.LAYOUT.PAGINATION.RUNT_FINAL_PAGE"
+ ],
+ "paired clauses": [
+ "CMOS.PUNCTUATION.COMMAS.THE_MORE_THE_MORE"
+ ],
+ "paired commas": [
+ "CMOS.PUNCTUATION.COMMAS.PAIRS.SECOND_REQUIRED"
+ ],
+ "paired elements": [
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.PAIR_LAST_ITEM"
+ ],
+ "paired items": [
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.PAIR_WITH_AND"
+ ],
+ "pairing": [
+ "BRING.TYPOGRAPHY.CONTRAST.AVOID_EXTREME_MIX",
+ "BRING.TYPOGRAPHY.CONTRAST.FONT_PAIRING_MATCH",
+ "BRING.TYPOGRAPHY.SERIF.PAIR_WITH_COMPATIBLE_XHEIGHT",
+ "BRING.TYPOGRAPHY.SERIF.SERIF_SANS_BALANCE",
+ "BRING.TYPOGRAPHY.SERIF.STROKE_CONTRAST_COMPATIBLE",
+ "BRING.TYPOGRAPHY.TYPEFACE.SIMILAR_FACES_AVOID"
],
"pairs": [
"BRING.TYPOGRAPHY.KERNING.CONSISTENT_OR_NONE"
],
+ "palette": [
+ "CMOS.FIGURES.COLOR.PALETTE.CONSISTENT"
+ ],
+ "panel labels": [
+ "CMOS.FIGURES.MULTIPART.PANEL_LABELS"
+ ],
+ "panel order": [
+ "CMOS.FIGURES.PANEL_ORDER.LOGICAL"
+ ],
"paragraph": [
- "BRING.LAYOUT.PAGINATION.WIDOWS_AVOID"
+ "BRING.LAYOUT.PAGINATION.WIDOWS_AVOID",
+ "BRING.TYPOGRAPHY.NUMERALS.MIXED_STYLE_AVOID",
+ "CMOS.LAYOUT.PAGINATION.ORPHANS.AVOID",
+ "CMOS.LAYOUT.PAGINATION.WIDOWS.AVOID"
],
"paragraph breaks": [
"BRING.LAYOUT.PARAGRAPH.BLANK_LINES.SPARING"
@@ -1241,53 +4619,192 @@
"paragraph continuity": [
"BRING.LAYOUT.PAGINATION.ORPHANS_AVOID"
],
+ "paragraph format": [
+ "CMOS.PUNCTUATION.LISTS.AVOID_VERTICAL_FOR_LONG_SENTENCES"
+ ],
"paragraph indent": [
- "BRING.LAYOUT.PARAGRAPH.INDENT_AFTER_FIRST"
+ "BRING.LAYOUT.PARAGRAPH.INDENT_AFTER_FIRST",
+ "CMOS.LAYOUT.PARAGRAPHS.INDENT_POLICY"
],
"paragraph spacing": [
- "BRING.LAYOUT.PARAGRAPH.INDENT_OR_SPACE_NOT_BOTH"
+ "BRING.LAYOUT.PARAGRAPH.INDENT_OR_SPACE_NOT_BOTH",
+ "CMOS.LAYOUT.PARAGRAPHS.SPACING_POLICY",
+ "HOUSE.LAYOUT.MD.BLANK_LINES.SPARING"
],
"paragraphing": [
"CMOS.CITATIONS.NOTES.LONG_NOTES.PARAGRAPHING"
],
+ "paragraphs": [
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_BEFORE_LAST_LINE",
+ "BRING.TYPOGRAPHY.BOLD.AVOID_LONG_PASSAGES",
+ "BRING.TYPOGRAPHY.ITALICS.LONG_SPANS_AVOID",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.SECTIONS_PARAS_LINES",
+ "HOUSE.EDITORIAL.CLARITY.ONE_IDEA_PER_PARAGRAPH"
+ ],
+ "parallel grammar": [
+ "BRING.HEADINGS.SUBHEADS.PARALLEL_GRAMMAR"
+ ],
"parallel structure": [
- "CMOS.PUNCTUATION.HYPHENATION.SUSPENDED"
+ "CMOS.PUNCTUATION.HYPHENATION.SUSPENDED",
+ "HOUSE.EDITORIAL.LISTS.PARALLEL_STRUCTURE"
+ ],
+ "parallelism": [
+ "CMOS.PUNCTUATION.LISTS.PARALLEL_ELEMENTS"
],
"paratext": [
"BRING.HEADINGS.RELATED_ELEMENTS.COHERENT"
],
"parentheses": [
+ "CMOS.NUMBERS.S9_17.FRACTIONS.PARENS_BEFORE_SYMBOLS",
+ "CMOS.NUMBERS.S9_27.CURRENCY_YEAR.PARENS_NO_SPACE",
+ "CMOS.PUNCTUATION.COMMAS.IE_EG.PARENS",
+ "CMOS.PUNCTUATION.COMMAS.PARENS.TRAILING",
+ "CMOS.PUNCTUATION.COMMAS.PARENS_BRACKETS.AFTER_CLOSING",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_HEAVY",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.MARKERS.PARENS",
+ "CMOS.PUNCTUATION.PARENS.PUNCTUATION_PLACEMENT",
"CMOS.PUNCTUATION.PARENS.USE",
"CMOS.PUNCTUATION.PARENS_BRACKETS.BALANCE",
- "CMOS.PUNCTUATION.PERIODS.WITH_PARENS"
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.LINE_ALONE",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.MATCH_SURROUNDING",
+ "CMOS.PUNCTUATION.PERIODS.WITH_PARENS",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.SURROUNDING"
],
"parenthetical": [
- "CMOS.PUNCTUATION.COMMAS.NONRESTRICTIVE.SET_OFF"
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_CITATIONS.ORDER_POLICY",
+ "CMOS.CITATIONS.S13_2.AUTHOR_DATE_SYSTEM",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL.MID_END",
+ "CMOS.PUNCTUATION.COMMAS.NONRESTRICTIVE.SET_OFF",
+ "CMOS.PUNCTUATION.COMMAS.PAIRS.SECOND_REQUIRED",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICALS.SLIGHT_BREAK",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_ELEMENTS",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_HEAVY",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.ALTERNATIVE_TO_PARENS",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.SPARE_USE",
+ "HOUSE.CITATIONS.AUTHOR_DATE.PAREN_YEAR_ONLY"
+ ],
+ "parenthetical sentences": [
+ "CMOS.PUNCTUATION.PARENS.AVOID_MULTIPLE_SENTENCES"
+ ],
+ "part": [
+ "BRING.HEADINGS.NUMBERING.PREFIXES.CONSISTENT"
+ ],
+ "part break": [
+ "CMOS.LAYOUT.PAGINATION.PAGE_BREAKS.BEFORE_PARTS"
+ ],
+ "participial phrase": [
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_INTRO",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_LINKING_VERB",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_MID_END"
],
"participial phrases": [
- "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_PHRASES"
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL.LINKING_VERB",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_PHRASES",
+ "CMOS.PUNCTUATION.COMMAS.PHRASE_PLUS_CONJUNCTION"
+ ],
+ "particles": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.PARTICLES.CONSISTENT_FORMAT",
+ "CMOS.CITATIONS.S13_71.BIBLIOGRAPHY.ALPHABETIZATION.PREFIXES_POLICY"
+ ],
+ "parts": [
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.CHAPTERS_PARTS"
+ ],
+ "passages": [
+ "BRING.TYPOGRAPHY.WEIGHT.BOLD_IN_LONG_PASSAGES_AVOID"
+ ],
+ "password reset": [
+ "HOUSE.LINKS.AUTO.PASSWORD_RESET.AVOID",
+ "HOUSE.LINKS.URLS.AVOID.PASSWORD_RESET"
+ ],
+ "path": [
+ "HOUSE.CODE.EXAMPLES.FILE_PATH.LABEL"
+ ],
+ "paths": [
+ "HOUSE.CODE.BLOCKS.NO_PERSONAL_PATHS"
+ ],
+ "paywall": [
+ "CMOS.CITATIONS.S13_8.SUBSCRIPTION_URLS"
+ ],
+ "pdf": [
+ "CMOS.CITATIONS.S13_14.SAME_URL.FORMATS",
+ "CMOS.FIGURES.FORMAT.VECTOR_WHEN_POSSIBLE"
+ ],
+ "pdf bookmarks": [
+ "HOUSE.ACCESSIBILITY.NAVIGATION.PDF_BOOKMARKS"
+ ],
+ "pence": [
+ "CMOS.NUMBERS.S9_24.BRITISH.PENCE_SYMBOL"
],
"percent": [
"CMOS.NUMBERS.NUMERALS.MEASUREMENTS.UNITS",
- "CMOS.NUMBERS.PERCENTAGES.NUMERALS"
+ "CMOS.NUMBERS.PERCENTAGES.NUMERALS",
+ "CMOS.NUMBERS.PERCENTAGES.SYMBOL_OR_WORD.CONSISTENT",
+ "CMOS.NUMBERS.S9_18.NO_SPACE.DEGREE_PERCENT_PRIME",
+ "CMOS.NUMBERS.S9_20.PERCENT.WORD_VS_SYMBOL",
+ "CMOS.NUMBERS.S9_20.PERCENT_VS_PERCENTAGE",
+ "CMOS.NUMBERS.S9_8.PERCENT.NUMERALS"
+ ],
+ "percent ranges": [
+ "CMOS.NUMBERS.S9_20.PERCENT_RANGES.REPEAT"
+ ],
+ "percent sign": [
+ "CMOS.NUMBERS.PERCENTAGES.SYMBOL_OR_WORD.CONSISTENT"
+ ],
+ "percent symbol": [
+ "CMOS.NUMBERS.PERCENTAGES.SYMBOL_NO_SPACE"
],
"percentage": [
- "CMOS.NUMBERS.PERCENTAGES.NUMERALS"
+ "CMOS.NUMBERS.PERCENTAGES.NUMERALS",
+ "CMOS.NUMBERS.S9_20.PERCENT_VS_PERCENTAGE"
],
"percentages": [
- "CMOS.NUMBERS.CONTEXTS.ALWAYS_NUMERALS"
+ "CMOS.NUMBERS.CONTEXTS.ALWAYS_NUMERALS",
+ "CMOS.NUMBERS.S9_20.PERCENT.NUMERALS"
+ ],
+ "period": [
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.NOTES_PERIOD",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.NO_PERIOD",
+ "CMOS.PUNCTUATION.PERIODS.NOT_WITH_QM_EXCL",
+ "CMOS.PUNCTUATION.QUOTES.ITALIC_TITLE_EXCEPTION"
+ ],
+ "period omission": [
+ "CMOS.PUNCTUATION.PERIODS.OMIT_DISPLAY_LINES"
],
"period placement": [
"CMOS.PUNCTUATION.PERIODS.WITH_PARENS"
],
+ "periodicals": [
+ "CMOS.NUMBERS.S9_29.PERIODICALS.ORDER"
+ ],
"periods": [
- "CMOS.PUNCTUATION.PERIODS.USE"
+ "BRING.HEADINGS.NO_TERMINAL_PERIOD",
+ "CMOS.ABBREVIATIONS.INITIALISMS.NO_PERIODS.DEFAULT",
+ "CMOS.ABBREVIATIONS.PUNCTUATION.ABBREV_WITH_PERIODS.AVOID_DOUBLE",
+ "CMOS.ABBREVIATIONS.UNITS.NO_PERIODS",
+ "CMOS.PUNCTUATION.PERIODS.USE",
+ "CMOS.PUNCTUATION.QUOTES.US_STYLE_PERIODS_COMMAS",
+ "HOUSE.EDITORIAL.LISTS.PUNCTUATION.CONSISTENT"
],
"periods in quotes": [
"CMOS.PUNCTUATION.QUOTATION_MARKS.PUNCTUATION_PLACEMENT_US"
],
"permalink": [
- "CMOS.CITATIONS.ONLINE.PERMALINKS.PREFERRED"
+ "CMOS.CITATIONS.ONLINE.PERMALINKS.PREFERRED",
+ "CMOS.CITATIONS.S13_100.BIBLIOGRAPHY.ONLINE.SOURCE_STABILITY",
+ "CMOS.CITATIONS.S13_108.BIBLIOGRAPHY.PLATFORMS.PERMALINKS_PREFERRED",
+ "CMOS.CITATIONS.S13_8.PERMALINK.PREFERRED",
+ "CMOS.CITATIONS.S13_8.PERMALINK.TEST",
+ "CMOS.CITATIONS.S13_8.PREFERRED_ORDER"
+ ],
+ "permanent links": [
+ "CMOS.CITATIONS.S13_17.ARCHIVE_SERVICES"
+ ],
+ "permissions": [
+ "CMOS.FIGURES.CAPTION.CREDITS.INLINE_OR_NOTE",
+ "CMOS.FIGURES.CREDIT.SOURCE_WHEN_REQUIRED",
+ "CMOS.FIGURES.PERMISSIONS.DOCUMENTED",
+ "CMOS.FRONTMATTER.COPYRIGHT.RIGHTS.CONTACT"
],
"persistent identifier": [
"CMOS.CITATIONS.DOI.PREFERRED_OVER_URL"
@@ -1296,56 +4813,338 @@
"BRING.TYPOGRAPHY.NUMBER_STRINGS.SPACE_FOR_READABILITY"
],
"phone numbers": [
- "CMOS.NUMBERS.TELEPHONE.FORMAT"
+ "CMOS.NUMBERS.TELEPHONE.FORMAT",
+ "CMOS.PUNCTUATION.HYPHENS.SEPARATORS"
+ ],
+ "phrase boundaries": [
+ "BRING.HEADINGS.BREAKS.AT_PHRASE_BOUNDARIES"
+ ],
+ "pii": [
+ "HOUSE.EDITORIAL.OPSEC.REMOVE_PII"
+ ],
+ "place-names": [
+ "CMOS.PUNCTUATION.COMMAS.ADDRESSES.RUN_IN"
+ ],
+ "placeholder": [
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_LOREM_IPSUM",
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_TBD_TKTK"
+ ],
+ "placeholders": [
+ "HOUSE.CODE.BLOCKS.NO_PERSONAL_PATHS",
+ "HOUSE.CODE.PLACEHOLDERS.CLEAR",
+ "HOUSE.CODE.TYPED_VALUES.DISTINGUISH"
],
"placement": [
"BRING.HEADINGS.SUBHEADS.MIXING.HIERARCHY_PLACEMENT",
- "BRING.TABLES.TITLES.CONSISTENT_PLACEMENT"
+ "BRING.LAYOUT.PAGE.TEXTBLOCK.POSITION",
+ "BRING.TABLES.TITLES.CONSISTENT_PLACEMENT",
+ "CMOS.BACKMATTER.ACKNOWLEDGMENTS.PLACEMENT",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AFTER_QUOTE",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AVOID_MIDCLAUSE",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.BEFORE_DASH",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.PLACEMENT_END_SENTENCE",
+ "CMOS.FIGURES.PLACEMENT.NEAR_MENTION",
+ "CMOS.FIGURES.PLACEMENT.TOP_OR_BOTTOM.CONSISTENT",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.PLACEMENT",
+ "CMOS.FRONTMATTER.EPIGRAPH.PLACEMENT.CONSISTENT",
+ "CMOS.LAYOUT.FOOTNOTES.PLACEMENT",
+ "CMOS.LAYOUT.ILLUSTRATIONS.PLACEMENT_NEAR_REF",
+ "CMOS.LAYOUT.PAGINATION.RUNNING_HEADS.PLACEMENT",
+ "CMOS.LAYOUT.TABLES.PLACEMENT_NEAR_REF",
+ "CMOS.NUMBERS.S9_36.ERAS.ABBREVIATION_PLACEMENT",
+ "CMOS.TABLES.FOOTNOTES.PLACEMENT",
+ "CMOS.TABLES.TITLES.PLACEMENT.CONSISTENT"
+ ],
+ "plain text": [
+ "CMOS.CITATIONS.S13_13.STRIP_CODES"
+ ],
+ "plans": [
+ "HOUSE.EDITORIAL.STRUCTURE.RISKS.MITIGATIONS"
+ ],
+ "platform": [
+ "HOUSE.CODE.BLOCKS.PLATFORM.NOTED"
+ ],
+ "plural": [
+ "CMOS.ABBREVIATIONS.PLURALS.NO_APOSTROPHE",
+ "CMOS.ABBREVIATIONS.UNITS.NO_PLURAL_SYMBOLS",
+ "CMOS.NUMBERS.S9_34.CENTURIES.NUMERAL_PLURALS"
],
"plural numbers": [
"CMOS.NUMBERS.PLURALS.SPELLED_OUT"
],
+ "plural units": [
+ "CMOS.NUMBERS.S9_21.UNITS.LESS_THAN_ONE"
+ ],
+ "policy": [
+ "CMOS.CITATIONS.AUTHOR_DATE.NO_DATE.POLICY",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REPEATED_NAMES.POLICY",
+ "CMOS.CITATIONS.S13_90.TITLE_PUNCTUATION.CHANGES.POLICY_LIMITED"
+ ],
"popes": [
"CMOS.NUMBERS.NAMES.MONARCHS_POPES"
],
+ "portability": [
+ "HOUSE.CODE.TYPOGRAPHY.UNICODE.MINIMIZE"
+ ],
+ "position": [
+ "CMOS.LAYOUT.PAGINATION.PAGE_NUMBERS.POSITION"
+ ],
+ "possessive": [
+ "CMOS.ABBREVIATIONS.POSSESSIVE.FORM",
+ "CMOS.PUNCTUATION.APOSTROPHE.USE_CASES",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIPS.AVOID_POSSESSIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_AWKWARD_POSSESSIVE"
+ ],
+ "postal": [
+ "CMOS.ABBREVIATIONS.STATES.POSTAL_ONLY",
+ "CMOS.PUNCTUATION.COMMAS.ADDRESSES.MAILING_SPARING"
+ ],
+ "pound": [
+ "CMOS.NUMBERS.S9_24.BRITISH.POUND_SYMBOL"
+ ],
"powers of ten": [
+ "CMOS.NUMBERS.S9_10.POWERS_OF_TEN",
"CMOS.NUMBERS.SCIENTIFIC.POWERS_OF_TEN"
],
"precision": [
- "BRING.TABLES.NUMERIC_PRECISION.CONSISTENT"
+ "BRING.TABLES.NUMERIC_PRECISION.CONSISTENT",
+ "CMOS.NUMBERS.DECIMALS.TRAILING_ZEROS.AVOID",
+ "CMOS.NUMBERS.S9_21.DECIMAL_CONTEXT.CONSISTENT",
+ "CMOS.NUMBERS.S9_22.MONEY.MINIMUM_DECIMALS",
+ "CMOS.NUMBERS.S9_4.NONROUND.LARGE_NUMERALS",
+ "CMOS.NUMBERS.TIME.SECONDS.INCLUDE_FOR_PRECISION",
+ "CMOS.NUMBERS.TIME.SECONDS.OMIT_IF_NOT_NEEDED",
+ "CMOS.TABLES.PRECISION.CONSISTENT",
+ "CMOS.TABLES.ROUNDING.CONSISTENT",
+ "HOUSE.EDITORIAL.TONE.CALIBRATE_CERTAINTY",
+ "HOUSE.TABLES.NUMERIC.PRECISION.CONSISTENT"
+ ],
+ "preface": [
+ "CMOS.FRONTMATTER.PREFACE.DATE_IF_PRESENT",
+ "CMOS.FRONTMATTER.PREFACE.PURPOSE"
+ ],
+ "prefix": [
+ "BRING.HEADINGS.NUMBERING.PREFIXES.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.PREFIX.CONSISTENT",
+ "CMOS.NUMBERS.S9_12.BASE_PREFIXES"
+ ],
+ "prefixes": [
+ "CMOS.CITATIONS.S13_71.BIBLIOGRAPHY.ALPHABETIZATION.PREFIXES_POLICY"
+ ],
+ "preposition": [
+ "CMOS.PUNCTUATION.COLONS.AVOID_AFTER_PREPOSITION"
+ ],
+ "prerequisites": [
+ "HOUSE.CODE.BLOCKS.PRECONDITIONS.STATED"
+ ],
+ "preservation": [
+ "CMOS.CITATIONS.S13_17.PRESERVE.NONPUBLISHED"
+ ],
+ "prime": [
+ "CMOS.NUMBERS.S9_18.NO_SPACE.DEGREE_PERCENT_PRIME",
+ "CMOS.NUMBERS.S9_18.PRIME_SYMBOLS"
+ ],
+ "print": [
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.PRINT_HAIR_SPACE"
+ ],
+ "print only": [
+ "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.PRINT_ONLY"
+ ],
+ "printing": [
+ "BRING.LAYOUT.MARGINS.BLEED.ONLY_WHEN_ENABLED",
+ "CMOS.FIGURES.BLEED.ONLY_WHEN_ENABLED"
+ ],
+ "printouts": [
+ "CMOS.CITATIONS.S13_17.PRESERVE.FORMAT_OPTIONS"
+ ],
+ "priority": [
+ "CMOS.CITATIONS.S13_8.PREFERRED_ORDER",
+ "HOUSE.EDITORIAL.LISTS.ORDERED_ONLY_WHEN_ORDERED"
+ ],
+ "privacy": [
+ "CMOS.FIGURES.SENSITIVE.DATA.REDACT",
+ "HOUSE.CODE.BLOCKS.DATA.SYNTHETIC_FOR_SENSITIVE",
+ "HOUSE.EDITORIAL.OPSEC.REMOVE_PII",
+ "HOUSE.LINKS.EMAILS.MAILTO_POLICY"
+ ],
+ "private ip": [
+ "HOUSE.LINKS.AUTO.PRIVATE_IPS.AVOID",
+ "HOUSE.LINKS.URLS.AVOID_PRIVATE_IPS"
+ ],
+ "private keys": [
+ "HOUSE.EDITORIAL.REVIEW.SENSITIVE_INFO.NO_SECRETS"
+ ],
+ "probabilities": [
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.OMIT_PROBABILITIES"
+ ],
+ "procedures": [
+ "HOUSE.EDITORIAL.CLARITY.EXAMPLES_WHEN_COMPLEX"
+ ],
+ "professional": [
+ "HOUSE.EDITORIAL.TONE.PROFESSIONAL_AND_RESPECTFUL"
],
"profiles": [
"BRING.LAYOUT.RHYTHM.RULES_SERVE_TEXT"
],
+ "prompts": [
+ "HOUSE.CODE.SHELL.PROMPTS.CONSISTENT"
+ ],
+ "pronouns": [
+ "HOUSE.EDITORIAL.CLARITY.AVOID_AMBIGUOUS_PRONOUNS"
+ ],
+ "proofread": [
+ "HOUSE.EDITORIAL.REVIEW.SPELLCHECK_AND_READTHROUGH"
+ ],
+ "propagation": [
+ "CMOS.CITATIONS.S13_13.REPAIR_AT_SOURCE"
+ ],
"proper names": [
"BRING.TYPOGRAPHY.HYPHENATION.AVOID_PROPER_NAMES"
],
+ "proper nouns": [
+ "BRING.HEADINGS.CASE.PROPER_NOUNS_PRESERVE"
+ ],
+ "proportion": [
+ "BRING.LAYOUT.PARAGRAPH.INDENT.PROPORTIONAL"
+ ],
+ "proportional figures": [
+ "BRING.TYPOGRAPHY.NUMERALS.PROPORTIONAL_FOR_PROSE"
+ ],
+ "prose": [
+ "BRING.TYPOGRAPHY.NUMERALS.OLDSTYLE_FOR_TEXT",
+ "BRING.TYPOGRAPHY.NUMERALS.PROPORTIONAL_FOR_PROSE",
+ "CMOS.ABBREVIATIONS.GENERAL.AVOID_OVERUSE"
+ ],
+ "protocol": [
+ "CMOS.CITATIONS.S13_12.URLS.PROTOCOL"
+ ],
+ "protocol relative": [
+ "HOUSE.LINKS.URLS.NO_PROTOCOL_RELATIVE"
+ ],
+ "provinces": [
+ "CMOS.ABBREVIATIONS.STATES.SPELL_OUT_IN_TEXT"
+ ],
+ "pseudo-code": [
+ "HOUSE.CODE.BLOCKS.TESTED_OR_MARKED"
+ ],
"pseudonyms": [
"CMOS.CITATIONS.BIBLIOGRAPHY.PSEUDONYMS.CONSISTENT"
],
+ "public": [
+ "HOUSE.ACCESSIBILITY.LINKS.TARGETS.PUBLIC"
+ ],
"public documents": [
- "CMOS.CITATIONS.LEGAL_PUBLIC_DOCS.USE_JURISDICTIONAL_FORMAT"
+ "CMOS.CITATIONS.LEGAL_PUBLIC_DOCS.USE_JURISDICTIONAL_FORMAT",
+ "CMOS.CITATIONS.S13_104.BIBLIOGRAPHY.PUBLIC_DOCUMENTS.IDENTIFIERS"
+ ],
+ "publication date": [
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.PREFERENCE"
+ ],
+ "publication details": [
+ "CMOS.CITATIONS.S13_62.BIBLIOGRAPHY.ENTRY_COMPLETENESS.MORE_THAN_SHORT_FORM"
+ ],
+ "publication facts": [
+ "CMOS.CITATIONS.S13_92.BIBLIOGRAPHY.BOOKS.CORE_ELEMENTS"
+ ],
+ "publication place": [
+ "CMOS.CITATIONS.S13_22.BOOK_PLACE_OMIT"
+ ],
+ "published": [
+ "CMOS.CITATIONS.S13_1.ALL_SOURCE_TYPES"
],
"published form": [
"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.PUBLISHED_FORM"
],
+ "published sources": [
+ "CMOS.CITATIONS.S13_6.URLS.EASILY_FOUND"
+ ],
+ "publisher": [
+ "CMOS.CITATIONS.S13_1.DISCIPLINE_POLICY"
+ ],
+ "publisher policy": [
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.PUBLISHER_POLICY"
+ ],
+ "publishers": [
+ "CMOS.CITATIONS.S13_11.PUBLISHER_OPTION"
+ ],
"punctuation": [
+ "BRING.HEADINGS.RUN_IN.END_PUNCTUATION",
+ "BRING.TYPOGRAPHY.FAMILY.ITALIC_PUNCTUATION_MATCH",
+ "BRING.TYPOGRAPHY.ITALICS.PUNCTUATION_FOLLOWS_STYLE",
+ "CMOS.ABBREVIATIONS.PUNCTUATION.ABBREV_WITH_PERIODS.AVOID_DOUBLE",
+ "CMOS.ABBREVIATIONS.TITLES.COURTESY_PERIODS",
+ "CMOS.CITATIONS.S13_12.URLS.PUNCTUATION_AFTER",
+ "CMOS.CITATIONS.S13_2.STYLE_ELEMENTS.SHARED",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AFTER_PUNCTUATION",
+ "CMOS.CITATIONS.S13_90.TITLE_PUNCTUATION.CHANGES.POLICY_LIMITED",
+ "CMOS.FIGURES.CAPTION.PUNCTUATION.CONSISTENT",
+ "CMOS.I18N.PUNCTUATION.SPACING.LANGUAGE_RULES",
+ "CMOS.I18N.QUOTES.NESTING.CONSISTENT",
+ "CMOS.LINKS.HYPERLINK_EXCLUDES_PUNCTUATION",
+ "CMOS.LINKS.PUNCTUATE_NORMALLY",
+ "CMOS.PUNCTUATION.COMMAS.INDIRECT_QUESTIONS",
"CMOS.PUNCTUATION.DEGRADED.EXTRA_SPACES.AFTER_PUNCT",
- "HOUSE.LINKS.PUNCTUATION.NO_TRAILING_PUNCT"
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.PUNCTUATION_LEVELS",
+ "CMOS.PUNCTUATION.OVERVIEW.CONSISTENT.PRINCIPLES",
+ "CMOS.PUNCTUATION.OVERVIEW.CONTEXT.REGISTER",
+ "CMOS.PUNCTUATION.OVERVIEW.FUNCTION.CLARITY",
+ "CMOS.PUNCTUATION.URLS.HYPERTEXT_EXCLUDES_PUNCTUATION",
+ "CMOS.PUNCTUATION.URLS.PUNCTUATE_NORMALLY",
+ "HOUSE.EDITORIAL.HEADINGS.NO_TRAILING_PUNCTUATION",
+ "HOUSE.LINKS.PUNCTUATION.NO_TRAILING_PUNCT",
+ "HOUSE.LINKS.URLS.NO_TRAILING_PARENS"
+ ],
+ "punctuation ownership": [
+ "CMOS.PUNCTUATION.BOLD_COLOR.SEMANTIC_OWNERSHIP",
+ "CMOS.PUNCTUATION.ITALICS.TITLE_OWNERSHIP"
+ ],
+ "punctuation placement": [
+ "CMOS.PUNCTUATION.PARENS.PUNCTUATION_PLACEMENT"
+ ],
+ "punctuation stacking": [
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.PUNCTUATION_BEFORE"
+ ],
+ "punctuation style": [
+ "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.ELECTRONIC_PREFERS_LOGICAL",
+ "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.PRINT_ONLY",
+ "CMOS.PUNCTUATION.ITALICS.SURROUNDING_STYLE"
],
"punctuation with quotes": [
"CMOS.PUNCTUATION.QUOTATION_MARKS.PUNCTUATION_PLACEMENT_US"
],
+ "purpose": [
+ "BRING.TYPOGRAPHY.TYPEFACE.PURPOSE_MATCH_CONTENT"
+ ],
+ "quantify": [
+ "HOUSE.EDITORIAL.CLAIMS.QUANTIFY_WHEN_POSSIBLE"
+ ],
+ "query strings": [
+ "HOUSE.LINKS.URLS.NO_QUERY_WHEN_NOT_NEEDED"
+ ],
+ "question mark": [
+ "CMOS.PUNCTUATION.COMMAS.QUOTE_ENDING_QM_EXCL",
+ "CMOS.PUNCTUATION.PERIODS.NOT_WITH_QM_EXCL",
+ "CMOS.PUNCTUATION.QUESTION_EXCLAMATION.DUAL_MARKS",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.DIRECT",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.LIST_INTRO"
+ ],
"question marks": [
+ "BRING.HEADINGS.QUESTION_MARK_ONLY_IF_QUESTION",
"CMOS.PUNCTUATION.QUESTION_MARK.DIRECT_VS_INDIRECT",
"CMOS.PUNCTUATION.QUESTION_MARK.USE",
- "CMOS.PUNCTUATION.QUESTION_MARK.WITH_PUNCT"
+ "CMOS.PUNCTUATION.QUESTION_MARK.WITH_PUNCT",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.QUOTE_PLACEMENT",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.SURROUNDING"
],
"questions": [
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.EXAMPLES_QUESTIONS_RULES",
"CMOS.PUNCTUATION.EXCLAMATION.VS_QUESTION"
],
"quotation": [
- "CMOS.CITATIONS.QUOTATIONS.LOCATORS.PAGE_REQUIRED"
+ "CMOS.CITATIONS.QUOTATIONS.LOCATORS.PAGE_REQUIRED",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AFTER_QUOTE",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.DIALOGUE",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.THAT_WHETHER"
],
"quotation in note": [
"CMOS.CITATIONS.NOTES.QUOTE_IN_NOTE.LOCATOR"
@@ -1353,39 +5152,165 @@
"quotation introduction": [
"CMOS.PUNCTUATION.COLONS.INTRO_QUOTE_QUESTION"
],
+ "quotation mark": [
+ "CMOS.PUNCTUATION.QUOTES.APOSTROPHE_NOT_QUOTE"
+ ],
"quotation marks": [
+ "BRING.TYPOGRAPHY.ITALICS.CONSISTENT_TITLE_TREATMENT",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.QUOTE_TITLE",
+ "CMOS.I18N.QUOTES.STYLE.MATCH_LOCALE",
"CMOS.PUNCTUATION.BLOCK_QUOTES.NO_QUOTE_MARKS",
+ "CMOS.PUNCTUATION.COMMAS.QUOTE_ENDING_QM_EXCL",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.DIALOGUE_STYLE",
"CMOS.PUNCTUATION.DASHES.EM_INSTEAD_OF_QUOTES",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.QUOTE_PLACEMENT",
+ "CMOS.PUNCTUATION.QUESTION_MARKS.SURROUNDING",
"CMOS.PUNCTUATION.QUOTATION_MARKS.DOUBLE_PRIMARY_US",
- "CMOS.PUNCTUATION.QUOTES.SMART_QUOTES"
+ "CMOS.PUNCTUATION.QUOTES.ITALIC_TITLE_EXCEPTION",
+ "CMOS.PUNCTUATION.QUOTES.LINE_ALONE",
+ "CMOS.PUNCTUATION.QUOTES.MATCH_SURROUNDING",
+ "CMOS.PUNCTUATION.QUOTES.SMART_QUOTES",
+ "CMOS.PUNCTUATION.QUOTES.US_STYLE_PERIODS_COMMAS",
+ "HOUSE.I18N.QUOTES.MIXED_STYLES"
+ ],
+ "quotation style": [
+ "CMOS.PUNCTUATION.QUOTES.ALT_STYLE.DOCUMENT"
+ ],
+ "quotations": [
+ "CMOS.PUNCTUATION.COLONS.QUOTATIONS",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.DIALOGUE_VERB_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.NO_COMMA_CONJUNCTION"
+ ],
+ "quote placement": [
+ "CMOS.PUNCTUATION.EXCLAMATION.QUOTE_PLACEMENT"
],
"quoted titles": [
"CMOS.PUNCTUATION.COMMAS.QUOTED_TITLES"
],
+ "rag": [
+ "BRING.CODE.RAG.NO_MIN_LINE"
+ ],
+ "ragged": [
+ "BRING.CODE.RAG.NO_AUTO_HYPHENATION"
+ ],
+ "ragged bottom": [
+ "BRING.LAYOUT.COLUMNS.RAGGED_BOTTOM.AVOID"
+ ],
"ragged right": [
- "BRING.LAYOUT.JUSTIFICATION.RAGGED_RIGHT_IF_NEEDED"
+ "BRING.CODE.MONO_RAGGED_RIGHT",
+ "BRING.LAYOUT.JUSTIFICATION.RAGGED_RIGHT_IF_NEEDED",
+ "HOUSE.TYPOGRAPHY.HTML.JUSTIFICATION.RAGGED_RIGHT"
],
"range": [
"CMOS.PUNCTUATION.DASHES.EN_DASH.RANGES"
],
+ "ranges": [
+ "CMOS.NUMBERS.RANGES.NO_MIXED_FROM_BETWEEN",
+ "CMOS.NUMBERS.RANGES.REPEAT_UNIT_IF_AMBIG",
+ "CMOS.NUMBERS.RANGES.UNITS.PLACEMENT_CONSISTENT",
+ "CMOS.NUMBERS.S9_19.REPEAT_UNITS.CLOSED_UP",
+ "CMOS.NUMBERS.S9_19.UNIT_REPETITION.CONSISTENT",
+ "CMOS.NUMBERS.S9_19.UNIT_SPACED.SINGLE",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.AVOID_FROM_BETWEEN",
+ "HOUSE.EDITORIAL.CLAIMS.QUANTIFY_WHEN_POSSIBLE"
+ ],
+ "raster": [
+ "HOUSE.FIGURES.RESOLUTION.MINIMUM"
+ ],
+ "raster text": [
+ "HOUSE.FIGURES.TEXT.NOT_RASTERIZED"
+ ],
+ "rationale": [
+ "HOUSE.EDITORIAL.STRUCTURE.DECISIONS.EXPLICIT"
+ ],
"ratios": [
+ "CMOS.NUMBERS.RATIOS.COLON_SPACING",
"CMOS.NUMBERS.RATIOS.FORMAT"
],
+ "rd": [
+ "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.ND_RD"
+ ],
"readability": [
+ "BRING.LAYOUT.COLUMNS.GUTTER.SUFFICIENT",
"BRING.LAYOUT.LEADING.AVOID_TOO_TIGHT",
"BRING.LAYOUT.MEASURE.AVOID_TOO_LONG",
"BRING.LAYOUT.PAGE.DENSITY.DONT_SUFFOCATE",
"BRING.LAYOUT.RHYTHM.RULES_SERVE_TEXT",
"BRING.TABLES.EDIT_AS_TEXT.READABILITY",
- "BRING.TABLES.ROW_SPACING.READABLE"
+ "BRING.TABLES.ROW_SPACING.READABLE",
+ "BRING.TYPOGRAPHY.BOLD.AVOID_LONG_PASSAGES",
+ "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_AVOID_LONG_RUNS",
+ "BRING.TYPOGRAPHY.CAPS.AVOID_FOR_EMPHASIS",
+ "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_NOT_FOR_LONG_PASSAGES",
+ "BRING.TYPOGRAPHY.ITALICS.EMPHASIS_NOT_UNDERLINE",
+ "BRING.TYPOGRAPHY.ITALICS.LONG_SPANS_AVOID",
+ "BRING.TYPOGRAPHY.ITALICS.SPARING",
+ "BRING.TYPOGRAPHY.LIGATURES.DO_NOT_USE_IF_AMBIGUOUS",
+ "BRING.TYPOGRAPHY.SIZE.LEADING_RELATION",
+ "BRING.TYPOGRAPHY.WEIGHT.BOLD_IN_LONG_PASSAGES_AVOID",
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_STACKING",
+ "CMOS.ABBREVIATIONS.GENERAL.AVOID_OVERUSE",
+ "CMOS.ABBREVIATIONS.PARENTHETICALS.AVOID_STACKING",
+ "CMOS.FIGURES.EMBEDDED_TEXT.MINIMAL",
+ "CMOS.FIGURES.SIZE.MATCH_READABILITY",
+ "CMOS.NUMBERS.S9_1.READABILITY_OVER_CONSISTENCY",
+ "CMOS.NUMBERS.S9_7.AVOID_DENSE_WORDS",
+ "CMOS.PUNCTUATION.OVERVIEW.FUNCTION.CLARITY",
+ "HOUSE.ACCESSIBILITY.CONTRAST.TEXT_READABLE",
+ "HOUSE.ACCESSIBILITY.EMPHASIS.USE_SPARELY",
+ "HOUSE.CODE.COMMENTS.MINIMIZE_NOISE",
+ "HOUSE.EDITORIAL.HEADINGS.AVOID_ALL_CAPS",
+ "HOUSE.EDITORIAL.LISTS.AVOID_DEEP_NESTING",
+ "HOUSE.LINKS.AUTO.LABEL_LENGTH.AVOID_OVERLONG",
+ "HOUSE.LINKS.AUTO.PARTIAL_WORD.AVOID",
+ "HOUSE.LINKS.TEXT.AVOID_OVERLONG_LABELS",
+ "HOUSE.LINKS.TEXT.PARTIAL_WORD.AVOID",
+ "HOUSE.LINKS.URLS.AVOID.NAKED_URLS_IN_PROSE",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_LONG.AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.ITALIC_LONG.AVOID"
+ ],
+ "readers": [
+ "CMOS.CITATIONS.S13_1.PURPOSE.COURTESY"
],
"reading direction": [
"BRING.TABLES.GUIDES.READING_DIRECTION"
],
+ "reading order": [
+ "HOUSE.ACCESSIBILITY.LINKS.FOCUS_ORDER"
+ ],
+ "reading time": [
+ "CMOS.FRONTMATTER.READING_TIME.WHEN_HELPFUL"
+ ],
+ "recast": [
+ "CMOS.NUMBERS.S9_5.SENTENCE_INITIAL.RECAST"
+ ],
+ "recommendations": [
+ "HOUSE.EDITORIAL.CLAIMS.DISTINGUISH_FACT_OPINION"
+ ],
+ "redaction": [
+ "CMOS.FIGURES.SENSITIVE.DATA.REDACT",
+ "HOUSE.CODE.SECURITY.REDACT_SECRETS",
+ "HOUSE.EDITORIAL.OPSEC.REMOVE_PII"
+ ],
+ "redundancy": [
+ "HOUSE.EDITORIAL.CLARITY.EDIT_FOR_BREVITY",
+ "HOUSE.LINKS.TEXT.MIRROR.LABEL"
+ ],
+ "redundant data": [
+ "CMOS.CITATIONS.S13_13.METADATA.MISSING"
+ ],
"reference list": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.CORPORATE_AUTHORS.SHORT_FORM",
+ "CMOS.CITATIONS.AUTHOR_DATE.NO_AUTHOR.TITLE_KEY",
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ALPHABETICAL",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ENTRY_TEMPLATES.CONSISTENT",
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REQUIRED",
- "CMOS.CITATIONS.NOTES_BIBLIO.BIBLIOGRAPHY.INCLUDE_WHEN_USED"
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SAME_AUTHOR.ORDER_POLICY",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SORTING_STABLE",
+ "CMOS.CITATIONS.NOTES_BIBLIO.BIBLIOGRAPHY.INCLUDE_WHEN_USED",
+ "CMOS.CITATIONS.S13_107.AUTHOR_DATE.REFERENCE_LIST.MULTI_AUTHOR.ORDERING",
+ "CMOS.CITATIONS.S13_111.AUTHOR_DATE.REFERENCE_LIST.REQUIRED",
+ "HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.REQUIRED"
],
"reference list entries": [
"CMOS.CITATIONS.MATCHING.BIBLIO_ENTRY_REQUIRED"
@@ -1393,15 +5318,61 @@
"reference list format": [
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ORDER_AND_YEAR"
],
+ "references": [
+ "CMOS.BACKMATTER.BIBLIOGRAPHY.CONSISTENT_STYLE",
+ "CMOS.BACKMATTER.REFERENCES.AUTHOR_NAMES.CONSISTENT",
+ "CMOS.BACKMATTER.REFERENCES.SECTION_PRESENT",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.NOTES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.PAGES",
+ "HOUSE.ACCESSIBILITY.FIGURES.REFERENCED_IN_TEXT",
+ "HOUSE.BACKMATTER.REFERENCES.DEDUPLICATE",
+ "HOUSE.BACKMATTER.REFERENCES.SORTING.CONSISTENT",
+ "HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.YEAR_REQUIRED",
+ "HOUSE.CITATIONS.NOTES.BIBLIOGRAPHY.REQUIRED",
+ "HOUSE.EDITORIAL.STRUCTURE.REFERENCES.WHEN_CITED"
+ ],
"reflow": [
"BRING.LAYOUT.DEGRADED.HARD_WRAP_REFLOW",
"HOUSE.TABLES.OVERFLOW.NO_CLIPPING"
],
+ "register": [
+ "CMOS.PUNCTUATION.COMMAS.REGISTER.FLEX",
+ "CMOS.PUNCTUATION.OVERVIEW.CONTEXT.REGISTER"
+ ],
+ "reintroduce": [
+ "CMOS.ABBREVIATIONS.ACRONYMS.REINTRODUCE_AFTER_GAP"
+ ],
+ "relationships": [
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIPS.AVOID_POSSESSIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIPS.UNIQUE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_ALWAYS_USE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_NAMES"
+ ],
+ "relative clause": [
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_RESTRICTIVE"
+ ],
+ "relative clauses": [
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_THAT_WHICH"
+ ],
+ "relative links": [
+ "HOUSE.LINKS.URLS.RELATIVE.REPO_LOCAL"
+ ],
+ "relevance": [
+ "CMOS.CITATIONS.S13_5.CITE_RELEVANT"
+ ],
"repeat headers": [
"HOUSE.TABLES.HEADERS.REPEAT_ON_PAGEBREAK"
],
+ "repeated adjectives": [
+ "CMOS.PUNCTUATION.COMMAS.REPEATED_ADJECTIVES.USE_COMMA"
+ ],
+ "repeated links": [
+ "HOUSE.LINKS.TEXT.DIFFERENTIATE_REPEATED_LINKS"
+ ],
"repeated names": [
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REPEATED_NAMES",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REPEATED_NAMES.POLICY",
"CMOS.CITATIONS.BIBLIOGRAPHY.REPEATED_NAMES.THREE_EM_DASH"
],
"repeated units": [
@@ -1410,95 +5381,326 @@
"repeated word": [
"BRING.LAYOUT.LINEBREAKS.AVOID_SAME_WORD_START"
],
+ "reports": [
+ "CMOS.CITATIONS.S13_105.BIBLIOGRAPHY.REPORTS.ISSUING_BODY_AND_VERSION"
+ ],
+ "repos": [
+ "HOUSE.LINKS.URLS.RELATIVE.REPO_LOCAL"
+ ],
+ "repository": [
+ "CMOS.CITATIONS.S13_106.BIBLIOGRAPHY.DATASETS.VERSION_AND_PROVENANCE",
+ "CMOS.FRONTMATTER.CHANGELOG.LINKS"
+ ],
+ "reprint": [
+ "CMOS.CITATIONS.S13_59.NOTES.MULTI_EDITIONS.CITE_VERSION_USED"
+ ],
"reprints": [
"CMOS.CITATIONS.NOTES.SOURCE_NOTES.REPRINTS"
],
+ "reproducibility": [
+ "CMOS.BACKMATTER.DATA.AVAILABILITY",
+ "HOUSE.CODE.REFERENCES.VERSION_PIN"
+ ],
+ "requirements": [
+ "HOUSE.EDITORIAL.CLARITY.AVOID_DOUBLE_NEGATIVES"
+ ],
"research": [
- "CMOS.CITATIONS.RESEARCH.METADATA.CAPTURE_EARLY"
+ "CMOS.CITATIONS.RESEARCH.METADATA.CAPTURE_EARLY",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.RECORD_ANYWAY"
+ ],
+ "resolution": [
+ "CMOS.CITATIONS.S13_111.AUTHOR_DATE.REFERENCE_LIST.REQUIRED",
+ "CMOS.FIGURES.RESOLUTION.RASTER_SUFFICIENT",
+ "HOUSE.FIGURES.RESOLUTION.MINIMUM"
+ ],
+ "resolve": [
+ "CMOS.CITATIONS.S13_7.DOI.RESOLUTION"
],
"resolve citations": [
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REQUIRED",
"CMOS.CITATIONS.MATCHING.BIBLIO_ENTRY_REQUIRED"
],
+ "respect": [
+ "HOUSE.EDITORIAL.TONE.PROFESSIONAL_AND_RESPECTFUL"
+ ],
"responsive": [
- "BRING.LAYOUT.MEASURE.MULTICOLUMN_TARGETS"
+ "BRING.LAYOUT.MEASURE.MULTICOLUMN_TARGETS",
+ "HOUSE.LAYOUT.HTML.GUTTERS.MIN_PADDING"
],
"restrictive": [
- "CMOS.PUNCTUATION.COMMAS.APPOSITIVES"
+ "CMOS.PUNCTUATION.COMMAS.APPOSITIVES",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING.RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING_RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASE",
+ "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASES.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.SUCH_AS_INCLUDING"
],
"restrictive clause": [
"CMOS.PUNCTUATION.COMMAS.RESTRICTIVE.NO_SET_OFF"
],
+ "retrieval": [
+ "CMOS.CITATIONS.S13_62.BIBLIOGRAPHY.ENTRY_COMPLETENESS.MORE_THAN_SHORT_FORM"
+ ],
+ "review": [
+ "CMOS.CITATIONS.S13_13.CITATIONS.REVIEW"
+ ],
+ "review notes": [
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_REVIEW_NOTES_INLINE"
+ ],
"revision date": [
- "CMOS.CITATIONS.ONLINE.REVISION_DATE.DISTINCT"
+ "CMOS.CITATIONS.ONLINE.REVISION_DATE.DISTINCT",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.FORMAT",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.PREFERENCE",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.WHEN_ONLY_DATE"
+ ],
+ "revision history": [
+ "CMOS.FRONTMATTER.REVISION_HISTORY.WHEN_REQUIRED",
+ "HOUSE.EDITORIAL.STRUCTURE.CHANGELOG.LIVING_DOCS"
+ ],
+ "rhetorical questions": [
+ "CMOS.PUNCTUATION.EXCLAMATION.RHETORICAL"
],
"rhythm": [
- "BRING.TYPOGRAPHY.HYPHENATION.AVOID_AFTER_SHORT_LINE"
+ "BRING.TYPOGRAPHY.HYPHENATION.AVOID_AFTER_SHORT_LINE",
+ "CMOS.LAYOUT.MEASURE.MIN_LINE_LENGTH"
],
"right aligned": [
"BRING.HEADINGS.SUBHEADS.RIGHT_SIDEHEADS.VISIBILITY"
],
+ "risks": [
+ "HOUSE.EDITORIAL.STRUCTURE.RISKS.MITIGATIONS"
+ ],
"rivers": [
"BRING.LAYOUT.JUSTIFICATION.RAGGED_RIGHT_IF_NEEDED",
"BRING.TYPOGRAPHY.SPACING.WORD_SPACE.DEFINE"
],
+ "roles": [
+ "BRING.TYPOGRAPHY.SERIF.AVOID_MIX_SAME_ROLE",
+ "BRING.TYPOGRAPHY.TYPEFACE.CONTRAST_INTENTIONAL",
+ "BRING.TYPOGRAPHY.TYPEFACE.MIXING_BY_ROLE_ONLY",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.CONTRIBUTOR_ROLES.LABEL_CLEARLY",
+ "CMOS.CITATIONS.S13_93.BIBLIOGRAPHY.EDITED_VOLUMES.ROLE_MARKING"
+ ],
+ "roman": [
+ "BRING.TYPOGRAPHY.FAMILY.SINGLE_FAMILY_BODY",
+ "BRING.TYPOGRAPHY.ITALICS.RUNNING_HEADS_AVOID",
+ "BRING.TYPOGRAPHY.TYPEFACE.FAMILY_WITH_VARIANTS",
+ "CMOS.PUNCTUATION.ITALICS.SURROUNDING_STYLE"
+ ],
"roman numerals": [
- "CMOS.NUMBERS.ROMAN_NUMERALS.USE"
+ "BRING.TYPOGRAPHY.CAPS.ROMAN_NUMERALS_SPACING",
+ "CMOS.NUMBERS.ROMAN_NUMERALS.CASE_CONSISTENT",
+ "CMOS.NUMBERS.ROMAN_NUMERALS.USE",
+ "CMOS.NUMBERS.S9_28.FRONT_MATTER.ROMAN",
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.NUMERALS"
+ ],
+ "roman type": [
+ "CMOS.CITATIONS.S13_26.JOURNAL.VOLUME_FORMAT"
+ ],
+ "romanization": [
+ "CMOS.I18N.ROMANIZATION.DIACRITICS.KEEP"
+ ],
+ "rooms": [
+ "CMOS.NUMBERS.S9_8.PLACES.STREETS_ROOMS"
],
"rotation": [
- "BRING.TABLES.TEXT_ORIENTATION.HORIZONTAL"
+ "BRING.TABLES.TEXT_ORIENTATION.HORIZONTAL",
+ "CMOS.TABLES.ROTATION.LANDSCAPE.WHEN_NEEDED"
],
"round numbers": [
- "CMOS.NUMBERS.ROUND_NUMBERS.SPELL_OUT"
+ "CMOS.NUMBERS.ROUND_NUMBERS.SPELL_OUT",
+ "CMOS.NUMBERS.S9_2.ROUND_MULTIPLES.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_3.ALTERNATIVE_ROUND_MULTIPLES"
+ ],
+ "rounding": [
+ "CMOS.TABLES.ROUNDING.CONSISTENT"
],
"route numbers": [
"CMOS.NUMBERS.PLACES.HIGHWAYS"
],
+ "row headers": [
+ "HOUSE.ACCESSIBILITY.TABLES.ROW_HEADERS_FOR_STUB"
+ ],
"row labels": [
- "BRING.TABLES.STUB_COLUMN.USE"
+ "BRING.TABLES.STUB_COLUMN.USE",
+ "CMOS.TABLES.STUB_COLUMN.USE"
],
"row order": [
- "BRING.TABLES.ORDER.LOGICAL"
+ "BRING.TABLES.ORDER.LOGICAL",
+ "CMOS.TABLES.ROW_ORDER.LOGICAL"
],
"row spacing": [
- "BRING.TABLES.ROW_SPACING.READABLE"
+ "BRING.TABLES.ROW_SPACING.READABLE",
+ "CMOS.TABLES.ROW_SPACING.READABLE"
+ ],
+ "rows": [
+ "CMOS.TABLES.SPLITS.AVOID_ROW_BREAKS"
+ ],
+ "rtl": [
+ "CMOS.I18N.RIGHT_TO_LEFT.MARKUP"
],
"rules": [
- "BRING.TABLES.GUIDES.READING_DIRECTION"
+ "BRING.TABLES.GUIDES.READING_DIRECTION",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.EXAMPLES_QUESTIONS_RULES",
+ "CMOS.TABLES.RULES.MINIMAL"
+ ],
+ "run-in heading": [
+ "BRING.HEADINGS.RUN_IN.END_PUNCTUATION",
+ "BRING.HEADINGS.RUN_IN.SEPARATION.CONSISTENT"
],
"run-in heads": [
- "BRING.HEADINGS.RUN_IN.STANDALONE.CONSISTENT"
+ "BRING.HEADINGS.RUN_IN.STANDALONE.CONSISTENT",
+ "BRING.LAYOUT.PARAGRAPH.RUN_IN_HEADS.CONSISTENT"
+ ],
+ "run-in list": [
+ "CMOS.PUNCTUATION.LISTS.RUNIN.INTRO_COMPLETE_COLON",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.LETTERS.ITALIC_OPTION",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.MARKERS.PARENS",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SENTENCE_ITEMS_VERTICAL",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SEPARATORS",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SHORT_SIMPLE"
+ ],
+ "run-on": [
+ "CMOS.PUNCTUATION.COMMAS.COMMA_SPLICE.AVOID_FORMAL",
+ "CMOS.PUNCTUATION.COMMAS.SPLICES.AVOID_FORMAL"
+ ],
+ "running head": [
+ "CMOS.LAYOUT.PAGINATION.RUNNING_HEADS.CONSISTENCY",
+ "CMOS.LAYOUT.PAGINATION.RUNNING_HEADS.PLACEMENT",
+ "CMOS.LAYOUT.RUNNING_HEADS.CHAPTER_TITLES",
+ "CMOS.LAYOUT.RUNNING_HEADS.SECTION_TITLES"
],
"running heads": [
"BRING.HEADINGS.SUBHEADS.MARGIN_HEADS.RUNNING_SHOULDERHEADS",
+ "BRING.LAYOUT.MARGINS.RUNNING_HEAD.CLEARANCE",
+ "BRING.TYPOGRAPHY.ITALICS.RUNNING_HEADS_AVOID",
"CMOS.CITATIONS.NOTES.ENDNOTES.RUNNING_HEADS",
"CMOS.HEADINGS.RUNNING_HEADS.DEFINITION",
"CMOS.HEADINGS.RUNNING_HEADS.DIVISION_MATCH",
"CMOS.HEADINGS.RUNNING_HEADS.LENGTH_SHORT",
"CMOS.HEADINGS.RUNNING_HEADS.NAVIGATION_SCOPE"
],
+ "running text": [
+ "CMOS.ABBREVIATIONS.DAYS.SPELL_OUT_IN_TEXT",
+ "CMOS.ABBREVIATIONS.MONTHS.SPELL_OUT_IN_TEXT"
+ ],
+ "runover lines": [
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.RUNOVER_ALIGN",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.RUNOVER_ALIGN"
+ ],
+ "runt": [
+ "CMOS.LAYOUT.PAGINATION.AVOID_SHORT_LAST_LINE"
+ ],
+ "safety": [
+ "HOUSE.CODE.SHELL.DESTRUCTIVE.WARN"
+ ],
+ "salutations": [
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS.GREETINGS"
+ ],
"same author": [
- "CMOS.CITATIONS.BIBLIOGRAPHY.SAME_AUTHOR.ORDER"
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SAME_AUTHOR.ORDER_POLICY",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.SAME_AUTHOR.ORDER",
+ "CMOS.CITATIONS.S13_36.SHORT_FORM.DISAMBIGUATE_AUTHOR"
],
"same surname": [
"CMOS.CITATIONS.BIBLIOGRAPHY.SAME_SURNAME.DISAMBIGUATE"
],
+ "same year": [
+ "CMOS.CITATIONS.AUTHOR_DATE.SAME_AUTHOR_SAME_YEAR.SUFFIXES"
+ ],
+ "sans": [
+ "BRING.TYPOGRAPHY.SERIF.AVOID_MIX_SAME_ROLE"
+ ],
+ "sans serif": [
+ "BRING.TYPOGRAPHY.SERIF.SANS_FOR_DISPLAY"
+ ],
+ "scale": [
+ "CMOS.FIGURES.SCALE.LEGIBLE"
+ ],
+ "scaled caps": [
+ "BRING.TYPOGRAPHY.FAMILY.TRUE_SMALL_CAPS"
+ ],
"scalex": [
"BRING.TYPOGRAPHY.LETTERFORMS.AVOID_DISTORTION"
],
+ "scaling": [
+ "CMOS.FIGURES.ASPECT_RATIO.PRESERVE",
+ "CMOS.FIGURES.SCALING.UNIFORM"
+ ],
"scanability": [
+ "BRING.HEADINGS.LENGTH.CONCISE",
+ "HOUSE.EDITORIAL.LISTS.PARALLEL_STRUCTURE",
"HOUSE.TABLES.ALIGNMENT.DECIMALS"
],
+ "scanning": [
+ "BRING.TYPOGRAPHY.BOLD.LABELS_SHORT"
+ ],
+ "scenes": [
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.ACT_SCENE"
+ ],
+ "sciences": [
+ "CMOS.CITATIONS.S13_2.DISCIPLINE_PREFERENCE"
+ ],
"scientific notation": [
+ "CMOS.NUMBERS.S9_10.SCIENTIFIC_NOTATION.USE",
+ "CMOS.NUMBERS.S9_10.SCI_NOTATION.CONSISTENT",
+ "CMOS.NUMBERS.SCIENTIFIC.NOTATION.MANTISSA_RANGE",
+ "CMOS.NUMBERS.SCIENTIFIC.NOTATION.TIMES_SYMBOL",
"CMOS.NUMBERS.SCIENTIFIC.POWERS_OF_TEN"
],
+ "scope": [
+ "CMOS.CITATIONS.S13_66.BIBLIOGRAPHY.INCLUDE_ONLY_PER_SCOPE",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.SCOPE",
+ "CMOS.FRONTMATTER.AUDIENCE.SCOPE.STATED",
+ "CMOS.FRONTMATTER.INTRODUCTION.SCOPE",
+ "CMOS.TABLES.TITLES.SCOPE.CONSISTENT",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADERS.SCOPE",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADER_SCOPE",
+ "HOUSE.EDITORIAL.CLAIMS.SCOPE_TIMEBOUND",
+ "HOUSE.EDITORIAL.STRUCTURE.ASSUMPTIONS.EXPLICIT",
+ "HOUSE.EDITORIAL.STRUCTURE.SCOPE.STATED"
+ ],
+ "scores": [
+ "CMOS.NUMBERS.S9_8.SCORES_VOTES.NUMERALS"
+ ],
"screen pdf": [
"HOUSE.CODE.BLOCKS.WRAP_POLICY"
],
+ "screen reader": [
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_TEXT.QUALITY.NO_FILENAME"
+ ],
"screen readers": [
"HOUSE.A11Y.DOCUMENT_LANGUAGE.DECLARE",
"HOUSE.A11Y.IMAGES.ALT_REQUIRED"
],
+ "screenshots": [
+ "CMOS.CITATIONS.S13_17.PRESERVE.FORMAT_OPTIONS"
+ ],
+ "script mixing": [
+ "CMOS.I18N.SCRIPT_MIXING.AVOID"
+ ],
+ "searchable": [
+ "HOUSE.FIGURES.TEXT.NOT_RASTERIZED"
+ ],
+ "season": [
+ "CMOS.CITATIONS.S13_26.JOURNAL.OMIT_MONTH_SEASON"
+ ],
+ "second decade": [
+ "CMOS.NUMBERS.S9_35.DECADES.SECOND_DECADE"
+ ],
+ "seconds": [
+ "CMOS.NUMBERS.TIME.SECONDS.INCLUDE_FOR_PRECISION",
+ "CMOS.NUMBERS.TIME.SECONDS.OMIT_IF_NOT_NEEDED"
+ ],
+ "secrets": [
+ "HOUSE.CODE.SECURITY.REDACT_SECRETS",
+ "HOUSE.EDITORIAL.REVIEW.SENSITIVE_INFO.NO_SECRETS"
+ ],
+ "section breaks": [
+ "BRING.LAYOUT.PAGINATION.CLEAR_SECTION_BREAKS",
+ "BRING.LAYOUT.PARAGRAPH.SECTION_BREAKS.CLEAR"
+ ],
"section context": [
"CMOS.HEADINGS.RUNNING_HEADS.NAVIGATION_SCOPE"
],
@@ -1508,73 +5710,250 @@
"section layout": [
"BRING.LAYOUT.MEASURE.CONSISTENT_WITHIN_SECTION"
],
+ "section opening": [
+ "BRING.HEADINGS.SECTION_OPENING.PARAGRAPH_REQUIRED"
+ ],
+ "section title": [
+ "CMOS.LAYOUT.RUNNING_HEADS.SECTION_TITLES"
+ ],
+ "sections": [
+ "BRING.LAYOUT.MARGINS.CONSISTENT.ACROSS_SECTIONS",
+ "BRING.LAYOUT.PAGE.OPENING_SPREAD.RULE",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.SECTIONS_PARAS_LINES",
+ "HOUSE.LAYOUT.HTML.SECTION_SPACING.CONSISTENT"
+ ],
"security": [
+ "CMOS.FRONTMATTER.SECURITY.CLASSIFICATION",
+ "CMOS.I18N.SECURITY.HOMOGLYPHS.AWARE",
+ "HOUSE.CODE.PLACEHOLDERS.CLEAR",
+ "HOUSE.LINKS.AUTO.EMBEDDED_CREDENTIALS.AVOID",
+ "HOUSE.LINKS.AUTO.FTP.AVOID",
+ "HOUSE.LINKS.AUTO.PASSWORD_RESET.AVOID",
+ "HOUSE.LINKS.DISALLOW.JAVASCRIPT_URIS",
+ "HOUSE.LINKS.URLS.AVOID.PASSWORD_RESET",
+ "HOUSE.LINKS.URLS.DISALLOW.FTP",
+ "HOUSE.LINKS.URLS.NO_EMBEDDED_CREDENTIALS",
+ "HOUSE.LINKS.URLS.NO_ZERO_WIDTH",
"HOUSE.LINKS.URLS.PREFER_HTTPS"
],
+ "see also": [
+ "CMOS.BACKMATTER.INDEX.SEE_ALSO.USE_WHEN_NEEDED",
+ "HOUSE.BACKMATTER.GLOSSARY.CROSS_REFERENCES",
+ "HOUSE.BACKMATTER.INDEX.CROSS_REFERENCES.CONSISTENT"
+ ],
"see note": [
"CMOS.CITATIONS.NOTES.SHORT_FORM.CROSS_REFERENCE"
],
+ "selected bibliography": [
+ "CMOS.CITATIONS.S13_61.BIBLIOGRAPHY.SCOPE.LABEL_CLEARLY"
+ ],
+ "self-contained": [
+ "HOUSE.EDITORIAL.CLARITY.AVOID_METACOMMENTARY"
+ ],
+ "semantics": [
+ "HOUSE.ACCESSIBILITY.TABLES.HEADERS.SCOPE",
+ "HOUSE.ACCESSIBILITY.TABLES.NO_LAYOUT",
+ "HOUSE.CODE.BLOCKS.LINE_BREAKS.SEMANTIC_SAFE"
+ ],
"semicolon": [
"CMOS.PUNCTUATION.SEMICOLONS.COMPLEX_SERIES.SEPARATE"
],
"semicolons": [
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SEPARATORS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_PUNCTUATION",
+ "CMOS.PUNCTUATION.SEMICOLONS.AVOID_DIALOGUE",
"CMOS.PUNCTUATION.SEMICOLONS.BEFORE_CONJUNCTION",
- "CMOS.PUNCTUATION.SEMICOLONS.CONJUNCTIVE_PHRASES"
+ "CMOS.PUNCTUATION.SEMICOLONS.COMPLEX_SERIES",
+ "CMOS.PUNCTUATION.SEMICOLONS.CONJUNCTIVE_ADVERBS",
+ "CMOS.PUNCTUATION.SEMICOLONS.CONJUNCTIVE_PHRASES",
+ "CMOS.PUNCTUATION.SEMICOLONS.INDEPENDENT_CLAUSES",
+ "CMOS.PUNCTUATION.SEMICOLONS.THAT_IS_CLAUSE"
],
"sentence after colon": [
"CMOS.PUNCTUATION.COLONS.CAPITALIZATION"
],
+ "sentence end": [
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_END",
+ "CMOS.PUNCTUATION.PERIODS.NO_DOUBLE_AT_SENTENCE_END"
+ ],
"sentence spacing": [
- "BRING.TYPOGRAPHY.SPACING.SENTENCE_SPACE.SINGLE"
+ "BRING.TYPOGRAPHY.SPACING.SENTENCE_SPACE.SINGLE",
+ "CMOS.PUNCTUATION.SPACING.ONE_SPACE_SENTENCES"
],
"sentence start": [
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_SENTENCE_START",
+ "CMOS.CITATIONS.S13_12.URLS.NO_SENTENCE_START",
+ "CMOS.NUMBERS.S9_31.YEAR_SENTENCE_START_ALLOWED",
+ "CMOS.NUMBERS.S9_5.SENTENCE_INITIAL.RECAST",
+ "CMOS.NUMBERS.S9_5.SENTENCE_INITIAL.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_5.TWO_NUMBERS.SAME_CATEGORY",
+ "CMOS.NUMBERS.S9_5.YEARS.MAY_BEGIN",
+ "CMOS.NUMBERS.S9_7.SENTENCE_START_EXCEPTION",
"CMOS.NUMBERS.SENTENCE_START.AVOID_NUMERAL"
],
"sentence style": [
+ "CMOS.CITATIONS.S13_18.NOTES.SENTENCE_STYLE",
"CMOS.CITATIONS.TITLES.CAPITALIZATION.CONSISTENT"
],
+ "sentence-style list": [
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_CONJUNCTION",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_LOWERCASE",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_PUNCTUATION",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_USE_ONLY_FOR_EMPHASIS"
+ ],
+ "sentences": [
+ "CMOS.PUNCTUATION.LISTS.MIXED_SENTENCE_TYPES",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SENTENCE_ITEMS_VERTICAL",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.END_PUNCT_SENTENCES"
+ ],
+ "separation": [
+ "HOUSE.CODE.BLOCKS.SPLIT_BY_LANGUAGE"
+ ],
+ "separator": [
+ "BRING.HEADINGS.RUN_IN.SEPARATION.CONSISTENT"
+ ],
+ "separators": [
+ "CMOS.NUMBERS.TELEPHONE.SEPARATORS.CONSISTENT",
+ "CMOS.PUNCTUATION.HYPHENS.SEPARATORS"
+ ],
"sequence": [
- "CMOS.CITATIONS.NOTES.NOTE_MARKERS.SEQUENCE_CONTINUOUS"
+ "CMOS.CITATIONS.NOTES.NOTE_MARKERS.SEQUENCE_CONTINUOUS",
+ "CMOS.TABLES.TITLES.NUMBERING.SEQUENTIAL",
+ "HOUSE.CODE.EXAMPLES.ORDERED_STEPS"
],
"serial comma": [
+ "CMOS.PUNCTUATION.COMMAS.AMPERSAND.NO_SERIAL",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.AMBIGUITY_REWORD",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.PAIR_LAST_ITEM",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.PAIR_WITH_AND",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.REQUIRED",
"CMOS.PUNCTUATION.COMMAS.SERIAL_COMMA.DEFAULT"
],
"serial number": [
"BRING.TYPOGRAPHY.NUMBER_STRINGS.SPACE_FOR_READABILITY"
],
+ "series": [
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.SERIES",
+ "CMOS.PUNCTUATION.COMMAS.ETC.FINAL_ELEMENT",
+ "CMOS.PUNCTUATION.COMMAS.ETC.TRAILING",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.ALL_CONJUNCTIONS",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.ALL_CONJUNCTIONS_NO_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.AS_WELL_AS",
+ "CMOS.PUNCTUATION.SEMICOLONS.COMPLEX_SERIES"
+ ],
+ "serif": [
+ "BRING.TYPOGRAPHY.SERIF.AVOID_MIX_SAME_ROLE",
+ "BRING.TYPOGRAPHY.SERIF.BODY_TEXT_DEFAULT"
+ ],
+ "session": [
+ "HOUSE.LINKS.AUTO.SESSION_PARAMS.AVOID"
+ ],
+ "session params": [
+ "HOUSE.LINKS.URLS.NO_SESSION_PARAMS"
+ ],
+ "shading": [
+ "CMOS.TABLES.SHADING.SPARING"
+ ],
+ "shell": [
+ "HOUSE.CODE.BLOCKS.PLATFORM.NOTED",
+ "HOUSE.CODE.SHELL.PROMPTS.CONSISTENT"
+ ],
+ "shell prompts": [
+ "HOUSE.CODE.BLOCKS.COMMANDS.PROMPT_FREE_COPY"
+ ],
+ "short clauses": [
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.SHORT",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.SHORT_OMIT"
+ ],
+ "short documents": [
+ "CMOS.CITATIONS.S13_20.ELECTRONIC.SHORT_DOCS"
+ ],
"short form": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.CORPORATE_AUTHORS.SHORT_FORM",
"CMOS.CITATIONS.IBID.MINIMIZE_OR_AVOID",
"CMOS.CITATIONS.NOTES.ENDNOTES.AVOID_IBID",
"CMOS.CITATIONS.NOTES.SHORT_FORM.BASIC_ELEMENTS",
"CMOS.CITATIONS.NOTES.SHORT_FORM.CROSS_REFERENCE",
- "CMOS.CITATIONS.NOTES_BIBLIO.SUBSEQUENT_NOTES.SHORT_FORM"
+ "CMOS.CITATIONS.NOTES_BIBLIO.SUBSEQUENT_NOTES.SHORT_FORM",
+ "CMOS.CITATIONS.S13_35.SHORT_FORM.DISTINCT_TITLE",
+ "CMOS.CITATIONS.S13_36.SHORT_FORM.DISAMBIGUATE_AUTHOR",
+ "CMOS.CITATIONS.S13_40.SHORT_FORM.AVOID_OP_CIT",
+ "HOUSE.CITATIONS.NOTES.IBID.AVOID"
+ ],
+ "short forms": [
+ "CMOS.CITATIONS.S13_21.EXAMPLES.BIBLIO_SHORTENED",
+ "CMOS.CITATIONS.S13_21.EXAMPLES.SHORT_FORMS"
+ ],
+ "short items": [
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SHORT_SIMPLE"
+ ],
+ "short last line": [
+ "CMOS.LAYOUT.PAGINATION.AVOID_SHORT_LAST_LINE"
],
"short line": [
"BRING.TYPOGRAPHY.HYPHENATION.AVOID_AFTER_SHORT_LINE"
],
"short lines": [
- "BRING.LAYOUT.MEASURE.AVOID_TOO_SHORT"
+ "BRING.LAYOUT.MEASURE.AVOID_TOO_SHORT",
+ "CMOS.LAYOUT.MEASURE.MIN_LINE_LENGTH"
],
"short title": [
"CMOS.CITATIONS.NOTES.SHORT_FORM.BASIC_ELEMENTS",
- "CMOS.CITATIONS.NOTES_BIBLIO.SUBSEQUENT_NOTES.SHORT_FORM"
+ "CMOS.CITATIONS.NOTES_BIBLIO.SUBSEQUENT_NOTES.SHORT_FORM",
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.SHORTENED",
+ "CMOS.CITATIONS.S13_35.SHORT_FORM.DISTINCT_TITLE"
+ ],
+ "short titles": [
+ "CMOS.FRONTMATTER.TOC.SHORT_TITLES.CONSISTENT"
+ ],
+ "short urls": [
+ "CMOS.CITATIONS.S13_11.PUBLISHER_OPTION",
+ "CMOS.CITATIONS.S13_11.SHORTENERS.OBSCURE"
+ ],
+ "shorten": [
+ "CMOS.CITATIONS.S13_9.SHORTEN_LONG_URLS"
+ ],
+ "shortened notes": [
+ "CMOS.CITATIONS.S13_18.BIBLIO.SHORTENED_NOTES",
+ "CMOS.CITATIONS.S13_22.BOOK_EDITOR_ONLY.SHORTENED_NO_ED"
],
"shortened range": [
"CMOS.NUMBERS.INCLUSIVE_RANGES.PAGE_NUMBERS.SHORTEN"
],
+ "shorteners": [
+ "CMOS.CITATIONS.S13_11.NO_SHORTENERS_IN_MS",
+ "CMOS.CITATIONS.S13_9.SHORT_URLS.ARE_NOT_SHORTENERS",
+ "HOUSE.LINKS.URLS.SHORTENERS.AVOID"
+ ],
+ "shortening": [
+ "CMOS.NUMBERS.INCLUSIVE.SHORTEN_SECOND_NUMBER"
+ ],
"shoulderheads": [
"BRING.HEADINGS.SUBHEADS.MARGIN_HEADS.RUNNING_SHOULDERHEADS"
],
"shrink limit": [
"BRING.TABLES.TYPE_SIZE.READABLE"
],
+ "si": [
+ "CMOS.ABBREVIATIONS.MEASURES.SI.SPACE",
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.LARGE"
+ ],
"si grouping": [
"CMOS.NUMBERS.DIGIT_GROUPING.SI_SPACE"
],
"si prefixes": [
+ "CMOS.NUMBERS.S9_12.DECIMAL_PREFIXES",
"CMOS.NUMBERS.SI_PREFIXES.NO_HYPHEN"
],
+ "si units": [
+ "CMOS.NUMBERS.S9_11.PREFIX_SYMBOLS",
+ "CMOS.NUMBERS.S9_18.SPACING.NUMERAL_UNIT"
+ ],
+ "sic": [
+ "CMOS.PUNCTUATION.EXCLAMATION.BRACKETED_AVOID"
+ ],
"sidebars": [
+ "BRING.LAYOUT.COLUMNS.SIDEBARS.DISTINCT_MEASURE",
"BRING.LAYOUT.MEASURE.CHANGE_FOR_LISTS"
],
"sideheads": [
@@ -1584,8 +5963,24 @@
"signatures": [
"CMOS.HEADINGS.LETTERS_DIARIES.SIGNATURE_FORMAT"
],
+ "signed urls": [
+ "HOUSE.LINKS.URLS.AVOID.EXPIRING_SIGNED"
+ ],
+ "signin": [
+ "HOUSE.LINKS.AUTO.LOGIN_LINKS.AVOID"
+ ],
"simple fractions": [
- "CMOS.NUMBERS.FRACTIONS.SIMPLE.SPELL_OUT"
+ "CMOS.NUMBERS.FRACTIONS.SIMPLE.SPELL_OUT",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.SPELLED_OUT"
+ ],
+ "single author": [
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.NOTE_BIBLIO"
+ ],
+ "single item": [
+ "CMOS.PUNCTUATION.COMMAS.ETC_SINGLE_ITEM"
+ ],
+ "single line": [
+ "CMOS.LAYOUT.PAGINATION.AVOID_SINGLE_LINE_ENDING"
],
"single quotes": [
"CMOS.PUNCTUATION.QUOTATION_MARKS.DOUBLE_PRIMARY_US"
@@ -1594,122 +5989,476 @@
"BRING.TYPOGRAPHY.SPACING.SENTENCE_SPACE.SINGLE",
"CMOS.PUNCTUATION.COLONS.SPACE_AFTER"
],
+ "single-item list": [
+ "HOUSE.EDITORIAL.LISTS.AVOID_SINGLE_ITEM"
+ ],
+ "singular verb": [
+ "CMOS.NUMBERS.S9_22.MONEY.SINGULAR_VERB"
+ ],
"size": [
"BRING.HEADINGS.SUBHEADS.RIGHT_SIDEHEADS.VISIBILITY",
- "BRING.HEADINGS.WEIGHT_SIZE.HIERARCHY_SCALE"
+ "BRING.HEADINGS.WEIGHT_SIZE.HIERARCHY_SCALE",
+ "BRING.TYPOGRAPHY.TYPEFACE.LEGIBILITY_AT_SIZE",
+ "CMOS.FIGURES.SIZE.MATCH_READABILITY"
+ ],
+ "size scale": [
+ "BRING.TYPOGRAPHY.SIZE.SCALE_CONSISTENT"
+ ],
+ "skip link": [
+ "HOUSE.ACCESSIBILITY.LINKS.SKIP_TO_CONTENT"
],
"skipped levels": [
"BRING.HEADINGS.HIERARCHY.NO_SKIPPED_LEVELS"
],
+ "slant": [
+ "BRING.TYPOGRAPHY.FAMILY.TRUE_ITALICS"
+ ],
+ "slash": [
+ "CMOS.NUMBERS.FRACTIONS.SLASH_INLINE",
+ "CMOS.NUMBERS.S9_17.ALGEBRAIC.SLASH",
+ "CMOS.NUMBERS.S9_17.FRACTIONS.RUNNING_TEXT.SLASH",
+ "CMOS.NUMBERS.S9_17.SLASH_BINDING",
+ "CMOS.PUNCTUATION.SLASHES.NO_SPACES"
+ ],
+ "slashed zero": [
+ "BRING.TYPOGRAPHY.NUMERALS.SLASHED_ZERO_IF_CONFUSION"
+ ],
"slashes": [
"CMOS.PUNCTUATION.SLASHES.ALTERNATIVES",
- "CMOS.PUNCTUATION.SLASHES.TWO_YEAR_SPANS"
+ "CMOS.PUNCTUATION.SLASHES.TWO_YEAR_SPANS",
+ "HOUSE.LINKS.URLS.NO_BACKSLASH"
],
"small caps": [
+ "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_FOR_ACRONYMS",
+ "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_NOT_FOR_LONG_PASSAGES",
+ "BRING.TYPOGRAPHY.FAMILY.SMALL_CAPS_SPARE",
+ "BRING.TYPOGRAPHY.FAMILY.TRUE_SMALL_CAPS",
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ALL_CAPS",
+ "BRING.TYPOGRAPHY.NUMERALS.SMALL_CAPS_AND_FIGURES",
"BRING.TYPOGRAPHY.TRACKING.CAPS_SMALLCAPS_AND_LONG_DIGITS"
],
+ "small sizes": [
+ "BRING.TYPOGRAPHY.LIGATURES.DO_NOT_USE_IF_AMBIGUOUS"
+ ],
+ "smart apostrophes": [
+ "CMOS.PUNCTUATION.APOSTROPHE.SMART"
+ ],
"smart quotes": [
- "CMOS.PUNCTUATION.QUOTES.SMART_QUOTES"
+ "CMOS.PUNCTUATION.QUOTES.SMART_QUOTES",
+ "HOUSE.CODE.BLOCKS.NO_SMART_QUOTES"
+ ],
+ "snapshot": [
+ "CMOS.CITATIONS.S13_103.BIBLIOGRAPHY.SOCIAL_MEDIA.ARCHIVE"
+ ],
+ "social media": [
+ "CMOS.CITATIONS.S13_103.BIBLIOGRAPHY.SOCIAL_MEDIA.ARCHIVE"
],
"soft hyphen": [
- "CMOS.CITATIONS.DEGRADED.URL_LINEBREAKS.NORMALIZE"
+ "CMOS.CITATIONS.DEGRADED.URL_LINEBREAKS.NORMALIZE",
+ "HOUSE.CODE.WRAPPING.NO_SOFT_HYPHENS"
+ ],
+ "sorting": [
+ "CMOS.BACKMATTER.BIBLIOGRAPHY.SORTING",
+ "CMOS.BACKMATTER.GLOSSARY.SORTING",
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SORTING_STABLE",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.PARTICLES.CONSISTENT_FORMAT",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.GROUP_AUTHORS.SUBUNITS.CONSISTENT",
+ "CMOS.CITATIONS.S13_72.BIBLIOGRAPHY.SORTING.DIACRITICS_AND_TRANSLITERATION",
+ "CMOS.TABLES.SORTING.LOGICAL",
+ "HOUSE.BACKMATTER.REFERENCES.SORTING.CONSISTENT"
],
"source citation": [
"CMOS.CITATIONS.NOTES.SUBSTANTIVE.SEPARATE_FROM_SOURCE"
],
+ "source language": [
+ "HOUSE.I18N.TRANSLATION.LABELS"
+ ],
"source notes": [
- "CMOS.CITATIONS.NOTES.SOURCE_NOTES.REPRINTS"
+ "CMOS.CITATIONS.NOTES.SOURCE_NOTES.REPRINTS",
+ "CMOS.CITATIONS.S13_57.NOTES.SEPARATE_SOURCE_VS_COMMENTARY"
+ ],
+ "source type": [
+ "CMOS.CITATIONS.S13_68.BIBLIOGRAPHY.ENTRY_TYPES.NOT_MIXED"
],
"sources": [
- "BRING.TABLES.SOURCES.NOTES.DISTINCT"
+ "BRING.TABLES.SOURCES.NOTES.DISTINCT",
+ "CMOS.TABLES.SOURCE.NOTES.DISTINCT"
+ ],
+ "spaces": [
+ "CMOS.CITATIONS.S13_12.URLS.NO_SPACES"
],
"spacing": [
"BRING.HEADINGS.BLOCK_QUOTE.SPACING_AROUND",
"BRING.HEADINGS.SPACING.VERTICAL_RHYTHM",
"BRING.LAYOUT.BLOCK_QUOTES.BEFORE_AFTER_SPACING",
"BRING.LAYOUT.BLOCK_QUOTES.EXTRA_LEAD",
+ "BRING.LAYOUT.COLUMNS.GUTTER.CONSISTENT",
+ "BRING.LAYOUT.PARAGRAPH.BLOCK_STYLE.CONSISTENT",
+ "BRING.LAYOUT.PARAGRAPH.SECTION_BREAKS.CLEAR",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.CAPTIONS.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.FIGURES.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.FOOTNOTES.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.HEADINGS.BEFORE_AFTER",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.LISTS.SPACING",
"BRING.LAYOUT.VERTICAL_RHYTHM.MEASURED_INTERVALS.MULTIPLES",
- "BRING.TYPOGRAPHY.ALIGNMENT.DONT_STRETCH_SPACE"
+ "BRING.LAYOUT.VERTICAL_RHYTHM.TABLES.SPACING",
+ "BRING.TYPOGRAPHY.ALIGNMENT.DONT_STRETCH_SPACE",
+ "BRING.TYPOGRAPHY.CAPS.ROMAN_NUMERALS_SPACING",
+ "BRING.TYPOGRAPHY.CAPS.TRACKING_REVIEW",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.CONSISTENT_SPACING",
+ "CMOS.I18N.PUNCTUATION.SPACING.LANGUAGE_RULES",
+ "CMOS.LAYOUT.PARAGRAPHS.BLOCK_QUOTE_STYLE",
+ "CMOS.LAYOUT.SPACING.VERTICAL_RHYTHM",
+ "CMOS.NUMBERS.CURRENCY.SYMBOL_ADJACENT",
+ "CMOS.NUMBERS.PERCENTAGES.SYMBOL_NO_SPACE",
+ "CMOS.NUMBERS.RATIOS.COLON_SPACING",
+ "CMOS.NUMBERS.S9_18.SPACING.NUMERAL_UNIT",
+ "CMOS.NUMBERS.S9_25.CURRENCY_CODES.SPACING",
+ "CMOS.NUMBERS.S9_27.CURRENCY_YEAR.CODES_SPACING",
+ "CMOS.NUMBERS.TIME.AM_PM.CONSISTENT_SPACING",
+ "CMOS.NUMBERS.UNITS.SPACE_BETWEEN_NUMBER_UNIT",
+ "CMOS.PUNCTUATION.COLONS.ONE_SPACE",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.SPACED_BRITISH",
+ "CMOS.PUNCTUATION.EMOJIS.PUNCTUATION",
+ "CMOS.PUNCTUATION.SLASHES.NO_SPACES",
+ "CMOS.PUNCTUATION.SPACING.DESIGN_SPECIFIED",
+ "CMOS.PUNCTUATION.SPACING.FIXED_WIDTHS",
+ "CMOS.PUNCTUATION.SPACING.WORD_SPACE_DEFAULT",
+ "HOUSE.I18N.UNITS.SPACING.CONSISTENT",
+ "HOUSE.LAYOUT.HTML.SECTION_SPACING.CONSISTENT"
+ ],
+ "span": [
+ "BRING.LAYOUT.COLUMNS.SPAN_POLICY.FIGURES",
+ "BRING.LAYOUT.COLUMNS.SPAN_POLICY.TABLES"
],
"spell out numbers": [
"CMOS.NUMBERS.SPELLING.ONE_TO_ONE_HUNDRED.DEFAULT"
],
+ "spellcheck": [
+ "HOUSE.EDITORIAL.REVIEW.SPELLCHECK_AND_READTHROUGH"
+ ],
"spelled out": [
+ "CMOS.ABBREVIATIONS.UNITS.SPELL_OUT_WITHOUT_NUMERALS",
"CMOS.NUMBERS.CONSISTENCY.MIXED_FORMS.AVOID",
- "CMOS.NUMBERS.FRACTIONS.SIMPLE.SPELL_OUT"
+ "CMOS.NUMBERS.FRACTIONS.SIMPLE.SPELL_OUT",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_18.UNIT_WITHOUT_NUMERAL.SPELLED_OUT"
+ ],
+ "spelling": [
+ "CMOS.I18N.LANGUAGE.CONSISTENT_SPELLING",
+ "CMOS.NUMBERS.S9_22.MONEY.SPELL_OUT_SMALL",
+ "CMOS.NUMBERS.S9_5.SENTENCE_INITIAL.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_6.ORDINALS.RULE_PARALLEL",
+ "HOUSE.EDITORIAL.CONSISTENCY.SPELLING_VARIANT.CHOOSE_ONE"
+ ],
+ "splitting": [
+ "CMOS.FIGURES.PLACEMENT.AVOID_SPLIT"
],
"spread": [
- "BRING.LAYOUT.PAGINATION.BALANCE_FACING_PAGES"
+ "BRING.LAYOUT.PAGINATION.BALANCE_FACING_PAGES",
+ "CMOS.LAYOUT.PAGINATION.FACING_PAGES.BALANCE"
+ ],
+ "spreads": [
+ "BRING.LAYOUT.PAGE.FACING_ELEMENTS.ALIGN",
+ "BRING.LAYOUT.PAGE.SPREADS.BALANCE_CONTENT"
+ ],
+ "sr": [
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.NONE"
+ ],
+ "sr.": [
+ "CMOS.ABBREVIATIONS.TITLES.JR_SR.CONSISTENT",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.RUNNING"
+ ],
+ "stability": [
+ "CMOS.CITATIONS.S13_101.BIBLIOGRAPHY.EBOOKS.EDITION_AND_FORMAT",
+ "CMOS.CITATIONS.S13_108.BIBLIOGRAPHY.PLATFORMS.PERMALINKS_PREFERRED",
+ "CMOS.CITATIONS.S13_7.DOI.PREFERRED",
+ "CMOS.CITATIONS.S13_9.SHORT_URLS.ARE_NOT_SHORTENERS",
+ "HOUSE.LINKS.TEXT.STABILITY.NOTE",
+ "HOUSE.LINKS.URLS.STABLE_ANCHORS"
],
"stable identifier": [
"CMOS.CITATIONS.ONLINE.PERMALINKS.PREFERRED"
],
+ "stable url": [
+ "CMOS.CITATIONS.S13_8.PERMALINK.PREFERRED"
+ ],
+ "stable urls": [
+ "CMOS.BACKMATTER.REFERENCES.URLS.STABLE"
+ ],
+ "stacked headings": [
+ "BRING.HEADINGS.AVOID_STACKED_LEVELS",
+ "HOUSE.LAYOUT.PAGINATION.HEADINGS.NO_ADJACENT"
+ ],
"stacked punctuation": [
"CMOS.PUNCTUATION.QUESTION_MARK.WITH_PUNCT"
],
+ "stacking": [
+ "CMOS.ABBREVIATIONS.PARENTHETICALS.AVOID_STACKING"
+ ],
+ "stage": [
+ "CMOS.NUMBERS.S9_8.SEVERITY_CLASSIFICATIONS"
+ ],
+ "staging": [
+ "HOUSE.LINKS.AUTO.STAGING_HOSTNAMES.AVOID",
+ "HOUSE.LINKS.URLS.AVOID.STAGING_DOMAINS"
+ ],
"stand-alone heads": [
"BRING.HEADINGS.RUN_IN.STANDALONE.CONSISTENT"
],
+ "standalone": [
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.LINE_ALONE",
+ "CMOS.PUNCTUATION.QUOTES.LINE_ALONE"
+ ],
+ "standalone url": [
+ "CMOS.LINKS.URL_ONLY_LINE_NO_PUNCT"
+ ],
+ "standards": [
+ "CMOS.CITATIONS.S13_3.SOURCE_MANUALS"
+ ],
+ "state abbreviations": [
+ "CMOS.ABBREVIATIONS.GEOGRAPHY.STATE_ABBREVS.CONSISTENT",
+ "CMOS.ABBREVIATIONS.STATES.POSTAL_ONLY"
+ ],
+ "states": [
+ "CMOS.ABBREVIATIONS.STATES.SPELL_OUT_IN_TEXT"
+ ],
+ "status": [
+ "HOUSE.FRONTMATTER.METADATA.DOC_STATUS"
+ ],
+ "stderr": [
+ "HOUSE.CODE.BLOCKS.ERROR_OUTPUT.LABELED"
+ ],
+ "steps": [
+ "HOUSE.CODE.EXAMPLES.ORDERED_STEPS",
+ "HOUSE.EDITORIAL.LISTS.ORDERED_ONLY_WHEN_ORDERED"
+ ],
+ "sterling": [
+ "CMOS.NUMBERS.S9_24.BRITISH.POUND_SYMBOL"
+ ],
"stranded heading": [
"HOUSE.HEADINGS.KEEPS.AVOID_STRANDED",
+ "HOUSE.HEADINGS.KEEP_WITH_NEXT",
"HOUSE.LAYOUT.PAGINATION.KEEP_WITH_NEXT.HEADINGS"
],
"streets": [
- "CMOS.NUMBERS.PLACES.STREETS"
+ "CMOS.NUMBERS.PLACES.STREETS",
+ "CMOS.NUMBERS.S9_8.PLACES.STREETS_ROOMS"
+ ],
+ "strict": [
+ "CMOS.CITATIONS.S13_4.JOURNALS.STRICT"
+ ],
+ "stroke": [
+ "BRING.TYPOGRAPHY.CONTRAST.FONT_PAIRING_MATCH"
+ ],
+ "stroke contrast": [
+ "BRING.TYPOGRAPHY.SERIF.STROKE_CONTRAST_COMPATIBLE"
+ ],
+ "strokes": [
+ "CMOS.FIGURES.LINE_WEIGHTS.CONSISTENT"
],
"structure": [
"BRING.HEADINGS.STRUCTURE.MATCH_TEXT_LOGIC",
"BRING.HEADINGS.SUBHEADS.LEVELS.AS_MANY_AS_NEEDED",
- "HOUSE.A11Y.HEADINGS.NO_SKIPS"
+ "BRING.TYPOGRAPHY.TYPEFACE.CONTRAST_INTENTIONAL",
+ "HOUSE.A11Y.HEADINGS.NO_SKIPS",
+ "HOUSE.ACCESSIBILITY.HEADINGS.NO_DECORATIVE",
+ "HOUSE.ACCESSIBILITY.LINKS.FOCUS_ORDER",
+ "HOUSE.ACCESSIBILITY.TABLES.SIMPLE_STRUCTURE",
+ "HOUSE.EDITORIAL.CLARITY.ONE_IDEA_PER_PARAGRAPH",
+ "HOUSE.EDITORIAL.HEADINGS.AVOID_GENERIC",
+ "HOUSE.EDITORIAL.LISTS.AVOID_DEEP_NESTING",
+ "HOUSE.EDITORIAL.LISTS.AVOID_SINGLE_ITEM",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.SINGLE"
],
"stub": [
"BRING.LAYOUT.HYPHENATION.STUB_END_AVOID"
],
"stub column": [
- "BRING.TABLES.STUB_COLUMN.USE"
+ "BRING.TABLES.STUB_COLUMN.USE",
+ "CMOS.TABLES.STUB_COLUMN.USE",
+ "HOUSE.ACCESSIBILITY.TABLES.ROW_HEADERS_FOR_STUB"
],
"style": [
- "BRING.HEADINGS.SUBHEADS.STYLE_CONTRIBUTES_TO_WHOLE"
+ "BRING.HEADINGS.SUBHEADS.STYLE_CONTRIBUTES_TO_WHOLE",
+ "BRING.TYPOGRAPHY.NUMERALS.FIGURE_STYLE_FOR_CAPTIONS",
+ "CMOS.ABBREVIATIONS.CAPS.AVOID_ALL_CAPS_WORDS",
+ "CMOS.ABBREVIATIONS.GENERAL.CONSISTENCY",
+ "CMOS.LAYOUT.PAGINATION.PAGE_NUMBERS.STYLE",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.MATCH_SURROUNDING",
+ "CMOS.PUNCTUATION.QUOTES.MATCH_SURROUNDING",
+ "HOUSE.CODE.BLOCKS.INDENTATION.CONSISTENT"
],
"style palette": [
"BRING.HEADINGS.STYLE.PALETTE_LIMIT"
],
+ "style sheet": [
+ "CMOS.CITATIONS.S13_4.DOCUMENTED_DEVIATIONS",
+ "CMOS.NUMBERS.S9_7.DOCUMENT_EXCEPTIONS"
+ ],
+ "styling": [
+ "BRING.TYPOGRAPHY.NUMERALS.FRACTIONS_TRUE_GLYPHS"
+ ],
+ "subentries": [
+ "CMOS.BACKMATTER.INDEX.SUBENTRIES.NESTED"
+ ],
+ "subentry order": [
+ "CMOS.BACKMATTER.INDEX.SUBENTRY.ORDER.LOGICAL"
+ ],
"subheads": [
"BRING.HEADINGS.SUBHEADS.MIXING_SYMM_ASYMM.AVOID_HAPHAZARD",
"BRING.HEADINGS.SUBHEADS.STYLE_CONTRIBUTES_TO_WHOLE"
],
+ "sublevel numbering": [
+ "BRING.HEADINGS.NUMBERING.SUBLEVELS.DECIMAL_STYLE"
+ ],
+ "subscript": [
+ "CMOS.NUMBERS.S9_12.BASE_SUBSCRIPT"
+ ],
+ "subscription": [
+ "CMOS.CITATIONS.S13_10.DATABASES.NAME_INSTEAD",
+ "CMOS.CITATIONS.S13_8.SUBSCRIPTION_URLS"
+ ],
"subsequent notes": [
"CMOS.CITATIONS.NOTES_BIBLIO.SUBSEQUENT_NOTES.SHORT_FORM"
],
"substantive notes": [
"CMOS.CITATIONS.NOTES.SUBSTANTIVE.SEPARATE_FROM_SOURCE"
],
+ "subtitle": [
+ "CMOS.CITATIONS.S13_91.TITLE_SUBTITLE.SEPARATOR.COLON",
+ "CMOS.CITATIONS.S13_94.TITLES.TRAILING_PHRASE.PLACEMENT"
+ ],
+ "subtotals": [
+ "CMOS.TABLES.SUBTOTALS.CLEAR"
+ ],
+ "subunits": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.GROUP_AUTHORS.SUBUNITS.CONSISTENT",
+ "CMOS.NUMBERS.S9_25.OTHER_CURRENCIES.DECIMAL"
+ ],
+ "such as": [
+ "CMOS.PUNCTUATION.COMMAS.SUCH_AS_INCLUDING"
+ ],
"suffix": [
- "CMOS.NUMBERS.ORDINALS.SUFFIX.CORRECT"
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.SUFFIXES.INCLUDE",
+ "CMOS.NUMBERS.ORDINALS.SUFFIX.CORRECT",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.INVERTED"
+ ],
+ "suffix letters": [
+ "CMOS.CITATIONS.AUTHOR_DATE.SAME_AUTHOR_SAME_YEAR.SUFFIXES"
+ ],
+ "suffixes": [
+ "CMOS.ABBREVIATIONS.TITLES.JR_SR.CONSISTENT",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.RUNNING"
+ ],
+ "suites": [
+ "CMOS.NUMBERS.S9_8.PLACES.STREETS_ROOMS"
+ ],
+ "sum": [
+ "CMOS.NUMBERS.S9_22.MONEY.SINGULAR_VERB"
+ ],
+ "summary": [
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_SUMMARY_FOR_CHARTS",
+ "HOUSE.EDITORIAL.STRUCTURE.SUMMARY.EARLY",
+ "HOUSE.FIGURES.CAPTIONS.TAKEAWAY",
+ "HOUSE.FRONTMATTER.ABSTRACT.REQUIRED_FOR_LONG_DOCS"
+ ],
+ "superior": [
+ "BRING.TYPOGRAPHY.NUMERALS.SUPERIOR_INFERIOR_FOR_NOTES"
],
"superscript": [
- "CMOS.CITATIONS.NOTES.NOTE_MARKERS.SUPERSCRIPT_TEXT"
+ "CMOS.CITATIONS.NOTES.NOTE_MARKERS.SUPERSCRIPT_TEXT",
+ "CMOS.CITATIONS.S13_18.NOTES_BIBLIO.OVERVIEW",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.MANUSCRIPT_SUPERSCRIPT_OK",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.TEXT_SUPERSCRIPT",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.TEXT_SUPERSCRIPT",
+ "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.NO_SUPERSCRIPT"
+ ],
+ "support": [
+ "CMOS.BACKMATTER.CONTACT.SUPPORT"
+ ],
+ "surrounding text": [
+ "CMOS.PUNCTUATION.QUOTES.MATCH_SURROUNDING"
],
"suspended hyphens": [
"CMOS.PUNCTUATION.HYPHENATION.SUSPENDED"
],
+ "svg": [
+ "CMOS.FIGURES.FORMAT.VECTOR_WHEN_POSSIBLE"
+ ],
+ "symbol": [
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SEPARATE_SYSTEMS",
+ "CMOS.NUMBERS.S9_20.PERCENT.WORD_VS_SYMBOL"
+ ],
+ "symbol sequence": [
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SYMBOL_SEQUENCE_STANDARD"
+ ],
+ "symbols": [
+ "BRING.TYPOGRAPHY.TYPEFACE.GLYPH_COVERAGE_REQUIRED",
+ "CMOS.ABBREVIATIONS.MEASURES.SI.SPACE",
+ "CMOS.ABBREVIATIONS.UNITS.ABBREV_WITH_NUMERALS_ONLY",
+ "CMOS.ABBREVIATIONS.UNITS.NO_PERIODS",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.BASELINE_FALLBACK",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.CONSISTENT_SPACING",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.NOTES_FULL_SIZE",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.NO_PERIOD",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.TEXT_SUPERSCRIPT",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SYMBOLS_FOR_FEW",
+ "CMOS.FIGURES.LEGENDS.EXPLAIN_SYMBOLS",
+ "CMOS.FIGURES.SYMBOLS.CONSISTENT",
+ "CMOS.I18N.UNITS.SYMBOLS.STANDARD",
+ "CMOS.NUMBERS.CURRENCY.RANGES.REPEAT_SYMBOL",
+ "CMOS.NUMBERS.S9_11.PREFIX_SYMBOLS",
+ "CMOS.NUMBERS.S9_18.ABBREVIATIONS.NUMERALS_ONLY",
+ "CMOS.NUMBERS.S9_19.REPEAT_UNITS.CLOSED_UP",
+ "CMOS.NUMBERS.S9_8.SYMBOLS.NUMERALS",
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.SYMBOL_ONLY.AVOID"
+ ],
"symmetry": [
"BRING.HEADINGS.SUBHEADS.MIXING_SYMM_ASYMM.AVOID_HAPHAZARD"
],
"syntax highlighting": [
"HOUSE.CODE.BLOCKS.LANGUAGE_TAGS.PREFERRED"
],
+ "synthetic": [
+ "BRING.TYPOGRAPHY.FAMILY.AVOID_FAUX_BOLD"
+ ],
+ "synthetic data": [
+ "HOUSE.CODE.BLOCKS.DATA.SYNTHETIC_FOR_SENSITIVE"
+ ],
"tab leaders": [
"BRING.TYPOGRAPHY.ALIGNMENT.DONT_STRETCH_SPACE"
],
+ "table": [
+ "CMOS.LAYOUT.TABLES.PLACEMENT_NEAR_REF"
+ ],
"table captions": [
- "BRING.TABLES.CAPTIONS.CLEAR"
+ "BRING.TABLES.CAPTIONS.CLEAR",
+ "CMOS.TABLES.CAPTIONS.PRESENT"
],
"table guides": [
"BRING.TABLES.GUIDES.READING_DIRECTION"
],
+ "table headers": [
+ "HOUSE.ACCESSIBILITY.TABLES.HEADERS.SCOPE",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADER_SCOPE"
+ ],
+ "table mention": [
+ "CMOS.TABLES.REFERENCES.IN_TEXT"
+ ],
"table notes": [
- "BRING.TABLES.SOURCES.NOTES.DISTINCT"
+ "BRING.TABLES.SOURCES.NOTES.DISTINCT",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.TABLE_NOTES_SEPARATE",
+ "CMOS.TABLES.FOOTNOTES.PLACEMENT",
+ "CMOS.TABLES.NOTES.ORDERED_MARKERS",
+ "CMOS.TABLES.SOURCE.NOTES.DISTINCT"
+ ],
+ "table numbering": [
+ "CMOS.TABLES.TITLES.NUMBERING.SEQUENTIAL"
+ ],
+ "table of contents": [
+ "BRING.HEADINGS.TOC.MATCH",
+ "CMOS.FRONTMATTER.TOC.WHEN_NEEDED"
],
"table overflow": [
"BRING.TABLES.TYPE_SIZE.READABLE",
@@ -1724,20 +6473,110 @@
"table rules": [
"BRING.TABLES.FURNITURE.MINIMIZE"
],
+ "table sources": [
+ "HOUSE.TABLES.SOURCE.NOTES"
+ ],
"table titles": [
- "BRING.TABLES.TITLES.CONSISTENT_PLACEMENT"
+ "BRING.TABLES.TITLES.CONSISTENT_PLACEMENT",
+ "CMOS.TABLES.TITLES.PLACEMENT.CONSISTENT"
],
"tables": [
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_TABLES",
+ "BRING.LAYOUT.COLUMNS.SPAN_POLICY.TABLES",
"BRING.LAYOUT.FLOATS.PLACEMENT.NEAR_REFERENCE",
+ "BRING.LAYOUT.PAGINATION.KEEP_TABLE_WITH_HEADER",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.TABLES.SPACING",
"BRING.TABLES.EDIT_AS_TEXT.READABILITY",
"BRING.TABLES.TEXT_ORIENTATION.HORIZONTAL",
- "BRING.TYPOGRAPHY.ALIGNMENT.DONT_STRETCH_SPACE"
+ "BRING.TYPOGRAPHY.ALIGNMENT.DONT_STRETCH_SPACE",
+ "BRING.TYPOGRAPHY.NUMERALS.TABULAR_FOR_TABLES",
+ "CMOS.ABBREVIATIONS.TABLES.ABBREV_KEY",
+ "CMOS.ABBREVIATIONS.TABLES.KEYS.WHEN_DENSE",
+ "CMOS.FIGURES.TABLE_VS_FIGURE.CHOOSE",
+ "CMOS.NUMBERS.S9_28.DIVISIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.FIGURES_TABLES_EQUATIONS",
+ "HOUSE.ACCESSIBILITY.TABLES.AVOID_SCREENSHOT",
+ "HOUSE.ACCESSIBILITY.TABLES.CAPTION_SUMMARY",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADER_ROW.REQUIRED",
+ "HOUSE.ACCESSIBILITY.TABLES.SIMPLE_STRUCTURE",
+ "HOUSE.CODE.TABLES.AVOID_FOR_CODE",
+ "HOUSE.EDITORIAL.REVIEW.CROSS_REFERENCES.VERIFY",
+ "HOUSE.LAYOUT.PAGINATION.CAPTIONS.KEEP_WITH_CONTENT"
+ ],
+ "tabs": [
+ "HOUSE.CODE.BLOCKS.TABS.AVOID"
+ ],
+ "tabular figures": [
+ "BRING.TYPOGRAPHY.NUMERALS.TABULAR_FOR_TABLES"
+ ],
+ "tagged pdf": [
+ "HOUSE.ACCESSIBILITY.PDF.TAGS.WHEN_AVAILABLE"
+ ],
+ "tangential sources": [
+ "CMOS.CITATIONS.S13_5.AVOID_TANGENTIAL"
+ ],
+ "tasks": [
+ "HOUSE.EDITORIAL.LISTS.TASKS.CHECKLIST"
+ ],
+ "tbd": [
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_TBD_TKTK"
+ ],
+ "technical": [
+ "CMOS.ABBREVIATIONS.TECH.TERMS.CASE_SENSITIVE"
+ ],
+ "technical writing": [
+ "CMOS.NUMBERS.S9_1.GENERAL_WORKS_SCOPE",
+ "CMOS.NUMBERS.S9_18.SCIENTIFIC_CONTEXT.NUMERALS"
+ ],
+ "telephone": [
+ "CMOS.NUMBERS.TELEPHONE.COUNTRY_CODE.WHEN_INTERNATIONAL",
+ "CMOS.NUMBERS.TELEPHONE.SEPARATORS.CONSISTENT"
+ ],
+ "temperature": [
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.GENERAL_RULE"
+ ],
+ "templates": [
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ENTRY_TEMPLATES.CONSISTENT"
+ ],
+ "temporary links": [
+ "HOUSE.LINKS.URLS.AVOID.TEMP_FILESHARES"
+ ],
+ "tera": [
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.LARGE"
],
"terminal punctuation": [
"CMOS.PUNCTUATION.PERIODS.USE"
],
+ "terminology": [
+ "HOUSE.EDITORIAL.CONSISTENCY.TERMINOLOGY.STABLE"
+ ],
+ "terms": [
+ "BRING.TYPOGRAPHY.ITALICS.TERMS_INTRODUCED_SPARE",
+ "CMOS.BACKMATTER.GLOSSARY.TERMS.CONSISTENT_STYLE",
+ "CMOS.BACKMATTER.INDEX.WHEN_REQUIRED",
+ "CMOS.FRONTMATTER.TERMS.DEFINITIONS.EARLY"
+ ],
+ "test": [
+ "HOUSE.LINKS.AUTO.STAGING_HOSTNAMES.AVOID",
+ "HOUSE.LINKS.URLS.AVOID.STAGING_DOMAINS"
+ ],
+ "tested": [
+ "HOUSE.CODE.BLOCKS.TESTED_OR_MARKED"
+ ],
+ "testing": [
+ "CMOS.CITATIONS.S13_10.TEST_LOGGED_OUT",
+ "CMOS.CITATIONS.S13_8.PERMALINK.TEST"
+ ],
+ "text": [
+ "HOUSE.ACCESSIBILITY.IMAGES.TEXT_IN_IMAGES.AVOID"
+ ],
+ "text alignment": [
+ "CMOS.TABLES.ALIGNMENT.TEXT_LEFT"
+ ],
"text block": [
+ "BRING.LAYOUT.MARGINS.PROPORTION.BALANCED",
"BRING.LAYOUT.PAGE.FRAME.TEXTBLOCK_BALANCE",
+ "BRING.LAYOUT.PAGE.TEXTBLOCK.POSITION",
"BRING.LAYOUT.TEXTBLOCK.CONSISTENT_WIDTH"
],
"text cohesion": [
@@ -1746,15 +6585,58 @@
"text color": [
"BRING.TYPOGRAPHY.SPACING.WORD_SPACE.DEFINE"
],
+ "text cut": [
+ "BRING.TYPOGRAPHY.TYPEFACE.OPTICAL_SIZES_USE"
+ ],
+ "text face": [
+ "BRING.TYPOGRAPHY.TYPEFACE.TEXT_FACES_FOR_BODY"
+ ],
+ "text fragments": [
+ "HOUSE.LINKS.URLS.AVOID.TEXT_FRAGMENTS"
+ ],
+ "texture": [
+ "BRING.TYPOGRAPHY.NUMERALS.AVOID_LINING_IN_LOWERCASE"
+ ],
+ "that": [
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.THAT_WHETHER",
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_THAT_WHICH"
+ ],
+ "that is": [
+ "CMOS.PUNCTUATION.COMMAS.THAT_IS.TRAILING_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.THAT_IS_NAMELY",
+ "CMOS.PUNCTUATION.SEMICOLONS.THAT_IS_CLAUSE"
+ ],
+ "the more": [
+ "CMOS.PUNCTUATION.COMMAS.THE_MORE_THE_MORE"
+ ],
+ "then": [
+ "CMOS.PUNCTUATION.COMMAS.AND_THEN",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.THEN_SHORTHAND"
+ ],
+ "therefore": [
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTIVE_ADVERBS"
+ ],
+ "thesis": [
+ "CMOS.CITATIONS.S13_98.BIBLIOGRAPHY.THESES_DISSERTATIONS.INSTITUTION"
+ ],
"thin space": [
"BRING.TYPOGRAPHY.SPACING.INITIALS.THIN_SPACE",
"CMOS.NUMBERS.DIGIT_GROUPING.SI_SPACE"
],
+ "third-party": [
+ "CMOS.BACKMATTER.LICENSES.THIRD_PARTY"
+ ],
+ "thousand": [
+ "CMOS.NUMBERS.S9_4.HUNDREDS_THOUSANDS.SPELLED_OUT"
+ ],
"thousands": [
- "CMOS.NUMBERS.ROUND_NUMBERS.SPELL_OUT"
+ "CMOS.NUMBERS.ROUND_NUMBERS.SPELL_OUT",
+ "CMOS.NUMBERS.S9_26.K_THOUSANDS"
],
"thousands separator": [
- "CMOS.NUMBERS.GROUPING.THOUSANDS_SEPARATOR"
+ "CMOS.I18N.NUMBERS.DECIMAL_SEPARATOR.LOCALE",
+ "CMOS.NUMBERS.GROUPING.THOUSANDS_SEPARATOR",
+ "HOUSE.I18N.NUMBERS.GROUPING.CONSISTENT"
],
"three dots": [
"CMOS.PUNCTUATION.ELLIPSIS.FORMAT.CONSISTENT"
@@ -1762,44 +6644,286 @@
"tight leading": [
"BRING.LAYOUT.LEADING.AVOID_TOO_TIGHT"
],
+ "time": [
+ "CMOS.ABBREVIATIONS.TIME.AM_PM.FORM",
+ "CMOS.NUMBERS.TIME.LEADING_ZERO_MINUTES",
+ "HOUSE.EDITORIAL.CLAIMS.SCOPE_TIMEBOUND"
+ ],
"time format": [
"CMOS.NUMBERS.TIME.TWENTY_FOUR_HOUR"
],
"time of day": [
"CMOS.NUMBERS.TIME.GENERAL_NUMERALS"
],
+ "time ranges": [
+ "CMOS.NUMBERS.TIME.RANGES.CONSISTENT_FORMAT"
+ ],
+ "time zone": [
+ "CMOS.NUMBERS.TIME.ZONE.INCLUDE_WHEN_AMBIGUOUS",
+ "HOUSE.EDITORIAL.CONSISTENCY.TIMEZONE.EXPLICIT"
+ ],
+ "times symbol": [
+ "CMOS.NUMBERS.SCIENTIFIC.NOTATION.TIMES_SYMBOL"
+ ],
+ "timestamps": [
+ "HOUSE.EDITORIAL.CONSISTENCY.TIMEZONE.EXPLICIT"
+ ],
+ "title": [
+ "CMOS.CITATIONS.S13_90.TITLE_PUNCTUATION.CHANGES.POLICY_LIMITED",
+ "CMOS.CITATIONS.S13_91.TITLE_SUBTITLE.SEPARATOR.COLON",
+ "CMOS.CITATIONS.S13_94.TITLES.TRAILING_PHRASE.PLACEMENT",
+ "CMOS.FRONTMATTER.TITLEPAGE.PRESENT",
+ "CMOS.PUNCTUATION.ITALICS.TITLE_OWNERSHIP",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.PRESENT",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.SINGLE"
+ ],
+ "title key": [
+ "CMOS.CITATIONS.AUTHOR_DATE.NO_AUTHOR.TITLE_KEY"
+ ],
"title lead": [
"CMOS.CITATIONS.BIBLIOGRAPHY.NO_AUTHOR.TITLE_LEAD"
],
"title notes": [
"CMOS.CITATIONS.NOTES.NOTE_MARKERS.HEADINGS_END"
],
+ "title placement": [
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.EARLY"
+ ],
+ "title styling": [
+ "CMOS.CITATIONS.S13_35.SHORT_FORM.DISTINCT_TITLE"
+ ],
+ "titles": [
+ "BRING.TYPOGRAPHY.ITALICS.CONSISTENT_TITLE_TREATMENT",
+ "BRING.TYPOGRAPHY.ITALICS.TITLES_STANDALONE_WORKS",
+ "CMOS.ABBREVIATIONS.TITLES.HONORIFICS.CONSISTENT",
+ "CMOS.CITATIONS.S13_6.LINK_TITLE_PREFERRED",
+ "CMOS.CITATIONS.S13_99.LONG_TITLES.TRUNCATION.AVOID",
+ "CMOS.FRONTMATTER.LIST_OF_FIGURES.SECTION_TITLE",
+ "CMOS.FRONTMATTER.LIST_OF_TABLES.SECTION_TITLE",
+ "CMOS.I18N.CAPITALIZATION.TITLES.LANGUAGE_RULES",
+ "CMOS.I18N.CITATIONS.TITLES.ORIGINAL_OR_TRANSLATED",
+ "CMOS.NUMBERS.S9_8.TITLE_NUMBERS",
+ "CMOS.PUNCTUATION.COMMAS.PAIRS.TITLES_EXCEPTION",
+ "CMOS.PUNCTUATION.COMMAS.TITLES.APPOSITIVE_RULE",
+ "CMOS.PUNCTUATION.COMMAS.TITLES_AND_EXPRESSIONS",
+ "HOUSE.EDITORIAL.HEADINGS.NO_TRAILING_PUNCTUATION"
+ ],
+ "tktk": [
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_TBD_TKTK"
+ ],
+ "toc": [
+ "CMOS.BACKMATTER.APPENDIX.TOC.ENTRIES",
+ "CMOS.FRONTMATTER.TOC.ENTRIES.MATCH_HEADINGS",
+ "CMOS.FRONTMATTER.TOC.FRONT_BACK_MATTER.INCLUDED",
+ "CMOS.FRONTMATTER.TOC.INDENTATION.BY_LEVEL",
+ "CMOS.FRONTMATTER.TOC.LEADERS.CONSISTENT",
+ "CMOS.FRONTMATTER.TOC.LEVELS.CONSISTENT",
+ "CMOS.FRONTMATTER.TOC.ORDER.MATCH_BODY",
+ "CMOS.FRONTMATTER.TOC.PAGE_NUMBERS.MATCH",
+ "CMOS.FRONTMATTER.TOC.SHORT_TITLES.CONSISTENT",
+ "HOUSE.ACCESSIBILITY.TOC.LINKED_ENTRIES",
+ "HOUSE.BACKMATTER.APPENDICES.LABELS.MATCH",
+ "HOUSE.FRONTMATTER.TOC.AUTO_GENERATED"
+ ],
+ "todo": [
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_TODO_FIXME"
+ ],
+ "token": [
+ "HOUSE.LINKS.AUTO.SESSION_PARAMS.AVOID"
+ ],
+ "tokens": [
+ "HOUSE.EDITORIAL.REVIEW.SENSITIVE_INFO.NO_SECRETS",
+ "HOUSE.LINKS.URLS.AVOID.EXPIRING_SIGNED"
+ ],
"tone": [
- "CMOS.PUNCTUATION.EXCLAMATION.USE_SPARINGLY"
+ "BRING.TYPOGRAPHY.SERIF.BODY_TEXT_DEFAULT",
+ "BRING.TYPOGRAPHY.SERIF.SERIF_SANS_BALANCE",
+ "BRING.TYPOGRAPHY.TYPEFACE.PURPOSE_MATCH_CONTENT",
+ "CMOS.PUNCTUATION.COMMAS.REGISTER.FLEX",
+ "CMOS.PUNCTUATION.EXCLAMATION.USE_SPARINGLY",
+ "HOUSE.EDITORIAL.STRUCTURE.AUDIENCE.STATED",
+ "HOUSE.EDITORIAL.TONE.PROFESSIONAL_AND_RESPECTFUL"
+ ],
+ "too": [
+ "CMOS.PUNCTUATION.COMMAS.TOO_EITHER.OMIT",
+ "CMOS.PUNCTUATION.COMMAS.TOO_MID_SENTENCE"
+ ],
+ "top margin": [
+ "BRING.LAYOUT.MARGINS.TOP_BOTTOM.BALANCE"
+ ],
+ "totals": [
+ "CMOS.TABLES.SUBTOTALS.CLEAR"
],
"tracking": [
+ "BRING.CODE.RAG.NO_LETTERSPACING",
+ "BRING.TYPOGRAPHY.CAPS.TRACKING_REVIEW",
"BRING.TYPOGRAPHY.TRACKING.CAPS_SMALLCAPS_AND_LONG_DIGITS",
- "BRING.TYPOGRAPHY.TRACKING.LOWERCASE.AVOID"
+ "BRING.TYPOGRAPHY.TRACKING.LOWERCASE.AVOID",
+ "HOUSE.LINKS.URLS.CANONICAL.NO_TRACKING_PARAMS"
+ ],
+ "tracking params": [
+ "HOUSE.LINKS.AUTO.TRACKING_PARAMS.AVOID"
],
"trailing period": [
"HOUSE.LINKS.PUNCTUATION.NO_TRAILING_PUNCT"
],
+ "trailing phrase": [
+ "CMOS.CITATIONS.S13_94.TITLES.TRAILING_PHRASE.PLACEMENT"
+ ],
+ "trailing punctuation": [
+ "CMOS.LINKS.TRAILING_PUNCTUATION_OUTSIDE",
+ "CMOS.PUNCTUATION.URLS.TRAILING_PUNCTUATION"
+ ],
+ "trailing slash": [
+ "CMOS.CITATIONS.S13_12.URLS.TRAILING_SLASH",
+ "HOUSE.LINKS.URLS.BARE_DOMAIN.TRAILING_SLASH"
+ ],
+ "trailing thought": [
+ "CMOS.PUNCTUATION.ELLIPSIS.USE_CASES"
+ ],
+ "trailing whitespace": [
+ "HOUSE.CODE.BLOCKS.TRAILING_WHITESPACE.AVOID"
+ ],
+ "trailing zeros": [
+ "CMOS.NUMBERS.DECIMALS.TRAILING_ZEROS.AVOID"
+ ],
+ "transcripts": [
+ "HOUSE.ACCESSIBILITY.MEDIA.TRANSCRIPTS"
+ ],
+ "translated by": [
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.BIBLIO",
+ "CMOS.CITATIONS.S13_24.AUTHOR_PLUS_EDITOR.BIBLIO_SPELL_OUT"
+ ],
"translated text": [
"CMOS.PUNCTUATION.BRACKETS.TRANSLATED_TEXT"
],
+ "translation": [
+ "CMOS.I18N.ACRONYMS.LANGUAGE_SPECIFIC",
+ "CMOS.I18N.MEANINGFUL_TRANSLATIONS.NOT_LITERAL",
+ "CMOS.I18N.TRANSLATION.INDICATE"
+ ],
"translations": [
- "CMOS.PUNCTUATION.PARENS.GLOSSES_TRANSLATIONS"
+ "CMOS.PUNCTUATION.PARENS.GLOSSES_TRANSLATIONS",
+ "HOUSE.I18N.TRANSLATION.LABELS"
+ ],
+ "translator": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.CONTRIBUTOR_ROLES.LABEL_CLEARLY",
+ "CMOS.CITATIONS.BIBLIOGRAPHY.NO_AUTHOR.EDITOR_AS_LEAD_WHEN_APPROPRIATE",
+ "CMOS.CITATIONS.S13_24.AUTHOR_PLUS_EDITOR.NOTES_ABBREVIATE"
+ ],
+ "translator notes": [
+ "CMOS.I18N.PARENS.BRACKETS.TRANSLATOR_NOTES"
+ ],
+ "translators": [
+ "CMOS.CITATIONS.S13_93.BIBLIOGRAPHY.EDITED_VOLUMES.ROLE_MARKING"
+ ],
+ "transliteration": [
+ "CMOS.CITATIONS.S13_72.BIBLIOGRAPHY.SORTING.DIACRITICS_AND_TRANSLITERATION",
+ "CMOS.I18N.TRANSLITERATION.SYSTEM.CONSISTENT"
+ ],
+ "transparency": [
+ "CMOS.CITATIONS.S13_11.SHORTENERS.OBSCURE",
+ "HOUSE.ACCESSIBILITY.LINKS.AVOID_SHORTENERS"
+ ],
+ "trillion": [
+ "CMOS.NUMBERS.S9_9.BILLION_TRILLION.LOCALE_CHECK"
+ ],
+ "true italics": [
+ "BRING.TYPOGRAPHY.FAMILY.TRUE_ITALICS"
+ ],
+ "truncation": [
+ "CMOS.CITATIONS.S13_99.LONG_TITLES.TRUNCATION.AVOID",
+ "HOUSE.CODE.OUTPUT.TRUNCATION.LABELED"
+ ],
+ "trust": [
+ "HOUSE.LINKS.TEXT.LINK_TARGET_MISMATCH"
+ ],
+ "turn of the century": [
+ "CMOS.NUMBERS.S9_34.CENTURY_TURN.AVOID_AMBIGUITY"
+ ],
+ "two authors": [
+ "CMOS.CITATIONS.S13_23.TWO_AUTHORS.NOTES_LIST_BOTH"
+ ],
+ "two-sided": [
+ "CMOS.LAYOUT.PAGINATION.FACING_PAGES.BLANKS"
],
"two-year spans": [
"CMOS.PUNCTUATION.SLASHES.TWO_YEAR_SPANS"
],
+ "type": [
+ "CMOS.NUMBERS.S9_8.SEVERITY_CLASSIFICATIONS"
+ ],
"type size": [
"BRING.LAYOUT.LEADING.ADJUST_FOR_SIZE_CHANGES",
- "BRING.LAYOUT.MEASURE.ADJUST_FOR_TYPE_SIZE"
+ "BRING.LAYOUT.MEASURE.ADJUST_FOR_TYPE_SIZE",
+ "CMOS.LAYOUT.SPACING.LEADING.CHOOSE"
+ ],
+ "type sizes": [
+ "BRING.TYPOGRAPHY.SIZE.AVOID_TOO_MANY_SIZES"
+ ],
+ "typeface": [
+ "BRING.TYPOGRAPHY.TYPEFACE.PURPOSE_MATCH_CONTENT"
+ ],
+ "typefaces": [
+ "BRING.TYPOGRAPHY.TYPEFACE.LIMIT_NUMBER",
+ "BRING.TYPOGRAPHY.TYPEFACE.SIMILAR_FACES_AVOID"
+ ],
+ "typefitting": [
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.PRINT_HAIR_SPACE"
+ ],
+ "typography": [
+ "CMOS.FIGURES.LABELS.FONT.CONSISTENT",
+ "CMOS.PUNCTUATION.APOSTROPHE.SMART",
+ "HOUSE.CODE.BLOCKS.NO_SMART_QUOTES"
+ ],
+ "u.s.": [
+ "CMOS.ABBREVIATIONS.US_USA.CONSISTENT"
+ ],
+ "uk": [
+ "CMOS.I18N.LANGUAGE.CONSISTENT_SPELLING"
+ ],
+ "underline": [
+ "HOUSE.ACCESSIBILITY.LINKS.VISUALLY_DISTINCT",
+ "HOUSE.TYPOGRAPHY.HTML.LINK_DECORATION.CONSISTENT"
+ ],
+ "underlining": [
+ "BRING.TYPOGRAPHY.ITALICS.EMPHASIS_NOT_UNDERLINE"
+ ],
+ "unicode": [
+ "HOUSE.CODE.TYPOGRAPHY.UNICODE.MINIMIZE"
+ ],
+ "unified": [
+ "HOUSE.CODE.DIFFS.UNIFIED_FORMAT"
+ ],
+ "unique": [
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.UNIQUE_TARGETS"
+ ],
+ "unit placement": [
+ "CMOS.NUMBERS.RANGES.UNITS.PLACEMENT_CONSISTENT"
+ ],
+ "unit symbols": [
+ "CMOS.ABBREVIATIONS.UNITS.NO_PLURAL_SYMBOLS"
],
"units": [
"BRING.TABLES.UNITS.IN_HEADERS",
- "CMOS.NUMBERS.DEGRADED.HARD_WRAP_UNITS"
+ "CMOS.ABBREVIATIONS.UNITS.ABBREV_WITH_NUMERALS_ONLY",
+ "CMOS.ABBREVIATIONS.UNITS.NO_PERIODS",
+ "CMOS.ABBREVIATIONS.UNITS.SPELL_OUT_WITHOUT_NUMERALS",
+ "CMOS.FIGURES.AXES.UNITS.CONSISTENT",
+ "CMOS.FIGURES.UNITS.LABEL_AXES",
+ "CMOS.I18N.UNITS.SYMBOLS.STANDARD",
+ "CMOS.NUMBERS.DEGRADED.HARD_WRAP_UNITS",
+ "CMOS.NUMBERS.RANGES.REPEAT_UNIT_IF_AMBIG",
+ "CMOS.NUMBERS.S9_18.NO_HYPHEN.NUMERAL_UNIT",
+ "CMOS.NUMBERS.S9_18.UNIT_WITHOUT_NUMERAL.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_19.UNIT_SPACED.SINGLE",
+ "CMOS.NUMBERS.S9_8.ABBREVIATED_UNITS.NUMERALS",
+ "CMOS.TABLES.UNITS.CONSISTENT",
+ "CMOS.TABLES.UNITS.IN_HEADERS",
+ "HOUSE.EDITORIAL.CLARITY.DEFINE_METRICS",
+ "HOUSE.FIGURES.AXES.UNITS.LABELED",
+ "HOUSE.I18N.UNITS.SPACING.CONSISTENT",
+ "HOUSE.TABLES.UNITS.IN_HEADERS"
],
"units of measure": [
"CMOS.NUMBERS.NUMERALS.MEASUREMENTS.UNITS"
@@ -1807,69 +6931,260 @@
"unnumbered notes": [
"CMOS.CITATIONS.NOTES.UNNUMBERED.NOT_FOR_SOURCES"
],
+ "unordered lists": [
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.UNORDERED_FRAGMENTS"
+ ],
+ "unpublished": [
+ "CMOS.CITATIONS.S13_1.ALL_SOURCE_TYPES"
+ ],
+ "updated": [
+ "HOUSE.FRONTMATTER.METADATA.LAST_REVIEWED"
+ ],
+ "updated sources": [
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.WIKIS"
+ ],
+ "url": [
+ "CMOS.CITATIONS.S13_14.ONLINE.URL_INDICATOR",
+ "CMOS.CITATIONS.S13_26.JOURNAL.ONLINE.URL_OR_DOI",
+ "CMOS.CITATIONS.S13_7.DOI.URL_FORM",
+ "CMOS.PUNCTUATION.URLS.HYPERTEXT_EXCLUDES_PUNCTUATION",
+ "CMOS.PUNCTUATION.URLS.NO_WRAPPERS",
+ "CMOS.PUNCTUATION.URLS.PUNCTUATE_NORMALLY",
+ "CMOS.PUNCTUATION.URLS.TRAILING_PUNCTUATION"
+ ],
+ "url endings": [
+ "CMOS.LINKS.REPHRASE_IF_URL_ENDS_PUNCT"
+ ],
+ "url placement": [
+ "CMOS.CITATIONS.S13_6.URL.FINAL_ELEMENT"
+ ],
"url wrapping": [
"HOUSE.LINKS.WRAP.SAFE_BREAKS"
],
"urls": [
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_CODE_URLS",
+ "CMOS.BACKMATTER.REFERENCES.DOI.OR_URL",
"CMOS.CITATIONS.ONLINE.URLS.STABLE",
+ "CMOS.CITATIONS.S13_12.URLS.NO_SENTENCE_START",
+ "CMOS.CITATIONS.S13_12.URLS.PUNCTUATION_AFTER",
+ "CMOS.LINKS.NO_WRAPPERS",
+ "CMOS.LINKS.PUNCTUATE_NORMALLY",
+ "CMOS.LINKS.TRAILING_PUNCTUATION_OUTSIDE",
+ "HOUSE.CODE.URLS.IN_CODE.AVOID_WRAPPING",
+ "HOUSE.LINKS.URLS.NO_BACKSLASH",
+ "HOUSE.LINKS.URLS.NO_TRAILING_PARENS",
+ "HOUSE.LINKS.URLS.NO_WHITESPACE",
"HOUSE.LINKS.URLS.PREFER_HTTPS"
],
+ "us": [
+ "CMOS.ABBREVIATIONS.US_USA.CONSISTENT",
+ "CMOS.I18N.LANGUAGE.CONSISTENT_SPELLING"
+ ],
+ "us style": [
+ "CMOS.PUNCTUATION.QUOTES.US_STYLE_PERIODS_COMMAS"
+ ],
+ "us/uk": [
+ "HOUSE.EDITORIAL.CONSISTENCY.SPELLING_VARIANT.CHOOSE_ONE"
+ ],
+ "usa": [
+ "CMOS.ABBREVIATIONS.US_USA.CONSISTENT"
+ ],
"usd": [
"CMOS.NUMBERS.CURRENCY.FORMAT.SYMBOL_PLACEMENT"
],
+ "usernames": [
+ "HOUSE.CODE.BLOCKS.NO_PERSONAL_PATHS"
+ ],
+ "utc": [
+ "HOUSE.EDITORIAL.CONSISTENCY.TIMEZONE.EXPLICIT"
+ ],
+ "utm": [
+ "HOUSE.LINKS.AUTO.TRACKING_PARAMS.AVOID"
+ ],
+ "variable font": [
+ "BRING.TYPOGRAPHY.FAMILY.USE_DESIGNED_WEIGHTS"
+ ],
+ "variations": [
+ "CMOS.CITATIONS.S13_4.FLEXIBILITY.BY_AGREEMENT"
+ ],
+ "vector": [
+ "CMOS.FIGURES.FORMAT.VECTOR_WHEN_POSSIBLE",
+ "HOUSE.FIGURES.FORMAT.VECTOR_FOR_LINE_ART"
+ ],
"vehicles": [
"CMOS.NUMBERS.VEHICLES.VESSELS_NUMBERS"
],
+ "verb": [
+ "CMOS.PUNCTUATION.COLONS.AVOID_AFTER_PREPOSITION"
+ ],
+ "verbs": [
+ "HOUSE.EDITORIAL.LISTS.ITEMS.ACTIONABLE"
+ ],
+ "verification": [
+ "CMOS.CITATIONS.S13_1.PURPOSE.COURTESY",
+ "CMOS.CITATIONS.S13_13.METADATA.CHECK_FIELDS",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.UNVERIFIABLE",
+ "CMOS.CITATIONS.S13_6.URLS.IN_MANUSCRIPT",
+ "CMOS.CITATIONS.S13_7.DOI.RESOLUTION",
+ "HOUSE.EDITORIAL.REVIEW.LINKS.VERIFY"
+ ],
"version": [
- "CMOS.CITATIONS.ONLINE.VERSION.CITE_RIGHT_VERSION"
+ "CMOS.CITATIONS.ONLINE.VERSION.CITE_RIGHT_VERSION",
+ "CMOS.CITATIONS.S13_105.BIBLIOGRAPHY.REPORTS.ISSUING_BODY_AND_VERSION",
+ "CMOS.CITATIONS.S13_106.BIBLIOGRAPHY.DATASETS.VERSION_AND_PROVENANCE",
+ "CMOS.CITATIONS.S13_14.CITE_VERSION",
+ "CMOS.FRONTMATTER.EDITION.VERSION_VISIBLE",
+ "CMOS.FRONTMATTER.REVISION_HISTORY.WHEN_REQUIRED",
+ "HOUSE.FRONTMATTER.METADATA.VERSION"
+ ],
+ "version consulted": [
+ "CMOS.CITATIONS.S13_59.NOTES.MULTI_EDITIONS.CITE_VERSION_USED"
],
"versioned web": [
"CMOS.CITATIONS.ONLINE.ACCESS_DATE.WHEN_NEEDED"
],
+ "versions": [
+ "HOUSE.CODE.BLOCKS.PRECONDITIONS.STATED",
+ "HOUSE.CODE.REFERENCES.VERSION_PIN"
+ ],
+ "vertical list": [
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SENTENCE_ITEMS_VERTICAL",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.INTRO_COLON",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.LONG_OR_MULTI"
+ ],
"vertical rhythm": [
"BRING.HEADINGS.SPACING.VERTICAL_RHYTHM",
- "BRING.LAYOUT.VERTICAL_RHYTHM.MEASURED_INTERVALS.MULTIPLES"
+ "BRING.LAYOUT.VERTICAL_RHYTHM.MEASURED_INTERVALS.MULTIPLES",
+ "CMOS.LAYOUT.SPACING.VERTICAL_RHYTHM"
],
"vessels": [
"CMOS.NUMBERS.VEHICLES.VESSELS_NUMBERS"
],
+ "video": [
+ "CMOS.CITATIONS.S13_102.BIBLIOGRAPHY.AUDIOVISUAL.CREDITS"
+ ],
+ "vocative comma": [
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS"
+ ],
+ "voice": [
+ "CMOS.PUNCTUATION.COMMAS.SPLICES.EDITORIAL_DISCRETION",
+ "CMOS.PUNCTUATION.SEMICOLONS.AVOID_DIALOGUE"
+ ],
"volume": [
"CMOS.CITATIONS.NOTES.JOURNAL.ARTICLE_ELEMENTS",
- "CMOS.NUMBERS.PERIODICALS.VOLUME_ISSUE"
+ "CMOS.CITATIONS.S13_110.AUTHOR_DATE.JOURNAL_ARTICLES.CORE_FIELDS",
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_VOLUME",
+ "CMOS.CITATIONS.S13_96.BIBLIOGRAPHY.JOURNAL_ARTICLES.VOLUME_ISSUE_PAGES",
+ "CMOS.NUMBERS.PERIODICALS.VOLUME_ISSUE",
+ "CMOS.NUMBERS.S9_29.PERIODICALS.OMIT_WORDS",
+ "CMOS.NUMBERS.S9_29.PERIODICALS.ORDER",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.VOLUMES_ISSUES"
+ ],
+ "volume format": [
+ "CMOS.CITATIONS.S13_26.JOURNAL.VOLUME_FORMAT"
+ ],
+ "votes": [
+ "CMOS.NUMBERS.S9_8.SCORES_VOTES.NUMERALS"
],
"w.b.": [
"BRING.TYPOGRAPHY.SPACING.INITIALS.THIN_SPACE"
],
+ "warnings": [
+ "HOUSE.CODE.SHELL.DESTRUCTIVE.WARN"
+ ],
+ "weasel words": [
+ "HOUSE.EDITORIAL.CLARITY.AVOID_WEASEL_WORDS"
+ ],
+ "web sources": [
+ "CMOS.CITATIONS.S13_17.PRESERVE.NONPUBLISHED"
+ ],
"weight": [
"BRING.HEADINGS.SUBHEADS.RIGHT_SIDEHEADS.VISIBILITY",
- "BRING.HEADINGS.WEIGHT_SIZE.HIERARCHY_SCALE"
+ "BRING.HEADINGS.WEIGHT_SIZE.HIERARCHY_SCALE",
+ "BRING.TYPOGRAPHY.BOLD.HEADING_HIERARCHY_BALANCE",
+ "BRING.TYPOGRAPHY.FAMILY.WEIGHT_CONTRAST_CLEAR",
+ "BRING.TYPOGRAPHY.WEIGHT.HIERARCHY_CLEAR",
+ "CMOS.TABLES.GRIDLINES.LIGHT"
+ ],
+ "weights": [
+ "BRING.TYPOGRAPHY.FAMILY.LIMIT_STYLE_VARIANTS",
+ "BRING.TYPOGRAPHY.FAMILY.USE_DESIGNED_WEIGHTS",
+ "BRING.TYPOGRAPHY.WEIGHT.AVOID_TOO_MANY_WEIGHTS"
+ ],
+ "whether": [
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.THAT_WHETHER"
+ ],
+ "which": [
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_THAT_WHICH"
+ ],
+ "white space": [
+ "BRING.LAYOUT.PAGE.WHITE_SPACE.DISTRIBUTION",
+ "BRING.LAYOUT.PAGINATION.AVOID_EXCESS_WHITE_SPACE",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.AVOID_TOP_OF_PAGE"
],
"whitespace": [
"BRING.TABLES.FURNITURE.MINIMIZE",
- "BRING.TABLES.GROUPING.WHITESPACE"
+ "BRING.TABLES.GROUPING.WHITESPACE",
+ "CMOS.TABLES.GROUPING.WHITESPACE",
+ "HOUSE.CODE.BLOCKS.INDENTATION.CONSISTENT",
+ "HOUSE.LINKS.URLS.NO_WHITESPACE"
],
"whole numbers": [
"CMOS.NUMBERS.FRACTIONS.MIXED.WHOLE_PLUS_FRACTION"
],
"widow": [
- "BRING.LAYOUT.PAGINATION.WIDOWS_AVOID"
+ "BRING.HEADINGS.NO_SINGLE_WORD_LINE",
+ "BRING.LAYOUT.PAGINATION.WIDOWS_AVOID",
+ "BRING.LAYOUT.PARAGRAPH.AVOID_WIDOW_END",
+ "CMOS.LAYOUT.PAGINATION.AVOID_SINGLE_LINE_ENDING",
+ "CMOS.LAYOUT.PAGINATION.WIDOWS.AVOID"
+ ],
+ "widths": [
+ "BRING.TYPOGRAPHY.FAMILY.LIMIT_STYLE_VARIANTS"
+ ],
+ "wikis": [
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.WIKIS"
+ ],
+ "word ranges": [
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.WORD_RANGES"
],
"word space": [
- "BRING.TYPOGRAPHY.SPACING.WORD_SPACE.DEFINE"
+ "BRING.TYPOGRAPHY.SPACING.WORD_SPACE.DEFINE",
+ "CMOS.PUNCTUATION.SPACING.WORD_SPACE_DEFAULT"
],
"word spacing": [
"BRING.TYPOGRAPHY.SPACING.WORD_SPACE.DEFINE"
],
+ "words": [
+ "CMOS.NUMBERS.S9_1.OVERVIEW.FACTORS"
+ ],
+ "works cited": [
+ "CMOS.CITATIONS.S13_61.BIBLIOGRAPHY.SCOPE.LABEL_CLEARLY"
+ ],
"wrap": [
"HOUSE.CODE.BLOCKS.NO_CLIPPING"
],
+ "wrappers": [
+ "CMOS.LINKS.NO_WRAPPERS",
+ "CMOS.PUNCTUATION.URLS.NO_WRAPPERS"
+ ],
"wrapping": [
"HOUSE.LAYOUT.OVERFLOW.OVERFULL_LINES.REPORT"
],
+ "x-height": [
+ "BRING.TYPOGRAPHY.FAMILY.METRICS_MATCH_WHEN_MIXING",
+ "BRING.TYPOGRAPHY.SERIF.PAIR_WITH_COMPATIBLE_XHEIGHT",
+ "BRING.TYPOGRAPHY.TYPEFACE.FALLBACKS_COMPATIBLE_METRICS"
+ ],
+ "yaml": [
+ "HOUSE.CODE.BLOCKS.CONFIG.VALID"
+ ],
"year": [
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.PARENTHETICAL",
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_YEAR",
"CMOS.NUMBERS.CURRENCY.HISTORICAL.YEAR_CONTEXT",
- "CMOS.NUMBERS.DATES.YEAR_NUMERALS"
+ "CMOS.NUMBERS.DATES.YEAR_NUMERALS",
+ "HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.YEAR_REQUIRED"
],
"year placement": [
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ORDER_AND_YEAR"
@@ -1877,7 +7192,31 @@
"year range": [
"CMOS.NUMBERS.INCLUSIVE.YEARS"
],
+ "year ranges": [
+ "CMOS.NUMBERS.INCLUSIVE.YEARS.CENTURY_CROSSING"
+ ],
+ "year-only": [
+ "HOUSE.CITATIONS.AUTHOR_DATE.PAREN_YEAR_ONLY"
+ ],
+ "years": [
+ "CMOS.NUMBERS.S9_31.YEAR_SENTENCE_START_ALLOWED",
+ "CMOS.NUMBERS.S9_31.YEAR_STANDALONE",
+ "CMOS.NUMBERS.S9_5.YEARS.MAY_BEGIN"
+ ],
+ "yes": [
+ "CMOS.PUNCTUATION.COMMAS.INTRO_YES_NO"
+ ],
+ "zero": [
+ "CMOS.NUMBERS.S9_2.GENERAL_RULE.ZERO_TO_ONE_HUNDRED"
+ ],
"zero through nine": [
- "CMOS.NUMBERS.RULE_SELECTION.ALTERNATIVE_ZERO_TO_NINE"
+ "CMOS.NUMBERS.RULE_SELECTION.ALTERNATIVE_ZERO_TO_NINE",
+ "CMOS.NUMBERS.S9_3.ALTERNATIVE_RULE.ZERO_TO_NINE"
+ ],
+ "zero width": [
+ "HOUSE.LINKS.URLS.NO_ZERO_WIDTH"
+ ],
+ "zeroth": [
+ "CMOS.NUMBERS.S9_6.ZERO.ORDINAL_TH"
]
}
diff --git a/spec/indexes/source_refs_all.json b/spec/indexes/source_refs_all.json
index 8d4aafe..f6f9420 100644
--- a/spec/indexes/source_refs_all.json
+++ b/spec/indexes/source_refs_all.json
@@ -1,17 +1,33 @@
{
"BRING \u00a71.2.2 p20 (scan p19)": [
"BRING.HEADINGS.DEGRADED.INFER_STRUCTURE",
- "BRING.HEADINGS.STRUCTURE.MATCH_TEXT_LOGIC"
+ "BRING.HEADINGS.NUMBERING.APPENDIX_LABELS",
+ "BRING.HEADINGS.NUMBERING.CONSISTENT_STYLE",
+ "BRING.HEADINGS.NUMBERING.NO_GAPS",
+ "BRING.HEADINGS.NUMBERING.PREFIXES.CONSISTENT",
+ "BRING.HEADINGS.NUMBERING.PUNCTUATION.CONSISTENT",
+ "BRING.HEADINGS.NUMBERING.SUBLEVELS.DECIMAL_STYLE",
+ "BRING.HEADINGS.STRUCTURE.MATCH_TEXT_LOGIC",
+ "BRING.HEADINGS.TOC.MATCH"
],
"BRING \u00a71.2.3 p21 (scan p20)": [
"BRING.HEADINGS.RELATED_ELEMENTS.COHERENT"
],
+ "BRING \u00a71.2.4 p22 (scan p21)": [
+ "BRING.TYPOGRAPHY.TYPEFACE.CONTRAST_INTENTIONAL",
+ "BRING.TYPOGRAPHY.TYPEFACE.LIMIT_NUMBER",
+ "BRING.TYPOGRAPHY.TYPEFACE.MIXING_BY_ROLE_ONLY",
+ "BRING.TYPOGRAPHY.TYPEFACE.PURPOSE_MATCH_CONTENT",
+ "BRING.TYPOGRAPHY.TYPEFACE.SIMILAR_FACES_AVOID"
+ ],
"BRING \u00a71.2.5 p23 (scan p22)": [
"BRING.LAYOUT.ELEMENT_RELATIONSHIPS.VISIBLE",
"BRING.LAYOUT.FLOATS.PLACEMENT.NEAR_REFERENCE",
"BRING.LAYOUT.GRID.ALIGN_ELEMENTS",
"BRING.LAYOUT.MARGINS.FACING_PAGES.INNER_OUTER",
+ "BRING.LAYOUT.PAGE.BLANKS.INTENTIONAL",
"BRING.LAYOUT.PAGE.FRAME.TEXTBLOCK_BALANCE",
+ "BRING.LAYOUT.PAGE.HEAD_FOOT_BANDS.CONSISTENT",
"BRING.LAYOUT.TEXTBLOCK.CONSISTENT_WIDTH"
],
"BRING \u00a72-4.1 p42": [
@@ -70,6 +86,12 @@
"BRING.LAYOUT.MEASURE.TARGET_RANGE_CHARS"
],
"BRING \u00a72.1.3 p27": [
+ "BRING.CODE.MONO_RAGGED_RIGHT",
+ "BRING.CODE.RAG.AVOID_FAKE_JUSTIFY",
+ "BRING.CODE.RAG.FIXED_WORD_SPACES",
+ "BRING.CODE.RAG.NO_AUTO_HYPHENATION",
+ "BRING.CODE.RAG.NO_LETTERSPACING",
+ "BRING.CODE.RAG.NO_MIN_LINE",
"BRING.LAYOUT.JUSTIFICATION.RAGGED_RIGHT_IF_NEEDED"
],
"BRING \u00a72.1.4 p27": [
@@ -79,6 +101,7 @@
"BRING.TYPOGRAPHY.SPACING.INITIALS.THIN_SPACE"
],
"BRING \u00a72.1.6 p30 (scan p29)": [
+ "BRING.TYPOGRAPHY.CAPS.TRACKING_REVIEW",
"BRING.TYPOGRAPHY.NUMBER_STRINGS.SPACE_FOR_READABILITY",
"BRING.TYPOGRAPHY.TRACKING.CAPS_SMALLCAPS_AND_LONG_DIGITS"
],
@@ -92,6 +115,10 @@
"BRING.TYPOGRAPHY.LETTERFORMS.AVOID_DISTORTION"
],
"BRING \u00a72.2.1 p36 (scan p35)": [
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_BLOCK_QUOTES",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_CAPTIONS",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_HEADINGS",
+ "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_TABLES",
"BRING.LAYOUT.LEADING.ADJUST_FOR_SIZE_CHANGES",
"BRING.LAYOUT.LEADING.ALIGN_BASELINE_GRID",
"BRING.LAYOUT.LEADING.AVOID_TOO_LOOSE",
@@ -107,19 +134,30 @@
"BRING.LAYOUT.VERTICAL_RHYTHM.MEASURED_INTERVALS.MULTIPLES"
],
"BRING \u00a72.2.3 p39 (scan p38)": [
- "BRING.LAYOUT.PAGE.DENSITY.DONT_SUFFOCATE"
+ "BRING.LAYOUT.PAGE.DENSITY.DONT_SUFFOCATE",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.CAPTIONS.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.FIGURES.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.FOOTNOTES.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.HEADINGS.BEFORE_AFTER",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.LISTS.SPACING",
+ "BRING.LAYOUT.VERTICAL_RHYTHM.TABLES.SPACING"
],
"BRING \u00a72.3.1 p39 (scan p38)": [
- "BRING.LAYOUT.PARAGRAPH.OPENING_FLUSH_LEFT"
+ "BRING.LAYOUT.PARAGRAPH.DROP_CAPS.ALIGN_BASELINE",
+ "BRING.LAYOUT.PARAGRAPH.OPENING_FLUSH_LEFT",
+ "BRING.LAYOUT.PARAGRAPH.RUN_IN_HEADS.CONSISTENT"
],
"BRING \u00a72.3.2 p39 (scan p38)": [
"BRING.HEADINGS.PARAGRAPH_INDENT.AFTER_HEAD_NONE",
"BRING.LAYOUT.DEGRADED.HARD_WRAP_REFLOW",
+ "BRING.LAYOUT.PARAGRAPH.AFTER_QUOTE.FLUSH",
"BRING.LAYOUT.PARAGRAPH.BLANK_LINES.SPARING",
+ "BRING.LAYOUT.PARAGRAPH.BLOCK_STYLE.CONSISTENT",
"BRING.LAYOUT.PARAGRAPH.INDENT_AFTER_FIRST",
"BRING.LAYOUT.PARAGRAPH.INDENT_OR_SPACE_NOT_BOTH",
"BRING.LAYOUT.PARAGRAPH.INDENT_SIZE.CONSISTENT",
- "BRING.LAYOUT.PARAGRAPH.NO_INDENT_AFTER_BLOCKS"
+ "BRING.LAYOUT.PARAGRAPH.NO_INDENT_AFTER_BLOCKS",
+ "BRING.LAYOUT.PARAGRAPH.SECTION_BREAKS.CLEAR"
],
"BRING \u00a72.3.3 p40 (scan p39)": [
"BRING.HEADINGS.BLOCK_QUOTE.SPACING_AROUND",
@@ -128,17 +166,81 @@
"BRING.LAYOUT.BLOCK_QUOTES.EXTRA_LEAD",
"BRING.LAYOUT.BLOCK_QUOTES.INDENT_OR_NARROW"
],
+ "BRING \u00a72.3.4 p41 (scan p40)": [
+ "BRING.LAYOUT.PARAGRAPH.INDENT.NOT_TOO_DEEP",
+ "BRING.LAYOUT.PARAGRAPH.INDENT.PROPORTIONAL",
+ "BRING.LAYOUT.PARAGRAPH.INDENT.WITHIN_MEASURE",
+ "BRING.LAYOUT.PARAGRAPH.LISTS.ALIGN_WITH_BODY",
+ "BRING.LAYOUT.PARAGRAPH.LISTS.HANGING_INDENT"
+ ],
+ "BRING \u00a72.4.9 p44 (scan p43)": [
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_AFTER_HEADING",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_BEFORE_LAST_LINE",
+ "BRING.LAYOUT.PAGINATION.AVOID_LONELY_LINE_IN_LISTS",
+ "BRING.LAYOUT.PAGINATION.AVOID_STRANDED_CAPTIONS",
+ "BRING.LAYOUT.PAGINATION.KEEP_FIGURE_WITH_CAPTION",
+ "BRING.LAYOUT.PAGINATION.KEEP_LIST_WITH_INTRO",
+ "BRING.LAYOUT.PAGINATION.KEEP_TABLE_WITH_HEADER",
+ "BRING.LAYOUT.PARAGRAPH.AVOID_WIDOW_END",
+ "BRING.LAYOUT.PARAGRAPH.AVOID_WIDOW_START"
+ ],
+ "BRING \u00a72.5 p41 (scan p40)": [
+ "BRING.TYPOGRAPHY.SIZE.BODY_SIZE_MATCH_MEASURE",
+ "BRING.TYPOGRAPHY.SIZE.LEADING_RELATION"
+ ],
+ "BRING \u00a73.2.1 p46 (scan p45)": [
+ "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_AVOID_LONG_RUNS",
+ "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_SHORT_LABELS_ONLY",
+ "BRING.TYPOGRAPHY.CAPS.AVOID_FOR_EMPHASIS",
+ "BRING.TYPOGRAPHY.CAPS.MIXED_CAPS_CONSISTENT",
+ "BRING.TYPOGRAPHY.CAPS.ROMAN_NUMERALS_SPACING",
+ "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_FOR_ACRONYMS",
+ "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_NOT_FOR_LONG_PASSAGES"
+ ],
+ "BRING \u00a73.3 p50 (scan p49)": [
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_CODE_URLS",
+ "BRING.TYPOGRAPHY.LIGATURES.FI_FL_COLLISIONS",
+ "BRING.TYPOGRAPHY.LIGATURES.KEEP_CONSISTENT",
+ "BRING.TYPOGRAPHY.LIGATURES.STANDARD_ON_BODY"
+ ],
+ "BRING \u00a73.3.1 p50 (scan p49)": [
+ "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_IN_DISPLAY",
+ "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_SPARING"
+ ],
+ "BRING \u00a73.3.2 p52 (scan p51)": [
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ACRONYMS",
+ "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ALL_CAPS",
+ "BRING.TYPOGRAPHY.LIGATURES.DO_NOT_USE_IF_AMBIGUOUS",
+ "BRING.TYPOGRAPHY.LIGATURES.REVIEW_FOR_LANGUAGE"
+ ],
"BRING \u00a74.2 p65 (scan p64)": [
+ "BRING.HEADINGS.AVOID_ABBREVIATIONS",
+ "BRING.HEADINGS.AVOID_STACKED_LEVELS",
+ "BRING.HEADINGS.BREAKS.AT_PHRASE_BOUNDARIES",
"BRING.HEADINGS.CAPITALIZATION.CONSISTENT",
+ "BRING.HEADINGS.CASE.PROPER_NOUNS_PRESERVE",
+ "BRING.HEADINGS.HIERARCHY.MAX_DEPTH",
+ "BRING.HEADINGS.LEADIN_TEXT.BEFORE_LIST",
+ "BRING.HEADINGS.LENGTH.CONCISE",
+ "BRING.HEADINGS.NO_HYPHENATION",
+ "BRING.HEADINGS.NO_SINGLE_WORD_LINE",
+ "BRING.HEADINGS.NO_TERMINAL_COLON",
+ "BRING.HEADINGS.NO_TERMINAL_PERIOD",
+ "BRING.HEADINGS.QUESTION_MARK_ONLY_IF_QUESTION",
+ "BRING.HEADINGS.SECTION_OPENING.PARAGRAPH_REQUIRED",
"BRING.HEADINGS.SPACING.VERTICAL_RHYTHM",
"BRING.HEADINGS.STYLE.PALETTE_LIMIT",
+ "BRING.HEADINGS.SUBHEADS.PARALLEL_GRAMMAR",
"BRING.HEADINGS.SUBHEADS.STYLE_CONTRIBUTES_TO_WHOLE",
- "BRING.HEADINGS.WEIGHT_SIZE.HIERARCHY_SCALE"
+ "BRING.HEADINGS.WEIGHT_SIZE.HIERARCHY_SCALE",
+ "BRING.HEADINGS.WIDTH.BALANCED"
],
"BRING \u00a74.2.1 p65 (scan p64)": [
"BRING.HEADINGS.ALIGNMENT.CONSISTENT_LEVEL",
"BRING.HEADINGS.HIERARCHY.NO_SKIPPED_LEVELS",
"BRING.HEADINGS.MARGIN_HEADS.CLEAR_GUTTER",
+ "BRING.HEADINGS.RUN_IN.END_PUNCTUATION",
+ "BRING.HEADINGS.RUN_IN.SEPARATION.CONSISTENT",
"BRING.HEADINGS.RUN_IN.STANDALONE.CONSISTENT",
"BRING.HEADINGS.SUBHEADS.CROSSHEADS_SIDEHEADS.CHOOSE_DELIBERATELY",
"BRING.HEADINGS.SUBHEADS.LEVELS.AS_MANY_AS_NEEDED",
@@ -150,6 +252,18 @@
"BRING.HEADINGS.SUBHEADS.MIXING.HIERARCHY_PLACEMENT",
"BRING.HEADINGS.SUBHEADS.MIXING_SYMM_ASYMM.AVOID_HAPHAZARD"
],
+ "BRING \u00a74.3.2 p68 (scan p67)": [
+ "BRING.TYPOGRAPHY.WEIGHT.AVOID_TOO_MANY_WEIGHTS",
+ "BRING.TYPOGRAPHY.WEIGHT.BOLD_IN_LONG_PASSAGES_AVOID",
+ "BRING.TYPOGRAPHY.WEIGHT.HEAVY_WEIGHTS_SHORT_LABELS",
+ "BRING.TYPOGRAPHY.WEIGHT.HIERARCHY_CLEAR"
+ ],
+ "BRING \u00a74.3.3 p69 (scan p68)": [
+ "BRING.TYPOGRAPHY.SIZE.AVOID_TOO_MANY_SIZES",
+ "BRING.TYPOGRAPHY.SIZE.DISPLAY_SIZE_BALANCE",
+ "BRING.TYPOGRAPHY.SIZE.SCALE_CONSISTENT",
+ "BRING.TYPOGRAPHY.SIZE.SMALL_TEXT_MINIMUM"
+ ],
"BRING \u00a74.4 p70 (scan p69)": [
"BRING.TABLES.CAPTIONS.CLEAR",
"BRING.TABLES.TITLES.CONSISTENT_PLACEMENT"
@@ -174,12 +288,224 @@
"BRING.TABLES.TYPE_SIZE.READABLE",
"BRING.TABLES.UNITS.IN_HEADERS"
],
+ "BRING \u00a74.4.3 p111 (scan p110)": [
+ "BRING.TYPOGRAPHY.NUMERALS.FRACTIONS_TRUE_GLYPHS",
+ "BRING.TYPOGRAPHY.NUMERALS.SLASHED_ZERO_IF_CONFUSION",
+ "BRING.TYPOGRAPHY.NUMERALS.SUPERIOR_INFERIOR_FOR_NOTES",
+ "BRING.TYPOGRAPHY.NUMERALS.TABULAR_FOR_TABLES"
+ ],
+ "BRING \u00a74.4.3 p111 (scan p70)": [
+ "BRING.LAYOUT.COLUMNS.ALIGN_BASELINES",
+ "BRING.LAYOUT.COLUMNS.COUNT.MODERATE",
+ "BRING.LAYOUT.COLUMNS.GUTTER.CONSISTENT",
+ "BRING.LAYOUT.COLUMNS.GUTTER.SUFFICIENT",
+ "BRING.LAYOUT.COLUMNS.RAGGED_BOTTOM.AVOID",
+ "BRING.LAYOUT.COLUMNS.SIDEBARS.DISTINCT_MEASURE",
+ "BRING.LAYOUT.COLUMNS.SPAN_POLICY.FIGURES",
+ "BRING.LAYOUT.COLUMNS.SPAN_POLICY.TABLES",
+ "BRING.LAYOUT.COLUMNS.USE_FOR_LONG_LISTS",
+ "BRING.LAYOUT.COLUMNS.WIDTH.CONSISTENT"
+ ],
+ "BRING \u00a74.4.4 p72 (scan p71)": [
+ "BRING.TYPOGRAPHY.NUMERALS.AVOID_LINING_IN_LOWERCASE",
+ "BRING.TYPOGRAPHY.NUMERALS.CONSISTENT_STYLE_WITHIN_SECTION",
+ "BRING.TYPOGRAPHY.NUMERALS.FIGURE_STYLE_FOR_CAPTIONS",
+ "BRING.TYPOGRAPHY.NUMERALS.LINING_FOR_CAPS_AND_DISPLAY",
+ "BRING.TYPOGRAPHY.NUMERALS.MIXED_STYLE_AVOID",
+ "BRING.TYPOGRAPHY.NUMERALS.OLDSTYLE_FOR_TEXT",
+ "BRING.TYPOGRAPHY.NUMERALS.PROPORTIONAL_FOR_PROSE",
+ "BRING.TYPOGRAPHY.NUMERALS.SMALL_CAPS_AND_FIGURES"
+ ],
+ "BRING \u00a75.1 p92": [
+ "CMOS.I18N.ITALICS.FOREIGN_WORDS.SPARE"
+ ],
+ "BRING \u00a76.1.1 p93 (scan p92)": [
+ "BRING.TYPOGRAPHY.TYPEFACE.DISPLAY_FACES_FOR_DISPLAY",
+ "BRING.TYPOGRAPHY.TYPEFACE.FALLBACKS_COMPATIBLE_METRICS",
+ "BRING.TYPOGRAPHY.TYPEFACE.FAMILY_WITH_VARIANTS",
+ "BRING.TYPOGRAPHY.TYPEFACE.GLYPH_COVERAGE_REQUIRED",
+ "BRING.TYPOGRAPHY.TYPEFACE.LEGIBILITY_AT_SIZE",
+ "BRING.TYPOGRAPHY.TYPEFACE.OPTICAL_SIZES_USE",
+ "BRING.TYPOGRAPHY.TYPEFACE.TEXT_FACES_FOR_BODY"
+ ],
+ "BRING \u00a76.5.1 p102 (scan p101)": [
+ "BRING.TYPOGRAPHY.FAMILY.LIMIT_STYLE_VARIANTS",
+ "BRING.TYPOGRAPHY.FAMILY.METRICS_MATCH_WHEN_MIXING",
+ "BRING.TYPOGRAPHY.FAMILY.SINGLE_FAMILY_BODY"
+ ],
+ "BRING \u00a76.5.2 p103 (scan p102)": [
+ "BRING.TYPOGRAPHY.FAMILY.ITALIC_FOR_SUBTLE_EMPHASIS",
+ "BRING.TYPOGRAPHY.FAMILY.ITALIC_PUNCTUATION_MATCH",
+ "BRING.TYPOGRAPHY.FAMILY.SMALL_CAPS_SPARE",
+ "BRING.TYPOGRAPHY.FAMILY.TRUE_ITALICS",
+ "BRING.TYPOGRAPHY.FAMILY.TRUE_SMALL_CAPS"
+ ],
+ "BRING \u00a76.5.3 p103 (scan p102)": [
+ "BRING.TYPOGRAPHY.BOLD.AVOID_LONG_PASSAGES",
+ "BRING.TYPOGRAPHY.BOLD.HEADING_HIERARCHY_BALANCE",
+ "BRING.TYPOGRAPHY.BOLD.LABELS_SHORT",
+ "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ALL_CAPS",
+ "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ITALICS_LONG",
+ "BRING.TYPOGRAPHY.BOLD.SPARING_USE",
+ "BRING.TYPOGRAPHY.FAMILY.AVOID_FAUX_BOLD",
+ "BRING.TYPOGRAPHY.FAMILY.BOLD_FOR_STRONG_EMPHASIS",
+ "BRING.TYPOGRAPHY.FAMILY.USE_DESIGNED_WEIGHTS",
+ "BRING.TYPOGRAPHY.FAMILY.WEIGHT_CONTRAST_CLEAR"
+ ],
+ "BRING \u00a76.5.5 p105 (scan p104)": [
+ "BRING.TYPOGRAPHY.SERIF.AVOID_MIX_SAME_ROLE",
+ "BRING.TYPOGRAPHY.SERIF.BODY_TEXT_DEFAULT",
+ "BRING.TYPOGRAPHY.SERIF.SANS_FOR_DISPLAY",
+ "BRING.TYPOGRAPHY.SERIF.SERIF_SANS_BALANCE"
+ ],
+ "BRING \u00a77.2.1 p122 (scan p121)": [
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_NUMERAL_ITALICS",
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_STACKED_EMPHASIS",
+ "BRING.TYPOGRAPHY.ITALICS.EMPHASIS_NOT_UNDERLINE",
+ "BRING.TYPOGRAPHY.ITALICS.LONG_SPANS_AVOID",
+ "BRING.TYPOGRAPHY.ITALICS.PUNCTUATION_FOLLOWS_STYLE",
+ "BRING.TYPOGRAPHY.ITALICS.SPARING",
+ "BRING.TYPOGRAPHY.ITALICS.TERMS_INTRODUCED_SPARE"
+ ],
+ "BRING \u00a77.2.2 p124 (scan p123)": [
+ "BRING.TYPOGRAPHY.ITALICS.CONSISTENT_TITLE_TREATMENT",
+ "BRING.TYPOGRAPHY.ITALICS.TITLES_STANDALONE_WORKS"
+ ],
+ "BRING \u00a77.2.7 p130 (scan p129)": [
+ "BRING.TYPOGRAPHY.ITALICS.AVOID_IN_ALL_CAPS_HEADINGS",
+ "BRING.TYPOGRAPHY.ITALICS.HEADINGS_AVOID",
+ "BRING.TYPOGRAPHY.ITALICS.RUNNING_HEADS_AVOID"
+ ],
+ "BRING \u00a78.3 p160 (scan p117)": [
+ "BRING.LAYOUT.PAGE.SHAPE.PROPORTIONATE",
+ "BRING.LAYOUT.PAGE.WHITE_SPACE.DISTRIBUTION"
+ ],
+ "BRING \u00a78.3.1 p160 (scan p117)": [
+ "BRING.LAYOUT.PAGE.TEXTBLOCK.POSITION"
+ ],
+ "BRING \u00a78.4.2 p163 (scan p162)": [
+ "BRING.TYPOGRAPHY.CONTRAST.AVOID_EXTREME_MIX",
+ "BRING.TYPOGRAPHY.CONTRAST.FONT_PAIRING_MATCH",
+ "BRING.TYPOGRAPHY.SERIF.PAIR_WITH_COMPATIBLE_XHEIGHT",
+ "BRING.TYPOGRAPHY.SERIF.STROKE_CONTRAST_COMPATIBLE"
+ ],
+ "BRING \u00a78.5 p165 (scan p120)": [
+ "BRING.LAYOUT.MARGINS.AVOID_CROWDING",
+ "BRING.LAYOUT.MARGINS.CONSISTENT.ACROSS_SECTIONS",
+ "BRING.LAYOUT.MARGINS.FOOTNOTE.CLEARANCE",
+ "BRING.LAYOUT.MARGINS.NOTES.OUTSIDE_TEXTBLOCK",
+ "BRING.LAYOUT.MARGINS.PROPORTION.BALANCED",
+ "BRING.LAYOUT.MARGINS.RUNNING_HEAD.CLEARANCE"
+ ],
+ "BRING \u00a78.5.1 p165 (scan p120)": [
+ "BRING.LAYOUT.MARGINS.GUTTER.ALLOW_BINDING",
+ "BRING.LAYOUT.MARGINS.OUTER_LARGER_THAN_INNER"
+ ],
+ "BRING \u00a78.5.2 p165 (scan p120)": [
+ "BRING.LAYOUT.MARGINS.BLEED.ONLY_WHEN_ENABLED",
+ "BRING.LAYOUT.MARGINS.TOP_BOTTOM.BALANCE"
+ ],
+ "BRING \u00a78.6.1 p166 (scan p121)": [
+ "BRING.LAYOUT.PAGE.ODD_EVEN.CONSISTENT",
+ "BRING.LAYOUT.PAGE.OPENING_SPREAD.RULE"
+ ],
+ "BRING \u00a78.8.3 p178 (scan p122)": [
+ "BRING.LAYOUT.PAGE.FACING_ELEMENTS.ALIGN",
+ "BRING.LAYOUT.PAGE.SPREADS.ALIGN_BASELINES",
+ "BRING.LAYOUT.PAGE.SPREADS.BALANCE_CONTENT"
+ ],
+ "BRING \u00a79.4 p42 (scan p41)": [
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_IN_BLOCK_QUOTES",
+ "BRING.LAYOUT.PAGINATION.AVOID_BREAK_IN_EQUATIONS",
+ "BRING.LAYOUT.PAGINATION.AVOID_EXCESS_WHITE_SPACE",
+ "BRING.LAYOUT.PAGINATION.BALANCE_FINAL_PAGE",
+ "BRING.LAYOUT.PAGINATION.CLEAR_SECTION_BREAKS"
+ ],
+ "CMOS18 \u00a71.1 p5": [
+ "CMOS.FRONTMATTER.ABSTRACT.WHEN_APPROPRIATE",
+ "CMOS.FRONTMATTER.ACCESSIBILITY.NOTES",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.PLACEMENT",
+ "CMOS.FRONTMATTER.AUDIENCE.SCOPE.STATED",
+ "CMOS.FRONTMATTER.CHANGELOG.LINKS",
+ "CMOS.FRONTMATTER.CITATION_STYLE.DECLARED",
+ "CMOS.FRONTMATTER.CONTACT.OWNERSHIP",
+ "CMOS.FRONTMATTER.DISCLAIMERS.WHEN_REQUIRED",
+ "CMOS.FRONTMATTER.EDITION.VERSION_VISIBLE",
+ "CMOS.FRONTMATTER.LANGUAGE.NOTICE",
+ "CMOS.FRONTMATTER.LICENSE.ATTRIBUTION",
+ "CMOS.FRONTMATTER.LISTS.OF_FIGURES_TABLES.WHEN_NEEDED",
+ "CMOS.FRONTMATTER.NAVIGATION.METADATA",
+ "CMOS.FRONTMATTER.PREFACE.PURPOSE",
+ "CMOS.FRONTMATTER.READING_TIME.WHEN_HELPFUL",
+ "CMOS.FRONTMATTER.REVISION_HISTORY.WHEN_REQUIRED",
+ "CMOS.FRONTMATTER.SECURITY.CLASSIFICATION",
+ "CMOS.FRONTMATTER.TERMS.DEFINITIONS.EARLY",
+ "CMOS.FRONTMATTER.TITLEPAGE.PRESENT",
+ "CMOS.FRONTMATTER.TOC.WHEN_NEEDED"
+ ],
"CMOS18 \u00a71.10 p8 (scan p30)": [
"CMOS.HEADINGS.RUNNING_HEADS.DEFINITION",
"CMOS.HEADINGS.RUNNING_HEADS.DIVISION_MATCH",
"CMOS.HEADINGS.RUNNING_HEADS.LENGTH_SHORT",
"CMOS.HEADINGS.RUNNING_HEADS.NAVIGATION_SCOPE"
],
+ "CMOS18 \u00a71.111 p36 (scan p1129)": [
+ "CMOS.FRONTMATTER.COPYRIGHT.NOTICES.PRESENT"
+ ],
+ "CMOS18 \u00a71.112 p112 (scan p1129)": [
+ "CMOS.FRONTMATTER.COPYRIGHT.RIGHTS.CONTACT"
+ ],
+ "CMOS18 \u00a71.2 p7": [
+ "CMOS.FRONTMATTER.ACCESSIBILITY.NOTES",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.PLACEMENT",
+ "CMOS.FRONTMATTER.AUDIENCE.SCOPE.STATED",
+ "CMOS.FRONTMATTER.CHANGELOG.LINKS",
+ "CMOS.FRONTMATTER.CITATION_STYLE.DECLARED",
+ "CMOS.FRONTMATTER.CONTACT.OWNERSHIP",
+ "CMOS.FRONTMATTER.DISCLAIMERS.WHEN_REQUIRED",
+ "CMOS.FRONTMATTER.EDITION.VERSION_VISIBLE",
+ "CMOS.FRONTMATTER.LANGUAGE.NOTICE",
+ "CMOS.FRONTMATTER.LICENSE.ATTRIBUTION",
+ "CMOS.FRONTMATTER.LISTS.OF_FIGURES_TABLES.WHEN_NEEDED",
+ "CMOS.FRONTMATTER.NAVIGATION.METADATA",
+ "CMOS.FRONTMATTER.PREFACE.PURPOSE",
+ "CMOS.FRONTMATTER.READING_TIME.WHEN_HELPFUL",
+ "CMOS.FRONTMATTER.REVISION_HISTORY.WHEN_REQUIRED",
+ "CMOS.FRONTMATTER.SECURITY.CLASSIFICATION",
+ "CMOS.FRONTMATTER.TERMS.DEFINITIONS.EARLY",
+ "CMOS.FRONTMATTER.TITLEPAGE.PRESENT",
+ "CMOS.FRONTMATTER.TOC.WHEN_NEEDED"
+ ],
+ "CMOS18 \u00a71.22 p76 (scan p1127)": [
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.NAMES.CONSISTENT",
+ "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.SCOPE"
+ ],
+ "CMOS18 \u00a71.3 p9": [
+ "CMOS.BACKMATTER.APPENDICES.LABELED"
+ ],
+ "CMOS18 \u00a71.42 p118 (scan p1126)": [
+ "CMOS.FRONTMATTER.LIST_OF_FIGURES.SECTION_TITLE",
+ "CMOS.FRONTMATTER.LIST_OF_TABLES.SECTION_TITLE",
+ "CMOS.FRONTMATTER.TOC.ENTRIES.MATCH_HEADINGS",
+ "CMOS.FRONTMATTER.TOC.PAGE_NUMBERS.MATCH"
+ ],
+ "CMOS18 \u00a71.42 p48 (scan p1122)": [
+ "CMOS.TABLES.ROTATION.LANDSCAPE.WHEN_NEEDED",
+ "CMOS.TABLES.SPLITS.AVOID_ROW_BREAKS",
+ "CMOS.TABLES.SPLITS.REPEAT_HEADERS",
+ "CMOS.TABLES.WIDTH.FIT_PAGE"
+ ],
+ "CMOS18 \u00a71.44 p14 (scan p1123)": [
+ "CMOS.LAYOUT.PAGINATION.PAGE_NUMBERS.POSITION"
+ ],
+ "CMOS18 \u00a71.5 p112 (scan p1129)": [
+ "CMOS.FRONTMATTER.TOC.LEADERS.CONSISTENT",
+ "CMOS.FRONTMATTER.TOC.LEVELS.CONSISTENT"
+ ],
+ "CMOS18 \u00a71.53 p53 (scan p1129)": [
+ "CMOS.FRONTMATTER.FOREWORD.AUTHOR.ATTRIBUTED",
+ "CMOS.FRONTMATTER.FOREWORD.DATE_IF_PRESENT"
+ ],
"CMOS18 \u00a71.56 p33 (scan p55)": [
"CMOS.HEADINGS.DIVISIONS.CHAPTERS.MULTIAUTHOR",
"CMOS.HEADINGS.MULTIAUTHOR.AUTHOR_ATTRIBUTION_PLACEMENT",
@@ -190,9 +516,144 @@
"CMOS.HEADINGS.LETTERS_DIARIES.DATELINE_FORMAT",
"CMOS.HEADINGS.LETTERS_DIARIES.SIGNATURE_FORMAT"
],
+ "CMOS18 \u00a71.66 p66 (scan p1135)": [
+ "CMOS.BACKMATTER.APPENDIX.NUMBERING.SEQUENTIAL",
+ "CMOS.BACKMATTER.APPENDIX.START_ON_NEW_PAGE",
+ "CMOS.BACKMATTER.APPENDIX.TOC.ENTRIES"
+ ],
+ "CMOS18 \u00a71.81 p39 (scan p1122)": [
+ "CMOS.BACKMATTER.INDEX.ENTRIES.CONSISTENT_CASE"
+ ],
+ "CMOS18 \u00a71.82 p82 (scan p1122)": [
+ "CMOS.TABLES.COLUMN_ORDER.LOGICAL",
+ "CMOS.TABLES.DATA_TYPES.NOT_MIXED",
+ "CMOS.TABLES.ROW_ORDER.LOGICAL",
+ "CMOS.TABLES.SORTING.LOGICAL",
+ "CMOS.TABLES.SUBTOTALS.CLEAR"
+ ],
+ "CMOS18 \u00a710.1 p623": [
+ "CMOS.ABBREVIATIONS.ACADEMIC.DEGREES.STYLE",
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_IN_HEADINGS",
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_STACKING",
+ "CMOS.ABBREVIATIONS.ACRONYMS.DEFINE_FIRST_USE",
+ "CMOS.ABBREVIATIONS.AVOID_ONE_OFFS",
+ "CMOS.ABBREVIATIONS.BIBLIOGRAPHY.STANDARDS.FOLLOW",
+ "CMOS.ABBREVIATIONS.CAPS.AVOID_ALL_CAPS_WORDS",
+ "CMOS.ABBREVIATIONS.CAPTIONS.DEFINE_ON_FIRST_USE",
+ "CMOS.ABBREVIATIONS.COMPANIES.INC_LTD.CONSISTENT",
+ "CMOS.ABBREVIATIONS.FOOTNOTES.ABBREV_ON_FIRST_USE",
+ "CMOS.ABBREVIATIONS.GENERAL.AVOID_OVERUSE",
+ "CMOS.ABBREVIATIONS.GENERAL.CONSISTENCY",
+ "CMOS.ABBREVIATIONS.GENERAL.GLOSSARY.WHEN_NEEDED",
+ "CMOS.ABBREVIATIONS.GEOGRAPHY.STATE_ABBREVS.CONSISTENT",
+ "CMOS.ABBREVIATIONS.INITIALISMS.NO_PERIODS.DEFAULT",
+ "CMOS.ABBREVIATIONS.LATIN.EG_IE.PUNCTUATION",
+ "CMOS.ABBREVIATIONS.LATIN.ET_AL.USE",
+ "CMOS.ABBREVIATIONS.LATIN.VERSUS_ENGLISH",
+ "CMOS.ABBREVIATIONS.MEASURES.SI.SPACE",
+ "CMOS.ABBREVIATIONS.NAMES.INITIALS.SPACING",
+ "CMOS.ABBREVIATIONS.ORGANIZATIONS.SPELL_OUT_FIRST",
+ "CMOS.ABBREVIATIONS.PARENTHETICALS.AVOID_STACKING",
+ "CMOS.ABBREVIATIONS.PLURALS.NO_APOSTROPHE",
+ "CMOS.ABBREVIATIONS.POSSESSIVE.FORM",
+ "CMOS.ABBREVIATIONS.PUNCTUATION.ABBREV_WITH_PERIODS.AVOID_DOUBLE",
+ "CMOS.ABBREVIATIONS.READER_FAMILIARITY",
+ "CMOS.ABBREVIATIONS.TABLES.ABBREV_KEY",
+ "CMOS.ABBREVIATIONS.TABLES.KEYS.WHEN_DENSE",
+ "CMOS.ABBREVIATIONS.TECH.TERMS.CASE_SENSITIVE",
+ "CMOS.ABBREVIATIONS.TIME.AM_PM.FORM",
+ "CMOS.ABBREVIATIONS.TITLES.COURTESY_PERIODS",
+ "CMOS.ABBREVIATIONS.TITLES.HONORIFICS.CONSISTENT",
+ "CMOS.ABBREVIATIONS.TITLES.JR_SR.CONSISTENT",
+ "CMOS.ABBREVIATIONS.UNITS.ABBREV_WITH_NUMERALS_ONLY",
+ "CMOS.ABBREVIATIONS.UNITS.NO_PERIODS",
+ "CMOS.ABBREVIATIONS.UNITS.NO_PLURAL_SYMBOLS",
+ "CMOS.ABBREVIATIONS.UNITS.SPELL_OUT_WITHOUT_NUMERALS"
+ ],
+ "CMOS18 \u00a710.2 p624": [
+ "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_SENTENCE_START",
+ "CMOS.ABBREVIATIONS.ACRONYMS.DEFINE_FIRST_USE",
+ "CMOS.ABBREVIATIONS.ACRONYMS.REINTRODUCE_AFTER_GAP",
+ "CMOS.ABBREVIATIONS.LATIN.EG_IE.PUNCTUATION"
+ ],
+ "CMOS18 \u00a710.4 p626": [
+ "CMOS.ABBREVIATIONS.COUNTRIES.ABBREV_IN_TABLES_ONLY",
+ "CMOS.ABBREVIATIONS.DAYS.ABBREV_IN_TABLES",
+ "CMOS.ABBREVIATIONS.DAYS.SPELL_OUT_IN_TEXT",
+ "CMOS.ABBREVIATIONS.LATIN.EG_IE.PUNCTUATION",
+ "CMOS.ABBREVIATIONS.MONTHS.ABBREV_IN_TABLES",
+ "CMOS.ABBREVIATIONS.MONTHS.SPELL_OUT_IN_TEXT",
+ "CMOS.ABBREVIATIONS.STATES.POSTAL_ONLY",
+ "CMOS.ABBREVIATIONS.STATES.SPELL_OUT_IN_TEXT",
+ "CMOS.ABBREVIATIONS.US_USA.CONSISTENT"
+ ],
+ "CMOS18 \u00a711.1 p673": [
+ "CMOS.I18N.ACRONYMS.LANGUAGE_SPECIFIC",
+ "CMOS.I18N.CAPITALIZATION.TITLES.LANGUAGE_RULES",
+ "CMOS.I18N.CITATIONS.TITLES.ORIGINAL_OR_TRANSLATED",
+ "CMOS.I18N.CURRENCY.CODES.LABEL",
+ "CMOS.I18N.DATES.FORMAT.CONSISTENT",
+ "CMOS.I18N.DIACRITICS.PRESERVE",
+ "CMOS.I18N.GLOSSARY.MULTILINGUAL",
+ "CMOS.I18N.HYPHENATION.LANGUAGE_TAGS",
+ "CMOS.I18N.ITALICS.FOREIGN_WORDS.SPARE",
+ "CMOS.I18N.LANGUAGE.CONSISTENT_SPELLING",
+ "CMOS.I18N.MEANINGFUL_TRANSLATIONS.NOT_LITERAL",
+ "CMOS.I18N.NAMES.SORTING.COLLATION",
+ "CMOS.I18N.NUMBERS.DECIMAL_SEPARATOR.LOCALE",
+ "CMOS.I18N.PARENS.BRACKETS.TRANSLATOR_NOTES",
+ "CMOS.I18N.PUNCTUATION.DASHES.MINUS_SIGN",
+ "CMOS.I18N.PUNCTUATION.ELLIPSIS.STYLE",
+ "CMOS.I18N.PUNCTUATION.SPACING.LANGUAGE_RULES",
+ "CMOS.I18N.QUOTES.NESTING.CONSISTENT",
+ "CMOS.I18N.QUOTES.STYLE.MATCH_LOCALE",
+ "CMOS.I18N.RIGHT_TO_LEFT.MARKUP",
+ "CMOS.I18N.ROMANIZATION.DIACRITICS.KEEP",
+ "CMOS.I18N.SCRIPT_MIXING.AVOID",
+ "CMOS.I18N.SECURITY.HOMOGLYPHS.AWARE",
+ "CMOS.I18N.TRANSLATION.INDICATE",
+ "CMOS.I18N.TRANSLITERATION.SYSTEM.CONSISTENT",
+ "CMOS.I18N.TYPOGRAPHY.FONT_COVERAGE",
+ "CMOS.I18N.UNITS.SYMBOLS.STANDARD"
+ ],
+ "CMOS18 \u00a711.2 p674": [
+ "CMOS.I18N.ACRONYMS.LANGUAGE_SPECIFIC",
+ "CMOS.I18N.CAPITALIZATION.TITLES.LANGUAGE_RULES",
+ "CMOS.I18N.CITATIONS.TITLES.ORIGINAL_OR_TRANSLATED",
+ "CMOS.I18N.CURRENCY.CODES.LABEL",
+ "CMOS.I18N.DATES.FORMAT.CONSISTENT",
+ "CMOS.I18N.DIACRITICS.PRESERVE",
+ "CMOS.I18N.GLOSSARY.MULTILINGUAL",
+ "CMOS.I18N.HYPHENATION.LANGUAGE_TAGS",
+ "CMOS.I18N.ITALICS.FOREIGN_WORDS.SPARE",
+ "CMOS.I18N.LANGUAGE.CONSISTENT_SPELLING",
+ "CMOS.I18N.MEANINGFUL_TRANSLATIONS.NOT_LITERAL",
+ "CMOS.I18N.NAMES.SORTING.COLLATION",
+ "CMOS.I18N.NUMBERS.DECIMAL_SEPARATOR.LOCALE",
+ "CMOS.I18N.PARENS.BRACKETS.TRANSLATOR_NOTES",
+ "CMOS.I18N.PUNCTUATION.DASHES.MINUS_SIGN",
+ "CMOS.I18N.PUNCTUATION.ELLIPSIS.STYLE",
+ "CMOS.I18N.PUNCTUATION.SPACING.LANGUAGE_RULES",
+ "CMOS.I18N.QUOTES.NESTING.CONSISTENT",
+ "CMOS.I18N.QUOTES.STYLE.MATCH_LOCALE",
+ "CMOS.I18N.RIGHT_TO_LEFT.MARKUP",
+ "CMOS.I18N.ROMANIZATION.DIACRITICS.KEEP",
+ "CMOS.I18N.SCRIPT_MIXING.AVOID",
+ "CMOS.I18N.SECURITY.HOMOGLYPHS.AWARE",
+ "CMOS.I18N.TRANSLITERATION.SYSTEM.CONSISTENT",
+ "CMOS.I18N.TYPOGRAPHY.FONT_COVERAGE",
+ "CMOS.I18N.UNITS.SYMBOLS.STANDARD"
+ ],
+ "CMOS18 \u00a711.49 p86 (scan p1127)": [
+ "CMOS.FRONTMATTER.PREFACE.DATE_IF_PRESENT"
+ ],
"CMOS18 \u00a712.31 p746 (scan p768)": [
"CMOS.PUNCTUATION.BLOCK_QUOTES.NO_QUOTE_MARKS"
],
+ "CMOS18 \u00a712.35 p11 (scan p1130)": [
+ "CMOS.FRONTMATTER.EPIGRAPH.ATTRIBUTION",
+ "CMOS.FRONTMATTER.EPIGRAPH.PLACEMENT.CONSISTENT"
+ ],
"CMOS18 \u00a712.59 p760 (scan p782)": [
"CMOS.PUNCTUATION.ELLIPSIS.FORMAT.CONSISTENT"
],
@@ -215,12 +676,77 @@
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ORDER_AND_YEAR",
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REQUIRED"
],
+ "CMOS18 \u00a713.1 p776 (scan p798)": [
+ "CMOS.CITATIONS.S13_1.ALL_SOURCE_TYPES",
+ "CMOS.CITATIONS.S13_1.DISCIPLINE_POLICY",
+ "CMOS.CITATIONS.S13_1.PURPOSE.COPYRIGHT",
+ "CMOS.CITATIONS.S13_1.PURPOSE.COURTESY",
+ "CMOS.CITATIONS.S13_1.PURPOSE.ETHICS",
+ "CMOS.CITATIONS.S13_1.SUFFICIENT_INFO"
+ ],
+ "CMOS18 \u00a713.10 p779 (scan p796)": [
+ "CMOS.CITATIONS.S13_10.DATABASES.NAME_INSTEAD",
+ "CMOS.CITATIONS.S13_10.DATABASE_IN_CITATION",
+ "CMOS.CITATIONS.S13_10.DOI_PRECEDENCE",
+ "CMOS.CITATIONS.S13_10.TEST_LOGGED_OUT"
+ ],
+ "CMOS18 \u00a713.100 p831 (scan p853)": [
+ "CMOS.CITATIONS.S13_100.BIBLIOGRAPHY.ONLINE.SOURCE_STABILITY"
+ ],
+ "CMOS18 \u00a713.101 p832 (scan p854)": [
+ "CMOS.CITATIONS.S13_101.BIBLIOGRAPHY.EBOOKS.EDITION_AND_FORMAT"
+ ],
+ "CMOS18 \u00a713.102 p833 (scan p855)": [
+ "CMOS.CITATIONS.S13_102.BIBLIOGRAPHY.AUDIOVISUAL.CREDITS"
+ ],
+ "CMOS18 \u00a713.103 p835 (scan p857)": [
+ "CMOS.CITATIONS.S13_103.BIBLIOGRAPHY.SOCIAL_MEDIA.ARCHIVE"
+ ],
+ "CMOS18 \u00a713.104 p835 (scan p857)": [
+ "CMOS.CITATIONS.S13_104.BIBLIOGRAPHY.PUBLIC_DOCUMENTS.IDENTIFIERS"
+ ],
+ "CMOS18 \u00a713.105 p835 (scan p857)": [
+ "CMOS.CITATIONS.S13_105.BIBLIOGRAPHY.REPORTS.ISSUING_BODY_AND_VERSION"
+ ],
+ "CMOS18 \u00a713.106 p836 (scan p858)": [
+ "CMOS.CITATIONS.S13_106.BIBLIOGRAPHY.DATASETS.VERSION_AND_PROVENANCE"
+ ],
+ "CMOS18 \u00a713.107 p836 (scan p858)": [
+ "CMOS.CITATIONS.S13_107.AUTHOR_DATE.REFERENCE_LIST.MULTI_AUTHOR.ORDERING"
+ ],
+ "CMOS18 \u00a713.108 p836 (scan p858)": [
+ "CMOS.CITATIONS.S13_108.BIBLIOGRAPHY.PLATFORMS.PERMALINKS_PREFERRED"
+ ],
+ "CMOS18 \u00a713.109 p836 (scan p858)": [
+ "CMOS.FIGURES.CAPTION.CREDITS.INLINE_OR_NOTE",
+ "CMOS.FIGURES.PERMISSIONS.DOCUMENTED"
+ ],
+ "CMOS18 \u00a713.11 p780 (scan p796)": [
+ "CMOS.CITATIONS.S13_11.NO_SHORTENERS_IN_MS",
+ "CMOS.CITATIONS.S13_11.PUBLISHER_OPTION",
+ "CMOS.CITATIONS.S13_11.SHORTENERS.OBSCURE"
+ ],
+ "CMOS18 \u00a713.110 p837 (scan p859)": [
+ "CMOS.CITATIONS.S13_110.AUTHOR_DATE.JOURNAL_ARTICLES.CORE_FIELDS"
+ ],
+ "CMOS18 \u00a713.111 p837 (scan p859)": [
+ "CMOS.CITATIONS.S13_111.AUTHOR_DATE.REFERENCE_LIST.REQUIRED"
+ ],
"CMOS18 \u00a713.112 p838 (scan p860)": [
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ALPHABETICAL"
],
"CMOS18 \u00a713.113 p838 (scan p860)": [
"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REPEATED_NAMES"
],
+ "CMOS18 \u00a713.114 p839 (scan p861)": [
+ "CMOS.CITATIONS.AUTHOR_DATE.SAME_AUTHOR_SAME_YEAR.SUFFIXES"
+ ],
+ "CMOS18 \u00a713.115 p839 (scan p861)": [
+ "CMOS.CITATIONS.AUTHOR_DATE.NO_AUTHOR.TITLE_KEY"
+ ],
+ "CMOS18 \u00a713.116 p840 (scan p862)": [
+ "CMOS.CITATIONS.AUTHOR_DATE.NO_DATE.POLICY"
+ ],
"CMOS18 \u00a713.117 p840 (scan p862)": [
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.LOCATORS"
],
@@ -230,39 +756,216 @@
"CMOS18 \u00a713.119 p841 (scan p863)": [
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.PLACEMENT"
],
+ "CMOS18 \u00a713.12 p780 (scan p796)": [
+ "CMOS.CITATIONS.S13_12.URLS.CASE_SENSITIVE",
+ "CMOS.CITATIONS.S13_12.URLS.NO_SENTENCE_START",
+ "CMOS.CITATIONS.S13_12.URLS.NO_SPACES",
+ "CMOS.CITATIONS.S13_12.URLS.PROTOCOL",
+ "CMOS.CITATIONS.S13_12.URLS.PUNCTUATION_AFTER",
+ "CMOS.CITATIONS.S13_12.URLS.TRAILING_SLASH"
+ ],
"CMOS18 \u00a713.120 p842 (scan p864)": [
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.DIRECT_QUOTES"
],
+ "CMOS18 \u00a713.121 p843 (scan p865)": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_AUTHORS.POLICY"
+ ],
+ "CMOS18 \u00a713.122 p843 (scan p865)": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.CORPORATE_AUTHORS.SHORT_FORM"
+ ],
+ "CMOS18 \u00a713.123 p843 (scan p865)": [
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ENTRY_TEMPLATES.CONSISTENT"
+ ],
"CMOS18 \u00a713.124 p844 (scan p866)": [
"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_SOURCES"
],
+ "CMOS18 \u00a713.125 p845 (scan p867)": [
+ "CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_CITATIONS.ORDER_POLICY"
+ ],
+ "CMOS18 \u00a713.126 p845 (scan p867)": [
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SORTING_STABLE"
+ ],
+ "CMOS18 \u00a713.127 p845 (scan p867)": [
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SAME_AUTHOR.ORDER_POLICY"
+ ],
+ "CMOS18 \u00a713.128 p845 (scan p867)": [
+ "CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REPEATED_NAMES.POLICY"
+ ],
+ "CMOS18 \u00a713.13 p780 (scan p796)": [
+ "CMOS.CITATIONS.S13_13.BACKUPS",
+ "CMOS.CITATIONS.S13_13.CITATIONS.REVIEW",
+ "CMOS.CITATIONS.S13_13.METADATA.CHECK_FIELDS",
+ "CMOS.CITATIONS.S13_13.METADATA.MISSING",
+ "CMOS.CITATIONS.S13_13.REPAIR_AT_SOURCE",
+ "CMOS.CITATIONS.S13_13.STRIP_CODES",
+ "CMOS.CITATIONS.S13_13.TOOLS.USE_METADATA"
+ ],
"CMOS18 \u00a713.13 p781 (scan p803)": [
"CMOS.CITATIONS.RESEARCH.METADATA.CAPTURE_EARLY"
],
+ "CMOS18 \u00a713.14 p781 (scan p796)": [
+ "CMOS.CITATIONS.S13_14.CITE_VERSION",
+ "CMOS.CITATIONS.S13_14.DEVICE_SPECIFIC",
+ "CMOS.CITATIONS.S13_14.ONLINE.URL_INDICATOR",
+ "CMOS.CITATIONS.S13_14.SAME_URL.FORMATS"
+ ],
"CMOS18 \u00a713.14 p782 (scan p804)": [
"CMOS.CITATIONS.ONLINE.VERSION.CITE_RIGHT_VERSION"
],
+ "CMOS18 \u00a713.15 p781 (scan p796)": [
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.NOT_REQUIRED",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.PUBLISHER_POLICY",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.RECORD_ANYWAY",
+ "CMOS.CITATIONS.S13_15.ACCESS_DATE.UNVERIFIABLE"
+ ],
"CMOS18 \u00a713.15 p782 (scan p804)": [
"CMOS.CITATIONS.ONLINE.ACCESS_DATE.WHEN_NEEDED"
],
+ "CMOS18 \u00a713.16 p782 (scan p796)": [
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.FORMAT",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.PREFERENCE",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.WHEN_ONLY_DATE",
+ "CMOS.CITATIONS.S13_16.REVISION_DATE.WIKIS"
+ ],
"CMOS18 \u00a713.16 p782 (scan p804)": [
"CMOS.CITATIONS.ONLINE.REVISION_DATE.DISTINCT"
],
+ "CMOS18 \u00a713.17 p782 (scan p796)": [
+ "CMOS.CITATIONS.S13_17.ARCHIVE_SERVICES",
+ "CMOS.CITATIONS.S13_17.PRESERVE.CRISIS_SOURCES",
+ "CMOS.CITATIONS.S13_17.PRESERVE.FORMAT_OPTIONS",
+ "CMOS.CITATIONS.S13_17.PRESERVE.NONPUBLISHED"
+ ],
+ "CMOS18 \u00a713.18 p782 (scan p796)": [
+ "CMOS.CITATIONS.S13_18.BIBLIO.SHORTENED_NOTES",
+ "CMOS.CITATIONS.S13_18.NAMES.NORMAL_ORDER",
+ "CMOS.CITATIONS.S13_18.NOTES.SENTENCE_STYLE",
+ "CMOS.CITATIONS.S13_18.NOTES_BIBLIO.OVERVIEW",
+ "CMOS.CITATIONS.S13_18.NO_BIBLIO.FULL_FIRST_NOTE"
+ ],
+ "CMOS18 \u00a713.18 p783 (scan p796)": [
+ "CMOS.CITATIONS.S13_18.BIBLIO.INVERT_FIRST_AUTHOR"
+ ],
+ "CMOS18 \u00a713.19 p783 (scan p796)": [
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.BIBLIO",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.CONSISTENT",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.NOTES",
+ "CMOS.CITATIONS.S13_19.ABBREVIATIONS.NOUN_FORMS"
+ ],
+ "CMOS18 \u00a713.2 p776 (scan p798)": [
+ "CMOS.CITATIONS.S13_2.AUTHOR_DATE_SYSTEM",
+ "CMOS.CITATIONS.S13_2.DEFAULT_SYSTEM",
+ "CMOS.CITATIONS.S13_2.DISCIPLINE_PREFERENCE",
+ "CMOS.CITATIONS.S13_2.JOURNAL_INSTRUCTIONS",
+ "CMOS.CITATIONS.S13_2.NOTES_BIBLIOGRAPHY_OPTIONAL",
+ "CMOS.CITATIONS.S13_2.NOTES_SYSTEM",
+ "CMOS.CITATIONS.S13_2.STYLE_ELEMENTS.SHARED",
+ "CMOS.CITATIONS.S13_2.SYSTEMS.TWO_TYPES",
+ "CMOS.CITATIONS.S13_2.SYSTEM_SWITCHING"
+ ],
+ "CMOS18 \u00a713.20 p783 (scan p796)": [
+ "CMOS.CITATIONS.S13_20.BIBLIO.PAGE_RANGE",
+ "CMOS.CITATIONS.S13_20.NOTES.PAGE_SPECIFIC",
+ "CMOS.CITATIONS.S13_20.PAGE_RANGE.EN_DASH"
+ ],
+ "CMOS18 \u00a713.20 p784 (scan p796)": [
+ "CMOS.CITATIONS.S13_20.BIBLIO.BOOKS.NO_PAGES",
+ "CMOS.CITATIONS.S13_20.ELECTRONIC.SHORT_DOCS",
+ "CMOS.CITATIONS.S13_20.LOCATORS.ALTERNATIVES"
+ ],
+ "CMOS18 \u00a713.21 p784 (scan p796)": [
+ "CMOS.CITATIONS.S13_21.EXAMPLES.BIBLIO_SHORTENED",
+ "CMOS.CITATIONS.S13_21.EXAMPLES.CHAPTER14",
+ "CMOS.CITATIONS.S13_21.EXAMPLES.SHORT_FORMS"
+ ],
+ "CMOS18 \u00a713.22 p784 (scan p796)": [
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.NOTE_BIBLIO",
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.PAGE_IN_NOTES",
+ "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.SHORTENED"
+ ],
+ "CMOS18 \u00a713.22 p785 (scan p796)": [
+ "CMOS.CITATIONS.S13_22.BOOK_EDITOR_ONLY",
+ "CMOS.CITATIONS.S13_22.BOOK_PLACE_OMIT"
+ ],
+ "CMOS18 \u00a713.22 p785 (scan p808)": [
+ "CMOS.CITATIONS.S13_22.BOOK_EDITOR_ONLY.SHORTENED_NO_ED"
+ ],
+ "CMOS18 \u00a713.23 p785 (scan p808)": [
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.BIBLIO_MORE_THAN_SIX",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.BIBLIO_UP_TO_SIX",
+ "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.NOTES_ET_AL",
+ "CMOS.CITATIONS.S13_23.NO_BIBLIO.NOTES_UP_TO_SIX",
+ "CMOS.CITATIONS.S13_23.TWO_AUTHORS.BIBLIO_INVERT_FIRST",
+ "CMOS.CITATIONS.S13_23.TWO_AUTHORS.NOTES_LIST_BOTH"
+ ],
+ "CMOS18 \u00a713.24 p786 (scan p808)": [
+ "CMOS.CITATIONS.S13_24.AUTHOR_PLUS_EDITOR.BIBLIO_SPELL_OUT",
+ "CMOS.CITATIONS.S13_24.AUTHOR_PLUS_EDITOR.NOTES_ABBREVIATE"
+ ],
+ "CMOS18 \u00a713.25 p786 (scan p809)": [
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.BIBLIO_NO_PAGE_RANGE",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.INCLUDE_AUTHOR",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.INCLUDE_EDITOR",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.IN_BEFORE_BOOK",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.NOTES_PAGE_LOCATOR",
+ "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.QUOTE_TITLE"
+ ],
"CMOS18 \u00a713.25 p787 (scan p809)": [
"CMOS.CITATIONS.NOTES.CHAPTER_IN_EDITED_BOOK"
],
+ "CMOS18 \u00a713.26 p786 (scan p809)": [
+ "CMOS.CITATIONS.S13_26.JOURNAL.BIBLIO_PAGE_RANGE",
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_ISSUE",
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_VOLUME",
+ "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_YEAR",
+ "CMOS.CITATIONS.S13_26.JOURNAL.NOTES_PAGE_SPECIFIC",
+ "CMOS.CITATIONS.S13_26.JOURNAL.OMIT_MONTH_SEASON",
+ "CMOS.CITATIONS.S13_26.JOURNAL.ONLINE.URL_OR_DOI",
+ "CMOS.CITATIONS.S13_26.JOURNAL.PAGE_COLON",
+ "CMOS.CITATIONS.S13_26.JOURNAL.TITLE_ITALIC",
+ "CMOS.CITATIONS.S13_26.JOURNAL.VOLUME_FORMAT"
+ ],
"CMOS18 \u00a713.26 p787 (scan p809)": [
"CMOS.CITATIONS.NOTES.JOURNAL.ARTICLE_ELEMENTS"
],
"CMOS18 \u00a713.27 p787 (scan p809)": [
"CMOS.CITATIONS.DEGRADED.NOTE_MARKERS.REPAIR",
- "CMOS.CITATIONS.NOTES.NOTE_MARKERS.SUPERSCRIPT_TEXT"
+ "CMOS.CITATIONS.NOTES.NOTE_MARKERS.SUPERSCRIPT_TEXT",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.NOTES_FULL_SIZE",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.NOTES_PERIOD",
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.TEXT_SUPERSCRIPT"
+ ],
+ "CMOS18 \u00a713.27 p787 (scan p810)": [
+ "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.MANUSCRIPT_SUPERSCRIPT_OK",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.BASELINE_FALLBACK",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.CONSISTENT_SPACING",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.NOTES_FULL_SIZE",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.NO_PERIOD",
+ "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.TEXT_SUPERSCRIPT"
],
"CMOS18 \u00a713.28 p788 (scan p810)": [
- "CMOS.CITATIONS.NOTES.NOTE_MARKERS.SEQUENCE_CONTINUOUS"
+ "CMOS.CITATIONS.NOTES.NOTE_MARKERS.SEQUENCE_CONTINUOUS",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.CONSECUTIVE",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.NO_BOOKWIDE_RUN",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SEPARATE_SYSTEMS",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SYMBOLS_FOR_FEW",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SYMBOL_SEQUENCE_STANDARD",
+ "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.TABLE_NOTES_SEPARATE"
],
"CMOS18 \u00a713.29 p788 (scan p810)": [
- "CMOS.CITATIONS.NOTES.NOTE_MARKERS.PLACEMENT_AFTER_PUNCT"
+ "CMOS.CITATIONS.NOTES.NOTE_MARKERS.PLACEMENT_AFTER_PUNCT",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AFTER_PUNCTUATION",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AFTER_QUOTE",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AVOID_MIDCLAUSE",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.BEFORE_DASH",
+ "CMOS.CITATIONS.S13_29.NOTE_NUMBER.PLACEMENT_END_SENTENCE"
+ ],
+ "CMOS18 \u00a713.3 p777 (scan p799)": [
+ "CMOS.CITATIONS.S13_3.JOURNALS.HOUSE_STYLE",
+ "CMOS.CITATIONS.S13_3.LEGAL.BLUEBOOK",
+ "CMOS.CITATIONS.S13_3.OTHER_SYSTEMS.AMA_CSE",
+ "CMOS.CITATIONS.S13_3.OTHER_SYSTEMS.MLA_APA",
+ "CMOS.CITATIONS.S13_3.SOURCE_MANUALS"
],
"CMOS18 \u00a713.30 p789 (scan p811)": [
"CMOS.CITATIONS.NOTES.NOTE_MARKERS.HEADINGS_END"
@@ -279,9 +982,30 @@
"CMOS18 \u00a713.34 p790 (scan p812)": [
"CMOS.CITATIONS.NOTES.SHORT_FORM.CROSS_REFERENCE"
],
+ "CMOS18 \u00a713.35 p791 (scan p813)": [
+ "CMOS.CITATIONS.S13_35.SHORT_FORM.DISTINCT_TITLE"
+ ],
+ "CMOS18 \u00a713.36 p791 (scan p813)": [
+ "CMOS.CITATIONS.S13_36.SHORT_FORM.DISAMBIGUATE_AUTHOR"
+ ],
"CMOS18 \u00a713.37 p791 (scan p813)": [
"CMOS.CITATIONS.IBID.MINIMIZE_OR_AVOID"
],
+ "CMOS18 \u00a713.38 p793 (scan p815)": [
+ "CMOS.CITATIONS.S13_38.IBID.IMMEDIATE_PRECEDENT"
+ ],
+ "CMOS18 \u00a713.39 p793 (scan p815)": [
+ "CMOS.CITATIONS.S13_39.IBID.LOCATOR_REQUIRED"
+ ],
+ "CMOS18 \u00a713.4 p777 (scan p799)": [
+ "CMOS.CITATIONS.S13_4.CONSISTENCY.REQUIRED",
+ "CMOS.CITATIONS.S13_4.DOCUMENTED_DEVIATIONS",
+ "CMOS.CITATIONS.S13_4.FLEXIBILITY.BY_AGREEMENT",
+ "CMOS.CITATIONS.S13_4.JOURNALS.STRICT"
+ ],
+ "CMOS18 \u00a713.40 p793 (scan p815)": [
+ "CMOS.CITATIONS.S13_40.SHORT_FORM.AVOID_OP_CIT"
+ ],
"CMOS18 \u00a713.41 p794 (scan p816)": [
"CMOS.CITATIONS.NOTES.QUOTE_IN_NOTE.LOCATOR"
],
@@ -294,27 +1018,68 @@
"CMOS18 \u00a713.44 p794 (scan p816)": [
"CMOS.CITATIONS.NOTES.FOOTNOTES.PAGE_BREAKS"
],
+ "CMOS18 \u00a713.45 p796 (scan p818)": [
+ "CMOS.CITATIONS.S13_45.NOTES.CITATION_FIRST"
+ ],
"CMOS18 \u00a713.46 p796 (scan p818)": [
"CMOS.CITATIONS.NOTES.FOOTNOTES_VS_ENDNOTES.CHOOSE"
],
+ "CMOS18 \u00a713.47 p796 (scan p818)": [
+ "CMOS.CITATIONS.S13_47.NOTES.SYSTEMS.DONT_MIX"
+ ],
+ "CMOS18 \u00a713.48 p797 (scan p819)": [
+ "CMOS.CITATIONS.S13_48.ENDNOTES.GROUP_BY_CHAPTER"
+ ],
"CMOS18 \u00a713.49 p797 (scan p819)": [
"CMOS.CITATIONS.NOTES.ENDNOTES.PLACEMENT"
],
+ "CMOS18 \u00a713.5 p777 (scan p799)": [
+ "CMOS.CITATIONS.S13_5.ACADEMIC_EXPECTATION",
+ "CMOS.CITATIONS.S13_5.AVOID_TANGENTIAL",
+ "CMOS.CITATIONS.S13_5.CITE_RELEVANT",
+ "CMOS.CITATIONS.S13_5.INFORMAL_SOURCES",
+ "CMOS.CITATIONS.S13_5.NONACADEMIC.MENTIONS_OK"
+ ],
"CMOS18 \u00a713.50 p797 (scan p819)": [
"CMOS.CITATIONS.NOTES.ENDNOTES.RUNNING_HEADS"
],
"CMOS18 \u00a713.51 p800 (scan p822)": [
"CMOS.CITATIONS.NOTES.ENDNOTES.AVOID_IBID"
],
+ "CMOS18 \u00a713.52 p800 (scan p822)": [
+ "CMOS.CITATIONS.S13_52.ENDNOTES.NAVIGATION_CUES"
+ ],
"CMOS18 \u00a713.53 p801 (scan p823)": [
"CMOS.CITATIONS.NOTES.AUTHOR_DATE_PLUS_NOTES"
],
+ "CMOS18 \u00a713.54 p801 (scan p823)": [
+ "CMOS.CITATIONS.S13_54.AUTHOR_DATE.NOTES.COMMENTARY_ONLY"
+ ],
"CMOS18 \u00a713.55 p801 (scan p823)": [
"CMOS.CITATIONS.NOTES.UNNUMBERED.NOT_FOR_SOURCES"
],
+ "CMOS18 \u00a713.56 p803 (scan p825)": [
+ "CMOS.CITATIONS.S13_56.NOTES.DUAL_STREAMS.DISTINCT_LABELS"
+ ],
+ "CMOS18 \u00a713.57 p109 (scan p1130)": [
+ "CMOS.BACKMATTER.NOTES.CITATIONS.COMPLETE"
+ ],
+ "CMOS18 \u00a713.57 p803 (scan p825)": [
+ "CMOS.CITATIONS.S13_57.NOTES.SEPARATE_SOURCE_VS_COMMENTARY"
+ ],
"CMOS18 \u00a713.58 p805 (scan p827)": [
"CMOS.CITATIONS.NOTES.SOURCE_NOTES.REPRINTS"
],
+ "CMOS18 \u00a713.59 p807 (scan p829)": [
+ "CMOS.CITATIONS.S13_59.NOTES.MULTI_EDITIONS.CITE_VERSION_USED"
+ ],
+ "CMOS18 \u00a713.6 p777 (scan p799)": [
+ "CMOS.CITATIONS.S13_6.LINK_TITLE_PREFERRED",
+ "CMOS.CITATIONS.S13_6.URL.FINAL_ELEMENT",
+ "CMOS.CITATIONS.S13_6.URLS.EASILY_FOUND",
+ "CMOS.CITATIONS.S13_6.URLS.IN_MANUSCRIPT",
+ "CMOS.CITATIONS.S13_6.URLS.READER_NEEDED"
+ ],
"CMOS18 \u00a713.6 p778 (scan p800)": [
"CMOS.CITATIONS.DEGRADED.URL_LINEBREAKS.NORMALIZE",
"CMOS.CITATIONS.ONLINE.URLS.STABLE"
@@ -322,18 +1087,51 @@
"CMOS18 \u00a713.60 p807 (scan p829)": [
"CMOS.CITATIONS.NOTES.AVOID_OVERLONG"
],
+ "CMOS18 \u00a713.61 p807 (scan p829)": [
+ "CMOS.CITATIONS.S13_61.BIBLIOGRAPHY.SCOPE.LABEL_CLEARLY"
+ ],
+ "CMOS18 \u00a713.62 p808 (scan p830)": [
+ "CMOS.CITATIONS.S13_62.BIBLIOGRAPHY.ENTRY_COMPLETENESS.MORE_THAN_SHORT_FORM"
+ ],
+ "CMOS18 \u00a713.63 p808 (scan p830)": [
+ "CMOS.CITATIONS.S13_63.BIBLIOGRAPHY.CONSISTENT_ELEMENT_ORDER"
+ ],
+ "CMOS18 \u00a713.64 p809 (scan p831)": [
+ "CMOS.CITATIONS.S13_64.BIBLIOGRAPHY.SUBSECTIONS.CLEAR_HEADINGS"
+ ],
"CMOS18 \u00a713.65 p809 (scan p831)": [
"CMOS.CITATIONS.NOTES_BIBLIO.BIBLIOGRAPHY.INCLUDE_WHEN_USED"
],
+ "CMOS18 \u00a713.66 p810 (scan p832)": [
+ "CMOS.CITATIONS.S13_66.BIBLIOGRAPHY.INCLUDE_ONLY_PER_SCOPE"
+ ],
+ "CMOS18 \u00a713.67 p812 (scan p834)": [
+ "CMOS.CITATIONS.S13_67.BIBLIOGRAPHY.ANNOTATIONS.CONSISTENT_AND_DISTINCT"
+ ],
+ "CMOS18 \u00a713.68 p812 (scan p834)": [
+ "CMOS.CITATIONS.S13_68.BIBLIOGRAPHY.ENTRY_TYPES.NOT_MIXED"
+ ],
"CMOS18 \u00a713.69 p816 (scan p838)": [
"CMOS.CITATIONS.NOTES_BIBLIO.BIBLIOGRAPHY.SORT_BY_AUTHOR"
],
+ "CMOS18 \u00a713.7 p778 (scan p798)": [
+ "CMOS.CITATIONS.S13_7.DOI.NO_PREFIX",
+ "CMOS.CITATIONS.S13_7.DOI.PREFERRED",
+ "CMOS.CITATIONS.S13_7.DOI.RESOLUTION",
+ "CMOS.CITATIONS.S13_7.DOI.URL_FORM"
+ ],
"CMOS18 \u00a713.7 p778 (scan p800)": [
"CMOS.CITATIONS.DOI.PREFERRED_OVER_URL"
],
"CMOS18 \u00a713.70 p816 (scan p838)": [
"CMOS.CITATIONS.BIBLIOGRAPHY.SAME_AUTHOR.ORDER"
],
+ "CMOS18 \u00a713.71 p817 (scan p839)": [
+ "CMOS.CITATIONS.S13_71.BIBLIOGRAPHY.ALPHABETIZATION.PREFIXES_POLICY"
+ ],
+ "CMOS18 \u00a713.72 p817 (scan p839)": [
+ "CMOS.CITATIONS.S13_72.BIBLIOGRAPHY.SORTING.DIACRITICS_AND_TRANSLITERATION"
+ ],
"CMOS18 \u00a713.73 p818 (scan p840)": [
"CMOS.CITATIONS.BIBLIOGRAPHY.REPEATED_NAMES.THREE_EM_DASH"
],
@@ -346,28 +1144,350 @@
"CMOS18 \u00a713.76 p820 (scan p842)": [
"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.INITIALS_PREFERRED"
],
+ "CMOS18 \u00a713.77 p820 (scan p842)": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_LIST.LENGTH.POLICY"
+ ],
"CMOS18 \u00a713.78 p821 (scan p843)": [
"CMOS.CITATIONS.BIBLIOGRAPHY.MULTI_AUTHORS.ORDER"
],
"CMOS18 \u00a713.79 p821 (scan p843)": [
"CMOS.CITATIONS.BIBLIOGRAPHY.SAME_SURNAME.DISAMBIGUATE"
],
+ "CMOS18 \u00a713.8 p778 (scan p798)": [
+ "CMOS.CITATIONS.S13_8.PERMALINK.PREFERRED",
+ "CMOS.CITATIONS.S13_8.PERMALINK.TEST",
+ "CMOS.CITATIONS.S13_8.PREFERRED_ORDER",
+ "CMOS.CITATIONS.S13_8.SUBSCRIPTION_URLS"
+ ],
"CMOS18 \u00a713.8 p779 (scan p801)": [
"CMOS.CITATIONS.ONLINE.PERMALINKS.PREFERRED"
],
+ "CMOS18 \u00a713.80 p822 (scan p844)": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.CORPORATE_AUTHORS.USE_AS_AUTHOR"
+ ],
"CMOS18 \u00a713.81 p822 (scan p844)": [
"CMOS.CITATIONS.BIBLIOGRAPHY.NO_AUTHOR.TITLE_LEAD"
],
"CMOS18 \u00a713.82 p823 (scan p845)": [
"CMOS.CITATIONS.BIBLIOGRAPHY.PSEUDONYMS.CONSISTENT"
],
+ "CMOS18 \u00a713.83 p824 (scan p846)": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.NO_AUTHOR.EDITOR_AS_LEAD_WHEN_APPROPRIATE"
+ ],
"CMOS18 \u00a713.84 p824 (scan p846)": [
"CMOS.CITATIONS.BIBLIOGRAPHY.ALT_NAMES.CROSSREF"
],
+ "CMOS18 \u00a713.85 p825 (scan p847)": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.SUFFIXES.INCLUDE"
+ ],
+ "CMOS18 \u00a713.86 p825 (scan p847)": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.PARTICLES.CONSISTENT_FORMAT"
+ ],
+ "CMOS18 \u00a713.87 p826 (scan p848)": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.CONTRIBUTOR_ROLES.LABEL_CLEARLY"
+ ],
+ "CMOS18 \u00a713.88 p826 (scan p848)": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.MULTIPLE_CONTRIBUTORS.POLICY_CONSISTENT"
+ ],
+ "CMOS18 \u00a713.89 p826 (scan p848)": [
+ "CMOS.CITATIONS.BIBLIOGRAPHY.GROUP_AUTHORS.SUBUNITS.CONSISTENT"
+ ],
+ "CMOS18 \u00a713.9 p779 (scan p796)": [
+ "CMOS.CITATIONS.S13_9.DATABASE_NAME_OK",
+ "CMOS.CITATIONS.S13_9.SHORTEN_LONG_URLS",
+ "CMOS.CITATIONS.S13_9.SHORT_URLS.ARE_NOT_SHORTENERS",
+ "CMOS.CITATIONS.S13_9.URL_TO_MAIN_PAGE"
+ ],
+ "CMOS18 \u00a713.90 p827 (scan p849)": [
+ "CMOS.CITATIONS.S13_90.TITLE_PUNCTUATION.CHANGES.POLICY_LIMITED"
+ ],
+ "CMOS18 \u00a713.91 p827 (scan p849)": [
+ "CMOS.CITATIONS.S13_91.TITLE_SUBTITLE.SEPARATOR.COLON"
+ ],
+ "CMOS18 \u00a713.92 p827 (scan p849)": [
+ "CMOS.CITATIONS.S13_92.BIBLIOGRAPHY.BOOKS.CORE_ELEMENTS"
+ ],
+ "CMOS18 \u00a713.93 p828 (scan p850)": [
+ "CMOS.CITATIONS.S13_93.BIBLIOGRAPHY.EDITED_VOLUMES.ROLE_MARKING"
+ ],
+ "CMOS18 \u00a713.94 p828 (scan p850)": [
+ "CMOS.CITATIONS.S13_94.TITLES.TRAILING_PHRASE.PLACEMENT"
+ ],
+ "CMOS18 \u00a713.95 p828 (scan p850)": [
+ "CMOS.CITATIONS.S13_95.BIBLIOGRAPHY.CHAPTERS.IN_EDITED_COLLECTIONS"
+ ],
+ "CMOS18 \u00a713.96 p829 (scan p851)": [
+ "CMOS.CITATIONS.S13_96.BIBLIOGRAPHY.JOURNAL_ARTICLES.VOLUME_ISSUE_PAGES"
+ ],
+ "CMOS18 \u00a713.97 p829 (scan p851)": [
+ "CMOS.CITATIONS.S13_97.BIBLIOGRAPHY.NEWSPAPER_MAGAZINE.DATES"
+ ],
+ "CMOS18 \u00a713.98 p830 (scan p852)": [
+ "CMOS.CITATIONS.S13_98.BIBLIOGRAPHY.THESES_DISSERTATIONS.INSTITUTION"
+ ],
+ "CMOS18 \u00a713.99 p831 (scan p853)": [
+ "CMOS.CITATIONS.S13_99.LONG_TITLES.TRUNCATION.AVOID"
+ ],
"CMOS18 \u00a714 p935": [
"CMOS.CITATIONS.LEGAL_PUBLIC_DOCS.USE_JURISDICTIONAL_FORMAT"
],
+ "CMOS18 \u00a714.1 p799": [
+ "CMOS.BACKMATTER.ABBREVIATIONS.LIST.WHEN_NEEDED",
+ "CMOS.BACKMATTER.ACKNOWLEDGMENTS.PLACEMENT",
+ "CMOS.BACKMATTER.APPENDICES.CROSS_REFERENCES",
+ "CMOS.BACKMATTER.APPENDICES.FORMAT_MATCH",
+ "CMOS.BACKMATTER.APPENDICES.SOURCES",
+ "CMOS.BACKMATTER.BIBLIOGRAPHY.CONSISTENT_STYLE",
+ "CMOS.BACKMATTER.BIBLIOGRAPHY.SORTING",
+ "CMOS.BACKMATTER.CONTACT.SUPPORT",
+ "CMOS.BACKMATTER.DATA.AVAILABILITY",
+ "CMOS.BACKMATTER.ENDNOTES.VERSUS_FOOTNOTES.CONSISTENT",
+ "CMOS.BACKMATTER.ERRATA.WHEN_NEEDED",
+ "CMOS.BACKMATTER.GLOSSARY.SORTING",
+ "CMOS.BACKMATTER.GLOSSARY.WHEN_TERMS",
+ "CMOS.BACKMATTER.INDEX.WHEN_REQUIRED",
+ "CMOS.BACKMATTER.LICENSES.THIRD_PARTY",
+ "CMOS.BACKMATTER.REFERENCES.SECTION_PRESENT",
+ "CMOS.BACKMATTER.REFERENCES.URLS.STABLE"
+ ],
+ "CMOS18 \u00a714.2 p801": [
+ "CMOS.BACKMATTER.ABBREVIATIONS.LIST.WHEN_NEEDED",
+ "CMOS.BACKMATTER.ACKNOWLEDGMENTS.PLACEMENT",
+ "CMOS.BACKMATTER.APPENDICES.CROSS_REFERENCES",
+ "CMOS.BACKMATTER.APPENDICES.FORMAT_MATCH",
+ "CMOS.BACKMATTER.APPENDICES.SOURCES",
+ "CMOS.BACKMATTER.BIBLIOGRAPHY.CONSISTENT_STYLE",
+ "CMOS.BACKMATTER.BIBLIOGRAPHY.SORTING",
+ "CMOS.BACKMATTER.CONTACT.SUPPORT",
+ "CMOS.BACKMATTER.DATA.AVAILABILITY",
+ "CMOS.BACKMATTER.ENDNOTES.VERSUS_FOOTNOTES.CONSISTENT",
+ "CMOS.BACKMATTER.ERRATA.WHEN_NEEDED",
+ "CMOS.BACKMATTER.GLOSSARY.SORTING",
+ "CMOS.BACKMATTER.GLOSSARY.WHEN_TERMS",
+ "CMOS.BACKMATTER.INDEX.WHEN_REQUIRED",
+ "CMOS.BACKMATTER.LICENSES.THIRD_PARTY",
+ "CMOS.BACKMATTER.REFERENCES.SECTION_PRESENT",
+ "CMOS.BACKMATTER.REFERENCES.URLS.STABLE"
+ ],
+ "CMOS18 \u00a715.103 p133 (scan p1125)": [
+ "CMOS.BACKMATTER.REFERENCES.AUTHOR_NAMES.CONSISTENT"
+ ],
+ "CMOS18 \u00a715.112 p40 (scan p1126)": [
+ "CMOS.BACKMATTER.REFERENCES.DOI.OR_URL"
+ ],
+ "CMOS18 \u00a715.112 p57 (scan p1120)": [
+ "CMOS.BACKMATTER.INDEX.SUBENTRIES.NESTED"
+ ],
+ "CMOS18 \u00a715.117 p117 (scan p1124)": [
+ "CMOS.LAYOUT.PAGINATION.PAGE_NUMBERS.STYLE",
+ "CMOS.LAYOUT.PAGINATION.PAGE_SEQUENCE.CONTINUITY"
+ ],
+ "CMOS18 \u00a715.119 p132 (scan p1124)": [
+ "CMOS.LAYOUT.PARAGRAPHS.INDENT_POLICY"
+ ],
+ "CMOS18 \u00a715.12 p108 (scan p1124)": [
+ "CMOS.LAYOUT.PARAGRAPHS.BLOCK_QUOTE_STYLE"
+ ],
+ "CMOS18 \u00a715.12 p29 (scan p1123)": [
+ "CMOS.FIGURES.SOURCE.DATA.CITED"
+ ],
+ "CMOS18 \u00a715.123 p29 (scan p1126)": [
+ "CMOS.BACKMATTER.REFERENCES.ACCESS_DATES.WHEN_NEEDED"
+ ],
+ "CMOS18 \u00a715.131 p32 (scan p1126)": [
+ "CMOS.BACKMATTER.INDEX.CROSS_REFERENCES.CONSISTENT"
+ ],
+ "CMOS18 \u00a715.22 p24 (scan p1130)": [
+ "CMOS.BACKMATTER.INDEX.PAGE_RANGES.STANDARD"
+ ],
+ "CMOS18 \u00a715.32 p31 (scan p1126)": [
+ "CMOS.BACKMATTER.INDEX.LOCATORS.ACCURATE"
+ ],
+ "CMOS18 \u00a715.44 p14 (scan p1126)": [
+ "CMOS.BACKMATTER.INDEX.SUBENTRY.ORDER.LOGICAL"
+ ],
+ "CMOS18 \u00a715.87 p88 (scan p1126)": [
+ "CMOS.BACKMATTER.INDEX.SEE_ALSO.USE_WHEN_NEEDED"
+ ],
+ "CMOS18 \u00a715.89 p90 (scan p1126)": [
+ "CMOS.BACKMATTER.INDEX.ABBREVIATIONS.CONSISTENT"
+ ],
+ "CMOS18 \u00a715.91 p92 (scan p1126)": [
+ "CMOS.BACKMATTER.INDEX.NAMES.SORTING"
+ ],
+ "CMOS18 \u00a72.14 p22 (scan p1124)": [
+ "CMOS.LAYOUT.PARAGRAPHS.SPACING_POLICY"
+ ],
+ "CMOS18 \u00a72.16 p177 (scan p1122)": [
+ "CMOS.LAYOUT.MEASURE.MAX_LINE_LENGTH"
+ ],
+ "CMOS18 \u00a72.27 p27 (scan p1124)": [
+ "CMOS.BACKMATTER.GLOSSARY.TERMS.CONSISTENT_STYLE"
+ ],
+ "CMOS18 \u00a72.61 p46 (scan p1120)": [
+ "CMOS.BACKMATTER.NOTES.NUMBERING.SEQUENTIAL",
+ "CMOS.BACKMATTER.NOTES.REFERENCE.MATCH",
+ "CMOS.LAYOUT.FOOTNOTES.PLACEMENT",
+ "CMOS.LAYOUT.FOOTNOTES.SEQUENCE"
+ ],
+ "CMOS18 \u00a73.1 p120": [
+ "CMOS.FIGURES.ACCESSIBILITY.ALT_TEXT",
+ "CMOS.FIGURES.ASPECT_RATIO.PRESERVE",
+ "CMOS.FIGURES.CAPTION.LENGTH.REASONABLE",
+ "CMOS.FIGURES.CAPTION.PLACEMENT.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.PUNCTUATION.CONSISTENT",
+ "CMOS.FIGURES.CAPTIONS.PRESENT",
+ "CMOS.FIGURES.COLOR.NOT_SOLE_SIGNAL",
+ "CMOS.FIGURES.CONTRAST.SUFFICIENT",
+ "CMOS.FIGURES.CREDIT.SOURCE_WHEN_REQUIRED",
+ "CMOS.FIGURES.FILENAME.STABLE",
+ "CMOS.FIGURES.FORMAT.VECTOR_WHEN_POSSIBLE",
+ "CMOS.FIGURES.LEGENDS.EXPLAIN_SYMBOLS",
+ "CMOS.FIGURES.MARGINS.AVOID_CLIPPING",
+ "CMOS.FIGURES.NUMBERING.SEQUENTIAL",
+ "CMOS.FIGURES.NUMBERING.WITHIN_CHAPTERS",
+ "CMOS.FIGURES.PLACEMENT.NEAR_MENTION",
+ "CMOS.FIGURES.REFERENCES.IN_TEXT",
+ "CMOS.FIGURES.RESOLUTION.RASTER_SUFFICIENT",
+ "CMOS.FIGURES.SCALE.LEGIBLE",
+ "CMOS.FIGURES.SENSITIVE.DATA.REDACT",
+ "CMOS.FIGURES.TABLE_VS_FIGURE.CHOOSE",
+ "CMOS.FIGURES.UNITS.LABEL_AXES"
+ ],
+ "CMOS18 \u00a73.12 p24 (scan p1122)": [
+ "CMOS.FIGURES.ANNOTATIONS.CONSISTENT_STYLE",
+ "CMOS.FIGURES.AXES.UNITS.CONSISTENT",
+ "CMOS.FIGURES.EMBEDDED_TEXT.MINIMAL",
+ "CMOS.FIGURES.LABELS.AVOID_OVERLAP",
+ "CMOS.FIGURES.LABELS.FONT.CONSISTENT",
+ "CMOS.FIGURES.MULTIPART.PANEL_LABELS",
+ "CMOS.FIGURES.PANEL_ORDER.LOGICAL"
+ ],
+ "CMOS18 \u00a73.2 p122": [
+ "CMOS.FIGURES.ACCESSIBILITY.ALT_TEXT",
+ "CMOS.FIGURES.ASPECT_RATIO.PRESERVE",
+ "CMOS.FIGURES.CAPTION.LENGTH.REASONABLE",
+ "CMOS.FIGURES.CAPTION.PLACEMENT.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.PUNCTUATION.CONSISTENT",
+ "CMOS.FIGURES.CAPTIONS.PRESENT",
+ "CMOS.FIGURES.COLOR.NOT_SOLE_SIGNAL",
+ "CMOS.FIGURES.CONTRAST.SUFFICIENT",
+ "CMOS.FIGURES.CREDIT.SOURCE_WHEN_REQUIRED",
+ "CMOS.FIGURES.FILENAME.STABLE",
+ "CMOS.FIGURES.FORMAT.VECTOR_WHEN_POSSIBLE",
+ "CMOS.FIGURES.LEGENDS.EXPLAIN_SYMBOLS",
+ "CMOS.FIGURES.MARGINS.AVOID_CLIPPING",
+ "CMOS.FIGURES.NUMBERING.SEQUENTIAL",
+ "CMOS.FIGURES.NUMBERING.WITHIN_CHAPTERS",
+ "CMOS.FIGURES.PLACEMENT.NEAR_MENTION",
+ "CMOS.FIGURES.RESOLUTION.RASTER_SUFFICIENT",
+ "CMOS.FIGURES.SCALE.LEGIBLE",
+ "CMOS.FIGURES.SENSITIVE.DATA.REDACT",
+ "CMOS.FIGURES.TABLE_VS_FIGURE.CHOOSE",
+ "CMOS.FIGURES.UNITS.LABEL_AXES"
+ ],
+ "CMOS18 \u00a73.2 p38 (scan p1123)": [
+ "CMOS.LAYOUT.TABLES.PLACEMENT_NEAR_REF",
+ "CMOS.TABLES.CAPTIONS.BREVITY",
+ "CMOS.TABLES.CAPTIONS.CLARITY",
+ "CMOS.TABLES.CAPTIONS.PRESENT",
+ "CMOS.TABLES.TITLES.NUMBERING.SEQUENTIAL",
+ "CMOS.TABLES.TITLES.PLACEMENT.CONSISTENT",
+ "CMOS.TABLES.TITLES.SCOPE.CONSISTENT"
+ ],
+ "CMOS18 \u00a73.3 p11 (scan p1122)": [
+ "CMOS.FIGURES.COLOR.PALETTE.CONSISTENT",
+ "CMOS.FIGURES.LINE_WEIGHTS.CONSISTENT",
+ "CMOS.FIGURES.SYMBOLS.CONSISTENT"
+ ],
+ "CMOS18 \u00a73.34 p120 (scan p1122)": [
+ "CMOS.LAYOUT.PAGINATION.FACING_PAGES.BALANCE",
+ "CMOS.LAYOUT.PAGINATION.FACING_PAGES.BLANKS",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.AVOID_BOTTOM_OF_PAGE",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.AVOID_TOP_OF_PAGE",
+ "CMOS.LAYOUT.PAGINATION.HEADINGS.KEEP_WITH_TEXT"
+ ],
+ "CMOS18 \u00a73.34 p33 (scan p1122)": [
+ "CMOS.FIGURES.LIST_ENTRIES.MATCH_CAPTIONS",
+ "CMOS.FIGURES.LIST_OF_FIGURES.WHEN_NEEDED"
+ ],
+ "CMOS18 \u00a73.38 p39 (scan p1122)": [
+ "CMOS.FIGURES.BLEED.ONLY_WHEN_ENABLED",
+ "CMOS.FIGURES.CALL_OUTS.AVOID_OVERLAP",
+ "CMOS.FIGURES.CROP.AVOID_LOSS",
+ "CMOS.FIGURES.ORIENTATION.CONSISTENT",
+ "CMOS.FIGURES.PLACEMENT.AVOID_SPLIT"
+ ],
+ "CMOS18 \u00a73.45 p130 (scan p1133)": [
+ "CMOS.LAYOUT.SPACING.LEADING.CHOOSE",
+ "CMOS.LAYOUT.SPACING.LINE_SPACING.CONSISTENT"
+ ],
+ "CMOS18 \u00a73.5 p64 (scan p1123)": [
+ "CMOS.FIGURES.CAPTION.ALIGNMENT.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.FONT.CONSISTENT",
+ "CMOS.FIGURES.CAPTION.NUMBER.MATCH_LABEL",
+ "CMOS.FIGURES.CAPTION.PREFIX.CONSISTENT",
+ "CMOS.FIGURES.KEY.READABLE",
+ "CMOS.FIGURES.SCALING.UNIFORM",
+ "CMOS.FIGURES.SIZE.MATCH_READABILITY",
+ "CMOS.LAYOUT.ILLUSTRATIONS.PLACEMENT_NEAR_REF"
+ ],
+ "CMOS18 \u00a73.6 p16 (scan p1122)": [
+ "CMOS.TABLES.HEADERS.ALIGNMENT.CONSISTENT",
+ "CMOS.TABLES.HEADERS.CAPITALIZATION.CONSISTENT",
+ "CMOS.TABLES.HEADERS.REQUIRED",
+ "CMOS.TABLES.REFERENCES.IN_TEXT",
+ "CMOS.TABLES.STUB_COLUMN.USE"
+ ],
+ "CMOS18 \u00a73.7 p120 (scan p1122)": [
+ "CMOS.LAYOUT.PAGINATION.RUNNING_HEADS.CONSISTENCY",
+ "CMOS.LAYOUT.PAGINATION.RUNNING_HEADS.PLACEMENT",
+ "CMOS.LAYOUT.RUNNING_HEADS.CHAPTER_TITLES",
+ "CMOS.LAYOUT.RUNNING_HEADS.SECTION_TITLES"
+ ],
+ "CMOS18 \u00a73.8 p15 (scan p1122)": [
+ "CMOS.FIGURES.PLACEMENT.TOP_OR_BOTTOM.CONSISTENT"
+ ],
+ "CMOS18 \u00a74.81 p81 (scan p1123)": [
+ "CMOS.LAYOUT.PAGINATION.ORPHANS.AVOID"
+ ],
+ "CMOS18 \u00a75.16 p81 (scan p1123)": [
+ "CMOS.LAYOUT.PAGINATION.AVOID_SHORT_LAST_LINE",
+ "CMOS.LAYOUT.PAGINATION.AVOID_SINGLE_LINE_ENDING",
+ "CMOS.LAYOUT.PAGINATION.WIDOWS.AVOID"
+ ],
+ "CMOS18 \u00a75.17 p177 (scan p1122)": [
+ "CMOS.LAYOUT.MEASURE.MIN_LINE_LENGTH"
+ ],
+ "CMOS18 \u00a75.170 p170 (scan p1129)": [
+ "CMOS.FRONTMATTER.INTRODUCTION.SCOPE"
+ ],
+ "CMOS18 \u00a75.207 p207 (scan p1123)": [
+ "CMOS.TABLES.ABBREVIATIONS.EXPLAIN",
+ "CMOS.TABLES.FOOTNOTES.PLACEMENT",
+ "CMOS.TABLES.MISSING_VALUES.EXPLAIN",
+ "CMOS.TABLES.NOTES.ORDERED_MARKERS",
+ "CMOS.TABLES.SOURCE.NOTES.DISTINCT"
+ ],
+ "CMOS18 \u00a75.210 p50 (scan p1120)": [
+ "CMOS.BACKMATTER.NOTES.BLOCKS.CONSISTENT",
+ "CMOS.BACKMATTER.NOTES.ORDER.FOLLOW_TEXT"
+ ],
+ "CMOS18 \u00a75.254 p84 (scan p1123)": [
+ "CMOS.TABLES.COLUMN_SPACING.READABLE",
+ "CMOS.TABLES.GRIDLINES.LIGHT",
+ "CMOS.TABLES.GROUPING.WHITESPACE",
+ "CMOS.TABLES.ROW_SPACING.READABLE",
+ "CMOS.TABLES.RULES.MINIMAL",
+ "CMOS.TABLES.SHADING.SPARING"
+ ],
+ "CMOS18 \u00a76.1 p377 (scan p400)": [
+ "CMOS.PUNCTUATION.OVERVIEW.CONSISTENT.PRINCIPLES",
+ "CMOS.PUNCTUATION.OVERVIEW.CONTEXT.REGISTER",
+ "CMOS.PUNCTUATION.OVERVIEW.FUNCTION.CLARITY"
+ ],
"CMOS18 \u00a76.101 p422 (scan p444)": [
+ "CMOS.PUNCTUATION.PARENS.PUNCTUATION_PLACEMENT",
"CMOS.PUNCTUATION.PARENS.USE",
"CMOS.PUNCTUATION.PARENS_BRACKETS.BALANCE"
],
@@ -376,16 +1496,22 @@
],
"CMOS18 \u00a76.103 p422 (scan p444)": [
"CMOS.PUNCTUATION.PARENS.NESTING",
+ "CMOS.PUNCTUATION.PARENS.PUNCTUATION_PLACEMENT",
"CMOS.PUNCTUATION.PARENS_BRACKETS.BALANCE"
],
"CMOS18 \u00a76.106 p424 (scan p446)": [
+ "CMOS.PUNCTUATION.BRACKETS.EDITORIAL_INSERTIONS",
"CMOS.PUNCTUATION.BRACKETS.TRANSLATED_TEXT"
],
"CMOS18 \u00a76.107 p424 (scan p446)": [
"CMOS.PUNCTUATION.BRACKETS.NESTED_PARENS"
],
+ "CMOS18 \u00a76.113 p118 (scan p1121)": [
+ "CMOS.LAYOUT.PAGINATION.PAGE_BREAKS.BEFORE_PARTS"
+ ],
"CMOS18 \u00a76.113 p426 (scan p448)": [
- "CMOS.PUNCTUATION.SLASHES.ALTERNATIVES"
+ "CMOS.PUNCTUATION.SLASHES.ALTERNATIVES",
+ "CMOS.PUNCTUATION.SLASHES.NO_SPACES"
],
"CMOS18 \u00a76.114 p426 (scan p448)": [
"CMOS.PUNCTUATION.SLASHES.TWO_YEAR_SPANS"
@@ -394,72 +1520,404 @@
"CMOS.PUNCTUATION.PERIODS.USE"
],
"CMOS18 \u00a76.122 p428 (scan p450)": [
+ "CMOS.PUNCTUATION.QUESTION_MARKS.QUOTE_PLACEMENT",
"CMOS.PUNCTUATION.QUOTATION_MARKS.DOUBLE_PRIMARY_US",
"CMOS.PUNCTUATION.QUOTATION_MARKS.PUNCTUATION_PLACEMENT_US"
],
"CMOS18 \u00a76.123 p428 (scan p450)": [
"CMOS.PUNCTUATION.QUOTES.SMART_QUOTES"
],
+ "CMOS18 \u00a76.124 p429 (scan p451)": [
+ "CMOS.PUNCTUATION.APOSTROPHE.USE_CASES"
+ ],
+ "CMOS18 \u00a76.125 p429 (scan p451)": [
+ "CMOS.PUNCTUATION.APOSTROPHE.SMART"
+ ],
+ "CMOS18 \u00a76.127 p430 (scan p452)": [
+ "CMOS.PUNCTUATION.SPACING.NONBREAKING",
+ "CMOS.PUNCTUATION.SPACING.WORD_SPACE_DEFAULT"
+ ],
+ "CMOS18 \u00a76.128 p430 (scan p452)": [
+ "CMOS.PUNCTUATION.SPACING.FIXED_WIDTHS"
+ ],
"CMOS18 \u00a76.13 p383 (scan p405)": [
"CMOS.PUNCTUATION.PERIODS.WITH_PARENS"
],
"CMOS18 \u00a76.131 p432 (scan p454)": [
"CMOS.PUNCTUATION.MULTIPLE_MARKS.AVOID_STACKING"
],
+ "CMOS18 \u00a76.132 p432 (scan p454)": [
+ "CMOS.PUNCTUATION.PERIODS.NO_DOUBLE_AT_SENTENCE_END"
+ ],
+ "CMOS18 \u00a76.133 p433 (scan p454)": [
+ "CMOS.PUNCTUATION.PERIODS.NOT_WITH_QM_EXCL"
+ ],
+ "CMOS18 \u00a76.134 p433 (scan p454)": [
+ "CMOS.PUNCTUATION.COMMAS.QUOTE_ENDING_QM_EXCL"
+ ],
+ "CMOS18 \u00a76.135 p433 (scan p454)": [
+ "CMOS.PUNCTUATION.QUESTION_EXCLAMATION.DUAL_MARKS"
+ ],
+ "CMOS18 \u00a76.136 p434 (scan p456)": [
+ "CMOS.PUNCTUATION.QUESTION_MARKS.LIST_INTRO"
+ ],
+ "CMOS18 \u00a76.137 p434 (scan p456)": [
+ "CMOS.PUNCTUATION.EMOJIS.PUNCTUATION"
+ ],
+ "CMOS18 \u00a76.138 p435 (scan p456)": [
+ "CMOS.PUNCTUATION.LISTS.CONSISTENT_FORMAT",
+ "CMOS.PUNCTUATION.LISTS.NUMERALS_ONLY_IF_NEEDED",
+ "CMOS.PUNCTUATION.LISTS.PARALLEL_ELEMENTS"
+ ],
+ "CMOS18 \u00a76.139 p435 (scan p457)": [
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SHORT_SIMPLE",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.LONG_OR_MULTI"
+ ],
+ "CMOS18 \u00a76.14 p384 (scan p405)": [
+ "CMOS.PUNCTUATION.PARENS.AVOID_MULTIPLE_SENTENCES",
+ "CMOS.PUNCTUATION.PERIODS.OMIT_DISPLAY_LINES"
+ ],
+ "CMOS18 \u00a76.140 p435 (scan p457)": [
+ "CMOS.PUNCTUATION.LISTS.RUNIN.INTRO_COMPLETE_COLON",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.LETTERS.ITALIC_OPTION",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.MARKERS.PARENS",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SENTENCE_ITEMS_VERTICAL",
+ "CMOS.PUNCTUATION.LISTS.RUNIN.SEPARATORS"
+ ],
+ "CMOS18 \u00a76.141 p436 (scan p458)": [
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.CAPITALIZATION_CONSISTENT",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.END_PUNCT_SENTENCES",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.INTRO_COLON",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.MULTI_COLUMN_SHORT_ITEMS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.ORDERED_MARKERS",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.RUNOVER_ALIGN",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.UNORDERED_FRAGMENTS"
+ ],
+ "CMOS18 \u00a76.142 p438 (scan p460)": [
+ "CMOS.PUNCTUATION.LISTS.AVOID_VERTICAL_FOR_LONG_SENTENCES",
+ "CMOS.PUNCTUATION.LISTS.MIXED_SENTENCE_TYPES",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_CONJUNCTION",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_LOWERCASE",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_PUNCTUATION",
+ "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_USE_ONLY_FOR_EMPHASIS"
+ ],
+ "CMOS18 \u00a76.143 p438 (scan p460)": [
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.MULTI_DIGIT_ALIGN",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.OUTLINE_MARKERS",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.PUNCTUATION_LEVELS",
+ "CMOS.PUNCTUATION.LISTS.MULTILEVEL.RUNOVER_ALIGN"
+ ],
+ "CMOS18 \u00a76.15 p384 (scan p405)": [
+ "CMOS.PUNCTUATION.ELLIPSIS.USE_CASES"
+ ],
+ "CMOS18 \u00a76.16 p384 (scan p405)": [
+ "CMOS.PUNCTUATION.COMMAS.LOGIC_OVER_PAUSE",
+ "CMOS.PUNCTUATION.COMMAS.REGISTER.FLEX"
+ ],
"CMOS18 \u00a76.17 p385 (scan p407)": [
- "CMOS.PUNCTUATION.COMMAS.NONRESTRICTIVE.SET_OFF"
+ "CMOS.PUNCTUATION.COMMAS.NONRESTRICTIVE.SET_OFF",
+ "CMOS.PUNCTUATION.COMMAS.PAIRS.SECOND_REQUIRED",
+ "CMOS.PUNCTUATION.COMMAS.PAIRS.TITLES_EXCEPTION"
+ ],
+ "CMOS18 \u00a76.18 p384 (scan p407)": [
+ "CMOS.PUNCTUATION.COMMAS.BRACKETS.EDITORIAL",
+ "CMOS.PUNCTUATION.COMMAS.PARENS.TRAILING"
+ ],
+ "CMOS18 \u00a76.18 p385 (scan p407)": [
+ "CMOS.PUNCTUATION.COMMAS.BRACKETS.EDITORIAL_INSERT",
+ "CMOS.PUNCTUATION.COMMAS.PARENS_BRACKETS.AFTER_CLOSING"
],
"CMOS18 \u00a76.19 p385 (scan p407)": [
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.ALL_CONJUNCTIONS",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.ALL_CONJUNCTIONS_NO_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.AMBIGUITY_REWORD",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.AS_WELL_AS",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.PAIR_LAST_ITEM",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.PAIR_WITH_AND",
+ "CMOS.PUNCTUATION.COMMAS.SERIAL.REQUIRED",
"CMOS.PUNCTUATION.COMMAS.SERIAL_COMMA.DEFAULT"
],
+ "CMOS18 \u00a76.2 p378 (scan p400)": [
+ "CMOS.PUNCTUATION.ITALICS.SURROUNDING_STYLE",
+ "CMOS.PUNCTUATION.ITALICS.TITLE_OWNERSHIP"
+ ],
+ "CMOS18 \u00a76.20 p386 (scan p409)": [
+ "CMOS.PUNCTUATION.COMMAS.ETC.FINAL_ELEMENT",
+ "CMOS.PUNCTUATION.COMMAS.ETC_ETAL.STYLE"
+ ],
+ "CMOS18 \u00a76.20 p387 (scan p409)": [
+ "CMOS.PUNCTUATION.COMMAS.ETC.FORMAL_LIMIT",
+ "CMOS.PUNCTUATION.COMMAS.ETC.TRAILING",
+ "CMOS.PUNCTUATION.COMMAS.ETC_SINGLE_ITEM"
+ ],
+ "CMOS18 \u00a76.21 p387 (scan p409)": [
+ "CMOS.PUNCTUATION.COMMAS.AMPERSAND.NO_SERIAL"
+ ],
+ "CMOS18 \u00a76.22 p387 (scan p409)": [
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.CONJUNCTION",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.SHORT",
+ "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.SHORT_OMIT"
+ ],
+ "CMOS18 \u00a76.23 p387 (scan p410)": [
+ "CMOS.PUNCTUATION.COMMAS.COMMA_SPLICE.AVOID_FORMAL"
+ ],
+ "CMOS18 \u00a76.23 p388 (scan p410)": [
+ "CMOS.PUNCTUATION.COMMAS.SPLICES.AVOID_FORMAL",
+ "CMOS.PUNCTUATION.COMMAS.SPLICES.EDITORIAL_DISCRETION"
+ ],
"CMOS18 \u00a76.24 p388 (scan p410)": [
+ "CMOS.PUNCTUATION.COMMAS.AND_THEN",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.CLARITY",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.NO_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.SERIES",
+ "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.THEN_SHORTHAND",
"CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATES"
],
+ "CMOS18 \u00a76.25 p389 (scan p411)": [
+ "CMOS.PUNCTUATION.COMMAS.IMPERATIVE_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.IMPERATIVE_CLAUSES.DEFAULT"
+ ],
+ "CMOS18 \u00a76.26 p389 (scan p412)": [
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_INTRODUCTORY"
+ ],
"CMOS18 \u00a76.26 p390 (scan p412)": [
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_INTRO",
"CMOS.PUNCTUATION.COMMAS.INTRODUCTORY_ELEMENTS.CLARITY"
],
"CMOS18 \u00a76.27 p390 (scan p412)": [
- "CMOS.PUNCTUATION.COMMAS.DEPENDENT_CLAUSE_AFTER"
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_CLAUSE_AFTER",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING.RESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING_NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING_RESTRICTIVE"
+ ],
+ "CMOS18 \u00a76.28 p391 (scan p413)": [
+ "CMOS.PUNCTUATION.COMMAS.CONSECUTIVE_CONJUNCTIONS",
+ "CMOS.PUNCTUATION.COMMAS.CONSECUTIVE_CONJUNCTIONS.NO_COMMA"
+ ],
+ "CMOS18 \u00a76.29 p391 (scan p414)": [
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_THAT_WHICH"
],
"CMOS18 \u00a76.29 p392 (scan p414)": [
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIVE_RESTRICTIVE",
"CMOS.PUNCTUATION.COMMAS.RESTRICTIVE.NO_SET_OFF"
],
+ "CMOS18 \u00a76.3 p379 (scan p401)": [
+ "CMOS.PUNCTUATION.BOLD_COLOR.CASE_BY_CASE",
+ "CMOS.PUNCTUATION.BOLD_COLOR.SEMANTIC_OWNERSHIP"
+ ],
"CMOS18 \u00a76.30 p392 (scan p414)": [
- "CMOS.PUNCTUATION.COMMAS.APPOSITIVES"
+ "CMOS.PUNCTUATION.COMMAS.APPOSITIVES",
+ "CMOS.PUNCTUATION.COMMAS.APPOSITIVES.NONRESTRICTIVE"
+ ],
+ "CMOS18 \u00a76.31 p393 (scan p415)": [
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIPS.AVOID_POSSESSIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIPS.UNIQUE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_ALWAYS_USE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_AWKWARD_POSSESSIVE",
+ "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_NAMES"
],
"CMOS18 \u00a76.32 p394 (scan p416)": [
- "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASES"
+ "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASE",
+ "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASES",
+ "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASES.NONRESTRICTIVE"
],
"CMOS18 \u00a76.33 p394 (scan p416)": [
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL.LINKING_VERB",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL.NONRESTRICTIVE",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_INTRO",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_LINKING_VERB",
+ "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_MID_END",
"CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_PHRASES"
],
+ "CMOS18 \u00a76.34 p395 (scan p417)": [
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL.INTRO_OPTIONAL",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL.MID_END",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_END",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_INTRO_OPTIONAL",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_INVERTED",
+ "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_MID"
+ ],
+ "CMOS18 \u00a76.34 p96 (scan p1129)": [
+ "CMOS.FRONTMATTER.TOC.INDENTATION.BY_LEVEL",
+ "CMOS.FRONTMATTER.TOC.ORDER.MATCH_BODY"
+ ],
+ "CMOS18 \u00a76.35 p395 (scan p418)": [
+ "CMOS.PUNCTUATION.COMMAS.PHRASE_PLUS_CONJUNCTION"
+ ],
+ "CMOS18 \u00a76.35 p396 (scan p418)": [
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTION_PLUS_PHRASE.INDEPENDENT",
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTION_PLUS_PHRASE.PREDICATE"
+ ],
"CMOS18 \u00a76.36 p396 (scan p418)": [
- "CMOS.PUNCTUATION.COMMAS.INTRODUCTORY_PHRASES"
+ "CMOS.PUNCTUATION.COMMAS.INTRODUCTORY_PHRASES",
+ "CMOS.PUNCTUATION.COMMAS.INTRO_PHRASES.GENERAL"
+ ],
+ "CMOS18 \u00a76.37 p397 (scan p419)": [
+ "CMOS.PUNCTUATION.COMMAS.INTRO_YES_NO"
+ ],
+ "CMOS18 \u00a76.38 p397 (scan p419)": [
+ "CMOS.PUNCTUATION.COMMAS.INTRO_OH_AH"
+ ],
+ "CMOS18 \u00a76.39 p397 (scan p419)": [
+ "CMOS.PUNCTUATION.COMMAS.COORDINATE_ADJECTIVES"
+ ],
+ "CMOS18 \u00a76.4 p379 (scan p401)": [
+ "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.ELECTRONIC_PREFERS_LOGICAL",
+ "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.PRINT_ONLY"
],
"CMOS18 \u00a76.40 p398 (scan p420)": [
- "CMOS.PUNCTUATION.COMMAS.REPEATED_ADJECTIVES"
+ "CMOS.PUNCTUATION.COMMAS.REPEATED_ADJECTIVES",
+ "CMOS.PUNCTUATION.COMMAS.REPEATED_ADJECTIVES.USE_COMMA"
+ ],
+ "CMOS18 \u00a76.41 p397 (scan p420)": [
+ "CMOS.PUNCTUATION.COMMAS.DATES.NO_COMMA_OTHER_STYLES"
],
"CMOS18 \u00a76.41 p398 (scan p420)": [
- "CMOS.PUNCTUATION.COMMAS.DATES"
+ "CMOS.PUNCTUATION.COMMAS.DATES",
+ "CMOS.PUNCTUATION.COMMAS.DATES.ALTERNATE_SYSTEMS",
+ "CMOS.PUNCTUATION.COMMAS.DATES.MONTH_DAY_YEAR"
+ ],
+ "CMOS18 \u00a76.42 p397 (scan p420)": [
+ "CMOS.PUNCTUATION.COMMAS.ADDRESSES.MAILING_SPARING"
],
"CMOS18 \u00a76.42 p398 (scan p420)": [
- "CMOS.PUNCTUATION.COMMAS.ADDRESSES"
+ "CMOS.PUNCTUATION.COMMAS.ADDRESSES",
+ "CMOS.PUNCTUATION.COMMAS.ADDRESSES.RUN_IN"
+ ],
+ "CMOS18 \u00a76.43 p398 (scan p421)": [
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.DIALOGUE_VERB_COMMA",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.NO_COMMA_CONJUNCTION"
+ ],
+ "CMOS18 \u00a76.43 p399 (scan p421)": [
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.DIALOGUE",
+ "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.THAT_WHETHER"
+ ],
+ "CMOS18 \u00a76.44 p399 (scan p422)": [
+ "CMOS.PUNCTUATION.COMMAS.TITLES.APPOSITIVE_RULE"
],
"CMOS18 \u00a76.44 p400 (scan p422)": [
- "CMOS.PUNCTUATION.COMMAS.QUOTED_TITLES"
+ "CMOS.PUNCTUATION.COMMAS.QUOTED_TITLES",
+ "CMOS.PUNCTUATION.COMMAS.TITLES_AND_EXPRESSIONS"
+ ],
+ "CMOS18 \u00a76.45 p399 (scan p422)": [
+ "CMOS.PUNCTUATION.COMMAS.QUESTIONS.DIRECT_IN_SENTENCE",
+ "CMOS.PUNCTUATION.COMMAS.QUESTIONS.INDIRECT"
],
"CMOS18 \u00a76.45 p400 (scan p422)": [
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_QUESTIONS",
+ "CMOS.PUNCTUATION.COMMAS.INDIRECT_QUESTIONS",
"CMOS.PUNCTUATION.COMMAS.QUESTIONS"
],
+ "CMOS18 \u00a76.46 p400 (scan p423)": [
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.NONE"
+ ],
+ "CMOS18 \u00a76.46 p401 (scan p423)": [
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.INVERTED",
+ "CMOS.PUNCTUATION.COMMAS.JR_SR.RUNNING"
+ ],
+ "CMOS18 \u00a76.47 p401 (scan p424)": [
+ "CMOS.PUNCTUATION.COMMAS.INC_LTD.NONE"
+ ],
+ "CMOS18 \u00a76.47 p402 (scan p424)": [
+ "CMOS.PUNCTUATION.COMMAS.CORPORATE_SUFFIX"
+ ],
+ "CMOS18 \u00a76.48 p401 (scan p424)": [
+ "CMOS.PUNCTUATION.COMMAS.NOT_PHRASE"
+ ],
+ "CMOS18 \u00a76.48 p402 (scan p424)": [
+ "CMOS.PUNCTUATION.COMMAS.NOT_PHRASES"
+ ],
+ "CMOS18 \u00a76.49 p401 (scan p424)": [
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE.INDEPENDENT_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE.PREDICATE"
+ ],
+ "CMOS18 \u00a76.49 p402 (scan p424)": [
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE_CLAUSES",
+ "CMOS.PUNCTUATION.COMMAS.CORRELATIVE_PHRASES"
+ ],
+ "CMOS18 \u00a76.5 p380 (scan p402)": [
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.LINE_ALONE",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.MATCH_SURROUNDING",
+ "CMOS.PUNCTUATION.PARENS_BRACKETS.PRINT_HAIR_SPACE"
+ ],
+ "CMOS18 \u00a76.50 p403 (scan p425)": [
+ "CMOS.PUNCTUATION.COMMAS.THE_MORE_THE_MORE"
+ ],
+ "CMOS18 \u00a76.51 p402 (scan p425)": [
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICALS.SLIGHT_BREAK"
+ ],
+ "CMOS18 \u00a76.51 p403 (scan p425)": [
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_ELEMENTS",
+ "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_HEAVY"
+ ],
+ "CMOS18 \u00a76.52 p403 (scan p425)": [
+ "CMOS.PUNCTUATION.COMMAS.CONJUNCTIVE_ADVERBS"
+ ],
+ "CMOS18 \u00a76.53 p404 (scan p426)": [
+ "CMOS.PUNCTUATION.COMMAS.SUCH_AS_INCLUDING"
+ ],
+ "CMOS18 \u00a76.54 p403 (scan p426)": [
+ "CMOS.PUNCTUATION.COMMAS.IE_EG.PARENS",
+ "CMOS.PUNCTUATION.COMMAS.THAT_IS.TRAILING_COMMA"
+ ],
+ "CMOS18 \u00a76.54 p404 (scan p426)": [
+ "CMOS.PUNCTUATION.COMMAS.THAT_IS_NAMELY"
+ ],
+ "CMOS18 \u00a76.55 p405 (scan p427)": [
+ "CMOS.PUNCTUATION.COMMAS.EXPLANATORY_ALTERNATIVES"
+ ],
+ "CMOS18 \u00a76.56 p405 (scan p427)": [
+ "CMOS.PUNCTUATION.COMMAS.TOO_EITHER.OMIT",
+ "CMOS.PUNCTUATION.COMMAS.TOO_MID_SENTENCE"
+ ],
+ "CMOS18 \u00a76.57 p405 (scan p427)": [
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS",
+ "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS.GREETINGS"
+ ],
+ "CMOS18 \u00a76.58 p406 (scan p428)": [
+ "CMOS.PUNCTUATION.COMMAS.ELISION"
+ ],
+ "CMOS18 \u00a76.59 p406 (scan p429)": [
+ "CMOS.PUNCTUATION.COMMAS.HOMONYMS.CLARITY"
+ ],
+ "CMOS18 \u00a76.6 p380 (scan p402)": [
+ "CMOS.PUNCTUATION.QUOTES.ITALIC_TITLE_EXCEPTION",
+ "CMOS.PUNCTUATION.QUOTES.MATCH_SURROUNDING"
+ ],
+ "CMOS18 \u00a76.6 p380 (scan p403)": [
+ "CMOS.PUNCTUATION.QUOTES.LINE_ALONE"
+ ],
+ "CMOS18 \u00a76.60 p407 (scan p429)": [
+ "CMOS.PUNCTUATION.SEMICOLONS.AVOID_DIALOGUE"
+ ],
+ "CMOS18 \u00a76.61 p407 (scan p429)": [
+ "CMOS.PUNCTUATION.SEMICOLONS.CONJUNCTIVE_ADVERBS"
+ ],
+ "CMOS18 \u00a76.62 p407 (scan p430)": [
+ "CMOS.PUNCTUATION.SEMICOLONS.THAT_IS_CLAUSE"
+ ],
"CMOS18 \u00a76.62 p408 (scan p430)": [
"CMOS.PUNCTUATION.SEMICOLONS.CONJUNCTIVE_PHRASES"
],
"CMOS18 \u00a76.63 p408 (scan p430)": [
- "CMOS.PUNCTUATION.SEMICOLONS.BEFORE_CONJUNCTION"
+ "CMOS.PUNCTUATION.SEMICOLONS.AVOID_COMMA_SPLICE",
+ "CMOS.PUNCTUATION.SEMICOLONS.BEFORE_CONJUNCTION",
+ "CMOS.PUNCTUATION.SEMICOLONS.INDEPENDENT_CLAUSES"
],
"CMOS18 \u00a76.64 p408 (scan p430)": [
+ "CMOS.PUNCTUATION.SEMICOLONS.COMPLEX_SERIES",
"CMOS.PUNCTUATION.SEMICOLONS.COMPLEX_SERIES.SEPARATE"
],
+ "CMOS18 \u00a76.65 p409 (scan p431)": [
+ "CMOS.PUNCTUATION.COLONS.AMPLIFY_OR_ILLUSTRATE",
+ "CMOS.PUNCTUATION.COLONS.EMPHASIS_SECOND_CLAUSE"
+ ],
+ "CMOS18 \u00a76.66 p409 (scan p432)": [
+ "CMOS.PUNCTUATION.COLONS.ONE_SPACE"
+ ],
"CMOS18 \u00a76.66 p410 (scan p432)": [
"CMOS.PUNCTUATION.COLONS.SPACE_AFTER",
"CMOS.PUNCTUATION.DEGRADED.EXTRA_SPACES.AFTER_PUNCT"
@@ -468,42 +1926,132 @@
"CMOS.PUNCTUATION.COLONS.CAPITALIZATION"
],
"CMOS18 \u00a76.68 p410 (scan p432)": [
- "CMOS.PUNCTUATION.COLONS.AS_FOLLOWS"
+ "CMOS.PUNCTUATION.COLONS.AS_FOLLOWS",
+ "CMOS.PUNCTUATION.COLONS.AVOID_AFTER_PREPOSITION",
+ "CMOS.PUNCTUATION.COLONS.COMPLETE_CLAUSE_REQUIRED"
+ ],
+ "CMOS18 \u00a76.69 p409 (scan p432)": [
+ "CMOS.PUNCTUATION.COLONS.QUOTATIONS"
],
"CMOS18 \u00a76.69 p410 (scan p432)": [
+ "CMOS.PUNCTUATION.COLONS.INTRODUCE_FORMAL_LISTS",
"CMOS.PUNCTUATION.COLONS.INTRO_QUOTE_QUESTION"
],
+ "CMOS18 \u00a76.7 p381 (scan p403)": [
+ "CMOS.PUNCTUATION.SPACING.DESIGN_SPECIFIED",
+ "CMOS.PUNCTUATION.SPACING.ONE_SPACE_AFTER_COLON",
+ "CMOS.PUNCTUATION.SPACING.ONE_SPACE_SENTENCES"
+ ],
+ "CMOS18 \u00a76.70 p411 (scan p433)": [
+ "CMOS.PUNCTUATION.COLONS.FORMAL_GREETINGS"
+ ],
+ "CMOS18 \u00a76.71 p411 (scan p433)": [
+ "CMOS.PUNCTUATION.COLONS.AVOID_INCOMPLETE_LEADIN"
+ ],
+ "CMOS18 \u00a76.72 p411 (scan p434)": [
+ "CMOS.PUNCTUATION.QUESTION_MARKS.DIRECT"
+ ],
"CMOS18 \u00a76.72 p412 (scan p434)": [
"CMOS.PUNCTUATION.QUESTION_MARK.USE"
],
+ "CMOS18 \u00a76.73 p411 (scan p434)": [
+ "CMOS.PUNCTUATION.QUESTION_MARKS.DIRECT_INDIRECT"
+ ],
"CMOS18 \u00a76.73 p412 (scan p434)": [
"CMOS.PUNCTUATION.QUESTION_MARK.DIRECT_VS_INDIRECT"
],
+ "CMOS18 \u00a76.74 p412 (scan p435)": [
+ "CMOS.PUNCTUATION.QUESTION_MARKS.SURROUNDING"
+ ],
"CMOS18 \u00a76.74 p413 (scan p435)": [
"CMOS.PUNCTUATION.QUESTION_MARK.WITH_PUNCT"
],
+ "CMOS18 \u00a76.75 p412 (scan p435)": [
+ "CMOS.PUNCTUATION.EXCLAMATION.USE_SPARING"
+ ],
"CMOS18 \u00a76.75 p413 (scan p435)": [
"CMOS.PUNCTUATION.EXCLAMATION.USE_SPARINGLY"
],
+ "CMOS18 \u00a76.76 p412 (scan p435)": [
+ "CMOS.PUNCTUATION.EXCLAMATION.RHETORICAL"
+ ],
"CMOS18 \u00a76.76 p413 (scan p435)": [
"CMOS.PUNCTUATION.EXCLAMATION.VS_QUESTION"
],
+ "CMOS18 \u00a76.77 p412 (scan p435)": [
+ "CMOS.PUNCTUATION.EXCLAMATION.BRACKETED_AVOID"
+ ],
+ "CMOS18 \u00a76.78 p414 (scan p436)": [
+ "CMOS.PUNCTUATION.EXCLAMATION.QUOTE_PLACEMENT"
+ ],
+ "CMOS18 \u00a76.79 p414 (scan p436)": [
+ "CMOS.PUNCTUATION.DASHES.DISTINCT_TYPES"
+ ],
+ "CMOS18 \u00a76.8 p381 (scan p403)": [
+ "CMOS.LINKS.HYPERLINK_EXCLUDES_PUNCTUATION",
+ "CMOS.LINKS.NO_WRAPPERS",
+ "CMOS.LINKS.PUNCTUATE_NORMALLY",
+ "CMOS.LINKS.REPHRASE_IF_URL_ENDS_PUNCT",
+ "CMOS.LINKS.TRAILING_PUNCTUATION_OUTSIDE",
+ "CMOS.LINKS.URL_ONLY_LINE_NO_PUNCT",
+ "CMOS.PUNCTUATION.URLS.HYPERTEXT_EXCLUDES_PUNCTUATION",
+ "CMOS.PUNCTUATION.URLS.NO_WRAPPERS",
+ "CMOS.PUNCTUATION.URLS.PUNCTUATE_NORMALLY",
+ "CMOS.PUNCTUATION.URLS.TRAILING_PUNCTUATION"
+ ],
+ "CMOS18 \u00a76.81 p415 (scan p437)": [
+ "CMOS.PUNCTUATION.HYPHENS.SEPARATORS"
+ ],
"CMOS18 \u00a76.83 p415 (scan p437)": [
"CMOS.NUMBERS.RANGES.EN_DASH.USE",
- "CMOS.PUNCTUATION.DASHES.EN_DASH.RANGES"
+ "CMOS.NUMBERS.RANGES.NO_MIXED_FROM_BETWEEN",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.AVOID_FROM_BETWEEN",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.RANGES",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.WORD_RANGES"
+ ],
+ "CMOS18 \u00a76.88 p418 (scan p440)": [
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.LINE_BREAKS"
],
"CMOS18 \u00a76.89 p418 (scan p440)": [
- "CMOS.PUNCTUATION.DASHES.EM_DASH.USE_WITHOUT_SPACES_US"
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.SPARE_USE",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.USE_WITHOUT_SPACES_US",
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.SPACED_BRITISH"
+ ],
+ "CMOS18 \u00a76.9 p381 (scan p403)": [
+ "CMOS.PUNCTUATION.QUOTES.ALT_STYLE.DOCUMENT",
+ "CMOS.PUNCTUATION.QUOTES.APOSTROPHE_NOT_QUOTE",
+ "CMOS.PUNCTUATION.QUOTES.US_STYLE_PERIODS_COMMAS"
+ ],
+ "CMOS18 \u00a76.90 p418 (scan p440)": [
+ "CMOS.PUNCTUATION.DASHES.EN_DASH.MINUS_SIGN"
],
"CMOS18 \u00a76.91 p418 (scan p440)": [
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.ALTERNATIVE_TO_PARENS",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.SPARE_USE",
"CMOS.PUNCTUATION.DASHES.EM_DASH.USE_WITHOUT_SPACES_US"
],
+ "CMOS18 \u00a76.95 p419 (scan p441)": [
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.AVOID_NESTED",
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.PUNCTUATION_BEFORE"
+ ],
"CMOS18 \u00a76.96 p420 (scan p442)": [
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.LINE_BREAKS_DETAIL",
"CMOS.PUNCTUATION.DASHES.EM_LINE_BREAKS"
],
"CMOS18 \u00a76.97 p420 (scan p442)": [
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.DIALOGUE_STYLE",
"CMOS.PUNCTUATION.DASHES.EM_INSTEAD_OF_QUOTES"
],
+ "CMOS18 \u00a76.98 p420 (scan p442)": [
+ "CMOS.PUNCTUATION.DASHES.EM_DASH.LISTS_TABLES"
+ ],
+ "CMOS18 \u00a76.99 p421 (scan p443)": [
+ "CMOS.PUNCTUATION.DASHES.TWO_EM.OMISSIONS"
+ ],
+ "CMOS18 \u00a77.57 p11 (scan p1130)": [
+ "CMOS.FRONTMATTER.TOC.FRONT_BACK_MATTER.INCLUDED",
+ "CMOS.FRONTMATTER.TOC.SHORT_TITLES.CONSISTENT"
+ ],
"CMOS18 \u00a77.87 p474 (scan p496)": [
"CMOS.PUNCTUATION.HYPHENATION.GENERAL_CHOICE"
],
@@ -517,7 +2065,8 @@
"CMOS.PUNCTUATION.HYPHENATION.READABILITY"
],
"CMOS18 \u00a77.91 p476 (scan p498)": [
- "CMOS.PUNCTUATION.HYPHENS.COMPOUND_MODIFIERS.BEFORE_NOUN"
+ "CMOS.PUNCTUATION.HYPHENS.COMPOUND_MODIFIERS.BEFORE_NOUN",
+ "CMOS.PUNCTUATION.HYPHENS.NUMERIC_COMPOUNDS"
],
"CMOS18 \u00a77.93 p476 (scan p498)": [
"CMOS.PUNCTUATION.HYPHENS.ADVERB_LY.NO_HYPHEN"
@@ -525,106 +2074,258 @@
"CMOS18 \u00a77.95 p477 (scan p499)": [
"CMOS.PUNCTUATION.HYPHENATION.SUSPENDED"
],
+ "CMOS18 \u00a78.2 p180 (scan p1130)": [
+ "CMOS.BACKMATTER.GLOSSARY.DEFINITIONS.CONCISE"
+ ],
+ "CMOS18 \u00a78.32 p128 (scan p1122)": [
+ "CMOS.LAYOUT.SPACING.VERTICAL_RHYTHM"
+ ],
+ "CMOS18 \u00a78.84 p128 (scan p1122)": [
+ "CMOS.LAYOUT.MEASURE.LINE_LENGTH.TARGET_RANGE"
+ ],
+ "CMOS18 \u00a79.1 p590 (scan p612)": [
+ "CMOS.NUMBERS.S9_1.GENERAL_WORKS_SCOPE",
+ "CMOS.NUMBERS.S9_1.OVERVIEW.FACTORS",
+ "CMOS.NUMBERS.S9_1.READABILITY_OVER_CONSISTENCY"
+ ],
"CMOS18 \u00a79.10 p596 (scan p618)": [
+ "CMOS.NUMBERS.S9_10.NEGATIVE_POWERS",
+ "CMOS.NUMBERS.S9_10.POWERS_OF_TEN",
+ "CMOS.NUMBERS.S9_10.SCIENTIFIC_NOTATION.USE",
+ "CMOS.NUMBERS.S9_10.SCI_NOTATION.CONSISTENT",
+ "CMOS.NUMBERS.SCIENTIFIC.NOTATION.MANTISSA_RANGE",
+ "CMOS.NUMBERS.SCIENTIFIC.NOTATION.TIMES_SYMBOL",
"CMOS.NUMBERS.SCIENTIFIC.POWERS_OF_TEN"
],
"CMOS18 \u00a79.11 p596 (scan p618)": [
+ "CMOS.NUMBERS.S9_11.MYR_GYR",
+ "CMOS.NUMBERS.S9_11.PREFIX_SYMBOLS",
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.LARGE",
+ "CMOS.NUMBERS.S9_11.SI_PREFIXES.SMALL",
"CMOS.NUMBERS.SI_PREFIXES.NO_HYPHEN"
],
"CMOS18 \u00a79.12 p596 (scan p618)": [
- "CMOS.NUMBERS.BASES.NON_DECIMAL.NO_GROUPING"
+ "CMOS.NUMBERS.BASES.NON_DECIMAL.NO_GROUPING",
+ "CMOS.NUMBERS.S9_12.BASE_INDICATOR",
+ "CMOS.NUMBERS.S9_12.BASE_PREFIXES",
+ "CMOS.NUMBERS.S9_12.BASE_SUBSCRIPT",
+ "CMOS.NUMBERS.S9_12.BINARY_PREFIXES",
+ "CMOS.NUMBERS.S9_12.DECIMAL_PREFIXES",
+ "CMOS.NUMBERS.S9_12.NO_COMMAS.IN_BASE"
+ ],
+ "CMOS18 \u00a79.13 p597 (scan p619)": [
+ "CMOS.NUMBERS.S9_13.DEX.DEFINITION"
],
"CMOS18 \u00a79.14 p597 (scan p619)": [
- "CMOS.NUMBERS.NUMERALS.MEASUREMENTS.UNITS"
+ "CMOS.NUMBERS.NUMERALS.MEASUREMENTS.UNITS",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.COMMON_NUMERALS",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.CONSISTENCY",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.EXACT_VALUES",
+ "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.GENERAL_RULE"
],
"CMOS18 \u00a79.15 p597 (scan p619)": [
- "CMOS.NUMBERS.FRACTIONS.SIMPLE.SPELL_OUT"
+ "CMOS.NUMBERS.FRACTIONS.SIMPLE.SPELL_OUT",
+ "CMOS.NUMBERS.S9_15.DECIMAL_FRACTIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.EMPHASIS_EXCEPTION",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.HYPHENATE",
+ "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.SPELLED_OUT"
],
"CMOS18 \u00a79.16 p598 (scan p620)": [
- "CMOS.NUMBERS.FRACTIONS.MIXED.WHOLE_PLUS_FRACTION"
+ "CMOS.NUMBERS.FRACTIONS.ADJECTIVAL.HYPHENATE",
+ "CMOS.NUMBERS.FRACTIONS.MIXED.WHOLE_PLUS_FRACTION",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.FRACTION_SYMBOLS",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.MEASUREMENTS",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.NUMERALS",
+ "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.SHORT_SPELLED_OUT"
],
"CMOS18 \u00a79.17 p598 (scan p620)": [
- "CMOS.NUMBERS.FRACTIONS.MATH.NUMERALS"
+ "CMOS.NUMBERS.FRACTIONS.MATH.NUMERALS",
+ "CMOS.NUMBERS.FRACTIONS.SLASH_INLINE",
+ "CMOS.NUMBERS.S9_17.ALGEBRAIC.SLASH",
+ "CMOS.NUMBERS.S9_17.CASE_FRACTIONS.USE_WITH_CARE",
+ "CMOS.NUMBERS.S9_17.DISPLAYED_FRACTIONS.BAR",
+ "CMOS.NUMBERS.S9_17.EXPONENT_FRACTIONS.SLASH",
+ "CMOS.NUMBERS.S9_17.FRACTIONS.IN_NUMERATOR_DENOMINATOR",
+ "CMOS.NUMBERS.S9_17.FRACTIONS.PARENS_BEFORE_SYMBOLS",
+ "CMOS.NUMBERS.S9_17.FRACTIONS.RUNNING_TEXT.SLASH",
+ "CMOS.NUMBERS.S9_17.SLASH_BINDING"
],
"CMOS18 \u00a79.18 p598 (scan p620)": [
- "CMOS.NUMBERS.NUMERALS.MEASUREMENTS.UNITS"
+ "CMOS.NUMBERS.NUMERALS.MEASUREMENTS.UNITS",
+ "CMOS.NUMBERS.S9_18.ABBREVIATIONS.NUMERALS_ONLY",
+ "CMOS.NUMBERS.S9_18.NO_HYPHEN.NUMERAL_UNIT",
+ "CMOS.NUMBERS.S9_18.NO_SPACE.DEGREE_PERCENT_PRIME",
+ "CMOS.NUMBERS.S9_18.PRIME_SYMBOLS",
+ "CMOS.NUMBERS.S9_18.SCIENTIFIC_CONTEXT.NUMERALS",
+ "CMOS.NUMBERS.S9_18.SPACING.NUMERAL_UNIT",
+ "CMOS.NUMBERS.S9_18.UNIT_WITHOUT_NUMERAL.SPELLED_OUT"
],
"CMOS18 \u00a79.19 p599 (scan p621)": [
"CMOS.NUMBERS.DEGRADED.HARD_WRAP_UNITS",
- "CMOS.NUMBERS.UNITS.REPEATED.OMIT_REPEAT"
+ "CMOS.NUMBERS.RANGES.REPEAT_UNIT_IF_AMBIG",
+ "CMOS.NUMBERS.RANGES.UNITS.PLACEMENT_CONSISTENT",
+ "CMOS.NUMBERS.S9_19.REPEAT_UNITS.CLOSED_UP",
+ "CMOS.NUMBERS.S9_19.UNIT_REPETITION.CONSISTENT",
+ "CMOS.NUMBERS.S9_19.UNIT_SPACED.SINGLE",
+ "CMOS.NUMBERS.UNITS.REPEATED.OMIT_REPEAT",
+ "CMOS.NUMBERS.UNITS.SPACE_BETWEEN_NUMBER_UNIT"
],
"CMOS18 \u00a79.2 p590 (scan p612)": [
"CMOS.NUMBERS.CONSISTENCY.MIXED_FORMS.AVOID",
"CMOS.NUMBERS.RULE_SELECTION.GENERAL_OR_ALTERNATIVE",
+ "CMOS.NUMBERS.S9_2.GENERAL_RULE.ZERO_TO_ONE_HUNDRED",
+ "CMOS.NUMBERS.S9_2.NONROUND.ABOVE_ONE_HUNDRED",
+ "CMOS.NUMBERS.S9_2.ROUND_MULTIPLES.SPELLED_OUT",
"CMOS.NUMBERS.SPELLING.ONE_TO_ONE_HUNDRED.DEFAULT"
],
"CMOS18 \u00a79.20 p599 (scan p621)": [
- "CMOS.NUMBERS.PERCENTAGES.NUMERALS"
+ "CMOS.NUMBERS.PERCENTAGES.NUMERALS",
+ "CMOS.NUMBERS.PERCENTAGES.SYMBOL_NO_SPACE",
+ "CMOS.NUMBERS.PERCENTAGES.SYMBOL_OR_WORD.CONSISTENT",
+ "CMOS.NUMBERS.S9_20.PERCENT.LESS_FREQUENT",
+ "CMOS.NUMBERS.S9_20.PERCENT.NUMERALS",
+ "CMOS.NUMBERS.S9_20.PERCENT.WORD_VS_SYMBOL",
+ "CMOS.NUMBERS.S9_20.PERCENT_RANGES.REPEAT",
+ "CMOS.NUMBERS.S9_20.PERCENT_VS_PERCENTAGE"
],
"CMOS18 \u00a79.21 p600 (scan p622)": [
"CMOS.NUMBERS.DECIMALS.LEADING_ZERO",
- "CMOS.NUMBERS.DECIMALS.NUMERALS"
+ "CMOS.NUMBERS.DECIMALS.NUMERALS",
+ "CMOS.NUMBERS.DECIMALS.TRAILING_ZEROS.AVOID",
+ "CMOS.NUMBERS.S9_21.DECIMALS.NUMERALS",
+ "CMOS.NUMBERS.S9_21.DECIMAL_CONTEXT.CONSISTENT",
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.CALIBERS",
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.CONTEXT",
+ "CMOS.NUMBERS.S9_21.LEADING_ZERO.OMIT_PROBABILITIES",
+ "CMOS.NUMBERS.S9_21.UNITS.LESS_THAN_ONE"
],
"CMOS18 \u00a79.22 p600 (scan p622)": [
"CMOS.NUMBERS.CURRENCY.FORMAT.SYMBOL_PLACEMENT",
- "CMOS.NUMBERS.CURRENCY.WORDS_VS_SYMBOLS"
+ "CMOS.NUMBERS.CURRENCY.RANGES.REPEAT_SYMBOL",
+ "CMOS.NUMBERS.CURRENCY.SYMBOL_ADJACENT",
+ "CMOS.NUMBERS.CURRENCY.WORDS_VS_SYMBOLS",
+ "CMOS.NUMBERS.S9_22.MONEY.DECIMALS.ONLY_WHEN_MIXED",
+ "CMOS.NUMBERS.S9_22.MONEY.MINIMUM_DECIMALS",
+ "CMOS.NUMBERS.S9_22.MONEY.NUMERALS_EXACT",
+ "CMOS.NUMBERS.S9_22.MONEY.SINGULAR_VERB",
+ "CMOS.NUMBERS.S9_22.MONEY.SPELL_OUT_SMALL",
+ "CMOS.NUMBERS.S9_22.MONEY.SYMBOL_OR_WORD"
],
"CMOS18 \u00a79.23 p601 (scan p623)": [
- "CMOS.NUMBERS.CURRENCY.NON_US.DISAMBIGUATE"
+ "CMOS.NUMBERS.CURRENCY.NON_US.DISAMBIGUATE",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.CONTEXT_CLEAR",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.DISAMBIGUATE",
+ "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.ISO_CODES"
+ ],
+ "CMOS18 \u00a79.24 p601 (scan p623)": [
+ "CMOS.NUMBERS.S9_24.BRITISH.DECIMAL_FORMAT",
+ "CMOS.NUMBERS.S9_24.BRITISH.PENCE_SYMBOL",
+ "CMOS.NUMBERS.S9_24.BRITISH.POUND_SYMBOL"
],
"CMOS18 \u00a79.25 p602 (scan p624)": [
- "CMOS.NUMBERS.CURRENCY.ISO_CODES"
+ "CMOS.NUMBERS.CURRENCY.CODE_POSITION.CONSISTENT",
+ "CMOS.NUMBERS.CURRENCY.ISO_CODES",
+ "CMOS.NUMBERS.S9_25.CURRENCY_CODES.CONSISTENT",
+ "CMOS.NUMBERS.S9_25.CURRENCY_CODES.SPACING",
+ "CMOS.NUMBERS.S9_25.ISO_CODES.FORMAL",
+ "CMOS.NUMBERS.S9_25.OTHER_CURRENCIES.DECIMAL"
],
"CMOS18 \u00a79.26 p602 (scan p624)": [
- "CMOS.NUMBERS.CURRENCY.LARGE_AMOUNTS"
+ "CMOS.NUMBERS.CURRENCY.LARGE_AMOUNTS",
+ "CMOS.NUMBERS.S9_26.K_THOUSANDS",
+ "CMOS.NUMBERS.S9_26.LARGE_MONEY.MIXED",
+ "CMOS.NUMBERS.S9_26.LARGE_MONEY.NUMERALS",
+ "CMOS.NUMBERS.S9_26.MONEY.COMMAS"
],
"CMOS18 \u00a79.27 p602 (scan p624)": [
- "CMOS.NUMBERS.CURRENCY.HISTORICAL.YEAR_CONTEXT"
+ "CMOS.NUMBERS.CURRENCY.HISTORICAL.YEAR_CONTEXT",
+ "CMOS.NUMBERS.S9_27.CURRENCY_YEAR.CODES_SPACING",
+ "CMOS.NUMBERS.S9_27.CURRENCY_YEAR.PARENS_NO_SPACE"
],
"CMOS18 \u00a79.28 p603 (scan p625)": [
- "CMOS.NUMBERS.REFERENCES.PAGE_CHAPTER_FIGURE"
+ "CMOS.NUMBERS.REFERENCES.PAGE_CHAPTER_FIGURE",
+ "CMOS.NUMBERS.S9_28.BIBLICAL_REFERENCES",
+ "CMOS.NUMBERS.S9_28.DIVISIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_28.FRONT_MATTER.ROMAN"
],
"CMOS18 \u00a79.29 p603 (scan p625)": [
- "CMOS.NUMBERS.PERIODICALS.VOLUME_ISSUE"
+ "CMOS.NUMBERS.PERIODICALS.VOLUME_ISSUE",
+ "CMOS.NUMBERS.S9_29.PERIODICALS.OMIT_WORDS",
+ "CMOS.NUMBERS.S9_29.PERIODICALS.ORDER"
],
"CMOS18 \u00a79.3 p590 (scan p612)": [
- "CMOS.NUMBERS.RULE_SELECTION.ALTERNATIVE_ZERO_TO_NINE"
+ "CMOS.NUMBERS.RULE_SELECTION.ALTERNATIVE_ZERO_TO_NINE",
+ "CMOS.NUMBERS.S9_3.ALTERNATIVE_ROUND_MULTIPLES",
+ "CMOS.NUMBERS.S9_3.ALTERNATIVE_RULE.ZERO_TO_NINE"
+ ],
+ "CMOS18 \u00a79.30 p603 (scan p625)": [
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.MIXED_LEVELS",
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.NUMERALS",
+ "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.PREFER_ARABIC"
],
"CMOS18 \u00a79.31 p604 (scan p626)": [
"CMOS.NUMBERS.DATES.CONSISTENT_FORMAT",
- "CMOS.NUMBERS.DATES.YEAR_NUMERALS"
+ "CMOS.NUMBERS.DATES.YEAR_NUMERALS",
+ "CMOS.NUMBERS.S9_31.YEAR_SENTENCE_START_ALLOWED",
+ "CMOS.NUMBERS.S9_31.YEAR_STANDALONE"
],
"CMOS18 \u00a79.32 p604 (scan p626)": [
- "CMOS.NUMBERS.DATES.ABBREVIATED_YEAR"
+ "CMOS.NUMBERS.DATES.ABBREVIATED_YEAR",
+ "CMOS.NUMBERS.S9_32.ABBREVIATED_YEAR.APOSTROPHE"
],
"CMOS18 \u00a79.33 p604 (scan p626)": [
- "CMOS.NUMBERS.DATES.MONTH_DAY_STYLE"
+ "CMOS.NUMBERS.DATES.MONTH_DAY_STYLE",
+ "CMOS.NUMBERS.DATES.ORDINALS.AVOID",
+ "CMOS.NUMBERS.S9_33.DAY_WITHOUT_MONTH.ORDINAL",
+ "CMOS.NUMBERS.S9_33.MONTH_DAY.CARDINALS",
+ "CMOS.NUMBERS.S9_33.MONTH_DAY_YEAR.COMMA"
],
"CMOS18 \u00a79.34 p605 (scan p627)": [
- "CMOS.NUMBERS.CENTURIES.SPELLED_OUT"
+ "CMOS.NUMBERS.CENTURIES.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_34.CENTURIES.NUMERAL_PLURALS",
+ "CMOS.NUMBERS.S9_34.CENTURIES.ORDINAL_LOWERCASE",
+ "CMOS.NUMBERS.S9_34.CENTURY_TURN.AVOID_AMBIGUITY"
],
"CMOS18 \u00a79.35 p605 (scan p627)": [
- "CMOS.NUMBERS.DECADES.CONSISTENT_FORM"
+ "CMOS.NUMBERS.DECADES.CONSISTENT_FORM",
+ "CMOS.NUMBERS.S9_35.DECADES.FIRST_DECADE",
+ "CMOS.NUMBERS.S9_35.DECADES.NO_APOSTROPHE",
+ "CMOS.NUMBERS.S9_35.DECADES.SECOND_DECADE"
],
"CMOS18 \u00a79.36 p606 (scan p628)": [
- "CMOS.NUMBERS.ERAS.BCE_CE"
+ "CMOS.NUMBERS.ERAS.BCE_CE",
+ "CMOS.NUMBERS.S9_36.ERAS.ABBREVIATION_PLACEMENT",
+ "CMOS.NUMBERS.S9_36.ERAS.CENTURY_PLACEMENT",
+ "CMOS.NUMBERS.S9_36.ERAS.NO_PERIODS"
],
"CMOS18 \u00a79.37 p607 (scan p629)": [
- "CMOS.NUMBERS.DATES.ALL_NUMERAL"
+ "CMOS.NUMBERS.DATES.ALL_NUMERAL",
+ "CMOS.NUMBERS.DATES.DAY_MONTH_ORDER.CONSISTENT"
],
"CMOS18 \u00a79.38 p607 (scan p629)": [
"CMOS.NUMBERS.DATES.ISO_8601"
],
"CMOS18 \u00a79.39 p607 (scan p629)": [
- "CMOS.NUMBERS.TIME.GENERAL_NUMERALS"
+ "CMOS.NUMBERS.TIME.AM_PM.CONSISTENT_SPACING",
+ "CMOS.NUMBERS.TIME.GENERAL_NUMERALS",
+ "CMOS.NUMBERS.TIME.LEADING_ZERO_MINUTES",
+ "CMOS.NUMBERS.TIME.RANGES.CONSISTENT_FORMAT",
+ "CMOS.NUMBERS.TIME.SECONDS.INCLUDE_FOR_PRECISION",
+ "CMOS.NUMBERS.TIME.SECONDS.OMIT_IF_NOT_NEEDED",
+ "CMOS.NUMBERS.TIME.ZONE.INCLUDE_WHEN_AMBIGUOUS"
],
"CMOS18 \u00a79.4 p591 (scan p613)": [
- "CMOS.NUMBERS.ROUND_NUMBERS.SPELL_OUT"
+ "CMOS.NUMBERS.ROUND_NUMBERS.SPELL_OUT",
+ "CMOS.NUMBERS.S9_4.APPROXIMATIONS.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_4.HUNDREDS_THOUSANDS.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_4.MIXED_LARGE_CONTEXTS",
+ "CMOS.NUMBERS.S9_4.NONROUND.LARGE_NUMERALS"
],
"CMOS18 \u00a79.40 p608 (scan p630)": [
"CMOS.NUMBERS.TIME.NOON_MIDNIGHT"
],
"CMOS18 \u00a79.41 p608 (scan p630)": [
+ "CMOS.NUMBERS.TIME.LEADING_ZERO_MINUTES",
"CMOS.NUMBERS.TIME.TWENTY_FOUR_HOUR"
],
"CMOS18 \u00a79.42 p609 (scan p631)": [
@@ -637,6 +2338,11 @@
"CMOS.NUMBERS.VEHICLES.VESSELS_NUMBERS"
],
"CMOS18 \u00a79.5 p591 (scan p613)": [
+ "CMOS.NUMBERS.S9_5.ALPHANUMERIC.MAY_BEGIN",
+ "CMOS.NUMBERS.S9_5.SENTENCE_INITIAL.RECAST",
+ "CMOS.NUMBERS.S9_5.SENTENCE_INITIAL.SPELLED_OUT",
+ "CMOS.NUMBERS.S9_5.TWO_NUMBERS.SAME_CATEGORY",
+ "CMOS.NUMBERS.S9_5.YEARS.MAY_BEGIN",
"CMOS.NUMBERS.SENTENCE_START.AVOID_NUMERAL"
],
"CMOS18 \u00a79.52 p611 (scan p633)": [
@@ -663,64 +2369,498 @@
"CMOS.NUMBERS.DIGIT_GROUPING.SI_SPACE"
],
"CMOS18 \u00a79.59 p614 (scan p636)": [
- "CMOS.NUMBERS.TELEPHONE.FORMAT"
+ "CMOS.NUMBERS.TELEPHONE.COUNTRY_CODE.WHEN_INTERNATIONAL",
+ "CMOS.NUMBERS.TELEPHONE.FORMAT",
+ "CMOS.NUMBERS.TELEPHONE.SEPARATORS.CONSISTENT"
],
"CMOS18 \u00a79.6 p592 (scan p614)": [
- "CMOS.NUMBERS.ORDINALS.SUFFIX.CORRECT"
+ "CMOS.NUMBERS.ORDINALS.CONSISTENT_FORM",
+ "CMOS.NUMBERS.ORDINALS.SUFFIX.CORRECT",
+ "CMOS.NUMBERS.S9_6.NTH_DEGREE.ITALIC_N",
+ "CMOS.NUMBERS.S9_6.ORDINALS.RULE_PARALLEL",
+ "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.ND_RD",
+ "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.NO_SUPERSCRIPT",
+ "CMOS.NUMBERS.S9_6.ZERO.ORDINAL_TH"
],
"CMOS18 \u00a79.60 p615 (scan p637)": [
+ "CMOS.NUMBERS.RATIOS.COLON_SPACING",
"CMOS.NUMBERS.RATIOS.FORMAT"
],
"CMOS18 \u00a79.61 p615 (scan p637)": [
"CMOS.NUMBERS.LISTS.OUTLINE.NUMERAL_STYLE"
],
+ "CMOS18 \u00a79.62 p108 (scan p1123)": [
+ "CMOS.TABLES.ALIGNMENT.NUMERIC_DECIMAL",
+ "CMOS.TABLES.ALIGNMENT.TEXT_LEFT",
+ "CMOS.TABLES.PRECISION.CONSISTENT",
+ "CMOS.TABLES.ROUNDING.CONSISTENT",
+ "CMOS.TABLES.UNITS.CONSISTENT",
+ "CMOS.TABLES.UNITS.IN_HEADERS"
+ ],
"CMOS18 \u00a79.62 p615 (scan p637)": [
- "CMOS.NUMBERS.RANGES.EN_DASH.USE"
+ "CMOS.NUMBERS.RANGES.EN_DASH.USE",
+ "CMOS.NUMBERS.RANGES.NO_MIXED_FROM_BETWEEN"
],
"CMOS18 \u00a79.63 p616 (scan p638)": [
"CMOS.NUMBERS.INCLUSIVE_RANGES.PAGE_NUMBERS.SHORTEN"
],
"CMOS18 \u00a79.65 p617 (scan p639)": [
- "CMOS.NUMBERS.INCLUSIVE.COMMAS"
+ "CMOS.NUMBERS.INCLUSIVE.COMMAS",
+ "CMOS.NUMBERS.INCLUSIVE.SHORTEN_SECOND_NUMBER"
],
"CMOS18 \u00a79.66 p617 (scan p639)": [
- "CMOS.NUMBERS.INCLUSIVE.YEARS"
+ "CMOS.NUMBERS.INCLUSIVE.YEARS",
+ "CMOS.NUMBERS.INCLUSIVE.YEARS.CENTURY_CROSSING"
],
"CMOS18 \u00a79.67 p617 (scan p639)": [
+ "CMOS.NUMBERS.ROMAN_NUMERALS.CASE_CONSISTENT",
"CMOS.NUMBERS.ROMAN_NUMERALS.USE"
],
"CMOS18 \u00a79.7 p592 (scan p614)": [
- "CMOS.NUMBERS.DENSE_CONTEXT.USE_NUMERALS"
+ "CMOS.NUMBERS.DENSE_CONTEXT.USE_NUMERALS",
+ "CMOS.NUMBERS.S9_7.AVOID_DENSE_WORDS",
+ "CMOS.NUMBERS.S9_7.CATEGORY_TRIGGER",
+ "CMOS.NUMBERS.S9_7.CONSISTENT_CONTEXT",
+ "CMOS.NUMBERS.S9_7.CROSS_CATEGORY.MIX_OK",
+ "CMOS.NUMBERS.S9_7.DOCUMENT_EXCEPTIONS",
+ "CMOS.NUMBERS.S9_7.SENTENCE_START_EXCEPTION"
],
"CMOS18 \u00a79.8 p593 (scan p615)": [
- "CMOS.NUMBERS.CONTEXTS.ALWAYS_NUMERALS"
+ "CMOS.NUMBERS.CONTEXTS.ALWAYS_NUMERALS",
+ "CMOS.NUMBERS.S9_8.ABBREVIATED_UNITS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.CLOTHING_SIZES.NUMERALS",
+ "CMOS.NUMBERS.S9_8.DATES.NUMERALS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.ACT_SCENE",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.BOXES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.CHAPTERS_PARTS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.EXAMPLES_QUESTIONS_RULES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.FIGURES_TABLES_EQUATIONS",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.NOTES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.PAGES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.SECTIONS_PARAS_LINES",
+ "CMOS.NUMBERS.S9_8.DOC_PARTS.VOLUMES_ISSUES",
+ "CMOS.NUMBERS.S9_8.GRADES_LEVELS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.PERCENT.NUMERALS",
+ "CMOS.NUMBERS.S9_8.PLACES.STREETS_ROOMS",
+ "CMOS.NUMBERS.S9_8.SCORES_VOTES.NUMERALS",
+ "CMOS.NUMBERS.S9_8.SEVERITY_CLASSIFICATIONS",
+ "CMOS.NUMBERS.S9_8.SYMBOLS.NUMERALS",
+ "CMOS.NUMBERS.S9_8.TITLE_NUMBERS"
],
"CMOS18 \u00a79.9 p595 (scan p617)": [
- "CMOS.NUMBERS.LARGE_VALUES.MILLIONS_BILLIONS"
+ "CMOS.NUMBERS.LARGE_VALUES.MILLIONS_BILLIONS",
+ "CMOS.NUMBERS.S9_9.BILLION_TRILLION.LOCALE_CHECK",
+ "CMOS.NUMBERS.S9_9.CONSISTENCY.WITH_FRACTIONS",
+ "CMOS.NUMBERS.S9_9.MILLIONS_BILLIONS.GENERAL_RULE",
+ "CMOS.NUMBERS.S9_9.MIXED_NUMERAL_WORD.FRACTIONS"
+ ],
+ "HOUSE \u00a7A11Y.BASICS p1": [
+ "HOUSE.ACCESSIBILITY.CODE.FENCES.LANGUAGE",
+ "HOUSE.ACCESSIBILITY.COLOR.NOT_SOLE_CONVEYOR",
+ "HOUSE.ACCESSIBILITY.CONTRAST.TEXT_READABLE",
+ "HOUSE.ACCESSIBILITY.EMPHASIS.USE_SPARELY",
+ "HOUSE.ACCESSIBILITY.HEADINGS.HIERARCHY.NO_SKIPS",
+ "HOUSE.ACCESSIBILITY.IMAGES.DECORATIVE.EMPTY_ALT",
+ "HOUSE.ACCESSIBILITY.IMAGES.TEXT_IN_IMAGES.AVOID",
+ "HOUSE.ACCESSIBILITY.LANGUAGE.METADATA",
+ "HOUSE.ACCESSIBILITY.LINKS.AVOID_SHORTENERS",
+ "HOUSE.ACCESSIBILITY.LINKS.FOCUS_ORDER",
+ "HOUSE.ACCESSIBILITY.LINKS.TARGETS.PUBLIC",
+ "HOUSE.ACCESSIBILITY.LINKS.VISUALLY_DISTINCT",
+ "HOUSE.ACCESSIBILITY.LISTS.USE_LIST_MARKUP",
+ "HOUSE.ACCESSIBILITY.PDF.TAGS.WHEN_AVAILABLE",
+ "HOUSE.ACCESSIBILITY.TABLES.AVOID_SCREENSHOT",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADER_ROW.REQUIRED",
+ "HOUSE.ACCESSIBILITY.TABLES.SIMPLE_STRUCTURE"
],
"HOUSE \u00a7A11Y.BASICS p2": [
"HOUSE.A11Y.DOCUMENT_LANGUAGE.DECLARE",
"HOUSE.A11Y.HEADINGS.NO_SKIPS",
"HOUSE.A11Y.IMAGES.ALT_REQUIRED",
"HOUSE.A11Y.LINK_TEXT.DESCRIPTIVE",
+ "HOUSE.ACCESSIBILITY.CONTRAST.NON_TEXT",
+ "HOUSE.ACCESSIBILITY.FIGURES.REFERENCED_IN_TEXT",
+ "HOUSE.ACCESSIBILITY.HEADINGS.NO_DECORATIVE",
+ "HOUSE.ACCESSIBILITY.HEADINGS.NO_EMPTY",
+ "HOUSE.ACCESSIBILITY.HEADINGS.SINGLE_H1",
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_AVOID_DUPLICATE_CAPTION",
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_SUMMARY_FOR_CHARTS",
+ "HOUSE.ACCESSIBILITY.IMAGES.CAPTION_FOR_COMPLEX",
+ "HOUSE.ACCESSIBILITY.LINKS.FOCUS_VISIBLE",
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.NO_BARE_URLS",
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.SYMBOL_ONLY.AVOID",
+ "HOUSE.ACCESSIBILITY.LINK_TEXT.UNIQUE_TARGETS",
+ "HOUSE.ACCESSIBILITY.LISTS.MARKER_CONSISTENT",
+ "HOUSE.ACCESSIBILITY.LISTS.NO_EMPTY_ITEMS",
+ "HOUSE.ACCESSIBILITY.MEDIA.TRANSCRIPTS",
+ "HOUSE.ACCESSIBILITY.TABLES.CAPTION_SUMMARY",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADER_SCOPE",
+ "HOUSE.ACCESSIBILITY.TABLES.NO_LAYOUT",
+ "HOUSE.ACCESSIBILITY.TABLES.ROW_HEADERS_FOR_STUB",
"HOUSE.LINKS.TEXT.DESCRIPTIVE"
],
+ "HOUSE \u00a7A11Y.IMAGES p2": [
+ "HOUSE.ACCESSIBILITY.IMAGES.ALT_TEXT.QUALITY.NO_FILENAME",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADER_ROW.REQUIRED"
+ ],
+ "HOUSE \u00a7A11Y.IMAGES p3": [
+ "HOUSE.ACCESSIBILITY.IMAGES.LINKED.ALT_TARGET"
+ ],
+ "HOUSE \u00a7A11Y.LINKS p3": [
+ "HOUSE.ACCESSIBILITY.LINKS.ICON_ONLY.TEXT",
+ "HOUSE.ACCESSIBILITY.LINKS.SKIP_TO_CONTENT"
+ ],
+ "HOUSE \u00a7A11Y.NAVIGATION p3": [
+ "HOUSE.ACCESSIBILITY.NAVIGATION.FOOTNOTE_BACKLINKS",
+ "HOUSE.ACCESSIBILITY.NAVIGATION.PDF_BOOKMARKS",
+ "HOUSE.ACCESSIBILITY.TOC.LINKED_ENTRIES"
+ ],
+ "HOUSE \u00a7A11Y.TABLES p3": [
+ "HOUSE.ACCESSIBILITY.TABLES.HEADERS.SCOPE",
+ "HOUSE.ACCESSIBILITY.TABLES.HEADER_ROW.REQUIRED"
+ ],
+ "HOUSE \u00a7BACKMATTER.APPENDICES p1": [
+ "HOUSE.BACKMATTER.APPENDICES.LABELS.MATCH"
+ ],
+ "HOUSE \u00a7BACKMATTER.GLOSSARY p1": [
+ "HOUSE.BACKMATTER.GLOSSARY.ALPHABETICAL",
+ "HOUSE.BACKMATTER.GLOSSARY.CROSS_REFERENCES"
+ ],
+ "HOUSE \u00a7BACKMATTER.INDEX p1": [
+ "HOUSE.BACKMATTER.INDEX.CROSS_REFERENCES.CONSISTENT"
+ ],
+ "HOUSE \u00a7BACKMATTER.REFERENCES p1": [
+ "HOUSE.BACKMATTER.REFERENCES.DEDUPLICATE",
+ "HOUSE.BACKMATTER.REFERENCES.SORTING.CONSISTENT"
+ ],
+ "HOUSE \u00a7CIT.AUTHOR_DATE.PAREN_YEAR_ONLY p1": [
+ "HOUSE.CITATIONS.AUTHOR_DATE.PAREN_YEAR_ONLY"
+ ],
+ "HOUSE \u00a7CIT.AUTHOR_DATE.REFLIST.REQUIRED p1": [
+ "HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.REQUIRED"
+ ],
+ "HOUSE \u00a7CIT.AUTHOR_DATE.REFLIST.YEAR_REQUIRED p1": [
+ "HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.YEAR_REQUIRED"
+ ],
+ "HOUSE \u00a7CIT.NOTES.BIBLIOGRAPHY.REQUIRED p1": [
+ "HOUSE.CITATIONS.NOTES.BIBLIOGRAPHY.REQUIRED"
+ ],
+ "HOUSE \u00a7CIT.NOTES.DEFINITIONS.REQUIRED p1": [
+ "HOUSE.CITATIONS.NOTES.DEFINITIONS.REQUIRED"
+ ],
+ "HOUSE \u00a7CIT.NOTES.IBID.AVOID p1": [
+ "HOUSE.CITATIONS.NOTES.IBID.AVOID"
+ ],
+ "HOUSE \u00a7CIT.NOTES.MARKERS.BRACKETED_NUMBERS.AVOID p1": [
+ "HOUSE.CITATIONS.NOTES.MARKERS.BRACKETED_NUMBERS.AVOID"
+ ],
+ "HOUSE \u00a7CODE.BLOCKS p1": [
+ "HOUSE.CODE.BLOCKS.ELISION.MARKED",
+ "HOUSE.CODE.BLOCKS.LINE_BREAKS.SEMANTIC_SAFE",
+ "HOUSE.CODE.BLOCKS.LONG_LINES.AVOID",
+ "HOUSE.CODE.BLOCKS.SPLIT_BY_LANGUAGE",
+ "HOUSE.CODE.BLOCKS.TABS.AVOID",
+ "HOUSE.CODE.BLOCKS.USE_FOR_MULTILINE",
+ "HOUSE.CODE.CAPTIONS.EXPLAIN_SNIPPET",
+ "HOUSE.CODE.COMMENTS.MINIMIZE_NOISE",
+ "HOUSE.CODE.DIFFS.UNIFIED_FORMAT",
+ "HOUSE.CODE.ERRORS.SHOW_FAILURES",
+ "HOUSE.CODE.FENCES.CLOSE_PROPERLY",
+ "HOUSE.CODE.FENCES.LANGUAGE_INFO.SUGGEST",
+ "HOUSE.CODE.INLINE.USE_FOR_IDENTIFIERS",
+ "HOUSE.CODE.LANGUAGE.CONSISTENT_FENCES",
+ "HOUSE.CODE.LANGUAGE.NOTATION.CONSISTENT",
+ "HOUSE.CODE.LINE_ENDINGS.NORMALIZE",
+ "HOUSE.CODE.MONO.FONT.PREFERRED",
+ "HOUSE.CODE.OUTPUT.DISTINGUISH_FROM_INPUT",
+ "HOUSE.CODE.OUTPUT.TRUNCATION.LABELED",
+ "HOUSE.CODE.PLACEHOLDERS.CLEAR",
+ "HOUSE.CODE.REFERENCES.VERSION_PIN",
+ "HOUSE.CODE.SECURITY.REDACT_SECRETS",
+ "HOUSE.CODE.SHELL.PROMPTS.CONSISTENT",
+ "HOUSE.CODE.TABLES.AVOID_FOR_CODE",
+ "HOUSE.CODE.TYPED_VALUES.DISTINGUISH",
+ "HOUSE.CODE.URLS.IN_CODE.AVOID_WRAPPING",
+ "HOUSE.CODE.WRAPPING.NO_SOFT_HYPHENS"
+ ],
+ "HOUSE \u00a7CODE.DIFFS p2": [
+ "HOUSE.CODE.DIFFS.CONTEXT_LINES.PRESENT",
+ "HOUSE.CODE.DIFFS.FILE_HEADERS.PRESENT"
+ ],
+ "HOUSE \u00a7CODE.EXAMPLES p1": [
+ "HOUSE.CODE.BLOCKS.CONFIG.VALID",
+ "HOUSE.CODE.BLOCKS.DETERMINISTIC_OUTPUT",
+ "HOUSE.CODE.BLOCKS.PRECONDITIONS.STATED",
+ "HOUSE.CODE.BLOCKS.TESTED_OR_MARKED",
+ "HOUSE.CODE.EXAMPLES.ENV_VARS.DOCUMENT",
+ "HOUSE.CODE.EXAMPLES.FILE_PATH.LABEL",
+ "HOUSE.CODE.EXAMPLES.MULTI_FILE.SEPARATE",
+ "HOUSE.CODE.EXAMPLES.ORDERED_STEPS"
+ ],
+ "HOUSE \u00a7CODE.SECURITY p2": [
+ "HOUSE.CODE.BLOCKS.DATA.SYNTHETIC_FOR_SENSITIVE",
+ "HOUSE.CODE.BLOCKS.NO_PERSONAL_PATHS"
+ ],
+ "HOUSE \u00a7CODE.SHELL p2": [
+ "HOUSE.CODE.BLOCKS.COMMANDS.PROMPT_FREE_COPY",
+ "HOUSE.CODE.BLOCKS.ERROR_OUTPUT.LABELED",
+ "HOUSE.CODE.BLOCKS.PLATFORM.NOTED",
+ "HOUSE.CODE.SHELL.DESTRUCTIVE.WARN"
+ ],
+ "HOUSE \u00a7CODE.TYPOGRAPHY p2": [
+ "HOUSE.CODE.BLOCKS.INDENTATION.CONSISTENT",
+ "HOUSE.CODE.BLOCKS.NO_LINE_NUMBERS",
+ "HOUSE.CODE.BLOCKS.NO_SMART_QUOTES",
+ "HOUSE.CODE.BLOCKS.TABS.AVOID",
+ "HOUSE.CODE.BLOCKS.TRAILING_WHITESPACE.AVOID",
+ "HOUSE.CODE.TYPOGRAPHY.UNICODE.MINIMIZE"
+ ],
+ "HOUSE \u00a7EDITORIAL.CLAIMS p1": [
+ "HOUSE.EDITORIAL.CLAIMS.AVOID_ABSOLUTES",
+ "HOUSE.EDITORIAL.CLAIMS.BASELINE_FOR_COMPARISONS",
+ "HOUSE.EDITORIAL.CLAIMS.DISTINGUISH_FACT_OPINION",
+ "HOUSE.EDITORIAL.CLAIMS.QUANTIFY_WHEN_POSSIBLE",
+ "HOUSE.EDITORIAL.CLAIMS.SCOPE_TIMEBOUND",
+ "HOUSE.EDITORIAL.CLAIMS.SUPPORT_WITH_SOURCES"
+ ],
+ "HOUSE \u00a7EDITORIAL.CLARITY p1": [
+ "HOUSE.EDITORIAL.CLARITY.ACTIVE_VOICE_INSTRUCTIONS",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_AMBIGUOUS_PRONOUNS",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_DOUBLE_NEGATIVES",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_METACOMMENTARY",
+ "HOUSE.EDITORIAL.CLARITY.AVOID_WEASEL_WORDS",
+ "HOUSE.EDITORIAL.CLARITY.DEFINE_JARGON_ON_FIRST_USE",
+ "HOUSE.EDITORIAL.CLARITY.DEFINE_METRICS",
+ "HOUSE.EDITORIAL.CLARITY.EDIT_FOR_BREVITY",
+ "HOUSE.EDITORIAL.CLARITY.EXAMPLES_WHEN_COMPLEX",
+ "HOUSE.EDITORIAL.CLARITY.ONE_IDEA_PER_PARAGRAPH"
+ ],
+ "HOUSE \u00a7EDITORIAL.CONSISTENCY p1": [
+ "HOUSE.EDITORIAL.CONSISTENCY.CAPITALIZATION.STABLE",
+ "HOUSE.EDITORIAL.CONSISTENCY.DATE_FORMAT.SINGLE",
+ "HOUSE.EDITORIAL.CONSISTENCY.NAMES.SAME_FORM",
+ "HOUSE.EDITORIAL.CONSISTENCY.SPELLING_VARIANT.CHOOSE_ONE",
+ "HOUSE.EDITORIAL.CONSISTENCY.TERMINOLOGY.STABLE",
+ "HOUSE.EDITORIAL.CONSISTENCY.TIMEZONE.EXPLICIT"
+ ],
+ "HOUSE \u00a7EDITORIAL.HEADINGS p1": [
+ "HOUSE.EDITORIAL.HEADINGS.AVOID_ALL_CAPS",
+ "HOUSE.EDITORIAL.HEADINGS.AVOID_GENERIC",
+ "HOUSE.EDITORIAL.HEADINGS.CASE.CONSISTENT",
+ "HOUSE.EDITORIAL.HEADINGS.LENGTH.CONCISE",
+ "HOUSE.EDITORIAL.HEADINGS.NO_DUPLICATE",
+ "HOUSE.EDITORIAL.HEADINGS.NO_TRAILING_PUNCTUATION"
+ ],
+ "HOUSE \u00a7EDITORIAL.LISTS p1": [
+ "HOUSE.EDITORIAL.LISTS.AVOID_DEEP_NESTING",
+ "HOUSE.EDITORIAL.LISTS.AVOID_SINGLE_ITEM",
+ "HOUSE.EDITORIAL.LISTS.ITEMS.ACTIONABLE",
+ "HOUSE.EDITORIAL.LISTS.ORDERED_ONLY_WHEN_ORDERED",
+ "HOUSE.EDITORIAL.LISTS.PARALLEL_STRUCTURE",
+ "HOUSE.EDITORIAL.LISTS.PUNCTUATION.CONSISTENT",
+ "HOUSE.EDITORIAL.LISTS.TASKS.CHECKLIST"
+ ],
+ "HOUSE \u00a7EDITORIAL.OPSEC p1": [
+ "HOUSE.EDITORIAL.OPSEC.REMOVE_PII",
+ "HOUSE.EDITORIAL.REVIEW.SENSITIVE_INFO.NO_SECRETS"
+ ],
+ "HOUSE \u00a7EDITORIAL.PLACEHOLDERS p1": [
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_LOREM_IPSUM",
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_REVIEW_NOTES_INLINE",
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_TBD_TKTK",
+ "HOUSE.EDITORIAL.PLACEHOLDERS.NO_TODO_FIXME"
+ ],
+ "HOUSE \u00a7EDITORIAL.REVIEW p1": [
+ "HOUSE.EDITORIAL.REVIEW.CROSS_REFERENCES.VERIFY",
+ "HOUSE.EDITORIAL.REVIEW.FACT_CHECK",
+ "HOUSE.EDITORIAL.REVIEW.LINKS.VERIFY",
+ "HOUSE.EDITORIAL.REVIEW.SPELLCHECK_AND_READTHROUGH"
+ ],
+ "HOUSE \u00a7EDITORIAL.STRUCTURE p1": [
+ "HOUSE.EDITORIAL.STRUCTURE.ACTION_ITEMS.EXPLICIT",
+ "HOUSE.EDITORIAL.STRUCTURE.ASSUMPTIONS.EXPLICIT",
+ "HOUSE.EDITORIAL.STRUCTURE.AUDIENCE.STATED",
+ "HOUSE.EDITORIAL.STRUCTURE.CHANGELOG.LIVING_DOCS",
+ "HOUSE.EDITORIAL.STRUCTURE.DECISIONS.EXPLICIT",
+ "HOUSE.EDITORIAL.STRUCTURE.GLOSSARY.WHEN_DENSE",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.EARLY",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.PRESENT",
+ "HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.SINGLE",
+ "HOUSE.EDITORIAL.STRUCTURE.METADATA.OWNER_DATE",
+ "HOUSE.EDITORIAL.STRUCTURE.REFERENCES.WHEN_CITED",
+ "HOUSE.EDITORIAL.STRUCTURE.RISKS.MITIGATIONS",
+ "HOUSE.EDITORIAL.STRUCTURE.SCOPE.STATED",
+ "HOUSE.EDITORIAL.STRUCTURE.SUMMARY.EARLY"
+ ],
+ "HOUSE \u00a7EDITORIAL.TONE p1": [
+ "HOUSE.EDITORIAL.TONE.AVOID_EXCESSIVE_EMPHASIS",
+ "HOUSE.EDITORIAL.TONE.CALIBRATE_CERTAINTY",
+ "HOUSE.EDITORIAL.TONE.INCLUSIVE_LANGUAGE",
+ "HOUSE.EDITORIAL.TONE.PROFESSIONAL_AND_RESPECTFUL"
+ ],
+ "HOUSE \u00a7FIGURES.AXES p1": [
+ "HOUSE.FIGURES.AXES.UNITS.LABELED"
+ ],
+ "HOUSE \u00a7FIGURES.CAPTIONS p1": [
+ "HOUSE.FIGURES.CAPTIONS.TAKEAWAY"
+ ],
+ "HOUSE \u00a7FIGURES.COLOR p1": [
+ "HOUSE.FIGURES.COLOR.CONTRAST_SAFE",
+ "HOUSE.FIGURES.COLOR.LEGEND.REQUIRED"
+ ],
+ "HOUSE \u00a7FIGURES.FORMAT p1": [
+ "HOUSE.FIGURES.FORMAT.VECTOR_FOR_LINE_ART",
+ "HOUSE.FIGURES.RESOLUTION.MINIMUM"
+ ],
+ "HOUSE \u00a7FIGURES.TEXT p1": [
+ "HOUSE.FIGURES.TEXT.NOT_RASTERIZED"
+ ],
+ "HOUSE \u00a7FRONTMATTER.ABSTRACT p1": [
+ "HOUSE.FRONTMATTER.ABSTRACT.REQUIRED_FOR_LONG_DOCS"
+ ],
+ "HOUSE \u00a7FRONTMATTER.DISTRIBUTION p1": [
+ "HOUSE.FRONTMATTER.DISTRIBUTION.CONTACT",
+ "HOUSE.FRONTMATTER.METADATA.CONFIDENTIALITY"
+ ],
+ "HOUSE \u00a7FRONTMATTER.METADATA p1": [
+ "HOUSE.FRONTMATTER.METADATA.DOC_STATUS",
+ "HOUSE.FRONTMATTER.METADATA.LAST_REVIEWED",
+ "HOUSE.FRONTMATTER.METADATA.VERSION"
+ ],
+ "HOUSE \u00a7FRONTMATTER.TOC p1": [
+ "HOUSE.FRONTMATTER.TOC.AUTO_GENERATED"
+ ],
+ "HOUSE \u00a7I18N.CURRENCY.DISAMBIGUATE p1": [
+ "HOUSE.I18N.CURRENCY.DISAMBIGUATE"
+ ],
+ "HOUSE \u00a7I18N.LANGUAGE.SWITCHES p1": [
+ "HOUSE.I18N.LANGUAGE.SWITCHES.MARK"
+ ],
+ "HOUSE \u00a7I18N.NUMBERS.DIGIT_SYSTEM p1": [
+ "HOUSE.I18N.NUMBERS.DIGIT_SYSTEM.CONSISTENT"
+ ],
+ "HOUSE \u00a7I18N.NUMBERS.GROUPING p1": [
+ "HOUSE.I18N.NUMBERS.GROUPING.CONSISTENT"
+ ],
+ "HOUSE \u00a7I18N.NUMBERS.MIXED_DECIMAL_SEPARATORS p1": [
+ "HOUSE.I18N.NUMBERS.MIXED_DECIMAL_SEPARATORS"
+ ],
+ "HOUSE \u00a7I18N.QUOTES.MIXED_STYLES p1": [
+ "HOUSE.I18N.QUOTES.MIXED_STYLES"
+ ],
+ "HOUSE \u00a7I18N.TRANSLATION.LABELS p1": [
+ "HOUSE.I18N.TRANSLATION.LABELS"
+ ],
+ "HOUSE \u00a7I18N.UNITS.SPACING p1": [
+ "HOUSE.I18N.UNITS.SPACING.CONSISTENT"
+ ],
+ "HOUSE \u00a7LAYOUT.HTML.GUTTERS p1": [
+ "HOUSE.LAYOUT.HTML.GUTTERS.MIN_PADDING"
+ ],
+ "HOUSE \u00a7LAYOUT.HTML.MEASURE p1": [
+ "HOUSE.LAYOUT.HTML.MEASURE.MAX_WIDTH"
+ ],
+ "HOUSE \u00a7LAYOUT.HTML.SECTION_SPACING p1": [
+ "HOUSE.LAYOUT.HTML.SECTION_SPACING.CONSISTENT"
+ ],
+ "HOUSE \u00a7LAYOUT.MD.BLANK_LINES.SPARING p1": [
+ "HOUSE.LAYOUT.MD.BLANK_LINES.SPARING"
+ ],
+ "HOUSE \u00a7LAYOUT.MD.HEADINGS.NON_EMPTY_SECTIONS p1": [
+ "HOUSE.LAYOUT.MD.HEADINGS.NON_EMPTY_SECTIONS"
+ ],
+ "HOUSE \u00a7LAYOUT.PAGINATION.RUNT_FINAL_PAGE p1": [
+ "HOUSE.LAYOUT.PAGINATION.RUNT_FINAL_PAGE"
+ ],
+ "HOUSE \u00a7LINKS.SECURITY p3": [
+ "HOUSE.LINKS.DISALLOW.JAVASCRIPT_URIS"
+ ],
+ "HOUSE \u00a7QA.CAPTIONS p2": [
+ "HOUSE.LAYOUT.PAGINATION.CAPTIONS.KEEP_WITH_CONTENT"
+ ],
"HOUSE \u00a7QA.CODE_OVERFLOW p2": [
"HOUSE.CODE.BLOCKS.LANGUAGE_TAGS.PREFERRED",
"HOUSE.CODE.BLOCKS.NO_CLIPPING",
"HOUSE.CODE.BLOCKS.WRAP_POLICY",
"HOUSE.CODE.INLINE.MONO_BACKTICKS"
],
+ "HOUSE \u00a7QA.HEADINGS p2": [
+ "HOUSE.LAYOUT.PAGINATION.HEADINGS.NO_ADJACENT"
+ ],
"HOUSE \u00a7QA.KEEPS p1": [
"HOUSE.HEADINGS.KEEPS.AVOID_STRANDED",
+ "HOUSE.HEADINGS.KEEP_WITH_NEXT",
"HOUSE.LAYOUT.PAGINATION.KEEP_WITH_NEXT.HEADINGS"
],
"HOUSE \u00a7QA.LINK_WRAP p2": [
+ "HOUSE.LINKS.AUTO.EMBEDDED_CREDENTIALS.AVOID",
+ "HOUSE.LINKS.AUTO.FILETYPE_LABEL.REQUIRED",
+ "HOUSE.LINKS.AUTO.FTP.AVOID",
+ "HOUSE.LINKS.AUTO.HTML_FALLBACK.REQUIRED",
+ "HOUSE.LINKS.AUTO.INTERNAL_HOSTNAMES.AVOID",
+ "HOUSE.LINKS.AUTO.INVITE_LINKS.AVOID",
+ "HOUSE.LINKS.AUTO.LABEL_LENGTH.AVOID_OVERLONG",
+ "HOUSE.LINKS.AUTO.LOGIN_LINKS.AVOID",
+ "HOUSE.LINKS.AUTO.PARTIAL_WORD.AVOID",
+ "HOUSE.LINKS.AUTO.PASSWORD_RESET.AVOID",
+ "HOUSE.LINKS.AUTO.PRIVATE_IPS.AVOID",
+ "HOUSE.LINKS.AUTO.SESSION_PARAMS.AVOID",
+ "HOUSE.LINKS.AUTO.STAGING_HOSTNAMES.AVOID",
+ "HOUSE.LINKS.AUTO.TRACKING_PARAMS.AVOID",
"HOUSE.LINKS.DISALLOW.FILE_URIS",
+ "HOUSE.LINKS.DISALLOW.JAVASCRIPT_URIS",
+ "HOUSE.LINKS.EMAILS.MAILTO_POLICY",
"HOUSE.LINKS.PUNCTUATION.NO_TRAILING_PUNCT",
+ "HOUSE.LINKS.TEXT.ACCESS_RESTRICTIONS.NOTE",
+ "HOUSE.LINKS.TEXT.ARCHIVE_AND_HTML.BOTH",
+ "HOUSE.LINKS.TEXT.AVOID_OVERLONG_LABELS",
+ "HOUSE.LINKS.TEXT.DIFFERENTIATE_REPEATED_LINKS",
+ "HOUSE.LINKS.TEXT.FILESIZE.LABEL",
+ "HOUSE.LINKS.TEXT.FILETYPE.LABEL",
+ "HOUSE.LINKS.TEXT.LANGUAGE.LABEL",
+ "HOUSE.LINKS.TEXT.LINK_TARGET_MISMATCH",
+ "HOUSE.LINKS.TEXT.MATCHES_TARGET",
+ "HOUSE.LINKS.TEXT.MIRROR.LABEL",
+ "HOUSE.LINKS.TEXT.NO_CLICK_HERE",
+ "HOUSE.LINKS.TEXT.NO_EMOJIS",
+ "HOUSE.LINKS.TEXT.PARTIAL_WORD.AVOID",
+ "HOUSE.LINKS.TEXT.STABILITY.NOTE",
+ "HOUSE.LINKS.URLS.ANCHORS.STABLE",
+ "HOUSE.LINKS.URLS.AVOID.EXPIRING_SIGNED",
+ "HOUSE.LINKS.URLS.AVOID.INTERNAL_HOSTNAMES",
+ "HOUSE.LINKS.URLS.AVOID.IP_LITERALS",
+ "HOUSE.LINKS.URLS.AVOID.NAKED_URLS_IN_PROSE",
+ "HOUSE.LINKS.URLS.AVOID.ONE_TIME_INVITES",
+ "HOUSE.LINKS.URLS.AVOID.PASSWORD_RESET",
+ "HOUSE.LINKS.URLS.AVOID.STAGING_DOMAINS",
+ "HOUSE.LINKS.URLS.AVOID.TEMP_FILESHARES",
+ "HOUSE.LINKS.URLS.AVOID.TEXT_FRAGMENTS",
+ "HOUSE.LINKS.URLS.AVOID_PRIVATE_IPS",
+ "HOUSE.LINKS.URLS.BARE_DOMAIN.TRAILING_SLASH",
+ "HOUSE.LINKS.URLS.CANONICAL.NO_TRACKING_PARAMS",
+ "HOUSE.LINKS.URLS.CANONICAL_HOST",
+ "HOUSE.LINKS.URLS.DISALLOW.FTP",
+ "HOUSE.LINKS.URLS.DISALLOW.LOCALHOST",
+ "HOUSE.LINKS.URLS.DOIS.PREFER_DOI_ORG",
+ "HOUSE.LINKS.URLS.MAILTO.INTENT",
+ "HOUSE.LINKS.URLS.NO_BACKSLASH",
+ "HOUSE.LINKS.URLS.NO_EMBEDDED_CREDENTIALS",
+ "HOUSE.LINKS.URLS.NO_PROTOCOL_RELATIVE",
+ "HOUSE.LINKS.URLS.NO_QUERY_WHEN_NOT_NEEDED",
+ "HOUSE.LINKS.URLS.NO_SESSION_PARAMS",
+ "HOUSE.LINKS.URLS.NO_TRAILING_PARENS",
+ "HOUSE.LINKS.URLS.NO_WHITESPACE",
+ "HOUSE.LINKS.URLS.NO_ZERO_WIDTH",
"HOUSE.LINKS.URLS.PREFER_HTTPS",
+ "HOUSE.LINKS.URLS.RELATIVE.REPO_LOCAL",
+ "HOUSE.LINKS.URLS.SHORTENERS.AVOID",
+ "HOUSE.LINKS.URLS.STABLE_ANCHORS",
"HOUSE.LINKS.WRAP.SAFE_BREAKS"
],
+ "HOUSE \u00a7QA.LISTS p2": [
+ "HOUSE.LAYOUT.PAGINATION.LISTS.AVOID_LONELY_ITEM",
+ "HOUSE.LAYOUT.PAGINATION.LISTS.KEEP_INTRO"
+ ],
"HOUSE \u00a7QA.OVERFLOW p1": [
"HOUSE.LAYOUT.OVERFLOW.OVERFULL_LINES.REPORT"
],
@@ -728,5 +2868,34 @@
"HOUSE.TABLES.ALIGNMENT.DECIMALS",
"HOUSE.TABLES.HEADERS.REPEAT_ON_PAGEBREAK",
"HOUSE.TABLES.OVERFLOW.NO_CLIPPING"
+ ],
+ "HOUSE \u00a7TABLES.ALIGNMENT p1": [
+ "HOUSE.TABLES.COLUMN_WIDTHS.BALANCED",
+ "HOUSE.TABLES.NUMERIC.ALIGN_DECIMALS",
+ "HOUSE.TABLES.NUMERIC.PRECISION.CONSISTENT"
+ ],
+ "HOUSE \u00a7TABLES.MISSING_DATA p1": [
+ "HOUSE.TABLES.MISSING_DATA.CONSISTENT_MARK"
+ ],
+ "HOUSE \u00a7TABLES.SOURCES p1": [
+ "HOUSE.TABLES.SOURCE.NOTES"
+ ],
+ "HOUSE \u00a7TABLES.UNITS p1": [
+ "HOUSE.TABLES.UNITS.IN_HEADERS"
+ ],
+ "HOUSE \u00a7TYPOGRAPHY.HTML.JUSTIFICATION p1": [
+ "HOUSE.TYPOGRAPHY.HTML.JUSTIFICATION.RAGGED_RIGHT"
+ ],
+ "HOUSE \u00a7TYPOGRAPHY.HTML.LINE_HEIGHT p1": [
+ "HOUSE.TYPOGRAPHY.HTML.LINE_HEIGHT.MINIMUM"
+ ],
+ "HOUSE \u00a7TYPOGRAPHY.HTML.LINK_DECORATION p1": [
+ "HOUSE.TYPOGRAPHY.HTML.LINK_DECORATION.CONSISTENT"
+ ],
+ "HOUSE \u00a7TYPOGRAPHY.MD.EMPHASIS.BALANCE p1": [
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ALL_CAPS.AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ITALIC_LONG.AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_LONG.AVOID",
+ "HOUSE.TYPOGRAPHY.EMPHASIS.ITALIC_LONG.AVOID"
]
}
diff --git a/spec/manifest.yaml b/spec/manifest.yaml
index 22c0167..1b1da6f 100644
--- a/spec/manifest.yaml
+++ b/spec/manifest.yaml
@@ -59,6 +59,8 @@ profiles:
- dense_tech
- memo
- slide_deck
+ - webtypography_nc
+ - cv_onepage
planned_rule_counts:
target_total_range: [800, 1500]
@@ -139,4 +141,3 @@ degraded_mode_contract:
- "layout-report.json"
- "coverage-report.json"
- "degraded-mode-report.json (what was inferred and why)"
-
diff --git a/spec/profiles/audit_report.yaml b/spec/profiles/audit_report.yaml
new file mode 100644
index 0000000..d3987b7
--- /dev/null
+++ b/spec/profiles/audit_report.yaml
@@ -0,0 +1,124 @@
+profile_id: "audit_report"
+description: "Evidence-heavy audit reports: 12pt baseline, branded tables, and tolerant QA thresholds for long sources/citations."
+
+page:
+ size: "A4"
+ orientation: "portrait"
+ two_sided: false
+ margins:
+ top: "27mm"
+ bottom: "27mm"
+ inner: "27mm"
+ outer: "27mm"
+
+fonts:
+ require_primary: true
+ body:
+ family: ["Noto Serif", "STIX Two Text", "serif"]
+ size: "12pt"
+ line_height: 1.50
+ heading:
+ family: ["Noto Sans", "Source Sans 3", "sans-serif"]
+ mono:
+ family: ["Noto Sans Mono", "Source Code Pro", "monospace"]
+ size: "10.5pt"
+ line_height: 1.30
+
+colors:
+ body: "#111827"
+ accent: "#1f3a5f"
+ heading: "#1f3a5f"
+ link: "#1f3a5f"
+ citation: "#3b4b63"
+ table_rule: "#cbd5e1"
+ table_stripe: "#f1f5f9"
+
+measure_targets:
+ columns: 1
+ body_chars_per_line:
+ min: 60
+ ideal: 75
+ max: 180
+
+hyphenation:
+ enabled: true
+ strategy: "balanced"
+ min_left: 2
+ min_right: 3
+ max_consecutive_hyphenated_lines: 3
+ avoid_proper_names_when_possible: true
+
+headings:
+ keep_with_next_lines: 1
+ avoid_stranded_headings: true
+ numbering:
+ enabled: false
+
+widows_orphans:
+ widow_lines: 2
+ orphan_lines: 2
+ balance_facing_pages: false
+
+code:
+ block:
+ font_size: "10pt"
+ line_height: 1.30
+ wrap: true
+ overflow_policy: "wrap_then_shrink_minor"
+ shrink_limit: 0.92
+ padding: "0.4em 0.6em"
+ background: "#f8fafc"
+ border: "1px solid #e5e7eb"
+ radius: "4px"
+
+tables:
+ cell_padding: "3pt 6pt"
+ header_repeat: true
+ overflow_policy: "shrink_then_wrap"
+ shrink_limit: 0.90
+ layout: "auto"
+ cell_wrap: true
+ keep_together: true
+ row_keep_together: true
+ grid_style: "rules_minimal"
+ header_align: "left"
+ cell_align: "left"
+ numeric_align: "right"
+ boolean_align: "center"
+
+figures:
+ max_width: "100%"
+ margin: "0.6em auto"
+
+typography:
+ small_caps_acronyms:
+ enabled: true
+ min_letters: 2
+ letter_spacing: "0.04em"
+
+lists:
+ hanging_punctuation:
+ enabled: true
+ indent: "1.2em"
+ hang: "0.4em"
+
+running_head:
+ enabled: true
+ placement: "footer"
+ template: "{page} | {title}"
+ font_size: "9pt"
+ font_style: "normal"
+ color: "#6b7280"
+
+severity_overrides:
+ - selector: { category: "accessibility" }
+ severity: "must"
+
+locale_defaults:
+ primary_language: "en"
+ fallback_languages: ["fr"]
+ quotation_style: "us"
+ date_format: "YYYY-MM-DD"
+ number_format:
+ decimal_separator: "."
+ thousands_separator: ","
diff --git a/spec/profiles/cv_onepage.yaml b/spec/profiles/cv_onepage.yaml
new file mode 100644
index 0000000..9d0bb64
--- /dev/null
+++ b/spec/profiles/cv_onepage.yaml
@@ -0,0 +1,162 @@
+profile_id: "cv_onepage"
+description: "Single-page CV profile: compact, readable, and print-ready with balanced spacing."
+
+page:
+ size: "A4"
+ orientation: "portrait"
+ two_sided: false
+ margins:
+ top: "16mm"
+ bottom: "16mm"
+ inner: "14mm"
+ outer: "14mm"
+
+fonts:
+ body:
+ family: ["Noto Sans", "Source Sans 3", "Arial", "sans-serif"]
+ size: "11.1pt"
+ line_height: 1.58
+ heading:
+ family: ["Noto Sans", "Source Sans 3", "Arial", "sans-serif"]
+ mono:
+ family: ["Noto Sans Mono", "Source Code Pro", "Consolas", "monospace"]
+ size: "9.5pt"
+ line_height: 1.25
+
+colors:
+ body: "#111827"
+ accent: "#111827"
+ heading: "#111827"
+ link: "#111827"
+ citation: "#111827"
+ table_rule: "#cbd5e1"
+ table_stripe: "#f8fafc"
+
+measure_targets:
+ columns: 1
+ body_chars_per_line:
+ min: 55
+ ideal: 66
+ max: 75
+
+hyphenation:
+ enabled: true
+ strategy: "balanced"
+ language_driven: true
+ min_left: 2
+ min_right: 3
+ max_consecutive_hyphenated_lines: 2
+ avoid_proper_names_when_possible: true
+
+paragraphs:
+ first_paragraph_indent: "0"
+ indent: "0"
+ block_paragraph_spacing: "0.7em"
+
+headings:
+ keep_with_next_lines: 2
+ avoid_stranded_headings: true
+ numbering:
+ enabled: false
+ sizes:
+ h1: "1.5em"
+ h2: "1.15em"
+ h3: "1.05em"
+ spacing:
+ top: "0.6em"
+ bottom: "0.2em"
+
+widows_orphans:
+ widow_lines: 2
+ orphan_lines: 2
+ balance_facing_pages: false
+
+code:
+ block:
+ font_size: "9pt"
+ line_height: 1.25
+ wrap: true
+ padding: "0.35em 0.5em"
+ background: "#f8fafc"
+ border: "1px solid #e5e7eb"
+ radius: "4px"
+
+tables:
+ cell_padding: "2pt 4pt"
+ header_repeat: false
+ overflow_policy: "shrink_then_wrap"
+ shrink_limit: 0.90
+ layout: "auto"
+ cell_wrap: true
+ keep_together: true
+ row_keep_together: true
+ grid_style: "rules_minimal"
+ header_align: "left"
+ cell_align: "left"
+ numeric_align: "right"
+ boolean_align: "center"
+
+figures:
+ max_width: "100%"
+ margin: "0.5em auto"
+
+typography:
+ small_caps_acronyms:
+ enabled: false
+ min_letters: 2
+ letter_spacing: "0.04em"
+ drop_caps:
+ enabled: false
+ size: "2.8em"
+ padding_right: "0.08em"
+ padding_top: "0.02em"
+ weight: "700"
+ text_wrap:
+ body: "pretty"
+ headings: "balance"
+
+lists:
+ hanging_punctuation:
+ enabled: true
+ indent: "0.9em"
+ hang: "0.3em"
+ text_wrap: "balance"
+ wrap_heuristics:
+ enabled: true
+ width_factor: 0.9
+ min_tail_ratio: 0.28
+ min_tail_chars: 14
+ max_shift_words: 4
+ indent_chars: 2
+ balance_with_playwright: true
+ max_passes: 2
+
+layout:
+ auto_density: true
+ density_thresholds:
+ tight_over: 42
+ loose_under: 34
+ density_overrides:
+ tight:
+ body_line_height: 1.44
+ paragraph_spacing: "0.5em"
+ heading_margin_top: "0.45em"
+ heading_margin_bottom: "0.12em"
+ normal:
+ body_line_height: 1.58
+ paragraph_spacing: "0.7em"
+ heading_margin_top: "0.6em"
+ heading_margin_bottom: "0.2em"
+ loose:
+ body_line_height: 1.72
+ paragraph_spacing: "0.95em"
+ heading_margin_top: "0.8em"
+ heading_margin_bottom: "0.25em"
+ section_overrides:
+ experience:
+ list_item_width: "60ch"
+ list_item_max_width: "60ch"
+ list_margin_right: "0.3em"
+
+running_head:
+ enabled: false
diff --git a/spec/profiles/dense_tech.yaml b/spec/profiles/dense_tech.yaml
index 6bcd14f..a44e9d9 100644
--- a/spec/profiles/dense_tech.yaml
+++ b/spec/profiles/dense_tech.yaml
@@ -1,5 +1,5 @@
profile_id: "dense_tech"
-description: "Technical papers and specs: denser copy, more code/table tolerance, strict numbering and citations."
+description: "Technical papers and specs: 12pt baseline, denser copy, more code/table tolerance, strict numbering and citations."
page:
size: "A4"
@@ -14,14 +14,23 @@ page:
fonts:
body:
family: ["Noto Serif", "STIX Two Text", "serif"]
- size: "10pt"
- line_height: 1.35
+ size: "12pt"
+ line_height: 1.45
heading:
family: ["Noto Sans", "Source Sans 3", "sans-serif"]
mono:
family: ["Noto Sans Mono", "Source Code Pro", "monospace"]
- size: "9pt"
- line_height: 1.25
+ size: "10.5pt"
+ line_height: 1.30
+
+colors:
+ body: "#111827"
+ accent: "#1f3a5f"
+ heading: "#1f3a5f"
+ link: "#1f3a5f"
+ citation: "#3b4b63"
+ table_rule: "#cbd5e1"
+ table_stripe: "#f1f5f9"
measure_targets:
columns: 1
@@ -53,17 +62,34 @@ widows_orphans:
code:
block:
- font_size: "8.8pt"
- line_height: 1.20
+ font_size: "10pt"
+ line_height: 1.30
wrap: true
overflow_policy: "wrap_then_shrink_minor"
shrink_limit: 0.90
+ padding: "0.35em 0.5em"
+ background: "#f8fafc"
+ border: "1px solid #e5e7eb"
+ radius: "4px"
tables:
- cell_padding: "2pt 4pt"
+ cell_padding: "3pt 6pt"
header_repeat: true
overflow_policy: "shrink_then_wrap"
- shrink_limit: 0.85
+ shrink_limit: 0.90
+ layout: "auto"
+ cell_wrap: true
+ keep_together: true
+ row_keep_together: true
+ grid_style: "rules_minimal"
+ header_align: "left"
+ cell_align: "left"
+ numeric_align: "right"
+ boolean_align: "center"
+
+figures:
+ max_width: "100%"
+ margin: "0.5em auto"
severity_overrides:
- selector: { category: "citations" }
@@ -81,4 +107,3 @@ locale_defaults:
number_format:
decimal_separator: "."
thousands_separator: ","
-
diff --git a/spec/profiles/memo.yaml b/spec/profiles/memo.yaml
index e7ce939..c9f35c8 100644
--- a/spec/profiles/memo.yaml
+++ b/spec/profiles/memo.yaml
@@ -14,7 +14,7 @@ page:
fonts:
body:
family: ["Noto Sans", "Source Sans 3", "Arial", "sans-serif"]
- size: "11pt"
+ size: "12pt"
line_height: 1.40
heading:
family: ["Noto Sans", "Source Sans 3", "Arial", "sans-serif"]
@@ -23,6 +23,15 @@ fonts:
size: "10pt"
line_height: 1.30
+colors:
+ body: "#111827"
+ accent: "#1f3a5f"
+ heading: "#1f3a5f"
+ link: "#1f3a5f"
+ citation: "#3b4b63"
+ table_rule: "#cbd5e1"
+ table_stripe: "#f1f5f9"
+
measure_targets:
columns: 1
body_chars_per_line:
@@ -52,12 +61,22 @@ code:
wrap: true
overflow_policy: "wrap"
shrink_limit: 1.0
+ padding: "0.35em 0.5em"
+ background: "#f8fafc"
+ border: "1px solid #e5e7eb"
+ radius: "4px"
tables:
cell_padding: "3pt 6pt"
header_repeat: false
overflow_policy: "wrap"
shrink_limit: 1.0
+ layout: "auto"
+ cell_wrap: true
+
+figures:
+ max_width: "100%"
+ margin: "0.5em auto"
severity_overrides:
- selector: { category: "layout", tag: "widows_orphans" }
@@ -73,4 +92,3 @@ locale_defaults:
number_format:
decimal_separator: "."
thousands_separator: ","
-
diff --git a/spec/profiles/print_pdf.yaml b/spec/profiles/print_pdf.yaml
index 71a1f0a..85c9d9d 100644
--- a/spec/profiles/print_pdf.yaml
+++ b/spec/profiles/print_pdf.yaml
@@ -23,6 +23,15 @@ fonts:
size: "9.5pt"
line_height: 1.30
+colors:
+ body: "#111827"
+ accent: "#111827"
+ heading: "#111827"
+ link: "#111827"
+ citation: "#111827"
+ table_rule: "#cbd5e1"
+ table_stripe: "#f8fafc"
+
measure_targets:
columns: 1
body_chars_per_line:
@@ -49,6 +58,8 @@ headings:
enabled: true
style: "decimal"
require_monotonic_increase: true
+ rule:
+ enabled: false
widows_orphans:
widow_lines: 2
@@ -59,15 +70,57 @@ code:
block:
font_size: "9pt"
line_height: 1.25
- wrap: false
- overflow_policy: "shrink_then_scroll_indicator"
+ wrap: true
+ overflow_policy: "wrap_then_shrink_minor"
shrink_limit: 0.90
+ padding: "0.4em 0.6em"
+ background: "#f8fafc"
+ border: "1px solid #e5e7eb"
+ radius: "4px"
tables:
cell_padding: "2.5pt 5pt"
header_repeat: true
overflow_policy: "shrink_then_rotate_if_allowed"
shrink_limit: 0.88
+ layout: "auto"
+ cell_wrap: true
+ keep_together: true
+ row_keep_together: true
+ grid_style: "rules_minimal"
+ header_align: "left"
+ cell_align: "left"
+ numeric_align: "right"
+ boolean_align: "center"
+
+figures:
+ max_width: "100%"
+ margin: "0.6em auto"
+
+typography:
+ small_caps_acronyms:
+ enabled: true
+ min_letters: 2
+ letter_spacing: "0.04em"
+ drop_caps:
+ enabled: true
+ size: "3em"
+ padding_right: "0.08em"
+ padding_top: "0.02em"
+
+lists:
+ hanging_punctuation:
+ enabled: true
+ indent: "1.1em"
+ hang: "0.4em"
+
+running_head:
+ enabled: true
+ placement: "footer"
+ template: "{page} | {title}"
+ font_size: "8.5pt"
+ font_style: "normal"
+ color: "#6b7280"
severity_overrides:
- selector: { category: "layout", tag: "widows_orphans" }
@@ -85,4 +138,3 @@ locale_defaults:
number_format:
decimal_separator: "."
thousands_separator: ","
-
diff --git a/spec/profiles/slide_deck.yaml b/spec/profiles/slide_deck.yaml
index a50587e..1c002c8 100644
--- a/spec/profiles/slide_deck.yaml
+++ b/spec/profiles/slide_deck.yaml
@@ -52,12 +52,22 @@ code:
wrap: true
overflow_policy: "wrap_then_shrink_minor"
shrink_limit: 0.92
+ padding: "0.35em 0.5em"
+ background: "#f8fafc"
+ border: "1px solid #e5e7eb"
+ radius: "4px"
tables:
cell_padding: "6pt 10pt"
header_repeat: false
overflow_policy: "shrink_then_wrap"
shrink_limit: 0.88
+ layout: "fixed"
+ cell_wrap: true
+
+figures:
+ max_width: "100%"
+ margin: "0.4em auto"
severity_overrides:
- selector: { category: "layout", tag: "overflow" }
@@ -73,4 +83,3 @@ locale_defaults:
number_format:
decimal_separator: "."
thousands_separator: ","
-
diff --git a/spec/profiles/web_pdf.yaml b/spec/profiles/web_pdf.yaml
index fab3b37..9b7aee3 100644
--- a/spec/profiles/web_pdf.yaml
+++ b/spec/profiles/web_pdf.yaml
@@ -6,23 +6,32 @@ page:
orientation: "portrait"
two_sided: false
margins:
- top: "22mm"
- bottom: "22mm"
- inner: "20mm"
- outer: "20mm"
+ top: "1in"
+ bottom: "1in"
+ inner: "1.5in"
+ outer: "1.5in"
fonts:
body:
family: ["Noto Serif", "STIX Two Text", "Times New Roman", "serif"]
- size: "11pt"
- line_height: 1.45
+ size: "12pt"
+ line_height: 1.50
heading:
family: ["Noto Sans", "Source Sans 3", "Arial", "sans-serif"]
mono:
family: ["Noto Sans Mono", "Source Code Pro", "Consolas", "monospace"]
- size: "10pt"
+ size: "10.5pt"
line_height: 1.35
+colors:
+ body: "#111827"
+ accent: "#1f3a5f"
+ heading: "#1f3a5f"
+ link: "#1f3a5f"
+ citation: "#3b4b63"
+ table_rule: "#cbd5e1"
+ table_stripe: "#f1f5f9"
+
measure_targets:
columns: 1
body_chars_per_line:
@@ -56,28 +65,76 @@ headings:
enabled: true
style: "decimal"
require_monotonic_increase: true
+ rule:
+ enabled: true
+ position: "under"
+ thickness: "1px"
+ color: "#1f3a5f"
+ spacing: "0.2em"
widows_orphans:
- widow_lines: 2
- orphan_lines: 2
+ widow_lines: 3
+ orphan_lines: 3
balance_facing_pages: false
code:
inline:
use_mono: true
block:
- font_size: "9.5pt"
+ font_size: "10pt"
line_height: 1.35
wrap: true
max_wrap_penalty: "medium"
overflow_policy: "wrap_then_shrink_minor"
shrink_limit: 0.92
+ padding: "0.4em 0.6em"
+ background: "#f8fafc"
+ border: "1px solid #e5e7eb"
+ radius: "4px"
tables:
cell_padding: "3pt 6pt"
header_repeat: true
overflow_policy: "shrink_then_wrap"
shrink_limit: 0.9
+ layout: "auto"
+ cell_wrap: true
+ keep_together: true
+ row_keep_together: true
+ grid_style: "rules_minimal"
+ header_align: "left"
+ cell_align: "left"
+ numeric_align: "right"
+ boolean_align: "center"
+
+figures:
+ max_width: "100%"
+ margin: "0.6em auto"
+
+typography:
+ small_caps_acronyms:
+ enabled: true
+ min_letters: 2
+ letter_spacing: "0.04em"
+ drop_caps:
+ enabled: true
+ size: "2.8em"
+ padding_right: "0.08em"
+ padding_top: "0.02em"
+
+lists:
+ hanging_punctuation:
+ enabled: true
+ indent: "1.2em"
+ hang: "0.4em"
+
+running_head:
+ enabled: true
+ placement: "footer"
+ template: "{page} | {title}"
+ font_size: "9pt"
+ font_style: "normal"
+ color: "#6b7280"
severity_overrides:
- selector: { category: "layout", tag: "widows_orphans" }
@@ -93,4 +150,3 @@ locale_defaults:
number_format:
decimal_separator: "."
thousands_separator: ","
-
diff --git a/spec/profiles/webtypography_nc.yaml b/spec/profiles/webtypography_nc.yaml
new file mode 100644
index 0000000..9c78f10
--- /dev/null
+++ b/spec/profiles/webtypography_nc.yaml
@@ -0,0 +1,148 @@
+profile_id: "webtypography_nc"
+description: "Non-commercial profile inspired by WebTypography.net (CC BY-NC 4.0)."
+
+license:
+ name: "CC BY-NC 4.0"
+ url: "https://creativecommons.org/licenses/by-nc/4.0/"
+ source: "https://github.com/clagnut/webtypography"
+ notes: "Non-commercial use only; attribution required."
+
+page:
+ size: "Letter"
+ orientation: "portrait"
+ two_sided: false
+ margins:
+ top: "1in"
+ bottom: "1in"
+ inner: "1.4in"
+ outer: "1.4in"
+
+fonts:
+ body:
+ family: ["Noto Serif", "STIX Two Text", "Times New Roman", "serif"]
+ size: "11pt"
+ line_height: 1.50
+ heading:
+ family: ["Noto Sans", "Source Sans 3", "Arial", "sans-serif"]
+ mono:
+ family: ["Noto Sans Mono", "Source Code Pro", "Consolas", "monospace"]
+ size: "10pt"
+ line_height: 1.35
+
+colors:
+ body: "#111827"
+ accent: "#1f3a5f"
+ heading: "#1f3a5f"
+ link: "#1f3a5f"
+ citation: "#3b4b63"
+ table_rule: "#cbd5e1"
+ table_stripe: "#f1f5f9"
+
+measure_targets:
+ columns: 1
+ body_chars_per_line:
+ min: 55
+ ideal: 66
+ max: 75
+
+hyphenation:
+ enabled: true
+ strategy: "balanced"
+ language_driven: true
+ min_left: 2
+ min_right: 3
+ max_consecutive_hyphenated_lines: 2
+ avoid_proper_names_when_possible: true
+ avoid_after_short_lines: true
+
+paragraphs:
+ first_paragraph_indent: "0"
+ indent: "1.2em"
+ block_paragraph_spacing: "0"
+
+headings:
+ keep_with_next_lines: 2
+ avoid_stranded_headings: true
+ numbering:
+ enabled: true
+ style: "decimal"
+ require_monotonic_increase: true
+ rule:
+ enabled: true
+ position: "under"
+ thickness: "1px"
+ color: "#1f3a5f"
+ spacing: "0.2em"
+
+widows_orphans:
+ widow_lines: 2
+ orphan_lines: 2
+ balance_facing_pages: false
+
+code:
+ inline:
+ use_mono: true
+ block:
+ font_size: "10pt"
+ line_height: 1.35
+ wrap: true
+ max_wrap_penalty: "medium"
+ overflow_policy: "wrap_then_shrink_minor"
+ shrink_limit: 0.92
+ padding: "0.4em 0.6em"
+ background: "#f8fafc"
+ border: "1px solid #e5e7eb"
+ radius: "4px"
+
+tables:
+ cell_padding: "3pt 6pt"
+ header_repeat: true
+ overflow_policy: "shrink_then_wrap"
+ shrink_limit: 0.9
+ layout: "auto"
+ cell_wrap: true
+ keep_together: true
+ row_keep_together: true
+ grid_style: "rules_minimal"
+ header_align: "left"
+ cell_align: "left"
+ numeric_align: "right"
+ boolean_align: "center"
+
+figures:
+ max_width: "100%"
+ margin: "0.6em auto"
+
+typography:
+ small_caps_acronyms:
+ enabled: true
+ min_letters: 2
+ letter_spacing: "0.04em"
+ drop_caps:
+ enabled: true
+ size: "2.8em"
+ padding_right: "0.08em"
+ padding_top: "0.02em"
+
+lists:
+ hanging_punctuation:
+ enabled: true
+ indent: "1.2em"
+ hang: "0.4em"
+
+running_head:
+ enabled: true
+ placement: "footer"
+ template: "{page} | {title}"
+ font_size: "9pt"
+ font_style: "normal"
+ color: "#6b7280"
+
+locale_defaults:
+ primary_language: "en"
+ fallback_languages: ["fr"]
+ quotation_style: "us"
+ date_format: "YYYY-MM-DD"
+ number_format:
+ decimal_separator: "."
+ thousands_separator: ","
diff --git a/spec/quality_gates.yaml b/spec/quality_gates.yaml
index 0c402ba..cb59080 100644
--- a/spec/quality_gates.yaml
+++ b/spec/quality_gates.yaml
@@ -13,6 +13,10 @@ metrics:
max_link_wrap_incidents: "Count of wrapped URLs/DOIs/emails violating link wrap policy."
max_heading_numbering_errors: "Count of numbering sequence/format violations."
max_citation_format_errors: "Count of citations not matching configured style format."
+ max_caption_separation_incidents: "Count of captions likely separated from their figures/tables."
+ max_list_break_incidents: "Count of list pagination issues (intro separated, lonely items)."
+ max_heading_proximity_incidents: "Count of adjacent/stacked headings with insufficient body text."
+ max_runt_final_page: "Count of final pages judged too short (runt pages) by PDF analysis."
overflow_detection:
overfull_line_threshold_css_px: 1.0
@@ -25,12 +29,16 @@ profiles:
max_widows_per_10_pages: 1
max_orphans_per_10_pages: 1
max_stranded_headings: 0
- max_overfull_lines: 2
+ max_overfull_lines: 1
max_table_overflow_incidents: 0
max_code_overflow_incidents: 1
- max_link_wrap_incidents: 2
+ max_link_wrap_incidents: 1
max_heading_numbering_errors: 0
max_citation_format_errors: 0
+ max_caption_separation_incidents: 1
+ max_list_break_incidents: 1
+ max_heading_proximity_incidents: 1
+ max_runt_final_page: 0
strict:
max_widows_per_10_pages: 0
max_orphans_per_10_pages: 0
@@ -41,6 +49,10 @@ profiles:
max_link_wrap_incidents: 0
max_heading_numbering_errors: 0
max_citation_format_errors: 0
+ max_caption_separation_incidents: 0
+ max_list_break_incidents: 0
+ max_heading_proximity_incidents: 0
+ max_runt_final_page: 0
print_pdf:
default:
@@ -53,6 +65,10 @@ profiles:
max_link_wrap_incidents: 0
max_heading_numbering_errors: 0
max_citation_format_errors: 0
+ max_caption_separation_incidents: 0
+ max_list_break_incidents: 0
+ max_heading_proximity_incidents: 0
+ max_runt_final_page: 0
strict:
max_widows_per_10_pages: 0
max_orphans_per_10_pages: 0
@@ -63,18 +79,26 @@ profiles:
max_link_wrap_incidents: 0
max_heading_numbering_errors: 0
max_citation_format_errors: 0
+ max_caption_separation_incidents: 0
+ max_list_break_incidents: 0
+ max_heading_proximity_incidents: 0
+ max_runt_final_page: 0
dense_tech:
default:
max_widows_per_10_pages: 1
max_orphans_per_10_pages: 1
max_stranded_headings: 0
- max_overfull_lines: 3
- max_table_overflow_incidents: 1
+ max_overfull_lines: 2
+ max_table_overflow_incidents: 0
max_code_overflow_incidents: 2
- max_link_wrap_incidents: 3
+ max_link_wrap_incidents: 2
max_heading_numbering_errors: 0
max_citation_format_errors: 0
+ max_caption_separation_incidents: 1
+ max_list_break_incidents: 1
+ max_heading_proximity_incidents: 1
+ max_runt_final_page: 0
strict:
max_widows_per_10_pages: 0
max_orphans_per_10_pages: 0
@@ -85,18 +109,26 @@ profiles:
max_link_wrap_incidents: 1
max_heading_numbering_errors: 0
max_citation_format_errors: 0
+ max_caption_separation_incidents: 0
+ max_list_break_incidents: 0
+ max_heading_proximity_incidents: 0
+ max_runt_final_page: 0
memo:
default:
max_widows_per_10_pages: 3
max_orphans_per_10_pages: 3
max_stranded_headings: 0
- max_overfull_lines: 2
- max_table_overflow_incidents: 1
+ max_overfull_lines: 1
+ max_table_overflow_incidents: 0
max_code_overflow_incidents: 1
- max_link_wrap_incidents: 4
+ max_link_wrap_incidents: 3
max_heading_numbering_errors: 1
max_citation_format_errors: 1
+ max_caption_separation_incidents: 2
+ max_list_break_incidents: 2
+ max_heading_proximity_incidents: 2
+ max_runt_final_page: 0
strict:
max_widows_per_10_pages: 1
max_orphans_per_10_pages: 1
@@ -107,6 +139,10 @@ profiles:
max_link_wrap_incidents: 2
max_heading_numbering_errors: 0
max_citation_format_errors: 0
+ max_caption_separation_incidents: 1
+ max_list_break_incidents: 1
+ max_heading_proximity_incidents: 1
+ max_runt_final_page: 0
slide_deck:
default:
@@ -119,6 +155,10 @@ profiles:
max_link_wrap_incidents: 0
max_heading_numbering_errors: 0
max_citation_format_errors: 1
+ max_caption_separation_incidents: 2
+ max_list_break_incidents: 2
+ max_heading_proximity_incidents: 2
+ max_runt_final_page: 0
strict:
max_widows_per_10_pages: 2
max_orphans_per_10_pages: 2
@@ -129,4 +169,37 @@ profiles:
max_link_wrap_incidents: 0
max_heading_numbering_errors: 0
max_citation_format_errors: 0
+ max_caption_separation_incidents: 1
+ max_list_break_incidents: 1
+ max_heading_proximity_incidents: 1
+ max_runt_final_page: 0
+ audit_report:
+ default:
+ max_widows_per_10_pages: 12
+ max_orphans_per_10_pages: 12
+ max_stranded_headings: 5
+ max_overfull_lines: 10
+ max_table_overflow_incidents: 10
+ max_code_overflow_incidents: 2
+ max_link_wrap_incidents: 5
+ max_heading_numbering_errors: 5
+ max_citation_format_errors: 1
+ max_caption_separation_incidents: 2
+ max_list_break_incidents: 2
+ max_heading_proximity_incidents: 2
+ max_runt_final_page: 0
+ strict:
+ max_widows_per_10_pages: 6
+ max_orphans_per_10_pages: 6
+ max_stranded_headings: 2
+ max_overfull_lines: 5
+ max_table_overflow_incidents: 5
+ max_code_overflow_incidents: 1
+ max_link_wrap_incidents: 3
+ max_heading_numbering_errors: 2
+ max_citation_format_errors: 0
+ max_caption_separation_incidents: 1
+ max_list_break_incidents: 1
+ max_heading_proximity_incidents: 1
+ max_runt_final_page: 0
diff --git a/spec/rules/abbreviations/v1_abbreviations_003.ndjson b/spec/rules/abbreviations/v1_abbreviations_003.ndjson
new file mode 100644
index 0000000..9addb1b
--- /dev/null
+++ b/spec/rules/abbreviations/v1_abbreviations_003.ndjson
@@ -0,0 +1,27 @@
+{"id":"CMOS.ABBREVIATIONS.ACADEMIC.DEGREES.STYLE","title":"Format academic degrees consistently","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Format academic degrees consistently (periods, spacing, and pluralization) and avoid mixing degree abbreviation styles.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["degrees","academic"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.ACRONYMS.AVOID_IN_HEADINGS","title":"Avoid uncommon acronyms in headings","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"md","rule_text":"Avoid introducing uncommon acronyms in headings; prefer the spelled-out term or ensure the acronym is defined earlier in the document.","rationale":"Headings should be scannable without requiring backtracking.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","headings","abbreviations"],"keywords":["headings","acronyms"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.ACRONYMS.DEFINE_FIRST_USE","title":"Define acronyms on first use","source_refs":["CMOS18 §10.1 p623","CMOS18 §10.2 p624"],"category":"abbreviations","severity":"should","applies_to":"md","rule_text":"When introducing an acronym/initialism that may be unfamiliar, spell out the term on first occurrence and give the abbreviation in parentheses; use the abbreviation consistently thereafter.","rationale":"Readers should not be forced to infer meanings of new abbreviations.","enforcement":"lint","autofix":"suggest","autofix_notes":"Warn when an all-caps acronym appears before any '(ACRONYM)' definition pattern; suggest defining it on first use.","tags":["abbreviations","acronyms"],"keywords":["acronym","initialism","define on first use"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.BIBLIOGRAPHY.STANDARDS.FOLLOW","title":"Follow domain standards in bibliographies","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"In bibliographies and references, follow the governing citation standard for abbreviations (journal titles, series names) rather than improvising.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["bibliography","journal abbreviations"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.CAPS.AVOID_ALL_CAPS_WORDS","title":"Avoid ALL CAPS words as faux abbreviations","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Avoid using ALL CAPS for ordinary words as a stylistic choice; reserve capitalization patterns for genuine abbreviations and proper names.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["all caps","style"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.COMPANIES.INC_LTD.CONSISTENT","title":"Handle corporate suffixes consistently","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Treat corporate suffixes (Inc., Ltd., LLC, etc.) consistently in names, and follow legal/branding requirements when applicable.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["Inc","LLC"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.FOOTNOTES.ABBREV_ON_FIRST_USE","title":"Define abbreviations in notes when first used","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"If an abbreviation first appears in a footnote/endnote, define it there rather than assuming it was defined in the main text.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["footnotes","endnotes"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.GENERAL.AVOID_OVERUSE","title":"Avoid excessive abbreviations in prose","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Avoid heavy abbreviation density in running prose; when abbreviations are necessary, prioritize reader comprehension over brevity.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["readability","prose"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.GENERAL.CONSISTENCY","title":"Use a consistent abbreviations style","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Choose a consistent approach to abbreviations (forms, punctuation, capitalization, and spacing) and apply it uniformly throughout the document.","rationale":"Consistency reduces reader friction and prevents copyediting churn.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations","consistency"],"keywords":["abbreviations","consistency","style"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.GENERAL.GLOSSARY.WHEN_NEEDED","title":"Provide a glossary when abbreviation load is high","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"If the document uses many specialized abbreviations, include a glossary or abbreviation list in front/back matter.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["glossary","abbreviation list"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.GEOGRAPHY.STATE_ABBREVS.CONSISTENT","title":"Use a consistent style for state/province abbreviations","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Use a consistent style for state/province abbreviations and ensure it matches the audience and citation context.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["state abbreviations","geography"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.INITIALISMS.NO_PERIODS.DEFAULT","title":"Prefer initialisms without periods","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"For most initialisms and acronyms, omit internal periods unless required by a specific standard or house style.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["initialism","periods"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.LATIN.EG_IE.PUNCTUATION","title":"Format common Latin abbreviations consistently","source_refs":["CMOS18 §10.1 p623","CMOS18 §10.2 p624","CMOS18 §10.4 p626"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Format common Latin abbreviations (such as e.g. and i.e.) consistently in punctuation and spacing, and prefer plain-language alternatives when clarity would improve.","rationale":"These forms are easy to misuse and can confuse readers.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations","latin"],"keywords":["e.g.","i.e.","latin abbreviations"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.LATIN.ET_AL.USE","title":"Use et al. consistently and sparingly","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Use et al. in citations only when the chosen citation style allows it; apply the same threshold and formatting throughout the document.","rationale":"Citation readability depends on uniform abbreviation rules.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","citations","abbreviations"],"keywords":["et al","citations"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.LATIN.VERSUS_ENGLISH","title":"Prefer plain English when precision matters","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Prefer plain-language equivalents to Latin abbreviations when precision matters or when the audience may not recognize the Latin form.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["latin","clarity"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.MEASURES.SI.SPACE","title":"Use standard spacing for SI symbols","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Use standard spacing and formatting for SI symbols (including temperature and percent) according to the chosen locale/profile.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["SI","symbols"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.NAMES.INITIALS.SPACING","title":"Use consistent spacing in personal initials","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"When representing personal names with initials, choose a consistent spacing/punctuation convention and apply it uniformly.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["initials","names"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.ORGANIZATIONS.SPELL_OUT_FIRST","title":"Spell out organization names before abbreviating","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Spell out an organization name before using its abbreviation, unless the abbreviation is universally recognized for the audience.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["organization","acronym"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.PARENTHETICALS.AVOID_STACKING","title":"Avoid stacking multiple abbreviations","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Avoid sequences of stacked abbreviations that force readers to decode multiple terms at once; restructure the sentence when necessary.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["readability","stacking"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.PLURALS.NO_APOSTROPHE","title":"Form plurals of abbreviations without apostrophes","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"must","applies_to":"md","rule_text":"Form plurals of most abbreviations and initialisms with a plain s (e.g., APIs), not an apostrophe (API’s), unless a specific exception is required for clarity.","rationale":"Apostrophes typically signal possession, not pluralization.","enforcement":"lint","autofix":"suggest","autofix_notes":"Warn on patterns like 'API's' and suggest 'APIs'; avoid rewriting when context looks possessive.","tags":["abbreviations","plurals"],"keywords":["plural","apostrophe","initialism"],"dependencies":[],"exceptions":["Possessive forms remain valid when intended; require human confirmation when ambiguous."],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.POSSESSIVE.FORM","title":"Use standard possessive formation for abbreviations","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Form possessives of abbreviations using the standard apostrophe rules appropriate to the style; avoid inconsistent possessive forms within the same document.","rationale":"Consistent possessives avoid distracting visual variation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations","possessives"],"keywords":["possessive","apostrophe"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.PUNCTUATION.ABBREV_WITH_PERIODS.AVOID_DOUBLE","title":"Avoid doubled periods at sentence end","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"When an abbreviation ends with a period and falls at sentence end, avoid producing doubled periods; keep sentence punctuation clean.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["periods","punctuation"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.TABLES.ABBREV_KEY","title":"Provide keys for table abbreviations","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"When abbreviations appear in tables or figures, provide a key/legend nearby or ensure the meaning is already established.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["tables","legend"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.TECH.TERMS.CASE_SENSITIVE","title":"Preserve case-sensitive technical abbreviations","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Preserve case for abbreviations whose meaning depends on capitalization (e.g., API vs Api) and treat them consistently.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["case","technical"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.TIME.AM_PM.FORM","title":"Use a consistent am/pm style","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Choose a single style for am/pm markers (case and punctuation) and apply it consistently; avoid mixing styles within one document.","rationale":"Time notations should be immediately legible and consistent.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations","time"],"keywords":["a.m.","p.m.","time"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.TITLES.HONORIFICS.CONSISTENT","title":"Use honorifics consistently","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"If honorifics or courtesy titles are used (e.g., Dr., Prof.), apply the chosen form consistently and avoid mixing styles.","rationale":"Abbreviation choices should optimize comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations"],"keywords":["honorifics","titles"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.ABBREVIATIONS.UNITS.NO_PERIODS","title":"Do not add periods to unit symbols","source_refs":["CMOS18 §10.1 p623"],"category":"abbreviations","severity":"should","applies_to":"all","rule_text":"Use standard unit symbols without trailing periods (e.g., kg, km) and do not pluralize symbols; keep spacing between numeral and unit consistent.","rationale":"Unit symbols are standardized and should not be treated as words.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","abbreviations","units"],"keywords":["units","symbols","periods"],"dependencies":[],"exceptions":[],"status":"active"}
diff --git a/spec/rules/abbreviations/v1_abbreviations_004.ndjson b/spec/rules/abbreviations/v1_abbreviations_004.ndjson
new file mode 100644
index 0000000..cd3b41a
--- /dev/null
+++ b/spec/rules/abbreviations/v1_abbreviations_004.ndjson
@@ -0,0 +1,20 @@
+{"id": "CMOS.ABBREVIATIONS.MONTHS.ABBREV_IN_TABLES", "title": "Abbreviate months in tables and citations only", "source_refs": ["CMOS18 \u00a710.4 p626"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "Abbreviate month names primarily in tables, notes, or citations; spell them out in running text.", "rationale": "Full month names improve readability in prose.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "dates"], "keywords": ["months", "abbreviations"], "dependencies": [], "exceptions": ["Space-limited labels may use standard month abbreviations if documented."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.MONTHS.SPELL_OUT_IN_TEXT", "title": "Spell out months in running text", "source_refs": ["CMOS18 \u00a710.4 p626"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "Spell out month names in running text unless a tabular or reference style is explicitly required.", "rationale": "Spelled-out months are easier to scan in prose.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "dates"], "keywords": ["months", "running text"], "dependencies": [], "exceptions": ["In data-heavy contexts, abbreviated month names may be acceptable with a legend."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.DAYS.ABBREV_IN_TABLES", "title": "Abbreviate days of the week only in compact contexts", "source_refs": ["CMOS18 \u00a710.4 p626"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "Abbreviate days of the week only in compact contexts such as tables or schedules.", "rationale": "Full day names improve readability in prose.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "dates"], "keywords": ["days of week", "abbreviations"], "dependencies": [], "exceptions": ["Compact UI labels may use standard abbreviations."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.DAYS.SPELL_OUT_IN_TEXT", "title": "Spell out days of the week in prose", "source_refs": ["CMOS18 \u00a710.4 p626"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "Spell out day names in running text unless a tabular format requires abbreviations.", "rationale": "Spelled-out day names are clearer in narrative text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "dates"], "keywords": ["days", "running text"], "dependencies": [], "exceptions": ["Short labels or calendar formats may use standard abbreviations."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.STATES.POSTAL_ONLY", "title": "Use postal abbreviations only in addresses", "source_refs": ["CMOS18 \u00a710.4 p626"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "Use two-letter postal abbreviations for states/provinces only in address blocks or data tables.", "rationale": "Postal abbreviations can be unclear in narrative text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "geography"], "keywords": ["state abbreviations", "postal"], "dependencies": [], "exceptions": ["Space-limited captions may use postal forms with a legend."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.STATES.SPELL_OUT_IN_TEXT", "title": "Spell out state and province names in prose", "source_refs": ["CMOS18 \u00a710.4 p626"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "In running text, spell out state and province names unless a standard abbreviated form is required by context.", "rationale": "Spelled-out names reduce ambiguity for international readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "geography"], "keywords": ["states", "provinces"], "dependencies": [], "exceptions": ["Institutional or legal standards may mandate abbreviations."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.COUNTRIES.ABBREV_IN_TABLES_ONLY", "title": "Use country abbreviations only in compact contexts", "source_refs": ["CMOS18 \u00a710.4 p626"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "Use country abbreviations primarily in tables or figures; spell out country names in prose.", "rationale": "Country abbreviations can be ambiguous without context.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "geography"], "keywords": ["countries", "abbreviations"], "dependencies": [], "exceptions": ["Well-known abbreviations (e.g., US, UK) may be acceptable if defined."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.UNITS.ABBREV_WITH_NUMERALS_ONLY", "title": "Use unit symbols with numerals", "source_refs": ["CMOS18 \u00a710.1 p623"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "Use unit symbols with numerals; spell out units when no numeral is present.", "rationale": "Symbol use is conventional when paired with numbers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "units"], "keywords": ["units", "symbols"], "dependencies": [], "exceptions": ["Technical profiles may require symbols throughout; document the choice."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.UNITS.SPELL_OUT_WITHOUT_NUMERALS", "title": "Spell out units when not paired with numbers", "source_refs": ["CMOS18 \u00a710.1 p623"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "When a unit is not paired with a numeral, spell it out rather than using a symbol.", "rationale": "Spelled-out units read more naturally in prose.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "units"], "keywords": ["units", "spelled out"], "dependencies": [], "exceptions": ["Scientific writing may permit symbols even without a numeral."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.UNITS.NO_PLURAL_SYMBOLS", "title": "Do not pluralize unit symbols", "source_refs": ["CMOS18 \u00a710.1 p623"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "Do not pluralize unit symbols; keep the symbol form invariant.", "rationale": "Unit symbols follow standard scientific conventions.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "units"], "keywords": ["unit symbols", "plural"], "dependencies": [], "exceptions": ["Spelled-out unit words can be pluralized normally."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_SENTENCE_START", "title": "Avoid starting sentences with acronyms", "source_refs": ["CMOS18 \u00a710.2 p624"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "Avoid starting sentences with unfamiliar acronyms; rewrite or spell out the term.", "rationale": "Sentence-initial acronyms slow readers and look abrupt.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "acronyms"], "keywords": ["sentence start", "acronyms"], "dependencies": [], "exceptions": ["Widely known acronyms may be acceptable if the audience expects them."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.ACRONYMS.AVOID_STACKING", "title": "Avoid stacking multiple acronyms", "source_refs": ["CMOS18 \u00a710.1 p623"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "Avoid strings of multiple acronyms in a row; expand or rephrase for clarity.", "rationale": "Dense acronym clusters reduce comprehension.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "acronyms"], "keywords": ["acronym stacking", "readability"], "dependencies": [], "exceptions": ["Technical identifiers may require dense acronyms; add a glossary if needed."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.ACRONYMS.REINTRODUCE_AFTER_GAP", "title": "Reintroduce acronyms after long gaps", "source_refs": ["CMOS18 \u00a710.2 p624"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "If an acronym is not used for a long stretch, reintroduce the expanded form on its next use.", "rationale": "Readers may forget rarely used abbreviations.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "acronyms"], "keywords": ["acronym", "reintroduce"], "dependencies": [], "exceptions": ["Short documents may not require reintroduction."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.CAPTIONS.DEFINE_ON_FIRST_USE", "title": "Define abbreviations on first use in captions", "source_refs": ["CMOS18 \u00a710.1 p623"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "If an abbreviation first appears in a figure or table caption, define it there.", "rationale": "Captions often stand alone and need local clarity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "captions"], "keywords": ["captions", "definitions"], "dependencies": [], "exceptions": ["If the abbreviation is defined immediately adjacent in the text, a caption may omit it."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.TABLES.KEYS.WHEN_DENSE", "title": "Provide a key for dense table abbreviations", "source_refs": ["CMOS18 \u00a710.1 p623"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "When tables use many abbreviations, include a key or legend nearby.", "rationale": "Table readers need immediate expansion without hunting the text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "tables"], "keywords": ["tables", "legend"], "dependencies": [], "exceptions": ["Very small tables with obvious abbreviations may omit a key."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.US_USA.CONSISTENT", "title": "Use a consistent form for US/USA/U.S.", "source_refs": ["CMOS18 \u00a710.4 p626"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "Choose a single form for US/USA/U.S. and use it consistently in comparable contexts.", "rationale": "Mixed forms look careless and can confuse readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "consistency"], "keywords": ["US", "USA", "U.S."], "dependencies": [], "exceptions": ["Proper names may preserve their official style."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.TITLES.COURTESY_PERIODS", "title": "Use courtesy titles consistently", "source_refs": ["CMOS18 \u00a710.1 p623"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "If courtesy titles (e.g., Mr., Ms., Dr.) are used, keep punctuation and spacing consistent.", "rationale": "Inconsistent courtesy titles weaken editorial polish.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "titles"], "keywords": ["courtesy titles", "punctuation"], "dependencies": [], "exceptions": ["Official titles may mandate specific styling."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.TITLES.JR_SR.CONSISTENT", "title": "Format Jr./Sr. consistently", "source_refs": ["CMOS18 \u00a710.1 p623"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent format for suffixes like Jr. and Sr., including punctuation and spacing.", "rationale": "Suffix inconsistency is a common copyediting defect.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations", "titles"], "keywords": ["Jr.", "Sr.", "suffixes"], "dependencies": [], "exceptions": ["Legal names may require a specific official format."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.AVOID_ONE_OFFS", "title": "Avoid abbreviations used only once", "source_refs": ["CMOS18 \u00a710.1 p623"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "Avoid creating abbreviations for terms that are used only once; spell them out instead.", "rationale": "One-off abbreviations add cognitive load without payoff.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations"], "keywords": ["one-off abbreviations", "clarity"], "dependencies": [], "exceptions": ["Technical identifiers may require abbreviated forms even when rare."], "status": "active"}
+{"id": "CMOS.ABBREVIATIONS.READER_FAMILIARITY", "title": "Prefer abbreviations only when familiar to the audience", "source_refs": ["CMOS18 \u00a710.1 p623"], "category": "abbreviations", "severity": "should", "applies_to": "all", "rule_text": "Use abbreviations only when the audience is likely to recognize them without effort.", "rationale": "Reader familiarity should guide abbreviation choices.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "abbreviations"], "keywords": ["audience", "familiarity"], "dependencies": [], "exceptions": ["Specialist documents may assume domain knowledge; include a glossary if needed."], "status": "active"}
diff --git a/spec/rules/accessibility/v1_accessibility_003.ndjson b/spec/rules/accessibility/v1_accessibility_003.ndjson
new file mode 100644
index 0000000..eb36977
--- /dev/null
+++ b/spec/rules/accessibility/v1_accessibility_003.ndjson
@@ -0,0 +1,18 @@
+{"id":"HOUSE.ACCESSIBILITY.CODE.FENCES.LANGUAGE","title":"Mark code language when helpful","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"When code blocks are present, mark the language when it helps readers (and renderers) interpret syntax.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["code fences","language"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.COLOR.NOT_SOLE_CONVEYOR","title":"Do not rely on color alone","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Do not rely on color alone to convey meaning; use text labels or patterns.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["color","meaning"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.CONTRAST.TEXT_READABLE","title":"Ensure text contrast is sufficient","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Ensure text has sufficient contrast against its background; avoid low-contrast gray-on-gray styling.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["contrast","readability"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.EMPHASIS.USE_SPARELY","title":"Use emphasis sparingly","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Use bold/italics sparingly and consistently; excessive emphasis reduces scanability.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["emphasis","readability"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.HEADINGS.HIERARCHY.NO_SKIPS","title":"Do not skip heading levels","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Maintain a logical heading hierarchy; do not jump from H1 to H3 without an intermediate level.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["headings","hierarchy"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.IMAGES.ALT_TEXT.QUALITY.NO_FILENAME","title":"Alt text should not be a filename","source_refs":["HOUSE §A11Y.IMAGES p2"],"category":"accessibility","severity":"should","applies_to":"md","rule_text":"Alt text should describe the image content, not repeat the image filename or a generic token like “image”; keep it concise and meaningful.","rationale":"Filenames and generic labels are not helpful to screen-reader users.","enforcement":"lint","autofix":"suggest","autofix_notes":"Warn when alt text looks like a filename (e.g., ends with .png/.jpg) or is generic; suggest a short content description.","tags":["accessibility","images"],"keywords":["alt text","filenames","screen reader"],"dependencies":["HOUSE.A11Y.IMAGES.ALT_REQUIRED"],"exceptions":["If the filename is intentionally meaningful, ensure surrounding text provides the needed description."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.IMAGES.DECORATIVE.EMPTY_ALT","title":"Use empty alt only for truly decorative images","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Use empty alt text only for purely decorative images; otherwise describe the informational content.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["alt text","decorative"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.IMAGES.TEXT_IN_IMAGES.AVOID","title":"Avoid embedding essential text only in images","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Avoid putting essential information only in images; provide an equivalent text description.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["images","text"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.LANGUAGE.METADATA","title":"Declare primary language when possible","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Declare the document's primary language where the platform supports it to improve hyphenation and screen-reader behavior.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["language","metadata"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.LINKS.AVOID_SHORTENERS","title":"Avoid opaque link shorteners","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Avoid opaque link shorteners for publication unless the shortener is under your control and stable.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["link shorteners","transparency"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.LINKS.FOCUS_ORDER","title":"Keep reading order logical","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Keep reading order and focus order logical; avoid layouts that visually reorder content without structural cues.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["reading order","structure"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.LINKS.TARGETS.PUBLIC","title":"Prefer public stable link targets","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Prefer public, stable link targets for published documents; avoid internal-only URLs when the audience is external.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["links","public"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.LINKS.VISUALLY_DISTINCT","title":"Make links visually distinguishable without color alone","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"html","rule_text":"Ensure links are visually distinguishable from surrounding text using a cue beyond color (e.g., underline) in rendered outputs.","rationale":"Non-color link cues improve accessibility and usability.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","links"],"keywords":["links","underline","color"],"dependencies":[],"exceptions":["If a design system uses a non-underline cue, ensure it meets contrast and distinguishability needs."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.LISTS.USE_LIST_MARKUP","title":"Use list markup for lists","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Use proper list markup for lists rather than manual line breaks and punctuation.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["lists","markup"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.PDF.TAGS.WHEN_AVAILABLE","title":"Enable PDF tagging when available","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"When a PDF engine supports tagged PDF or accessibility metadata, enable it as part of the rendering pipeline.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["tagged pdf","metadata"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.TABLES.AVOID_SCREENSHOT","title":"Avoid table screenshots","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Avoid publishing tables as screenshots; use real tables so text is selectable and accessible.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["tables","images"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.TABLES.HEADER_ROW.REQUIRED","title":"Tables should have a header row","source_refs":["HOUSE §A11Y.BASICS p1","HOUSE §A11Y.IMAGES p2","HOUSE §A11Y.TABLES p3"],"category":"accessibility","severity":"should","applies_to":"md","rule_text":"Data tables should include a header row so readers can interpret columns; avoid headerless tables in published outputs.","rationale":"Headers improve scanning and accessibility for assistive tech.","enforcement":"lint","autofix":"suggest","autofix_notes":"Warn when a table header row is present but empty; suggest adding column labels.","tags":["accessibility","tables"],"keywords":["tables","headers","accessibility"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.TABLES.SIMPLE_STRUCTURE","title":"Prefer simple table structures","source_refs":["HOUSE §A11Y.BASICS p1"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Prefer simple tables with clear headers; avoid complex merged-cell layouts that do not translate well to assistive technology.","rationale":"Accessibility requires explicit structural and content choices.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility"],"keywords":["tables","structure"],"dependencies":[],"exceptions":[],"status":"active"}
diff --git a/spec/rules/accessibility/v1_accessibility_004.ndjson b/spec/rules/accessibility/v1_accessibility_004.ndjson
new file mode 100644
index 0000000..e9c7a49
--- /dev/null
+++ b/spec/rules/accessibility/v1_accessibility_004.ndjson
@@ -0,0 +1,18 @@
+{"id":"HOUSE.ACCESSIBILITY.LINK_TEXT.UNIQUE_TARGETS","title":"Keep link text unique to a target","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Avoid using identical link text for different destinations within the same document.","rationale":"Duplicate link labels confuse screen-reader navigation lists.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["accessibility","links"],"keywords":["link text","unique"],"dependencies":[],"exceptions":["If repeated labels point to the same destination, consistency is acceptable."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.LINK_TEXT.NO_BARE_URLS","title":"Avoid bare URLs in prose","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Avoid bare URLs in running text; prefer descriptive link labels that convey destination or action.","rationale":"Bare URLs are difficult to read aloud and less accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","links"],"keywords":["bare URLs","link labels"],"dependencies":[],"exceptions":["Technical appendices may require literal URLs; provide a short label when possible."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.LINKS.FOCUS_VISIBLE","title":"Ensure focus indicators are visible","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"html","rule_text":"Ensure focus indicators are visible for links and controls in HTML outputs.","rationale":"Keyboard users rely on visible focus cues.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","links"],"keywords":["focus","keyboard"],"dependencies":[],"exceptions":["If focus is suppressed by design, document the alternative cue explicitly."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.IMAGES.CAPTION_FOR_COMPLEX","title":"Provide captions for complex images","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Provide a caption or adjacent explanation for complex images such as charts or diagrams.","rationale":"Captions supply context that alt text alone may not convey.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","images"],"keywords":["images","captions"],"dependencies":[],"exceptions":["Simple decorative images do not require captions."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.IMAGES.ALT_AVOID_DUPLICATE_CAPTION","title":"Avoid duplicating captions in alt text","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Do not duplicate the full caption in alt text; keep alt text focused on essential image content.","rationale":"Duplicate content is noisy for screen-reader users.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","images"],"keywords":["alt text","captions"],"dependencies":[],"exceptions":["If no caption exists, alt text may include a brief summary."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.IMAGES.ALT_SUMMARY_FOR_CHARTS","title":"Summarize chart meaning in alt text or nearby text","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Charts and graphs should include a brief summary of their takeaway in alt text or nearby text.","rationale":"Data visuals require a textual equivalent for accessibility.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","images"],"keywords":["charts","summary","alt text"],"dependencies":[],"exceptions":["Very small sparklines may be described in the surrounding sentence."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.FIGURES.REFERENCED_IN_TEXT","title":"Reference each figure in the text","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Ensure every figure is referenced in the surrounding text so its purpose is clear.","rationale":"References help readers locate and interpret figures.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","figures"],"keywords":["figures","references"],"dependencies":[],"exceptions":["Standalone galleries may use a dedicated list of captions."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.TABLES.CAPTION_SUMMARY","title":"Provide a caption or summary for data tables","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Provide a short caption or summary for data tables to explain their purpose.","rationale":"Captions help users interpret tables without guessing.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","tables"],"keywords":["tables","captions"],"dependencies":[],"exceptions":["Very small tables may be self-explanatory if labeled clearly."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.TABLES.NO_LAYOUT","title":"Avoid tables for layout","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Do not use tables purely for layout; use semantic structure instead.","rationale":"Layout tables are difficult for assistive tech to interpret.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","tables"],"keywords":["layout tables","semantics"],"dependencies":[],"exceptions":["Legacy content may require tables; document the exception."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.TABLES.HEADER_SCOPE","title":"Ensure table headers are identifiable","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Ensure table headers are clearly identifiable (row or column headers) so readers can interpret cell values.","rationale":"Header context is required for accessible table reading.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","tables"],"keywords":["table headers","scope"],"dependencies":[],"exceptions":["Simple two-column tables may be clear without explicit scope markers."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.TABLES.ROW_HEADERS_FOR_STUB","title":"Use row headers when stub columns are present","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"When a table has a stub (row-label) column, treat it as header information for that row.","rationale":"Row headers help readers associate values with labels.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","tables"],"keywords":["row headers","stub column"],"dependencies":[],"exceptions":["If the table is extremely simple, a caption may suffice."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.HEADINGS.SINGLE_H1","title":"Use a single top-level heading","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Use a single top-level heading for the document title; avoid multiple H1-equivalent headings.","rationale":"A single H1 improves navigation for assistive tech.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","headings"],"keywords":["H1","document title"],"dependencies":[],"exceptions":["Short standalone sections may omit a top-level heading if the container provides it."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.HEADINGS.NO_EMPTY","title":"Avoid empty or decorative headings","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Do not use empty headings or headings used only for visual spacing.","rationale":"Decorative headings create noise in navigation.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["accessibility","headings"],"keywords":["empty headings","decorative"],"dependencies":[],"exceptions":["Section dividers should use rules or spacing, not headings."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.HEADINGS.NO_DECORATIVE","title":"Do not use headings as decoration","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Use headings to convey structure, not decoration or layout.","rationale":"Structural headings are essential for assistive navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","headings"],"keywords":["headings","structure"],"dependencies":[],"exceptions":["Design-only labels should use non-heading styles."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.LISTS.NO_EMPTY_ITEMS","title":"Avoid empty list items","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Avoid empty list items or placeholder bullets in published documents.","rationale":"Empty list items create noise for assistive tech.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["accessibility","lists"],"keywords":["lists","empty items"],"dependencies":[],"exceptions":["Drafts may include placeholders but should be removed before publication."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.LISTS.MARKER_CONSISTENT","title":"Keep list marker styles consistent","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Use a consistent marker style within each list level (bullets or numbering).","rationale":"Consistent markers help readers follow structure.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","lists"],"keywords":["list markers","consistency"],"dependencies":[],"exceptions":["Mixed markers may be acceptable in intentionally nested outlines."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.CONTRAST.NON_TEXT","title":"Ensure non-text elements have sufficient contrast","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Icons, charts, and other non-text elements should have sufficient contrast to be distinguishable.","rationale":"Non-text contrast affects comprehension for low-vision readers.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","contrast"],"keywords":["contrast","icons","charts"],"dependencies":[],"exceptions":["If color is used, provide an additional differentiator such as patterns or labels."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.MEDIA.TRANSCRIPTS","title":"Provide transcripts for audio or video","source_refs":["HOUSE \u00a7A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"all","rule_text":"Provide transcripts or captions for any embedded audio or video content.","rationale":"Transcripts are essential for accessibility and offline review.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","media"],"keywords":["transcripts","captions"],"dependencies":[],"exceptions":["If media is purely decorative, omit it from published outputs."],"status":"active"}
diff --git a/spec/rules/accessibility/v1_accessibility_005.ndjson b/spec/rules/accessibility/v1_accessibility_005.ndjson
new file mode 100644
index 0000000..a6d9a01
--- /dev/null
+++ b/spec/rules/accessibility/v1_accessibility_005.ndjson
@@ -0,0 +1,7 @@
+{"id":"HOUSE.ACCESSIBILITY.LINKS.ICON_ONLY.TEXT","title":"Provide text alternatives for icon-only links","source_refs":["HOUSE §A11Y.LINKS p3"],"category":"accessibility","severity":"should","applies_to":"html","rule_text":"Icon-only links and controls must include accessible text (aria-label or visually hidden text) that describes the action.","rationale":"Screen-reader users rely on descriptive labels.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","links"],"keywords":["icon links","aria-label","labels"],"dependencies":[],"exceptions":["If visible text is present, a separate label is unnecessary."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.LINKS.SKIP_TO_CONTENT","title":"Provide a skip-to-content link for long pages","source_refs":["HOUSE §A11Y.LINKS p3"],"category":"accessibility","severity":"should","applies_to":"html","rule_text":"Provide a skip-to-content link for long HTML documents to allow keyboard users to bypass repeated navigation.","rationale":"Skip links improve keyboard navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","navigation"],"keywords":["skip link","navigation"],"dependencies":[],"exceptions":["Single-screen documents may omit a skip link."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.TOC.LINKED_ENTRIES","title":"Link TOC entries to sections when supported","source_refs":["HOUSE §A11Y.NAVIGATION p3"],"category":"accessibility","severity":"should","applies_to":"html","rule_text":"When a table of contents is present in HTML, ensure entries are actual links to the corresponding sections.","rationale":"Linked TOCs reduce navigation friction.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","navigation"],"keywords":["toc","links","navigation"],"dependencies":[],"exceptions":["Print-only outputs may use non-linked TOCs."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.NAVIGATION.FOOTNOTE_BACKLINKS","title":"Provide backlinks from notes to callouts","source_refs":["HOUSE §A11Y.NAVIGATION p3"],"category":"accessibility","severity":"should","applies_to":"html","rule_text":"Provide backlinks from footnotes/endnotes to their callouts when the format supports it.","rationale":"Backlinks reduce navigation overhead for readers.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","navigation"],"keywords":["footnotes","backlinks"],"dependencies":[],"exceptions":["PDF outputs may omit backlinks if the renderer cannot generate them."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.NAVIGATION.PDF_BOOKMARKS","title":"Generate PDF bookmarks from headings when supported","source_refs":["HOUSE §A11Y.NAVIGATION p3"],"category":"accessibility","severity":"should","applies_to":"pdf","rule_text":"Generate PDF bookmarks from headings when the PDF engine supports them.","rationale":"Bookmarks improve navigation in long PDFs.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","navigation"],"keywords":["pdf bookmarks","headings"],"dependencies":[],"exceptions":["If the engine cannot create bookmarks, document the limitation."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.IMAGES.LINKED.ALT_TARGET","title":"Linked images must describe destination or action","source_refs":["HOUSE §A11Y.IMAGES p3"],"category":"accessibility","severity":"should","applies_to":"html","rule_text":"If an image functions as a link, its alt text should describe the destination or action rather than only the visual.","rationale":"Linked images require action-focused labels.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","images","links"],"keywords":["linked images","alt text"],"dependencies":[],"exceptions":["Decorative linked images may use an aria-label on the link element."],"status":"active"}
+{"id":"HOUSE.ACCESSIBILITY.TABLES.HEADERS.SCOPE","title":"Mark table headers with clear scope semantics","source_refs":["HOUSE §A11Y.TABLES p3"],"category":"accessibility","severity":"should","applies_to":"html","rule_text":"When exporting HTML tables, mark header cells with clear scope or semantic roles so assistive tech can map headers to data cells.","rationale":"Header semantics improve table navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","accessibility","tables"],"keywords":["table headers","scope","semantics"],"dependencies":[],"exceptions":["Very small tables may rely on surrounding context if semantic markup is unavailable."],"status":"active"}
diff --git a/spec/rules/accessibility/v1_accessibility_006.ndjson b/spec/rules/accessibility/v1_accessibility_006.ndjson
new file mode 100644
index 0000000..c1dd43c
--- /dev/null
+++ b/spec/rules/accessibility/v1_accessibility_006.ndjson
@@ -0,0 +1 @@
+{"id":"HOUSE.ACCESSIBILITY.LINK_TEXT.SYMBOL_ONLY.AVOID","title":"Avoid symbol-only link text","source_refs":["HOUSE §A11Y.BASICS p2"],"category":"accessibility","severity":"should","applies_to":"md","rule_text":"Avoid link labels that are only symbols; use readable text labels for accessibility.","rationale":"Symbol-only links are ambiguous for screen readers.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["accessibility","links"],"keywords":["link text","symbols"],"dependencies":[],"exceptions":["Icon-only links must include accessible text via another mechanism."],"status":"active"}
diff --git a/spec/rules/backmatter/v1_backmatter_003.ndjson b/spec/rules/backmatter/v1_backmatter_003.ndjson
new file mode 100644
index 0000000..70cb86a
--- /dev/null
+++ b/spec/rules/backmatter/v1_backmatter_003.ndjson
@@ -0,0 +1,18 @@
+{"id":"CMOS.BACKMATTER.ABBREVIATIONS.LIST.WHEN_NEEDED","title":"Provide an abbreviations list when needed","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"When abbreviation density is high, provide an abbreviations list in backmatter and keep it synchronized with usage.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["abbreviations list","glossary"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.ACKNOWLEDGMENTS.PLACEMENT","title":"Keep acknowledgments placement consistent","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"If acknowledgments are placed in backmatter rather than frontmatter, keep placement consistent across editions.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["acknowledgments","placement"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.APPENDICES.CROSS_REFERENCES","title":"Cross-reference appendices from the body","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"When content is moved to appendices, add explicit cross-references so readers can find it.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["appendix","cross-reference"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.APPENDICES.FORMAT_MATCH","title":"Match appendix formatting to the body","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"Format appendix headings, numbering, and typography to match the body unless the genre requires a distinct style.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["appendix","formatting"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.APPENDICES.LABELED","title":"Label appendices clearly","source_refs":["CMOS18 §1.3 p9"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"If appendices are used, label them clearly (e.g., Appendix A) and reference them consistently from the main text.","rationale":"Clear appendix structure improves navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["appendix","labeling"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.APPENDICES.SOURCES","title":"Cite sources for appendix material","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"Appendix material should include the same citation rigor as the main body when it asserts facts or quotes sources.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["appendix","citations"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.BIBLIOGRAPHY.CONSISTENT_STYLE","title":"Keep bibliography formatting consistent","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"When a bibliography or reference list is present, keep entry structure, punctuation, and ordering consistent with the selected citation style.","rationale":"Inconsistent references erode trust and slow review.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter","citations"],"keywords":["bibliography","references","consistency"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.BIBLIOGRAPHY.SORTING","title":"Sort bibliography entries consistently","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"Sort bibliography entries according to the chosen style (alphabetical by author, etc.) and do not mix ordering schemes.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["bibliography","sorting"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.CONTACT.SUPPORT","title":"Provide support/contact details","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"Provide support or contact details for readers who need clarifications or updates.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["support","contact"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.DATA.AVAILABILITY","title":"Include data availability notes when applicable","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"When claims depend on datasets or code, include a data availability note describing how to access the supporting materials.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["data availability","reproducibility"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.ENDNOTES.VERSUS_FOOTNOTES.CONSISTENT","title":"Choose footnotes or endnotes and apply consistently","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"Choose footnotes or endnotes according to the document style and constraints; apply the choice consistently.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["footnotes","endnotes"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.ERRATA.WHEN_NEEDED","title":"Record errata for published revisions","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"For published documents that receive corrections, maintain an errata section or log to track fixes.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["errata","corrections"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.GLOSSARY.SORTING","title":"Sort glossary terms consistently","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"Sort glossary terms consistently (alphabetical or thematic) and apply consistent capitalization and punctuation.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["glossary","sorting"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.GLOSSARY.WHEN_TERMS","title":"Include a glossary when terminology is dense","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"Include a glossary when the document introduces many specialized terms; keep definitions concise and consistent.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["glossary","definitions"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.INDEX.WHEN_REQUIRED","title":"Include an index when required by genre","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"Include an index when the genre or audience requires it; ensure index terms are spelled and capitalized consistently.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["index","terms"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.LICENSES.THIRD_PARTY","title":"Document third-party licenses","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"If third-party materials are included, document their licenses/permissions in backmatter.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["third-party","licenses"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.REFERENCES.SECTION_PRESENT","title":"Include a references section when citing sources","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"If sources are cited, include a references section or bibliography appropriate to the citation system.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["references","citations"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.BACKMATTER.REFERENCES.URLS.STABLE","title":"Prefer stable URLs in references","source_refs":["CMOS18 §14.1 p799","CMOS18 §14.2 p801"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"In references, prefer stable URLs/DOIs and avoid ephemeral session links.","rationale":"Back matter supports verification and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter"],"keywords":["stable URLs","DOI"],"dependencies":[],"exceptions":[],"status":"active"}
diff --git a/spec/rules/backmatter/v1_backmatter_004.ndjson b/spec/rules/backmatter/v1_backmatter_004.ndjson
new file mode 100644
index 0000000..73efbb7
--- /dev/null
+++ b/spec/rules/backmatter/v1_backmatter_004.ndjson
@@ -0,0 +1,22 @@
+{"id": "CMOS.BACKMATTER.APPENDIX.START_ON_NEW_PAGE", "title": "Start appendices on a new page", "source_refs": ["CMOS18 \u00a71.66 p66 (scan p1135)"], "category": "backmatter", "severity": "should", "applies_to": "pdf", "rule_text": "Start each appendix on a new page or clear section break according to the chosen layout.", "rationale": "Clear breaks improve navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter"], "keywords": ["appendix", "page breaks"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.APPENDIX.NUMBERING.SEQUENTIAL", "title": "Number appendices sequentially", "source_refs": ["CMOS18 \u00a71.66 p66 (scan p1135)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Number appendices sequentially (A, B, C or 1, 2, 3) and keep the scheme consistent.", "rationale": "Sequential numbering aids reference.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter"], "keywords": ["appendix", "numbering"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.APPENDIX.TOC.ENTRIES", "title": "Include appendices in the TOC", "source_refs": ["CMOS18 \u00a71.66 p66 (scan p1135)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Include appendices in the table of contents according to the document\u2019s TOC policy.", "rationale": "TOC completeness improves navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter"], "keywords": ["appendix", "toc"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.NOTES.NUMBERING.SEQUENTIAL", "title": "Keep note numbering sequential", "source_refs": ["CMOS18 \u00a72.61 p46 (scan p1120)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Number notes sequentially within the chosen scope (chapter or document) and avoid resets without notice.", "rationale": "Sequential notes prevent confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "notes"], "keywords": ["notes", "numbering"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.NOTES.REFERENCE.MATCH", "title": "Match note references to note numbers", "source_refs": ["CMOS18 \u00a72.61 p46 (scan p1120)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Ensure note callouts in the text match the corresponding note numbers in backmatter.", "rationale": "Mismatched notes break traceability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "notes"], "keywords": ["notes", "callouts"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.NOTES.ORDER.FOLLOW_TEXT", "title": "Order notes in reading sequence", "source_refs": ["CMOS18 \u00a75.210 p50 (scan p1120)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Order notes in the same sequence as their callouts appear in the text.", "rationale": "Order preserves readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "notes"], "keywords": ["notes", "ordering"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.NOTES.BLOCKS.CONSISTENT", "title": "Use consistent note blocks", "source_refs": ["CMOS18 \u00a75.210 p50 (scan p1120)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "If notes are grouped by chapter or section, use the same grouping method throughout.", "rationale": "Consistent grouping reduces confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "notes"], "keywords": ["notes", "grouping"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.NOTES.CITATIONS.COMPLETE", "title": "Keep note citations complete", "source_refs": ["CMOS18 \u00a713.57 p109 (scan p1130)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Ensure notes include sufficient source details consistent with the chosen citation style.", "rationale": "Complete citations support verification.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "citations"], "keywords": ["notes", "citations"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.INDEX.ENTRIES.CONSISTENT_CASE", "title": "Keep index entry casing consistent", "source_refs": ["CMOS18 \u00a71.81 p39 (scan p1122)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Keep capitalization and casing consistent across index entries and subentries.", "rationale": "Consistency speeds lookup.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "index"], "keywords": ["index", "capitalization"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.INDEX.SUBENTRIES.NESTED", "title": "Nest index subentries clearly", "source_refs": ["CMOS18 \u00a715.112 p57 (scan p1120)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Use clear indentation or formatting to distinguish index subentries from main entries.", "rationale": "Clear nesting improves navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "index"], "keywords": ["index", "subentries"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.INDEX.CROSS_REFERENCES.CONSISTENT", "title": "Use consistent cross-references in the index", "source_refs": ["CMOS18 \u00a715.131 p32 (scan p1126)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Use cross-references (see/see also) consistently when multiple terms lead to the same content.", "rationale": "Cross-references prevent dead ends.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "index"], "keywords": ["index", "cross references"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.INDEX.PAGE_RANGES.STANDARD", "title": "Use standard page range notation", "source_refs": ["CMOS18 \u00a715.22 p24 (scan p1130)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent page range style in index locators.", "rationale": "Consistent ranges are easier to read.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "index"], "keywords": ["index", "page ranges"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.INDEX.LOCATORS.ACCURATE", "title": "Verify index locators", "source_refs": ["CMOS18 \u00a715.32 p31 (scan p1126)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Verify that index locators point to the correct pages after final pagination.", "rationale": "Accurate locators are essential.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "index"], "keywords": ["index", "locators"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.INDEX.SUBENTRY.ORDER.LOGICAL", "title": "Order subentries logically", "source_refs": ["CMOS18 \u00a715.44 p14 (scan p1126)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Order index subentries logically (alphabetical or thematic) and keep the scheme consistent.", "rationale": "Logical order improves scanning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "index"], "keywords": ["index", "subentry order"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.INDEX.SEE_ALSO.USE_WHEN_NEEDED", "title": "Use see-also for related topics", "source_refs": ["CMOS18 \u00a715.87 p88 (scan p1126)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Use see-also references for related topics to improve navigation.", "rationale": "See-also links reduce dead ends.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "index"], "keywords": ["index", "see also"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.INDEX.ABBREVIATIONS.CONSISTENT", "title": "Keep abbreviations consistent in the index", "source_refs": ["CMOS18 \u00a715.89 p90 (scan p1126)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Use consistent abbreviations in index entries and avoid mixing full forms and abbreviations without cross-references.", "rationale": "Consistency improves lookup.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "index"], "keywords": ["index", "abbreviations"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.INDEX.NAMES.SORTING", "title": "Sort names consistently in the index", "source_refs": ["CMOS18 \u00a715.91 p92 (scan p1126)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Sort personal and corporate names consistently (e.g., surname first) within the index.", "rationale": "Consistent sorting aids lookup.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "index"], "keywords": ["index", "names"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.REFERENCES.AUTHOR_NAMES.CONSISTENT", "title": "Keep author name formats consistent", "source_refs": ["CMOS18 \u00a715.103 p133 (scan p1125)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent author name format in references and avoid mixing initials with full names.", "rationale": "Consistency improves verification.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "references"], "keywords": ["references", "author names"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.REFERENCES.DOI.OR_URL", "title": "Include persistent identifiers", "source_refs": ["CMOS18 \u00a715.112 p40 (scan p1126)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Include persistent identifiers (DOI, stable URL) for sources when available.", "rationale": "Persistent identifiers support verification.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "references"], "keywords": ["doi", "urls"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.REFERENCES.ACCESS_DATES.WHEN_NEEDED", "title": "Include access dates when required", "source_refs": ["CMOS18 \u00a715.123 p29 (scan p1126)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Include access dates for online sources when required by the chosen citation style or policy.", "rationale": "Access dates help interpret volatile sources.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "references"], "keywords": ["access dates", "online sources"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.GLOSSARY.TERMS.CONSISTENT_STYLE", "title": "Keep glossary term formatting consistent", "source_refs": ["CMOS18 \u00a72.27 p27 (scan p1124)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Keep glossary term capitalization and formatting consistent across entries.", "rationale": "Consistency aids scanning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "glossary"], "keywords": ["glossary", "terms"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.BACKMATTER.GLOSSARY.DEFINITIONS.CONCISE", "title": "Keep glossary definitions concise", "source_refs": ["CMOS18 \u00a78.2 p180 (scan p1130)"], "category": "backmatter", "severity": "should", "applies_to": "all", "rule_text": "Keep glossary definitions concise and avoid reintroducing new terms without defining them.", "rationale": "Concise definitions improve clarity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "backmatter", "glossary"], "keywords": ["glossary", "definitions"], "dependencies": [], "exceptions": [], "status": "active"}
diff --git a/spec/rules/backmatter/v1_backmatter_005.ndjson b/spec/rules/backmatter/v1_backmatter_005.ndjson
new file mode 100644
index 0000000..45dc771
--- /dev/null
+++ b/spec/rules/backmatter/v1_backmatter_005.ndjson
@@ -0,0 +1,6 @@
+{"id":"HOUSE.BACKMATTER.REFERENCES.SORTING.CONSISTENT","title":"Keep reference list sorting consistent","source_refs":["HOUSE §BACKMATTER.REFERENCES p1"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"Sort references consistently (alphabetical or order of appearance) and apply the same scheme throughout.","rationale":"Consistent sorting makes sources easier to find.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter","references"],"keywords":["references","sorting"],"dependencies":[],"exceptions":["If a style guide mandates a specific order, follow it."],"status":"active"}
+{"id":"HOUSE.BACKMATTER.REFERENCES.DEDUPLICATE","title":"Avoid duplicate reference entries","source_refs":["HOUSE §BACKMATTER.REFERENCES p1"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"Do not list the same source multiple times with slight variations; consolidate duplicates.","rationale":"Duplicates confuse readers and inflate lists.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter","references"],"keywords":["references","dedupe"],"dependencies":[],"exceptions":["If distinct editions are cited, list them separately and label clearly."],"status":"active"}
+{"id":"HOUSE.BACKMATTER.GLOSSARY.ALPHABETICAL","title":"Sort glossary entries alphabetically","source_refs":["HOUSE §BACKMATTER.GLOSSARY p1"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"Sort glossary entries alphabetically to make lookup predictable.","rationale":"Alphabetical ordering improves scanning.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter","glossary"],"keywords":["glossary","alphabetical"],"dependencies":[],"exceptions":["If the glossary is intentionally grouped by theme, state the grouping scheme."],"status":"active"}
+{"id":"HOUSE.BACKMATTER.GLOSSARY.CROSS_REFERENCES","title":"Provide cross-references for glossary synonyms","source_refs":["HOUSE §BACKMATTER.GLOSSARY p1"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"Provide cross-references for synonymous or related glossary terms to prevent dead ends.","rationale":"Cross-references improve navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter","glossary"],"keywords":["glossary","see also"],"dependencies":[],"exceptions":["Very small glossaries may omit cross-references if all terms are obvious."],"status":"active"}
+{"id":"HOUSE.BACKMATTER.APPENDICES.LABELS.MATCH","title":"Appendix labels must match references and TOC","source_refs":["HOUSE §BACKMATTER.APPENDICES p1"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"Appendix labels in headings must match their references and TOC entries to avoid navigation errors.","rationale":"Label mismatches break cross-references.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter","appendix"],"keywords":["appendix","labels","toc"],"dependencies":[],"exceptions":["If appendices are unnamed, use stable numbering consistently."],"status":"active"}
+{"id":"HOUSE.BACKMATTER.INDEX.CROSS_REFERENCES.CONSISTENT","title":"Use consistent cross-reference phrasing in indexes","source_refs":["HOUSE §BACKMATTER.INDEX p1"],"category":"backmatter","severity":"should","applies_to":"all","rule_text":"Use consistent phrasing for index cross-references (see, see also) and apply it uniformly.","rationale":"Consistent cues improve scanning.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","backmatter","index"],"keywords":["index","see also"],"dependencies":[],"exceptions":["If a style guide mandates different wording, follow it consistently."],"status":"active"}
diff --git a/spec/rules/citations/v1_citations_003.ndjson b/spec/rules/citations/v1_citations_003.ndjson
new file mode 100644
index 0000000..513c778
--- /dev/null
+++ b/spec/rules/citations/v1_citations_003.ndjson
@@ -0,0 +1,2 @@
+{"id":"HOUSE.CITATIONS.AUTHOR_DATE.PAREN_YEAR_ONLY","title":"Avoid year-only parenthetical citations in author-date style","source_refs":["HOUSE §CIT.AUTHOR_DATE.PAREN_YEAR_ONLY p1"],"category":"citations","severity":"warn","applies_to":"md","rule_text":"In author-date style, parenthetical citations should include an author or disambiguating token; year-only parentheses are ambiguous and should be flagged.","rationale":"Year-only citations reduce traceability.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["author_date","citations"],"keywords":["author-date","parenthetical","year-only"],"dependencies":[],"exceptions":["Allow when a nearby caption or label explicitly names the author in the same figure or table."],"status":"active"}
+{"id":"HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.YEAR_REQUIRED","title":"Require year (or n.d.) in author-date reference entries","source_refs":["HOUSE §CIT.AUTHOR_DATE.REFLIST.YEAR_REQUIRED p1"],"category":"citations","severity":"should","applies_to":"md","rule_text":"When using author-date citations, reference list entries should include a year or n.d. to align with in-text citations.","rationale":"References without years cannot resolve author-date citations.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["author_date","references"],"keywords":["references","bibliography","year"],"dependencies":[],"exceptions":["Use explicit ranges for multi-year publications when required by the style."],"status":"active"}
diff --git a/spec/rules/citations/v1_citations_004.ndjson b/spec/rules/citations/v1_citations_004.ndjson
new file mode 100644
index 0000000..82391d2
--- /dev/null
+++ b/spec/rules/citations/v1_citations_004.ndjson
@@ -0,0 +1 @@
+{"id":"HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.REQUIRED","title":"Provide a reference list when using author-date citations","source_refs":["HOUSE §CIT.AUTHOR_DATE.REFLIST.REQUIRED p1"],"category":"citations","severity":"should","applies_to":"md","rule_text":"If author-date citations are used in the text, include a reference list or bibliography section in the document.","rationale":"Author-date citations require a list to resolve full details.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["author_date","references"],"keywords":["reference list","bibliography","author-date"],"dependencies":[],"exceptions":["Short internal notes may rely on inline citations if the context is self-contained."],"status":"active"}
diff --git a/spec/rules/citations/v1_citations_005.ndjson b/spec/rules/citations/v1_citations_005.ndjson
new file mode 100644
index 0000000..b64fef6
--- /dev/null
+++ b/spec/rules/citations/v1_citations_005.ndjson
@@ -0,0 +1,4 @@
+{"id":"HOUSE.CITATIONS.NOTES.DEFINITIONS.REQUIRED","title":"Define every footnote marker","source_refs":["HOUSE §CIT.NOTES.DEFINITIONS.REQUIRED p1"],"category":"citations","severity":"must","applies_to":"md","rule_text":"Every footnote marker in the text must have a corresponding footnote definition in the notes list.","rationale":"Undefined markers break citation resolution.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["notes","footnotes"],"keywords":["footnote definitions","missing notes"],"dependencies":[],"exceptions":["Skip for intentionally redacted citations if policy allows; document the omission."],"status":"active"}
+{"id":"HOUSE.CITATIONS.NOTES.MARKERS.BRACKETED_NUMBERS.AVOID","title":"Avoid bracketed numeric citations in prose","source_refs":["HOUSE §CIT.NOTES.MARKERS.BRACKETED_NUMBERS.AVOID p1"],"category":"citations","severity":"warn","applies_to":"md","rule_text":"Avoid bracketed numeric citations like [1] in narrative prose when a footnote system is expected; use Markdown footnotes instead.","rationale":"Bracketed numbers are ambiguous and often render poorly.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["notes","note_markers"],"keywords":["bracketed numbers","citation markers"],"dependencies":[],"exceptions":["Technical specs that mandate bracketed numeric citations may override by profile."],"status":"active"}
+{"id":"HOUSE.CITATIONS.NOTES.BIBLIOGRAPHY.REQUIRED","title":"Include a bibliography when using footnote citations","source_refs":["HOUSE §CIT.NOTES.BIBLIOGRAPHY.REQUIRED p1"],"category":"citations","severity":"should","applies_to":"md","rule_text":"When using footnote-style citations, include a bibliography or references section unless the project explicitly waives it.","rationale":"Readers need a consolidated source list.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["notes","bibliography"],"keywords":["bibliography","references"],"dependencies":[],"exceptions":["Short internal memos may omit a bibliography if the scope is self-contained."],"status":"active"}
+{"id":"HOUSE.CITATIONS.NOTES.IBID.AVOID","title":"Avoid ibid in notes","source_refs":["HOUSE §CIT.NOTES.IBID.AVOID p1"],"category":"citations","severity":"warn","applies_to":"md","rule_text":"Avoid ibid. in notes when notes may be reordered or extracted; prefer unambiguous short forms.","rationale":"Ibid references can break when note order changes.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["notes","ibid"],"keywords":["ibid","short form","note order"],"dependencies":[],"exceptions":["If policy requires ibid, ensure notes are stable and not programmatically reordered."],"status":"active"}
diff --git a/spec/rules/citations/v1_citations_006.ndjson b/spec/rules/citations/v1_citations_006.ndjson
new file mode 100644
index 0000000..e31ac31
--- /dev/null
+++ b/spec/rules/citations/v1_citations_006.ndjson
@@ -0,0 +1,151 @@
+{"id": "CMOS.CITATIONS.S13_1.PURPOSE.ETHICS", "title": "Citations are required for ethical attribution", "source_refs": ["CMOS18 §13.1 p776 (scan p798)"], "category": "citations", "severity": "must", "applies_to": "all", "rule_text": "Provide citations for direct quotations, paraphrases, and claims that are not common knowledge.", "rationale": "Ethical attribution is a core purpose of citation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["ethics", "attribution"], "dependencies": [], "exceptions": ["Common knowledge does not require citation."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_1.PURPOSE.COPYRIGHT", "title": "Citations support copyright compliance", "source_refs": ["CMOS18 §13.1 p776 (scan p798)"], "category": "citations", "severity": "must", "applies_to": "all", "rule_text": "Citations must make clear which material is borrowed to support copyright compliance.", "rationale": "Citations protect authors and publishers from misuse claims.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["copyright", "compliance"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_1.PURPOSE.COURTESY", "title": "Citations are a courtesy to readers", "source_refs": ["CMOS18 §13.1 p776 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Provide citations that guide readers to original sources as a courtesy.", "rationale": "Readers need sources to verify or explore claims.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["readers", "verification"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_1.SUFFICIENT_INFO", "title": "Citations must provide sufficient identifying information", "source_refs": ["CMOS18 §13.1 p776 (scan p798)"], "category": "citations", "severity": "must", "applies_to": "all", "rule_text": "Ensure each citation contains enough information to locate or positively identify the source.", "rationale": "Incomplete citations defeat verification.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["completeness", "identification"], "dependencies": [], "exceptions": ["If a source is not available, document the limitation."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_1.ALL_SOURCE_TYPES", "title": "Apply citation rules to all source types", "source_refs": ["CMOS18 §13.1 p776 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Apply citation requirements to published and unpublished sources and to print and electronic formats.", "rationale": "Source type does not remove the need for attribution.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["published", "unpublished", "formats"], "dependencies": [], "exceptions": ["Follow discipline-specific exceptions if mandated."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_1.DISCIPLINE_POLICY", "title": "Follow discipline and publisher citation policies", "source_refs": ["CMOS18 §13.1 p776 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Use citation conventions appropriate to the discipline and publisher or journal requirements.", "rationale": "Different fields have different citation norms.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["discipline", "publisher"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_2.SYSTEMS.TWO_TYPES", "title": "Use either notes-bibliography or author-date", "source_refs": ["CMOS18 §13.2 p776 (scan p798)"], "category": "citations", "severity": "must", "applies_to": "all", "rule_text": "Choose either the notes-bibliography system or the author-date system for Chicago-style citations.", "rationale": "Chicago provides two formal citation systems.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "systems"], "keywords": ["notes-bibliography", "author-date"], "dependencies": [], "exceptions": ["A hybrid system must be documented explicitly."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_2.NOTES_SYSTEM", "title": "Notes system uses numbered notes", "source_refs": ["CMOS18 §13.2 p776 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In notes-bibliography, use numbered notes in the text that correspond to footnotes or endnotes.", "rationale": "Note numbering ties the text to citations.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "systems"], "keywords": ["notes", "footnotes", "endnotes"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_2.NOTES_BIBLIOGRAPHY_OPTIONAL", "title": "Notes may be paired with a bibliography", "source_refs": ["CMOS18 §13.2 p776 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In the notes system, include a bibliography when the work benefits from a consolidated list of sources.", "rationale": "A bibliography helps readers scan sources quickly.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "systems"], "keywords": ["bibliography"], "dependencies": [], "exceptions": ["Short works may omit a bibliography by policy."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_2.AUTHOR_DATE_SYSTEM", "title": "Author-date uses parenthetical citations", "source_refs": ["CMOS18 §13.2 p776 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In author-date, use parenthetical text citations tied to a reference list.", "rationale": "Parenthetical citations link directly to the reference list.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "systems"], "keywords": ["author-date", "parenthetical"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_2.STYLE_ELEMENTS.SHARED", "title": "Keep capitalization and punctuation consistent across systems", "source_refs": ["CMOS18 §13.2 p776 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Both systems share the same capitalization, punctuation, and styling rules for sources.", "rationale": "The system choice affects placement, not core styling.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "systems"], "keywords": ["capitalization", "punctuation"], "dependencies": [], "exceptions": ["Follow journal-specific variations when required."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_2.DEFAULT_SYSTEM", "title": "Notes-bibliography is the default in Chicago examples", "source_refs": ["CMOS18 §13.2 p776 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Use notes-bibliography as the default system unless a discipline or publisher specifies author-date.", "rationale": "Chicago examples default to notes-bibliography.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "systems"], "keywords": ["default system"], "dependencies": [], "exceptions": ["Sciences and social sciences often use author-date."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_2.DISCIPLINE_PREFERENCE", "title": "Align system choice with disciplinary norms", "source_refs": ["CMOS18 §13.2 p776 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Use notes-bibliography in humanities and author-date in sciences unless directed otherwise.", "rationale": "Readers expect familiar citation systems by discipline.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "systems"], "keywords": ["discipline", "humanities", "sciences"], "dependencies": [], "exceptions": ["Publisher or journal policy may override."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_2.JOURNAL_INSTRUCTIONS", "title": "Follow journal instructions for system choice", "source_refs": ["CMOS18 §13.2 p776 (scan p798)"], "category": "citations", "severity": "must", "applies_to": "all", "rule_text": "When writing for a journal, use the citation system specified by that journal.", "rationale": "Journal style is not optional.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "systems"], "keywords": ["journals", "instructions"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_2.SYSTEM_SWITCHING", "title": "Do not mix citation systems without documentation", "source_refs": ["CMOS18 §13.2 p776 (scan p798)"], "category": "citations", "severity": "must", "applies_to": "all", "rule_text": "Avoid mixing notes-bibliography and author-date in the same work unless the hybrid is documented and approved.", "rationale": "Mixed systems confuse readers and reviewers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "systems"], "keywords": ["hybrid system"], "dependencies": [], "exceptions": ["Some journals allow limited hybrid formats; document them."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_3.OTHER_SYSTEMS.MLA_APA", "title": "Follow MLA or APA when required", "source_refs": ["CMOS18 §13.3 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When a publisher or discipline requires MLA or APA, follow those manuals rather than Chicago.", "rationale": "Publisher requirements supersede general guidance.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "systems"], "keywords": ["MLA", "APA"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_3.OTHER_SYSTEMS.AMA_CSE", "title": "Use AMA or CSE for numbered reference systems", "source_refs": ["CMOS18 §13.3 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "For disciplines that require numbered reference systems, follow AMA or CSE guidance.", "rationale": "Numbered systems have their own formatting conventions.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "systems"], "keywords": ["AMA", "CSE"], "dependencies": [], "exceptions": ["Journal-specific instructions override."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_3.JOURNALS.HOUSE_STYLE", "title": "Use journal house style when available", "source_refs": ["CMOS18 §13.3 p777 (scan p799)"], "category": "citations", "severity": "must", "applies_to": "all", "rule_text": "If a journal has its own citation style, follow it even if it differs from standard systems.", "rationale": "House style is authoritative.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "systems"], "keywords": ["house style", "journals"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_3.LEGAL.BLUEBOOK", "title": "Use Bluebook for legal citations", "source_refs": ["CMOS18 §13.3 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "For legal or public documents, use Bluebook conventions unless instructed otherwise.", "rationale": "Legal citation requires specialized formats.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "legal"], "keywords": ["Bluebook", "legal"], "dependencies": [], "exceptions": ["Jurisdiction-specific rules may override."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_3.SOURCE_MANUALS", "title": "Consult the official manuals for other systems", "source_refs": ["CMOS18 §13.3 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Use the official manuals of other systems for guidance rather than extrapolating from Chicago.", "rationale": "Each system defines its own standards and exceptions.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "systems"], "keywords": ["manuals", "standards"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_4.CONSISTENCY.REQUIRED", "title": "Maintain a consistent citation style within a work", "source_refs": ["CMOS18 §13.4 p777 (scan p799)"], "category": "citations", "severity": "must", "applies_to": "all", "rule_text": "Maintain a consistent citation style within the document.", "rationale": "Consistency is required for reviewer and reader confidence.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "consistency"], "keywords": ["consistency"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_4.FLEXIBILITY.BY_AGREEMENT", "title": "Allow variations only by agreement", "source_refs": ["CMOS18 §13.4 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Use variations on Chicago style only when author and publisher agree.", "rationale": "Unapproved variations can break publication workflows.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "consistency"], "keywords": ["variations", "agreement"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_4.JOURNALS.STRICT", "title": "Follow strict journal styles", "source_refs": ["CMOS18 §13.4 p777 (scan p799)"], "category": "citations", "severity": "must", "applies_to": "all", "rule_text": "For journal publication, adhere to the established journal citation style without exceptions.", "rationale": "Journal production relies on strict standardization.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "consistency"], "keywords": ["journals", "strict"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_4.DOCUMENTED_DEVIATIONS", "title": "Document any approved deviations", "source_refs": ["CMOS18 §13.4 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Record approved citation deviations in the style sheet or project notes.", "rationale": "Documentation prevents drift across revisions.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "consistency"], "keywords": ["style sheet", "deviations"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_5.ACADEMIC_EXPECTATION", "title": "Use formal citations in academic writing", "source_refs": ["CMOS18 §13.5 p777 (scan p799)"], "category": "citations", "severity": "must", "applies_to": "all", "rule_text": "In academic writing, provide formal citations rather than casual mentions.", "rationale": "Academic readers expect traceable sources.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["academic", "formal citations"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_5.NONACADEMIC.MENTIONS_OK", "title": "Use mentions instead of formal citations in nonacademic contexts", "source_refs": ["CMOS18 §13.5 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In nonacademic writing, mention sources in the text when formal citations are unnecessary.", "rationale": "Formal citations can be excessive in informal genres.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["nonacademic", "mentions"], "dependencies": [], "exceptions": ["Publisher policies may still require citations."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_5.CITE_RELEVANT", "title": "Cite sources that materially inform the work", "source_refs": ["CMOS18 §13.5 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Cite sources that materially support the argument or evidence.", "rationale": "Focused citations improve clarity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["relevance"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_5.AVOID_TANGENTIAL", "title": "Avoid citing tangential sources", "source_refs": ["CMOS18 §13.5 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Do not use citations as a repository for tangential or loosely related sources.", "rationale": "Overcitation dilutes the signal of key sources.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["tangential sources"], "dependencies": [], "exceptions": ["Literature reviews may require broader coverage."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_5.INFORMAL_SOURCES", "title": "Use formal citations only when informal sources are central", "source_refs": ["CMOS18 §13.5 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Cite informal or nonliterary sources only when they are central to the argument.", "rationale": "Informal sources may not warrant full citation in all contexts.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["informal sources"], "dependencies": [], "exceptions": ["Legal or scholarly work may require citations for all sources."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_6.URL.FINAL_ELEMENT", "title": "Place URLs at the end of citations", "source_refs": ["CMOS18 §13.6 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When a URL is included in a citation, place it as the final element.", "rationale": "A consistent placement makes citations easier to scan.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["URL placement"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_6.URLS.IN_MANUSCRIPT", "title": "Record URLs in manuscripts even if they may be omitted later", "source_refs": ["CMOS18 §13.6 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Include URLs in manuscript citations to support verification, even if publishers remove them later.", "rationale": "Editors need access to sources during review.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["manuscript", "verification"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_6.URLS.READER_NEEDED", "title": "Retain URLs when sources are hard to locate", "source_refs": ["CMOS18 §13.6 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Keep URLs when readers would struggle to locate the source without one.", "rationale": "URLs can be essential for obscure or web-only sources.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["hard to locate"], "dependencies": [], "exceptions": ["Formal publications may omit URLs for easily found works."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_6.LINK_TITLE_PREFERRED", "title": "Prefer linking the title rather than showing a long URL", "source_refs": ["CMOS18 §13.6 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "If possible, link a reader-friendly element such as the title rather than showing a long URL.", "rationale": "Readable citations are easier to scan and less error-prone.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["link text", "titles"], "dependencies": [], "exceptions": ["Manuscripts may still record the full URL for verification."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_6.URLS.EASILY_FOUND", "title": "Omit URLs for easily found published sources", "source_refs": ["CMOS18 §13.6 p777 (scan p799)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "For formally published sources that are easy to locate by title and metadata, URLs may be omitted.", "rationale": "URLs may add noise when they do not aid discovery.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["published sources"], "dependencies": [], "exceptions": ["Online-only sources usually require URLs."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_7.DOI.URL_FORM", "title": "Use DOI-based URLs in citations", "source_refs": ["CMOS18 §13.7 p778 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When a DOI is available, express it as a URL beginning with https://doi.org/.", "rationale": "DOI URLs are stable and resolvable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "doi"], "keywords": ["DOI", "URL"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_7.DOI.NO_PREFIX", "title": "Do not use the deprecated DOI: prefix", "source_refs": ["CMOS18 §13.7 p778 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Avoid the deprecated DOI: prefix; use the DOI as a URL instead.", "rationale": "URL form is the current standard.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "doi"], "keywords": ["DOI", "deprecated"], "dependencies": [], "exceptions": ["Quoted sources may preserve legacy formatting."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_7.DOI.PREFERRED", "title": "Prefer DOI URLs over other links", "source_refs": ["CMOS18 §13.7 p778 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "If a DOI exists, prefer it over other URLs because it is designed to remain stable.", "rationale": "DOIs reduce link rot.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "doi"], "keywords": ["stability"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_7.DOI.RESOLUTION", "title": "Ensure DOI URLs resolve to source information", "source_refs": ["CMOS18 §13.7 p778 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Verify that DOI URLs resolve to a page that identifies the source.", "rationale": "Resolvable DOIs support verification.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "doi"], "keywords": ["resolve", "verification"], "dependencies": [], "exceptions": ["If a DOI is broken, use a stable alternate URL."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_8.PERMALINK.PREFERRED", "title": "Prefer permalinks when no DOI exists", "source_refs": ["CMOS18 §13.8 p778 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Use a permalink, stable URL, or persistent link when no DOI is available.", "rationale": "Permalinks are more stable than transient URLs.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["permalink", "stable URL"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_8.PERMALINK.TEST", "title": "Test permalinks before use", "source_refs": ["CMOS18 §13.8 p778 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Test permalinks to confirm they lead to the intended source.", "rationale": "Unverified permalinks may lead to dead or incorrect pages.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["permalink", "testing"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_8.SUBSCRIPTION_URLS", "title": "Avoid subscription-only URLs when possible", "source_refs": ["CMOS18 §13.8 p778 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Avoid URLs that require subscriptions when a stable public URL or database name will work.", "rationale": "Paywalled links may not help readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["subscription", "paywall"], "dependencies": [], "exceptions": ["If no public URL exists, note the database name."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_8.PREFERRED_ORDER", "title": "Use DOI, then permalink, then best available URL", "source_refs": ["CMOS18 §13.8 p778 (scan p798)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Use DOI URLs first, then permalinks, then the best available URL.", "rationale": "This order balances stability and access.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["priority", "DOI", "permalink"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_9.SHORTEN_LONG_URLS", "title": "Replace long URLs with better alternatives", "source_refs": ["CMOS18 §13.9 p779 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "If a URL is long or complex, find a shorter, more stable alternative.", "rationale": "Shorter URLs reduce errors and improve readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["long URL", "shorten"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_9.URL_TO_MAIN_PAGE", "title": "Use the main page when it identifies the source", "source_refs": ["CMOS18 §13.9 p779 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When a page-specific URL is long, use the source's main page if the citation includes a locator such as page number.", "rationale": "Main pages are usually more stable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["main page", "locator"], "dependencies": [], "exceptions": ["If the main page is ambiguous, keep the specific URL."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_9.DATABASE_NAME_OK", "title": "Use a database name when a URL is impractical", "source_refs": ["CMOS18 §13.9 p779 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "If no workable URL exists, record the database or site name instead.", "rationale": "Database names can be more reliable than unwieldy links.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["database name"], "dependencies": [], "exceptions": ["Ensure the citation includes enough metadata to locate the source."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_9.SHORT_URLS.ARE_NOT_SHORTENERS", "title": "Prefer stable source URLs, not generic shorteners", "source_refs": ["CMOS18 §13.9 p779 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Shorten URLs by finding a stable source URL, not by using a third-party shortener.", "rationale": "Stable source URLs are more transparent and durable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["shorteners", "stability"], "dependencies": [], "exceptions": ["Publishers may use shorteners in final layouts."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_10.DATABASES.NAME_INSTEAD", "title": "Use database names for subscription-only sources", "source_refs": ["CMOS18 §13.10 p779 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "For sources accessible only via subscription databases, cite the database name rather than a login URL.", "rationale": "Readers without access can still identify the source.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "databases"], "keywords": ["database", "subscription"], "dependencies": [], "exceptions": ["Use DOI URLs when available."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_10.TEST_LOGGED_OUT", "title": "Test URLs while logged out", "source_refs": ["CMOS18 §13.10 p779 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Test database URLs while logged out to confirm they provide at least source metadata.", "rationale": "Editors and readers may not have access.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "databases"], "keywords": ["logged out", "testing"], "dependencies": [], "exceptions": ["If no public metadata is available, cite the database name."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_10.DOI_PRECEDENCE", "title": "Use DOI URLs for database sources when available", "source_refs": ["CMOS18 §13.10 p779 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Prefer DOI URLs over database-specific URLs when a DOI exists.", "rationale": "DOI URLs work for readers regardless of database access.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "databases"], "keywords": ["DOI", "database"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_10.DATABASE_IN_CITATION", "title": "Include database names when needed for access", "source_refs": ["CMOS18 §13.10 p779 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When a database is essential to access the source, name it in the citation.", "rationale": "Database context helps readers find the source.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "databases"], "keywords": ["database name", "access"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_11.NO_SHORTENERS_IN_MS", "title": "Do not use link shorteners in manuscripts", "source_refs": ["CMOS18 §13.11 p780 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Do not create short URLs via third-party services in manuscript citations.", "rationale": "Shorteners obscure domain names and can break over time.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["shorteners", "manuscripts"], "dependencies": [], "exceptions": ["Publishers may choose short URLs for final layouts."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_11.SHORTENERS.OBSCURE", "title": "Avoid short URLs that hide source details", "source_refs": ["CMOS18 §13.11 p780 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Avoid shortened URLs that hide the source domain and path details.", "rationale": "Hidden details complicate verification.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["short URLs", "transparency"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_11.PUBLISHER_OPTION", "title": "Publishers may choose short URLs for publication", "source_refs": ["CMOS18 §13.11 p780 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Short URLs may be used in published works if chosen and managed by the publisher.", "rationale": "Publishers can manage redirects when sources move.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["publishers", "short URLs"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_12.URLS.PROTOCOL", "title": "Include the protocol in URLs", "source_refs": ["CMOS18 §13.12 p780 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Present URLs in full, including the protocol (http or https).", "rationale": "Protocols make URLs unambiguous.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["protocol", "http", "https"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_12.URLS.CASE_SENSITIVE", "title": "Preserve URL capitalization", "source_refs": ["CMOS18 §13.12 p780 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Do not change URL capitalization because parts may be case sensitive.", "rationale": "Case changes can break links.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["case sensitivity"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_12.URLS.TRAILING_SLASH", "title": "Preserve trailing slashes in URLs", "source_refs": ["CMOS18 §13.12 p780 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "If a URL ends with a trailing slash, retain it.", "rationale": "Trailing slashes can be part of the resource path.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["trailing slash"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_12.URLS.NO_SPACES", "title": "Keep URLs as continuous strings", "source_refs": ["CMOS18 §13.12 p780 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "URLs should contain no spaces; avoid inserting breaks or spaces inside them.", "rationale": "Spaces break links and hinder copying.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["spaces", "line breaks"], "dependencies": [], "exceptions": ["Use line-break rules if a URL must wrap in print."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_12.URLS.PUNCTUATION_AFTER", "title": "Retain sentence punctuation after URLs", "source_refs": ["CMOS18 §13.12 p780 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Keep sentence punctuation after a URL as you would for any word.", "rationale": "Removing punctuation can break sentence grammar.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["punctuation", "URLs"], "dependencies": [], "exceptions": ["Ensure punctuation is not mistaken as part of the URL."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_12.URLS.NO_SENTENCE_START", "title": "Avoid starting sentences with URLs", "source_refs": ["CMOS18 §13.12 p780 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Do not begin a sentence with a URL; rephrase to move the URL later.", "rationale": "Sentence-initial URLs are hard to read and typeset.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls"], "keywords": ["sentence start", "URLs"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_13.TOOLS.USE_METADATA", "title": "Use citation tools to capture metadata", "source_refs": ["CMOS18 §13.13 p780 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Use citation management tools to capture author, title, and publication data when available.", "rationale": "Tools reduce manual entry errors.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "research"], "keywords": ["citation tools", "metadata"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_13.METADATA.CHECK_FIELDS", "title": "Verify captured citation fields", "source_refs": ["CMOS18 §13.13 p780 (scan p796)"], "category": "citations", "severity": "must", "applies_to": "all", "rule_text": "Verify captured metadata fields against the original source.", "rationale": "Automated exports often contain errors.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "research"], "keywords": ["verification", "metadata"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_13.METADATA.MISSING", "title": "Resolve missing or redundant metadata", "source_refs": ["CMOS18 §13.13 p780 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Check for missing or redundant metadata and correct it in the citation database.", "rationale": "Data errors propagate into manuscripts.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "research"], "keywords": ["missing data", "redundant data"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_13.CITATIONS.REVIEW", "title": "Review inserted citations for formatting errors", "source_refs": ["CMOS18 §13.13 p780 (scan p796)"], "category": "citations", "severity": "must", "applies_to": "all", "rule_text": "After inserting citations, review for incorrect punctuation, capitalization, or missing elements.", "rationale": "Tools do not guarantee correct formatting.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "research"], "keywords": ["review", "formatting"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_13.REPAIR_AT_SOURCE", "title": "Fix errors in the citation database, not only in text", "source_refs": ["CMOS18 §13.13 p780 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Correct errors in the citation tool or database so updates propagate correctly.", "rationale": "Editing only the manuscript can reintroduce errors later.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "research"], "keywords": ["citation database", "propagation"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_13.BACKUPS", "title": "Back up citation data", "source_refs": ["CMOS18 §13.13 p780 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Maintain backups of citation libraries and exported data.", "rationale": "Lost citation data can delay publication.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "research"], "keywords": ["backups"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_13.STRIP_CODES", "title": "Provide plain-text citations when required", "source_refs": ["CMOS18 §13.13 p780 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "If required by the publisher, convert citations to plain text and verify the result.", "rationale": "Hidden field codes can break production workflows.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "research"], "keywords": ["field codes", "plain text"], "dependencies": [], "exceptions": ["Keep a version with codes intact as a backup."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_14.CITE_VERSION", "title": "Cite the version consulted", "source_refs": ["CMOS18 §13.14 p781 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Record the version of a work that was consulted, especially when multiple formats exist.", "rationale": "Different versions may contain variations.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "versions"], "keywords": ["version", "format"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_14.ONLINE.URL_INDICATOR", "title": "Use a URL to indicate online consultation", "source_refs": ["CMOS18 §13.14 p781 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Include a URL when it signals that a work was consulted online.", "rationale": "URLs distinguish online use from print use.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "versions"], "keywords": ["online", "URL"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_14.SAME_URL.FORMATS", "title": "Do not specify format when versions share a URL", "source_refs": ["CMOS18 §13.14 p781 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When PDF and HTML versions share a URL, a separate format note is usually unnecessary.", "rationale": "The URL already identifies the source.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "versions"], "keywords": ["PDF", "HTML"], "dependencies": [], "exceptions": ["Specify format if required by publisher."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_14.DEVICE_SPECIFIC", "title": "Specify device-specific formats", "source_refs": ["CMOS18 §13.14 p781 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When a work is designed for a specific device or application, note the format or device.", "rationale": "Device-specific formats can affect content presentation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "versions"], "keywords": ["device", "format"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_15.ACCESS_DATE.NOT_REQUIRED", "title": "Access dates are usually unnecessary", "source_refs": ["CMOS18 §13.15 p781 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Do not include access dates unless the source lacks a publication or revision date or policy requires them.", "rationale": "Access dates are hard to verify and often unhelpful.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["access date"], "dependencies": [], "exceptions": ["Student work or publisher policy may require them."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_15.ACCESS_DATE.RECORD_ANYWAY", "title": "Record access dates during research", "source_refs": ["CMOS18 §13.15 p781 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Record access dates while researching even if they may not appear in the final citation.", "rationale": "Access dates can be useful if a source is updated later.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["research", "access date"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_15.ACCESS_DATE.PUBLISHER_POLICY", "title": "Follow publisher access-date policy", "source_refs": ["CMOS18 §13.15 p781 (scan p796)"], "category": "citations", "severity": "must", "applies_to": "all", "rule_text": "If a publisher requires access dates, include them.", "rationale": "Publisher requirements are mandatory.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["publisher policy"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_15.ACCESS_DATE.UNVERIFIABLE", "title": "Do not treat access dates as authoritative evidence", "source_refs": ["CMOS18 §13.15 p781 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Access dates are self-reported and should not be treated as verified evidence.", "rationale": "Access dates cannot be independently confirmed.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["access dates", "verification"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_16.REVISION_DATE.WHEN_ONLY_DATE", "title": "Use revision dates only when no publication date exists", "source_refs": ["CMOS18 §13.16 p782 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Include revision dates when they are the only available date or the de facto publication date.", "rationale": "Revision dates can stand in for missing publication dates.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["revision date"], "dependencies": [], "exceptions": ["If both publication and revision dates exist, prefer publication date."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_16.REVISION_DATE.PREFERENCE", "title": "Prefer publication dates over revision dates", "source_refs": ["CMOS18 §13.16 p782 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Use the publication date when available and add a revision date only if needed for clarity.", "rationale": "Publication dates are the primary temporal reference.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["publication date", "revision date"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_16.REVISION_DATE.WIKIS", "title": "Use revision dates for frequently updated sources", "source_refs": ["CMOS18 §13.16 p782 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Include revision dates for wikis or frequently updated sources when they clarify what was consulted.", "rationale": "Dynamic sources change over time.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["wikis", "updated sources"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_16.REVISION_DATE.FORMAT", "title": "Treat revision dates as publication dates when used", "source_refs": ["CMOS18 §13.16 p782 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When a revision date is used as the main date, format it as the publication date in the citation.", "rationale": "Readers need a clear single date for the source.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["revision date", "format"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_17.PRESERVE.NONPUBLISHED", "title": "Preserve copies of non-formally published sources", "source_refs": ["CMOS18 §13.17 p782 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Keep copies of sources that are not formally published, such as web pages or social media posts.", "rationale": "Unpublished sources can disappear or change.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "archiving"], "keywords": ["preservation", "web sources"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_17.PRESERVE.FORMAT_OPTIONS", "title": "Use printouts or screenshots for preservation", "source_refs": ["CMOS18 §13.17 p782 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Preserve sources via printouts, PDFs, or screenshots as appropriate.", "rationale": "A local copy protects against link rot.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "archiving"], "keywords": ["screenshots", "printouts"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_17.ARCHIVE_SERVICES", "title": "Use archiving services for unstable sources", "source_refs": ["CMOS18 §13.17 p782 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Use services like Perma.cc or the Internet Archive to preserve unstable sources.", "rationale": "Archived links provide persistent access.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "archiving"], "keywords": ["archiving", "permanent links"], "dependencies": [], "exceptions": ["Check institutional policies for approved services."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_17.PRESERVE.CRISIS_SOURCES", "title": "Preserve sources that may change during events", "source_refs": ["CMOS18 §13.17 p782 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Preserve sources that report ongoing events, as their content may change over time.", "rationale": "Historical verification requires stable records.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "archiving"], "keywords": ["ongoing events", "changes"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_18.NOTES_BIBLIO.OVERVIEW", "title": "Use numbered notes tied to superscripts", "source_refs": ["CMOS18 §13.18 p782 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In notes-bibliography, use numbered notes that correspond to superscript numbers in the text.", "rationale": "The system depends on a clear text-to-note link.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["notes", "superscript"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_18.NOTES.SENTENCE_STYLE", "title": "Write notes as sentence-style citations", "source_refs": ["CMOS18 §13.18 p782 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Notes are formatted like sentences, with elements separated by commas and parentheses as needed.", "rationale": "Sentence-style notes are the Chicago default.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["notes", "sentence style"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_18.NAMES.NORMAL_ORDER", "title": "Use normal name order in notes", "source_refs": ["CMOS18 §13.18 p782 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In notes, present author names in normal order.", "rationale": "Notes read like sentences rather than index entries.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["author names", "notes"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_18.BIBLIO.SHORTENED_NOTES", "title": "Use shortened notes when a full bibliography exists", "source_refs": ["CMOS18 §13.18 p782 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "If a bibliography includes full details for all sources, use shortened notes after the first full citation.", "rationale": "Short notes reduce repetition while preserving traceability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["shortened notes", "bibliography"], "dependencies": [], "exceptions": ["Works without a bibliography require full first notes."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_18.NO_BIBLIO.FULL_FIRST_NOTE", "title": "Use full notes when no bibliography exists", "source_refs": ["CMOS18 §13.18 p782 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In works without a bibliography, provide full citation details in the first note for each source.", "rationale": "Readers need complete information in the notes.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["full note", "no bibliography"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_18.BIBLIO.INVERT_FIRST_AUTHOR", "title": "Invert the first author name in bibliographies", "source_refs": ["CMOS18 §13.18 p783 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In bibliographies, invert the first-listed author name and separate elements with periods.", "rationale": "Inversion supports alphabetic sorting.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "bibliography"], "keywords": ["inverted names", "bibliography"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_19.ABBREVIATIONS.NOTES", "title": "Use abbreviations in notes for editors and editions", "source_refs": ["CMOS18 §13.19 p783 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In notes, abbreviate editor, translator, volume, and edition terms.", "rationale": "Notes are compact by design.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["abbreviations", "notes"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_19.ABBREVIATIONS.BIBLIO", "title": "Spell out verb forms in bibliographies", "source_refs": ["CMOS18 §13.19 p783 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In bibliographies, spell out verb forms such as edited by or translated by.", "rationale": "Bibliographies favor readability over brevity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "bibliography"], "keywords": ["edited by", "translated by"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_19.ABBREVIATIONS.NOUN_FORMS", "title": "Keep noun abbreviations in bibliographies", "source_refs": ["CMOS18 §13.19 p783 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In bibliographies, noun abbreviations such as ed. and trans. may still be used.", "rationale": "Chicago distinguishes noun and verb forms.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "bibliography"], "keywords": ["noun abbreviations"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_19.ABBREVIATIONS.CONSISTENT", "title": "Use abbreviations consistently within notes and bibliographies", "source_refs": ["CMOS18 §13.19 p783 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Apply abbreviation rules consistently across all notes and bibliography entries.", "rationale": "Inconsistent abbreviation usage looks unprofessional.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "consistency"], "keywords": ["abbreviations", "consistency"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_20.NOTES.PAGE_SPECIFIC", "title": "Use specific page numbers in notes", "source_refs": ["CMOS18 §13.20 p783 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In notes, cite the specific page or pages where the relevant passage appears.", "rationale": "Specific locators allow readers to verify claims.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["page numbers", "notes"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_20.PAGE_RANGE.EN_DASH", "title": "Use an en dash for page ranges", "source_refs": ["CMOS18 §13.20 p783 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Use an en dash to show page ranges in notes and bibliographies.", "rationale": "En dashes are the standard range marker.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["page ranges", "en dash"], "dependencies": [], "exceptions": ["If the platform cannot render en dashes, document the fallback."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_20.BIBLIO.PAGE_RANGE", "title": "Include full article page ranges in bibliographies", "source_refs": ["CMOS18 §13.20 p783 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Bibliographies should include the full page range for journal articles.", "rationale": "Full ranges help locate articles quickly.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "bibliography"], "keywords": ["page range", "articles"], "dependencies": [], "exceptions": ["Books do not require page ranges in bibliographies."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_20.BIBLIO.BOOKS.NO_PAGES", "title": "Do not include page numbers for books in bibliographies", "source_refs": ["CMOS18 §13.20 p784 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Bibliography entries for books should not include page numbers.", "rationale": "Books are cited as whole works in bibliographies.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "bibliography"], "keywords": ["books", "page numbers"], "dependencies": [], "exceptions": ["Chapters in edited volumes may include locators in notes."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_20.LOCATORS.ALTERNATIVES", "title": "Use alternative locators when pages are missing", "source_refs": ["CMOS18 §13.20 p784 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When page numbers are unavailable, use chapter numbers, section headings, paragraph numbers, or descriptive locators.", "rationale": "Readers still need a path to the cited passage.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["locators", "electronic sources"], "dependencies": [], "exceptions": ["Short searchable documents may omit locators."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_20.ELECTRONIC.SHORT_DOCS", "title": "Omit locators for short searchable documents", "source_refs": ["CMOS18 §13.20 p784 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "For short electronic works that are easily searchable, locators may be omitted.", "rationale": "Extra locators may be unnecessary in short documents.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["short documents", "locators"], "dependencies": [], "exceptions": ["Include locators if required by policy."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_21.EXAMPLES.SHORT_FORMS", "title": "Use short forms after full notes", "source_refs": ["CMOS18 §13.21 p784 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Shortened note forms may be used after a source has been fully cited.", "rationale": "Short forms reduce repetition while retaining traceability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["short forms"], "dependencies": [], "exceptions": ["Works without a bibliography need full first notes."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_21.EXAMPLES.BIBLIO_SHORTENED", "title": "Short forms may be used at first mention if a full bibliography exists", "source_refs": ["CMOS18 §13.21 p784 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In works with a full bibliography, shortened notes may be used even at first mention.", "rationale": "The bibliography supplies full publication details.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["short forms", "bibliography"], "dependencies": [], "exceptions": ["Some publishers still require full first notes."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_21.EXAMPLES.CHAPTER14", "title": "Use chapter 14 for expanded examples", "source_refs": ["CMOS18 §13.21 p784 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Refer to chapter 14 for extended citation examples and edge cases.", "rationale": "Chapter 14 contains source-specific formats.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["examples", "chapter 14"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.NOTE_BIBLIO", "title": "Single-author books use normal names in notes and inverted in bibliography", "source_refs": ["CMOS18 §13.22 p784 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "For single-author books, use normal name order in notes and invert the name in the bibliography.", "rationale": "Notes read like sentences while bibliographies sort by surname.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "books"], "keywords": ["single author", "inversion"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.PAGE_IN_NOTES", "title": "Include page numbers in book notes", "source_refs": ["CMOS18 §13.22 p784 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Notes for books should include page numbers for the cited passage.", "rationale": "Specific pages aid verification.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "books"], "keywords": ["page numbers", "notes"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_22.BOOK_SINGLE_AUTHOR.SHORTENED", "title": "Use shortened book citations after first full note", "source_refs": ["CMOS18 §13.22 p784 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "After a full note, use surname plus short title for subsequent book citations.", "rationale": "Short forms reduce repetition.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "books"], "keywords": ["short title"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_22.BOOK_EDITOR_ONLY", "title": "Use ed. or eds. when the editor replaces the author", "source_refs": ["CMOS18 §13.22 p785 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "If a book has an editor in place of an author, include ed. or eds. in the note and bibliography.", "rationale": "Editors must be identified when no author is listed.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "books"], "keywords": ["editor", "eds."], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_22.BOOK_PLACE_OMIT", "title": "Omit place of publication for books", "source_refs": ["CMOS18 §13.22 p785 (scan p796)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Chicago now omits the place of publication in most book citations.", "rationale": "Place of publication rarely adds value.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "books"], "keywords": ["publication place"], "dependencies": [], "exceptions": ["Include place only when required by policy."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_22.BOOK_EDITOR_ONLY.SHORTENED_NO_ED", "title": "Omit ed. in shortened editor-only citations", "source_refs": ["CMOS18 §13.22 p785 (scan p808)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In shortened notes for editor-only books, omit the ed. label.", "rationale": "Short forms keep citations compact.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "books", "editors"], "keywords": ["shortened notes", "editor"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_23.TWO_AUTHORS.NOTES_LIST_BOTH", "title": "List both names in notes for two-author books", "source_refs": ["CMOS18 §13.23 p785 (scan p808)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "For books with two authors or editors, list both names in notes.", "rationale": "Notes should show full author credit for two-name works.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "books"], "keywords": ["two authors", "notes"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_23.TWO_AUTHORS.BIBLIO_INVERT_FIRST", "title": "Invert only the first name in bibliographies for two-author books", "source_refs": ["CMOS18 §13.23 p785 (scan p808)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In bibliographies for two-author or two-editor books, invert only the first listed name.", "rationale": "Chicago uses a single inversion for alphabetic sorting.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "books"], "keywords": ["inverted name", "bibliography"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.NOTES_ET_AL", "title": "Use et al. in notes for books with more than two authors", "source_refs": ["CMOS18 §13.23 p785 (scan p808)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In notes for books with more than two authors or editors, list the first name followed by et al.", "rationale": "Shortened notes remain readable while identifying the source.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "books"], "keywords": ["et al.", "notes"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.BIBLIO_UP_TO_SIX", "title": "List up to six authors in bibliographies", "source_refs": ["CMOS18 §13.23 p785 (scan p808)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In bibliographies, list up to six authors or editors.", "rationale": "Chicago provides full credit up to six names.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "books"], "keywords": ["bibliography", "authors"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_23.MULTI_AUTHORS.BIBLIO_MORE_THAN_SIX", "title": "Use et al. after three names when more than six authors exist", "source_refs": ["CMOS18 §13.23 p785 (scan p808)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When a work has more than six authors or editors, list the first three followed by et al.", "rationale": "This keeps bibliography entries manageable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "books"], "keywords": ["et al.", "bibliography"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_23.NO_BIBLIO.NOTES_UP_TO_SIX", "title": "List up to six authors in full notes when no bibliography exists", "source_refs": ["CMOS18 §13.23 p785 (scan p808)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "If no bibliography is provided, list up to six authors in the first full note.", "rationale": "The first note must carry the full author set.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "books"], "keywords": ["no bibliography", "full note"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_24.AUTHOR_PLUS_EDITOR.NOTES_ABBREVIATE", "title": "Use ed. or trans. in notes for author plus editor or translator", "source_refs": ["CMOS18 §13.24 p786 (scan p808)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When a book has an author plus an editor or translator, abbreviate the role in notes (ed., trans.).", "rationale": "Notes favor compact role markers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "books", "roles"], "keywords": ["editor", "translator"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_24.AUTHOR_PLUS_EDITOR.BIBLIO_SPELL_OUT", "title": "Spell out Edited by or Translated by in bibliographies", "source_refs": ["CMOS18 §13.24 p786 (scan p808)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In bibliographies, spell out Edited by or Translated by for author-plus-editor/translator works.", "rationale": "Bibliographies prioritize clarity over brevity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "books", "roles"], "keywords": ["edited by", "translated by"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.INCLUDE_AUTHOR", "title": "Include chapter author in edited-book citations", "source_refs": ["CMOS18 §13.25 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Citations of chapters in edited books should include the chapter author.", "rationale": "Chapters are authored works within a larger volume.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "chapters"], "keywords": ["chapter author"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.QUOTE_TITLE", "title": "Put chapter titles in quotation marks", "source_refs": ["CMOS18 §13.25 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Chapter titles in edited-book citations should appear in quotation marks.", "rationale": "Chicago distinguishes chapter titles from book titles.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "chapters"], "keywords": ["chapter title", "quotation marks"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.INCLUDE_EDITOR", "title": "Include the editor for edited-book chapters", "source_refs": ["CMOS18 §13.25 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Citations of chapters in edited books should include the editor of the volume.", "rationale": "The editor identifies the container work.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "chapters"], "keywords": ["editor", "edited book"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.IN_BEFORE_BOOK", "title": "Use in before the book title for chapters", "source_refs": ["CMOS18 §13.25 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Precede the edited book title with in when citing a chapter.", "rationale": "The in marker clarifies container vs part.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "chapters"], "keywords": ["in", "container"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.NOTES_PAGE_LOCATOR", "title": "Include a page locator in chapter notes", "source_refs": ["CMOS18 §13.25 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Notes for chapters in edited books should include a page locator.", "rationale": "Notes direct readers to the cited passage.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "chapters"], "keywords": ["page locator", "notes"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_25.CHAPTER_IN_EDITED.BIBLIO_NO_PAGE_RANGE", "title": "Omit chapter page ranges in bibliographies", "source_refs": ["CMOS18 §13.25 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Bibliography entries for chapters in edited books should not include a page range.", "rationale": "Chicago no longer requires chapter ranges in bibliographies.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "chapters"], "keywords": ["bibliography", "page range"], "dependencies": [], "exceptions": ["Include a range if publisher policy requires it."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_VOLUME", "title": "Include journal volume numbers", "source_refs": ["CMOS18 §13.26 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Journal citations should include the volume number.", "rationale": "Volume identifies the journal run.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "journals"], "keywords": ["volume"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_ISSUE", "title": "Include journal issue numbers", "source_refs": ["CMOS18 §13.26 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Journal citations should include the issue number when available.", "rationale": "Issue numbers narrow the source within a volume.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "journals"], "keywords": ["issue number"], "dependencies": [], "exceptions": ["If the journal has no issue numbers, omit them."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_26.JOURNAL.INCLUDE_YEAR", "title": "Include the publication year for journals", "source_refs": ["CMOS18 §13.26 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Journal citations should include the year of publication.", "rationale": "The year anchors the volume and issue.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "journals"], "keywords": ["year"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_26.JOURNAL.TITLE_ITALIC", "title": "Italicize journal titles", "source_refs": ["CMOS18 §13.26 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Journal titles should be italicized in citations.", "rationale": "Italicized container titles distinguish the journal.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "journals"], "keywords": ["journal title", "italics"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_26.JOURNAL.VOLUME_FORMAT", "title": "Place volume numbers after the journal title without punctuation", "source_refs": ["CMOS18 §13.26 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "The volume number follows the italicized journal title in roman type with no intervening punctuation.", "rationale": "This is the standard Chicago format for journal references.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "journals"], "keywords": ["volume format", "roman type"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_26.JOURNAL.NOTES_PAGE_SPECIFIC", "title": "Include specific pages for journal notes", "source_refs": ["CMOS18 §13.26 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Notes for journal articles should include the specific page referenced.", "rationale": "Specific pages support verification.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "journals"], "keywords": ["notes", "page numbers"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_26.JOURNAL.BIBLIO_PAGE_RANGE", "title": "Include full page ranges in journal bibliographies", "source_refs": ["CMOS18 §13.26 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Bibliography entries for journal articles should include the full page range.", "rationale": "Full ranges identify the article scope.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "journals"], "keywords": ["bibliography", "page range"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_26.JOURNAL.PAGE_COLON", "title": "Use a colon before journal page numbers in full citations", "source_refs": ["CMOS18 §13.26 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In full citations, precede journal page numbers with a colon.", "rationale": "The colon separates issue data from page numbers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "journals"], "keywords": ["colon", "page numbers"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_26.JOURNAL.OMIT_MONTH_SEASON", "title": "Omit month or season unless required", "source_refs": ["CMOS18 §13.26 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Month or season details are usually omitted from journal citations unless required.", "rationale": "Volume, issue, and year typically suffice.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "journals"], "keywords": ["month", "season"], "dependencies": [], "exceptions": ["Include month or season when a publisher requires it."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_26.JOURNAL.ONLINE.URL_OR_DOI", "title": "Record a URL or DOI for online journal articles", "source_refs": ["CMOS18 §13.26 p786 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When a journal article is consulted online, record a URL or DOI.", "rationale": "Online access should be traceable to a stable locator.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "journals"], "keywords": ["URL", "DOI"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.TEXT_SUPERSCRIPT", "title": "Set note reference numbers as superscripts in text", "source_refs": ["CMOS18 §13.27 p787 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Note reference numbers in the text should be superscripts.", "rationale": "Superscripts are the Chicago default for note references.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["superscript", "note numbers"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.NOTES_FULL_SIZE", "title": "Use full-size numbers in notes", "source_refs": ["CMOS18 §13.27 p787 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In the notes themselves, note numbers are normally full size rather than superscript.", "rationale": "Notes are formatted like sentences, not text references.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["full size", "notes"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.NOTES_PERIOD", "title": "Follow note numbers with a period", "source_refs": ["CMOS18 §13.27 p787 (scan p809)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In notes, the note number is followed by a period.", "rationale": "The period separates the number from the note text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["period", "notes"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_27.NOTE_NUMBERS.MANUSCRIPT_SUPERSCRIPT_OK", "title": "Superscript note numbers in notes are acceptable in manuscripts", "source_refs": ["CMOS18 §13.27 p787 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In manuscripts, superscript note numbers in the notes are acceptable if produced by word processors.", "rationale": "Chicago allows common manuscript defaults.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["manuscripts", "superscript"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.TEXT_SUPERSCRIPT", "title": "Superscript symbols in text when symbols replace numbers", "source_refs": ["CMOS18 §13.27 p787 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "If symbols replace numbers, set the symbol as a superscript in the text.", "rationale": "Symbols function like note numbers in text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["symbols", "superscript"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.NOTES_FULL_SIZE", "title": "Use full-size symbols in notes", "source_refs": ["CMOS18 §13.27 p787 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When symbols are used for notes, display the symbol at full size in the note.", "rationale": "Notes prioritize readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["symbols", "notes"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.NO_PERIOD", "title": "Do not follow note symbols with a period", "source_refs": ["CMOS18 §13.27 p787 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "In notes, a symbol used for note references should not be followed by a period.", "rationale": "Chicago treats symbols differently from numbers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["symbols", "period"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.CONSISTENT_SPACING", "title": "Keep symbol spacing consistent in notes", "source_refs": ["CMOS18 §13.27 p787 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "If a space follows a note symbol, apply that spacing consistently throughout the notes.", "rationale": "Consistency avoids irregular note formatting.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["symbols", "spacing"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_27.NOTE_SYMBOLS.BASELINE_FALLBACK", "title": "Use baseline symbols when superscripts are hard to read", "source_refs": ["CMOS18 §13.27 p787 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "If superscript symbols are hard to read in a typeface, set them on the baseline in both text and notes.", "rationale": "Legibility is more important than strict superscripting.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["symbols", "legibility"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.CONSECUTIVE", "title": "Number notes consecutively from 1 within each article or chapter", "source_refs": ["CMOS18 §13.28 p788 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Notes should be numbered consecutively beginning with 1 within each article and each chapter.", "rationale": "Consecutive numbering avoids ambiguity across sections.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["consecutive numbering"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.NO_BOOKWIDE_RUN", "title": "Avoid numbering notes across an entire book with divisions", "source_refs": ["CMOS18 §13.28 p788 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Do not number notes across an entire book when the text has internal divisions.", "rationale": "Each chapter should restart numbering.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["chapter restart"], "dependencies": [], "exceptions": ["Books without divisions may use a single sequence."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SYMBOLS_FOR_FEW", "title": "Use symbols when only a few notes are needed", "source_refs": ["CMOS18 §13.28 p788 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When a text has only a handful of notes, symbols may be used instead of numbers.", "rationale": "Symbols are acceptable for very small note counts.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["symbols", "few notes"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SYMBOL_SEQUENCE_STANDARD", "title": "Use a standard symbol sequence when more than one symbol is needed", "source_refs": ["CMOS18 §13.28 p788 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "If multiple symbols are used on the same page, follow a standard symbol sequence.", "rationale": "Standard sequences reduce reader confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["symbol sequence"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.SEPARATE_SYSTEMS", "title": "Keep distinct systems for different note sets", "source_refs": ["CMOS18 §13.28 p788 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When a work uses both symbols and numbers for different note sets, keep the systems distinct.", "rationale": "Separate systems prevent misreading which notes apply.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["symbol", "numbering"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_28.NOTE_SEQUENCE.TABLE_NOTES_SEPARATE", "title": "Handle table notes separately from text notes", "source_refs": ["CMOS18 §13.28 p788 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Notes to tables and other nontext matter are handled independently from text notes.", "rationale": "Table note systems often follow their own conventions.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["table notes"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_29.NOTE_NUMBER.PLACEMENT_END_SENTENCE", "title": "Place note numbers at the end of a sentence or clause", "source_refs": ["CMOS18 §13.29 p788 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Note numbers should generally appear at the end of a sentence or clause.", "rationale": "End placement avoids interrupting the reading flow.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["placement", "end of sentence"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AFTER_QUOTE", "title": "Place note numbers after quotations", "source_refs": ["CMOS18 §13.29 p788 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Note numbers should follow quotations whether they are run in or set as extracts.", "rationale": "The note marks the end of the quoted material.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["quotation", "placement"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AFTER_PUNCTUATION", "title": "Place note numbers after punctuation", "source_refs": ["CMOS18 §13.29 p788 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Note numbers normally follow punctuation marks.", "rationale": "The note refers to the full clause or sentence.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["punctuation"], "dependencies": [], "exceptions": ["The note number precedes a dash."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_29.NOTE_NUMBER.BEFORE_DASH", "title": "Place note numbers before a dash", "source_refs": ["CMOS18 §13.29 p788 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "When a dash is the next punctuation, place the note number before the dash.", "rationale": "Chicago treats the dash as an interruption.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["dash", "placement"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.CITATIONS.S13_29.NOTE_NUMBER.AVOID_MIDCLAUSE", "title": "Avoid mid-clause note numbers when possible", "source_refs": ["CMOS18 §13.29 p788 (scan p810)"], "category": "citations", "severity": "should", "applies_to": "all", "rule_text": "Avoid inserting note numbers in the middle of a clause unless clarity requires it.", "rationale": "Mid-clause notes interrupt reading flow.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "notes"], "keywords": ["mid-clause", "placement"], "dependencies": [], "exceptions": ["When a note applies to a specific phrase."], "status": "active"}
diff --git a/spec/rules/citations/v1_citations_007.ndjson b/spec/rules/citations/v1_citations_007.ndjson
new file mode 100644
index 0000000..7a3ebfe
--- /dev/null
+++ b/spec/rules/citations/v1_citations_007.ndjson
@@ -0,0 +1,10 @@
+{"id":"CMOS.CITATIONS.S13_35.SHORT_FORM.DISTINCT_TITLE","title":"Shortened citations should keep enough of the title to distinguish the work","source_refs":["CMOS18 §13.35 p791 (scan p813)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"In shortened citations, include enough of the title to uniquely identify the work and keep the same title styling (italics or quotes) used in the full citation.","rationale":"Short forms must remain identifiable without the full publication details.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","short_form"],"keywords":["short form","short title","title styling"],"dependencies":[],"exceptions":["If the project uses a standardized abbreviation list, follow that list consistently."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_36.SHORT_FORM.DISAMBIGUATE_AUTHOR","title":"Disambiguate short forms for multiple works by the same author","source_refs":["CMOS18 §13.36 p791 (scan p813)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When citing multiple works by the same author in short form, add a distinguishing element such as a short title, volume, or date to avoid ambiguity.","rationale":"Author-only short forms can collide across multiple works.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","short_form"],"keywords":["short form","disambiguation","same author"],"dependencies":[],"exceptions":["If only one work by the author appears in the notes, a shorter form may be acceptable by policy."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_38.IBID.IMMEDIATE_PRECEDENT","title":"Use ibid only for the immediately preceding citation","source_refs":["CMOS18 §13.38 p793 (scan p815)"],"category":"citations","severity":"warn","applies_to":"all","rule_text":"Use ibid only when the note refers to exactly the same source as the immediately preceding note and no other source intervenes.","rationale":"Ibid becomes ambiguous when notes are reordered or separated.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","ibid"],"keywords":["ibid","immediate precedent"],"dependencies":[],"exceptions":["If a house style mandates ibid, keep notes stable and avoid renumbering."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_39.IBID.LOCATOR_REQUIRED","title":"Add locators when ibid refers to a different passage","source_refs":["CMOS18 §13.39 p793 (scan p815)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When ibid refers to a different page, section, or passage than the immediately preceding note, add the new locator to keep the reference precise.","rationale":"Locators preserve traceability even when ibid is used.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","ibid","locators"],"keywords":["ibid","locator","page number"],"dependencies":[],"exceptions":["If the locator is identical to the preceding note, ibid alone may be allowed by policy."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_40.SHORT_FORM.AVOID_OP_CIT","title":"Avoid op. cit. and loc. cit. in favor of short forms","source_refs":["CMOS18 §13.40 p793 (scan p815)"],"category":"citations","severity":"warn","applies_to":"all","rule_text":"Avoid op. cit. and loc. cit. in modern Chicago-style notes; use short forms or cross-references that remain unambiguous.","rationale":"Latin backreferences are easy to misread and fragile under reflow.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","short_form"],"keywords":["op. cit.","loc. cit.","short form"],"dependencies":[],"exceptions":["If a legacy style requires these forms, document the policy and enforce it consistently."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_45.NOTES.CITATION_FIRST","title":"Place the source citation first when notes include commentary","source_refs":["CMOS18 §13.45 p796 (scan p818)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When a note mixes a source citation with commentary, present the citation first and separate commentary clearly.","rationale":"Readers should find the source quickly before additional discussion.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","notes"],"keywords":["commentary notes","citation order"],"dependencies":[],"exceptions":["If commentary must precede the citation for context, keep the citation visually distinct."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_47.NOTES.SYSTEMS.DONT_MIX","title":"Do not mix footnotes and endnotes for the same note type","source_refs":["CMOS18 §13.47 p796 (scan p818)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"Do not mix footnotes and endnotes for the same kind of note; if both systems are used, label each and keep numbering distinct.","rationale":"Mixed systems confuse readers and complicate navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","notes","endnotes","footnotes"],"keywords":["footnotes","endnotes","numbering"],"dependencies":[],"exceptions":["Critical editions may use separate note streams if clearly labeled."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_48.ENDNOTES.GROUP_BY_CHAPTER","title":"Group endnotes by chapter or section when applicable","source_refs":["CMOS18 §13.48 p797 (scan p819)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When endnotes correspond to chapters or sections, group them under clear chapter or section headings.","rationale":"Grouping helps readers match notes to the correct portion of the text.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","endnotes"],"keywords":["endnotes","chapter notes","grouping"],"dependencies":[],"exceptions":["Short works may use a single endnote list without subheadings."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_52.ENDNOTES.NAVIGATION_CUES","title":"Provide navigation cues for endnotes in long works","source_refs":["CMOS18 §13.52 p800 (scan p822)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"In long works with endnotes, add navigation cues such as chapter numbers, section headings, or note ranges so readers can locate notes efficiently.","rationale":"Navigation cues reduce paging friction in endnote-heavy documents.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","endnotes","navigation"],"keywords":["endnotes","navigation","chapter numbering"],"dependencies":[],"exceptions":["If the format provides interactive note links, headings may be simplified."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_54.AUTHOR_DATE.NOTES.COMMENTARY_ONLY","title":"Keep author-date citations in text and reserve notes for commentary","source_refs":["CMOS18 §13.54 p801 (scan p823)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When author-date citations are used, keep source citations in the text and reference list, and reserve notes for substantive commentary only.","rationale":"Separating citations from commentary keeps the author-date system clear.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","author_date","notes"],"keywords":["author-date","notes","commentary"],"dependencies":[],"exceptions":["If a project requires source notes in addition to author-date citations, document the hybrid policy explicitly."],"status":"active"}
diff --git a/spec/rules/citations/v1_citations_008.ndjson b/spec/rules/citations/v1_citations_008.ndjson
new file mode 100644
index 0000000..b8a1ab6
--- /dev/null
+++ b/spec/rules/citations/v1_citations_008.ndjson
@@ -0,0 +1,12 @@
+{"id":"CMOS.CITATIONS.S13_56.NOTES.DUAL_STREAMS.DISTINCT_LABELS","title":"If two note streams are used, keep them clearly distinct","source_refs":["CMOS18 §13.56 p803 (scan p825)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"If a work uses two different note streams (for example, source notes versus explanatory notes), label each stream clearly and keep numbering distinct so readers can tell which system a note belongs to.","rationale":"Multiple note streams are easy to confuse and can break traceability when notes are renumbered or reformatted.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","notes"],"keywords":["dual notes","note streams","numbering"],"dependencies":[],"exceptions":["If the deliverable mandates a dual-stream apparatus (e.g., critical editions), enforce strong labeling and distinct numbering styles."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_57.NOTES.SEPARATE_SOURCE_VS_COMMENTARY","title":"Separate source notes from discursive commentary when both appear","source_refs":["CMOS18 §13.57 p803 (scan p825)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When notes include both source citations and discursive commentary, keep citation information visually and structurally separate from commentary so the source is easy to locate.","rationale":"Mixed notes slow review and increase the chance that source details are missed.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","notes"],"keywords":["discursive notes","source notes","commentary"],"dependencies":[],"exceptions":["If commentary must precede the source for context, keep the citation clearly demarcated (e.g., after a separator)."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_59.NOTES.MULTI_EDITIONS.CITE_VERSION_USED","title":"When sources have multiple editions or printings, cite the version used","source_refs":["CMOS18 §13.59 p807 (scan p829)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When a cited work exists in multiple editions, translations, or printings, cite the version actually consulted and include enough detail to distinguish it; add original-publication details only when the project requires it.","rationale":"Edition ambiguity makes locators and quotations hard to verify.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","notes","editions"],"keywords":["edition","version consulted","reprint"],"dependencies":[],"exceptions":["If a policy requires always citing both original and consulted edition, document that policy and apply it consistently."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_61.BIBLIOGRAPHY.SCOPE.LABEL_CLEARLY","title":"Label bibliography scope (works cited vs selected) explicitly","source_refs":["CMOS18 §13.61 p807 (scan p829)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"Label the bibliography/reference list to reflect its scope (e.g., works cited only versus a selected bibliography) and apply the same inclusion rule throughout the document.","rationale":"Clear scope prevents reviewers from assuming missing entries are errors (or vice versa).","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["bibliography scope","works cited","selected bibliography"],"dependencies":[],"exceptions":["Some publishers dictate the label regardless of scope; follow the publisher requirement and document any deviations."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_62.BIBLIOGRAPHY.ENTRY_COMPLETENESS.MORE_THAN_SHORT_FORM","title":"Bibliography entries should be complete enough to retrieve sources","source_refs":["CMOS18 §13.62 p808 (scan p830)"],"category":"citations","severity":"must","applies_to":"all","rule_text":"Ensure bibliography entries include enough publication detail to retrieve the source (author, full title, publication facts, and identifiers/URLs when relevant), not merely the shortened information used in subsequent notes.","rationale":"Bibliography entries are the primary lookup surface for verification.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["bibliography entry","retrieval","publication details"],"dependencies":[],"exceptions":["In constrained formats (one-page memos), a shortened bibliography may be allowed if policy explicitly permits it."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_63.BIBLIOGRAPHY.CONSISTENT_ELEMENT_ORDER","title":"Use a consistent element order within bibliography entries","source_refs":["CMOS18 §13.63 p808 (scan p830)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"Within a bibliography, keep the ordering and punctuation of elements consistent for the same source type (e.g., books, chapters, articles), and avoid mixing incompatible entry templates.","rationale":"Inconsistent entry structure causes audit churn and can hide missing fields.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["consistency","entry template","bibliography"],"dependencies":[],"exceptions":["If the bibliography intentionally mixes multiple governing standards (rare), separate them into labeled subsections."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_64.BIBLIOGRAPHY.SUBSECTIONS.CLEAR_HEADINGS","title":"When bibliography entries are subdivided, use clear headings and ordering","source_refs":["CMOS18 §13.64 p809 (scan p831)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"If the bibliography is subdivided (for example, primary vs secondary sources), use clear headings and apply a consistent ordering rule within each subsection.","rationale":"Subsections can improve readability, but only when rules are clear and consistent.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["bibliography subsections","headings","ordering"],"dependencies":[],"exceptions":["Short bibliographies may omit subsections entirely; keep a single ordered list."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_66.BIBLIOGRAPHY.INCLUDE_ONLY_PER_SCOPE","title":"Include bibliography entries according to the declared scope","source_refs":["CMOS18 §13.66 p810 (scan p832)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"Include works in the bibliography according to the declared scope (e.g., cited-only versus selected); do not mix inclusion criteria without an explicit note.","rationale":"Mixed criteria makes it unclear whether omissions or additions are intentional.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["inclusion criteria","scope","bibliography"],"dependencies":[],"exceptions":["If a publisher requires including additional background reading, label that section separately."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_67.BIBLIOGRAPHY.ANNOTATIONS.CONSISTENT_AND_DISTINCT","title":"If using annotated bibliography entries, keep annotations consistent and distinct","source_refs":["CMOS18 §13.67 p812 (scan p834)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"If bibliography entries include annotations, keep the annotation style consistent (length, voice, placement) and visually distinct from the citation itself.","rationale":"Annotations are helpful only when they do not obscure the citation data needed for retrieval.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography","annotations"],"keywords":["annotated bibliography","annotations","format"],"dependencies":[],"exceptions":["If only a few entries are annotated for special reasons, label them as notes rather than mixing styles silently."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_68.BIBLIOGRAPHY.ENTRY_TYPES.NOT_MIXED","title":"Avoid mixing incompatible bibliography entry types for the same source","source_refs":["CMOS18 §13.68 p812 (scan p834)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"For a given source type, avoid mixing incompatible entry forms (for example, sometimes treating a source as a whole book and elsewhere as a chapter) unless the difference is intentional and justified.","rationale":"Inconsistent entry typing makes it hard to reconcile citations against sources.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["entry types","source type","consistency"],"dependencies":[],"exceptions":["If a source is cited both as a whole work and as a specific contribution, ensure both entry forms are correct and distinguishable."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_71.BIBLIOGRAPHY.ALPHABETIZATION.PREFIXES_POLICY","title":"Apply a consistent policy for alphabetizing surnames with prefixes/particles","source_refs":["CMOS18 §13.71 p817 (scan p839)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When alphabetizing bibliography entries, apply a consistent policy for surnames with prefixes or particles (e.g., de, van) and document the choice when ambiguity exists.","rationale":"Prefix handling can change ordering and frustrate lookup if applied inconsistently.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography","sorting"],"keywords":["alphabetize","prefixes","particles"],"dependencies":[],"exceptions":["If the corpus has an authoritative catalog record for name sorting, follow that record consistently."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_72.BIBLIOGRAPHY.SORTING.DIACRITICS_AND_TRANSLITERATION","title":"Sort names with diacritics/transliteration consistently","source_refs":["CMOS18 §13.72 p817 (scan p839)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When sorting bibliography entries, treat diacritics and transliteration consistently according to the chosen system; avoid mixing competing transliterations for the same name.","rationale":"Inconsistent transliteration creates duplicate or misordered entries and complicates verification.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography","sorting"],"keywords":["diacritics","transliteration","sorting"],"dependencies":[],"exceptions":["If the project uses author-preferred spellings that conflict with a single system, document the policy and keep a cross-reference list."],"status":"active"}
diff --git a/spec/rules/citations/v1_citations_009.ndjson b/spec/rules/citations/v1_citations_009.ndjson
new file mode 100644
index 0000000..7ed9898
--- /dev/null
+++ b/spec/rules/citations/v1_citations_009.ndjson
@@ -0,0 +1,8 @@
+{"id":"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_LIST.LENGTH.POLICY","title":"Apply a consistent policy for listing many authors in bibliography entries","source_refs":["CMOS18 §13.77 p820 (scan p842)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When works have many authors, apply a consistent policy for how many names to list before abbreviating (e.g., using an abbreviation like “et al.”) and use the same policy across the bibliography.","rationale":"A consistent author-list policy improves scanability and prevents arbitrary truncation that can hide attribution.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["many authors","et al.","author list"],"dependencies":[],"exceptions":["If a publisher specifies an author-list limit, follow that requirement even if it differs from house defaults."],"status":"active"}
+{"id":"CMOS.CITATIONS.BIBLIOGRAPHY.CORPORATE_AUTHORS.USE_AS_AUTHOR","title":"Treat organizations as authors when they are credited as such","source_refs":["CMOS18 §13.80 p822 (scan p844)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When a work is credited to an organization or group, treat that entity as the author in the bibliography and alphabetize consistently by the chosen form of the name.","rationale":"Corporate authorship is part of the retrieval identity and should not be obscured.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["corporate author","organization","alphabetize"],"dependencies":[],"exceptions":["If the source has both an individual and a corporate author and the style requires one to lead, document the policy and apply it consistently."],"status":"active"}
+{"id":"CMOS.CITATIONS.BIBLIOGRAPHY.NO_AUTHOR.EDITOR_AS_LEAD_WHEN_APPROPRIATE","title":"For works without authors, use editors/translators as lead only when the work is primarily identified that way","source_refs":["CMOS18 §13.83 p824 (scan p846)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"For works without an author, use the title to lead by default; use an editor, translator, or compiler as the lead element only when the work is primarily identified by that person’s role and the policy allows it.","rationale":"Lead-element choices affect how entries are sorted and found.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["no author","editor","translator"],"dependencies":[],"exceptions":["If a catalog record or publisher standard dictates the lead element, follow it consistently."],"status":"active"}
+{"id":"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.SUFFIXES.INCLUDE","title":"Include name suffixes (Jr., III) consistently when they are part of the author’s published name","source_refs":["CMOS18 §13.85 p825 (scan p847)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When an author’s name includes a suffix or generational marker, include it consistently across entries when it appears in the published form or authoritative metadata.","rationale":"Suffixes can distinguish different individuals with the same name and prevent misattribution.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["suffix","Jr.","name disambiguation"],"dependencies":[],"exceptions":["If the corpus standardizes names without suffixes, document that policy and ensure disambiguation still works."],"status":"active"}
+{"id":"CMOS.CITATIONS.BIBLIOGRAPHY.AUTHOR_NAME.PARTICLES.CONSISTENT_FORMAT","title":"Format name particles and compounds consistently","source_refs":["CMOS18 §13.86 p825 (scan p847)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"Format name particles and compound surnames consistently within the bibliography (capitalization, spacing, and whether the particle is treated as part of the sorting key) according to the chosen policy.","rationale":"Inconsistent particle handling breaks ordering and fragments an author’s works across the list.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["particles","compound surnames","sorting"],"dependencies":[],"exceptions":["If an author has a clear preferred form, follow it and document deviations needed for sorting."],"status":"active"}
+{"id":"CMOS.CITATIONS.BIBLIOGRAPHY.CONTRIBUTOR_ROLES.LABEL_CLEARLY","title":"Label contributor roles (editor, translator, compiler) clearly and consistently","source_refs":["CMOS18 §13.87 p826 (scan p848)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When contributors other than the author are listed, label their roles clearly (editor, translator, compiler, etc.) and use consistent abbreviations and placement across entries.","rationale":"Role clarity prevents confusion about authorship and improves retrieval.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["editor","translator","roles"],"dependencies":[],"exceptions":["If the bibliography is constrained to a shortened form, include roles only when they materially affect identification."],"status":"active"}
+{"id":"CMOS.CITATIONS.BIBLIOGRAPHY.MULTIPLE_CONTRIBUTORS.POLICY_CONSISTENT","title":"When multiple contributor roles apply, follow a consistent ordering policy","source_refs":["CMOS18 §13.88 p826 (scan p848)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"If an entry includes multiple contributor roles (e.g., author plus editor, translator, or introducer), follow a consistent ordering and punctuation policy so entries remain comparable.","rationale":"Inconsistent contributor ordering makes similar entries hard to scan and compare.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["multiple roles","ordering","consistency"],"dependencies":[],"exceptions":["If different source types require different templates, keep templates consistent within each type."],"status":"active"}
+{"id":"CMOS.CITATIONS.BIBLIOGRAPHY.GROUP_AUTHORS.SUBUNITS.CONSISTENT","title":"Handle group authors with subunits consistently","source_refs":["CMOS18 §13.89 p826 (scan p848)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When a group author includes subunits (e.g., department, committee), use a consistent form and hierarchy so entries sort predictably and remain retrievable.","rationale":"Group-name variation can create duplicate entries and hide related works.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["group author","subunits","sorting"],"dependencies":[],"exceptions":["If an authoritative publication record specifies a canonical organizational name, follow that form."],"status":"active"}
diff --git a/spec/rules/citations/v1_citations_010.ndjson b/spec/rules/citations/v1_citations_010.ndjson
new file mode 100644
index 0000000..4f2ad9f
--- /dev/null
+++ b/spec/rules/citations/v1_citations_010.ndjson
@@ -0,0 +1,14 @@
+{"id":"CMOS.CITATIONS.S13_92.BIBLIOGRAPHY.BOOKS.CORE_ELEMENTS","title":"Book bibliography entries should include core publication elements","source_refs":["CMOS18 §13.92 p827 (scan p849)"],"category":"citations","severity":"must","applies_to":"all","rule_text":"For books cited in a bibliography, include the core elements needed for retrieval: author/editor, full title, publication place/publisher/date (as applicable), and an identifier when useful.","rationale":"Complete book entries make sources findable and verifiable.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["books","bibliography entry","publication facts"],"dependencies":[],"exceptions":["For archival or unpublished works, substitute the most stable locating information available."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_93.BIBLIOGRAPHY.EDITED_VOLUMES.ROLE_MARKING","title":"Edited-volume bibliography entries should clearly mark contributor roles","source_refs":["CMOS18 §13.93 p828 (scan p850)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When a bibliography entry involves editors, translators, or compilers, make the role explicit and use consistent wording/abbreviations across entries of the same type.","rationale":"Role clarity prevents misattribution and improves matching against source metadata.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["editors","translators","roles"],"dependencies":[],"exceptions":["If the bibliography is intentionally minimized, include roles only when they materially affect identification."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_95.BIBLIOGRAPHY.CHAPTERS.IN_EDITED_COLLECTIONS","title":"Chapters in edited collections should cite both chapter and book details","source_refs":["CMOS18 §13.95 p828 (scan p850)"],"category":"citations","severity":"must","applies_to":"all","rule_text":"For a chapter or contribution within an edited collection, include chapter author/title plus the edited book’s details (editor, book title, publication facts) and a locator such as page range when available.","rationale":"Readers must be able to locate the chapter within the larger work.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["chapter","edited collection","page range"],"dependencies":[],"exceptions":["If the contribution is the entire work (e.g., a single-author monograph), treat it as a book entry instead."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_96.BIBLIOGRAPHY.JOURNAL_ARTICLES.VOLUME_ISSUE_PAGES","title":"Journal article entries should include volume/issue and pages when available","source_refs":["CMOS18 §13.96 p829 (scan p851)"],"category":"citations","severity":"must","applies_to":"all","rule_text":"For journal articles, include journal title, publication year, volume/issue (as applicable), and page range or article identifier; include a DOI when available.","rationale":"Periodical metadata is necessary to retrieve and verify specific articles.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["journal article","volume","DOI"],"dependencies":[],"exceptions":["If the journal uses article numbers instead of pagination, cite the article number and identifier."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_97.BIBLIOGRAPHY.NEWSPAPER_MAGAZINE.DATES","title":"News and magazine entries should include a specific date","source_refs":["CMOS18 §13.97 p829 (scan p851)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"For newspapers, magazines, and similar periodicals, include the specific publication date (and edition information when needed) so the item can be located reliably.","rationale":"Many periodicals reset pagination and titles across issues; date is the primary locator.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["newspaper","magazine","date"],"dependencies":[],"exceptions":["If a stable URL or archive identifier is used instead of a print issue locator, include that identifier and ensure it is durable."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_98.BIBLIOGRAPHY.THESES_DISSERTATIONS.INSTITUTION","title":"Theses and dissertations should cite the granting institution and format","source_refs":["CMOS18 §13.98 p830 (scan p852)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"For theses or dissertations, include author, title, degree type, granting institution, year, and a stable access path or repository identifier when available.","rationale":"Academic works can be hard to retrieve without institution and degree context.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["thesis","dissertation","institution"],"dependencies":[],"exceptions":["If the work is published later as a book or article, cite the published version when that is the one used."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_100.BIBLIOGRAPHY.ONLINE.SOURCE_STABILITY","title":"Online bibliography entries should emphasize stability (identifier, archive, or permalink)","source_refs":["CMOS18 §13.100 p831 (scan p853)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"For online sources, prefer stable identifiers (DOI, repository ID) or a durable permalink/archive; include an access date when required by policy or when content is likely to change.","rationale":"Online citations rot quickly without stability cues.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography","online_sources"],"keywords":["online sources","permalink","access date"],"dependencies":[],"exceptions":["If the source is a stable, versioned archive, an access date may be omitted if the version identifier is captured."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_101.BIBLIOGRAPHY.EBOOKS.EDITION_AND_FORMAT","title":"E-books should record edition/version and a stable access path when relevant","source_refs":["CMOS18 §13.101 p832 (scan p854)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When citing an e-book, capture edition/version details that affect content and include a stable access path or identifier when applicable; avoid retailer-specific ephemeral URLs for publication.","rationale":"E-book editions can differ materially from print, and retailer links often expire.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography","online_sources"],"keywords":["e-book","edition","stability"],"dependencies":[],"exceptions":["If the e-book is accessed through a library platform with a stable record, cite the stable record rather than a session link."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_102.BIBLIOGRAPHY.AUDIOVISUAL.CREDITS","title":"Audio/visual sources should cite the credited creators and release context","source_refs":["CMOS18 §13.102 p833 (scan p855)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"For audio/visual sources (film, video, audio), cite the credited creators needed to identify the work (creator/producer/director as relevant), the title, release year, and a stable platform/edition identifier when applicable.","rationale":"A/V works can share titles; creator and release context disambiguate.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography"],"keywords":["film","video","audio","credits"],"dependencies":[],"exceptions":["If citing a specific recording of a work, include the performer/label/recording date as applicable."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_103.BIBLIOGRAPHY.SOCIAL_MEDIA.ARCHIVE","title":"Social media citations should capture enough context to remain verifiable","source_refs":["CMOS18 §13.103 p835 (scan p857)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"For social media or short-lived posts, capture author/account, platform, date/time, and a stable link or archived snapshot when feasible; avoid relying on feeds or search-result URLs.","rationale":"Ephemeral posts disappear or change; verification requires preserved context.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography","online_sources"],"keywords":["social media","archive","snapshot"],"dependencies":[],"exceptions":["If archiving is not allowed, record the best available metadata and document the limitation."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_104.BIBLIOGRAPHY.PUBLIC_DOCUMENTS.IDENTIFIERS","title":"Public documents should include issuing body and document identifiers","source_refs":["CMOS18 §13.104 p835 (scan p857)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"For public documents (standards, regulations, official reports), include the issuing body, document title, date, and any official identifier or number needed for retrieval.","rationale":"Official documents are often found via identifiers rather than titles alone.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography","public_documents"],"keywords":["public documents","issuing body","identifier"],"dependencies":[],"exceptions":["If a governing citation standard applies (e.g., legal citation), follow it and treat Chicago pointers as contextual."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_105.BIBLIOGRAPHY.REPORTS.ISSUING_BODY_AND_VERSION","title":"Reports should cite the issuing organization and version context","source_refs":["CMOS18 §13.105 p835 (scan p857)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"For reports (whitepapers, technical reports), cite the issuing organization, report title, publication date, and version/edition information when relevant; include a stable URL or identifier for access.","rationale":"Reports are frequently revised; version context prevents mismatches.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography","online_sources"],"keywords":["reports","version","issuing body"],"dependencies":[],"exceptions":["If only a draft exists, label it clearly as a draft and record access details."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_106.BIBLIOGRAPHY.DATASETS.VERSION_AND_PROVENANCE","title":"Datasets should record version/provenance and a durable identifier","source_refs":["CMOS18 §13.106 p836 (scan p858)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When citing datasets, include creator/issuing body, dataset title, version or release date, and a durable identifier or repository record; include access date when required by policy.","rationale":"Dataset contents change over time; version and provenance are essential for reproducibility.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography","online_sources"],"keywords":["dataset","version","repository"],"dependencies":[],"exceptions":["If the dataset is derived from a larger corpus, cite both the derived dataset and the upstream corpus as appropriate."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_108.BIBLIOGRAPHY.PLATFORMS.PERMALINKS_PREFERRED","title":"Prefer permalinks over transient platform URLs in bibliography entries","source_refs":["CMOS18 §13.108 p836 (scan p858)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When a platform offers a permalink or canonical record for an item, prefer that over transient URLs (session links, search URLs) and keep the link format consistent across entries.","rationale":"Stable links reduce breakage during review and future verification.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","bibliography","online_sources"],"keywords":["permalink","canonical URL","stability"],"dependencies":[],"exceptions":["If only a transient URL exists, document the limitation and include an access date if policy requires it."],"status":"active"}
diff --git a/spec/rules/citations/v1_citations_011.ndjson b/spec/rules/citations/v1_citations_011.ndjson
new file mode 100644
index 0000000..4c175d8
--- /dev/null
+++ b/spec/rules/citations/v1_citations_011.ndjson
@@ -0,0 +1,11 @@
+{"id":"CMOS.CITATIONS.S13_111.AUTHOR_DATE.REFERENCE_LIST.REQUIRED","title":"Author-date citations require a matching reference list","source_refs":["CMOS18 §13.111 p837 (scan p859)"],"category":"citations","severity":"must","applies_to":"all","rule_text":"When using author-date citations, provide a reference list (or equivalent) that includes full entries for all sources cited in the text.","rationale":"Without the reference list, author-date citations cannot be resolved for verification.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","author_date"],"keywords":["author-date","reference list","resolution"],"dependencies":[],"exceptions":["Short formats may omit the list only if the deliverable explicitly allows it and the omission is documented."],"status":"active"}
+{"id":"CMOS.CITATIONS.AUTHOR_DATE.SAME_AUTHOR_SAME_YEAR.SUFFIXES","title":"Disambiguate same-author same-year works with letter suffixes","source_refs":["CMOS18 §13.114 p839 (scan p861)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When an author has multiple works in the same year, disambiguate using a consistent letter suffix (e.g., 2020a, 2020b) and keep the suffix consistent between in-text citations and the reference list.","rationale":"Year collisions are common in author-date and must be resolved deterministically.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","author_date"],"keywords":["same year","suffix letters","disambiguation"],"dependencies":[],"exceptions":["If the corpus uses explicit short titles instead of letters for disambiguation, document and apply that policy consistently."],"status":"active"}
+{"id":"CMOS.CITATIONS.AUTHOR_DATE.NO_AUTHOR.TITLE_KEY","title":"For author-date works without an author, use a stable title key consistently","source_refs":["CMOS18 §13.115 p839 (scan p861)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"If a work lacks an author, use a stable title-based key in the author position for author-date citations and ensure the same key leads the reference list entry.","rationale":"A consistent key is required to match citations to the reference list.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","author_date"],"keywords":["no author","title key","reference list"],"dependencies":[],"exceptions":["If the work is best identified by an issuing body, treat the issuing body as the author consistently instead of a title key."],"status":"active"}
+{"id":"CMOS.CITATIONS.AUTHOR_DATE.NO_DATE.POLICY","title":"For undated works, apply a consistent no-date policy","source_refs":["CMOS18 §13.116 p840 (scan p862)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When a source has no publication date, apply a consistent no-date policy (e.g., “n.d.” or an approximate date) and keep it consistent across in-text citations and the reference list.","rationale":"Inconsistent no-date handling breaks matching and sorting.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","author_date"],"keywords":["no date","n.d.","policy"],"dependencies":[],"exceptions":["If the source has a clear revision or access date that stands in for publication date by policy, document the rule."],"status":"active"}
+{"id":"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_AUTHORS.POLICY","title":"Use a consistent policy for multi-author author-date citations","source_refs":["CMOS18 §13.121 p843 (scan p865)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"For multi-author works in author-date citations, apply a consistent policy for how names are shown (full list versus abbreviated forms) and ensure the in-text form still resolves unambiguously to the reference list entry.","rationale":"Inconsistent author rendering increases ambiguity and review friction.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","author_date"],"keywords":["multiple authors","et al.","author-date"],"dependencies":[],"exceptions":["If the publisher mandates a specific abbreviation threshold, follow that requirement."],"status":"active"}
+{"id":"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.CORPORATE_AUTHORS.SHORT_FORM","title":"Corporate-author citations should use a stable short form when needed","source_refs":["CMOS18 §13.122 p843 (scan p865)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When citing corporate authors in text, use a stable short form only if it remains unambiguous, and ensure the reference list entry makes the full organizational name clear.","rationale":"Corporate names can be long; shortening without a stable mapping breaks retrieval.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","author_date"],"keywords":["corporate author","short form","reference list"],"dependencies":[],"exceptions":["If a formal acronym is widely established for the organization, the acronym may be used if defined clearly in the work."],"status":"active"}
+{"id":"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.ENTRY_TEMPLATES.CONSISTENT","title":"Reference list entries should use consistent templates by source type","source_refs":["CMOS18 §13.123 p843 (scan p865)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"Within the reference list, use consistent entry templates for each source type (books, articles, reports, online sources) and avoid mixing incompatible element orders for the same type.","rationale":"Template consistency makes missing or incorrect fields easier to spot.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","author_date"],"keywords":["reference list","templates","consistency"],"dependencies":[],"exceptions":["If multiple governing standards are intentionally used, separate them into labeled subsections."],"status":"active"}
+{"id":"CMOS.CITATIONS.AUTHOR_DATE.IN_TEXT.MULTI_CITATIONS.ORDER_POLICY","title":"When multiple author-date citations appear together, use a consistent ordering policy","source_refs":["CMOS18 §13.125 p845 (scan p867)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When multiple author-date citations are grouped (e.g., in one parenthetical), apply a consistent ordering rule (alphabetical, chronological, or by relevance) and use consistent separators.","rationale":"Ordering consistency reduces ambiguity and aids scanning.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","author_date"],"keywords":["multiple citations","ordering","parenthetical"],"dependencies":[],"exceptions":["If a style guide mandates chronological ordering in a specific discipline, follow that discipline’s convention."],"status":"active"}
+{"id":"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SORTING_STABLE","title":"Sort reference list entries consistently and keep sorting keys stable","source_refs":["CMOS18 §13.126 p845 (scan p867)"],"category":"citations","severity":"must","applies_to":"all","rule_text":"Sort the reference list consistently (typically by author key, then year, then title) and keep sorting keys stable so entries are predictable and easy to locate.","rationale":"Stable sorting is essential for verification workflows and reviewer speed.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","author_date"],"keywords":["sorting","reference list","alphabetical"],"dependencies":[],"exceptions":["If a publisher requires a different sorting order, follow it and document the deviation from house defaults."],"status":"active"}
+{"id":"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.SAME_AUTHOR.ORDER_POLICY","title":"Order multiple reference list entries for the same author consistently","source_refs":["CMOS18 §13.127 p845 (scan p867)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When the reference list contains multiple works by the same author, order them consistently (e.g., by year, then title) and ensure any disambiguation scheme matches the in-text citations.","rationale":"Same-author ordering interacts with suffix letters and lookup behavior.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","author_date"],"keywords":["same author","ordering","reference list"],"dependencies":[],"exceptions":["Chronological ordering may be preferred in some corpora; pick one policy and apply it consistently."],"status":"active"}
+{"id":"CMOS.CITATIONS.AUTHOR_DATE.REFERENCE_LIST.REPEATED_NAMES.POLICY","title":"Apply a consistent policy for repeated author names in author-date reference lists","source_refs":["CMOS18 §13.128 p845 (scan p867)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"In author-date reference lists, apply a consistent policy for how repeated author names are shown (repeated in full versus substituted) and ensure the choice does not reduce clarity or sortability.","rationale":"Repeated-name conventions can confuse readers if applied inconsistently or inappropriately for author-date.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","author_date"],"keywords":["repeated names","policy","author-date"],"dependencies":[],"exceptions":["If the publisher forbids name substitution in author-date reference lists, keep full names on every entry."],"status":"active"}
diff --git a/spec/rules/citations/v1_citations_012.ndjson b/spec/rules/citations/v1_citations_012.ndjson
new file mode 100644
index 0000000..fc75abb
--- /dev/null
+++ b/spec/rules/citations/v1_citations_012.ndjson
@@ -0,0 +1,6 @@
+{"id":"CMOS.CITATIONS.S13_90.TITLE_PUNCTUATION.CHANGES.POLICY_LIMITED","title":"Limit and document punctuation changes in cited titles","source_refs":["CMOS18 §13.90 p827 (scan p849)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"In citations, preserve the title’s original punctuation and wording as given in the source. If a punctuation change is necessary for house style or consistency, apply a single documented policy and keep it consistent across the work.","rationale":"Undocumented title edits create ambiguity and make sources harder to verify.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true"],"keywords":["title","punctuation","normalization","policy"],"dependencies":[],"exceptions":["Minor normalization is acceptable only if it does not change meaning and is applied consistently; when in doubt, keep the original and note the exception."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_91.TITLE_SUBTITLE.SEPARATOR.COLON","title":"Use a colon to separate titles and subtitles in citations","source_refs":["CMOS18 §13.91 p827 (scan p849)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When a work has a title and subtitle, separate them with a colon in the citation, even if the source distinguishes them by typography or line breaks instead of punctuation.","rationale":"A consistent separator makes citations easier to parse and compare.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true"],"keywords":["title","subtitle","colon"],"dependencies":[],"exceptions":["If the source’s title page uses a different separator that is essential to the title’s meaning, preserve the original punctuation and document the choice."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_94.TITLES.TRAILING_PHRASE.PLACEMENT","title":"Treat generic trailing phrases as part of the subtitle in citations","source_refs":["CMOS18 §13.94 p828 (scan p850)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"When a book title ends with a generic trailing phrase (for example, a phrase indicating additional works of the same kind), format the main title as the title proper and treat the trailing phrase as part of the subtitle in the citation, using standard subtitle punctuation.","rationale":"Consistent title/subtitle structure improves readability and avoids accidental title edits.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true"],"keywords":["title","subtitle","trailing phrase"],"dependencies":[],"exceptions":["If the title page’s punctuation is distinctive and must be preserved verbatim, follow the source and document the exception policy."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_99.LONG_TITLES.TRUNCATION.AVOID","title":"Avoid truncating long titles in citations; if truncated, do it transparently","source_refs":["CMOS18 §13.99 p831 (scan p853)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"Do not truncate long titles in citations unless a constrained format requires it. If truncation is unavoidable, ensure the shortened form is clearly indicated (for example with an ellipsis) and does not imply the omitted words were absent in the original.","rationale":"Title truncation can change meaning and complicate source matching.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true"],"keywords":["titles","ellipsis","truncation"],"dependencies":[],"exceptions":["If an external style guide mandates a specific truncation scheme, apply it consistently and document it in the deliverable’s citation policy."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_107.AUTHOR_DATE.REFERENCE_LIST.MULTI_AUTHOR.ORDERING","title":"Keep author ordering consistent for multi-author works in author-date reference lists","source_refs":["CMOS18 §13.107 p836 (scan p858)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"For multi-author works in an author-date reference list, preserve the author order from the source and apply a consistent name-ordering scheme (e.g., invert only the first author for sorting) across all entries.","rationale":"Consistent ordering prevents mismatches between in-text citations and reference list entries.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","author_date"],"keywords":["author-date","reference list","multiple authors"],"dependencies":[],"exceptions":["If a house style limits the displayed author list (e.g., uses et al.), apply the same limit consistently and ensure entries remain uniquely identifiable."],"status":"active"}
+{"id":"CMOS.CITATIONS.S13_110.AUTHOR_DATE.JOURNAL_ARTICLES.CORE_FIELDS","title":"Include journal identifiers consistently in author-date reference list entries","source_refs":["CMOS18 §13.110 p837 (scan p859)"],"category":"citations","severity":"should","applies_to":"all","rule_text":"For journal articles in an author-date reference list, include enough journal identifiers to locate the work reliably (year plus journal title, and the journal’s volume/issue and page or article identifiers as applicable).","rationale":"Journal articles often require multiple identifiers for unambiguous retrieval.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","author_date"],"keywords":["journal articles","volume","issue","page"],"dependencies":[],"exceptions":["If a journal uses article numbers instead of page ranges, use the journal’s scheme consistently and do not invent pages."],"status":"active"}
diff --git a/spec/rules/code/v1_code_003.ndjson b/spec/rules/code/v1_code_003.ndjson
new file mode 100644
index 0000000..16c6f6b
--- /dev/null
+++ b/spec/rules/code/v1_code_003.ndjson
@@ -0,0 +1,24 @@
+{"id":"HOUSE.CODE.BLOCKS.LONG_LINES.AVOID","title":"Avoid very long code lines in published docs","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"md","rule_text":"Avoid very long code lines that will wrap awkwardly or overflow in PDF; prefer formatting or line breaks that preserve meaning.","rationale":"Overflowing code harms readability and can break layout.","enforcement":"lint","autofix":"suggest","autofix_notes":"Warn when code lines exceed a conservative length threshold; suggest wrapping or restructuring.","tags":["code","overflow"],"keywords":["code line length","overflow"],"dependencies":[],"exceptions":["Some identifiers/URLs in code may be inherently long; consider formatting guidance rather than strict wrapping."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.TABS.AVOID","title":"Avoid tabs in code blocks for publication","source_refs":["HOUSE §CODE.BLOCKS p1","HOUSE §CODE.TYPOGRAPHY p2"],"category":"code","severity":"should","applies_to":"md","rule_text":"Avoid tab characters in code blocks for publication; prefer spaces to ensure consistent rendering across environments.","rationale":"Tabs render inconsistently and can break alignment.","enforcement":"lint","autofix":"suggest","autofix_notes":"Warn when a code block contains tab characters; suggest converting to spaces if safe.","tags":["code","whitespace"],"keywords":["tabs","indentation"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.USE_FOR_MULTILINE","title":"Use code blocks for multi-line examples","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Use fenced code blocks for multi-line code examples and preserve exact whitespace.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["code blocks","fences"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.CAPTIONS.EXPLAIN_SNIPPET","title":"Explain what a snippet demonstrates","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Introduce code blocks with a sentence that explains what the snippet demonstrates.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["examples","explanation"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.COMMENTS.MINIMIZE_NOISE","title":"Avoid noisy commentary inside code","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Avoid excessive commentary inside code blocks; keep explanations in prose around the code.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["comments","readability"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.DIFFS.UNIFIED_FORMAT","title":"Use unified diffs for patches","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"When including diffs, prefer unified diff format and ensure it is syntactically valid.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["diff","unified"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.ERRORS.SHOW_FAILURES","title":"Show failure modes when helpful","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"When documenting commands, include failure modes or common errors when it improves operational safety.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["errors","docs"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.FENCES.CLOSE_PROPERLY","title":"Close code fences properly","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Ensure fenced code blocks are properly closed; avoid accidental fence nesting.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["fences","markdown"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.FENCES.LANGUAGE_INFO.SUGGEST","title":"Specify a language for fenced code blocks when useful","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"md","rule_text":"When using fenced code blocks, specify a language identifier when it improves readability and tooling (syntax highlight, copy/paste cues).","rationale":"Language tags improve comprehension and reduce ambiguity.","enforcement":"lint","autofix":"suggest","autofix_notes":"Warn on fenced code blocks with no info string; suggest adding a language when known.","tags":["code","fences"],"keywords":["code fences","language"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.INLINE.USE_FOR_IDENTIFIERS","title":"Use inline code for identifiers","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Use inline code formatting for identifiers, filenames, commands, and small code tokens.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["inline code","identifiers"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.LANGUAGE.CONSISTENT_FENCES","title":"Use consistent fence style","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Use a consistent fence style (``` vs ~~~) across the document.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["code fences","consistency"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.LANGUAGE.NOTATION.CONSISTENT","title":"Keep notation consistent","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Keep code notation consistent (quotes, indentation, naming) within a document.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["notation","consistency"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.LINE_ENDINGS.NORMALIZE","title":"Normalize line endings in code","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Avoid mixing CRLF/LF line endings in code examples; normalize for readability.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["line endings","consistency"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.MONO.FONT.PREFERRED","title":"Render code in monospaced fonts","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Render inline and block code in monospaced fonts for legibility.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["monospace","fonts"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.OUTPUT.DISTINGUISH_FROM_INPUT","title":"Distinguish input vs output","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"When showing command-line sessions, clearly distinguish input commands from output.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["cli","examples"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.OUTPUT.TRUNCATION.LABELED","title":"Label truncated output","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"When output is truncated for brevity, label the truncation so readers know it is incomplete.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["truncation","output"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.PLACEHOLDERS.CLEAR","title":"Use clear placeholders","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Use clear placeholders (e.g., ) rather than realistic-looking secrets in examples.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["placeholders","security"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.REFERENCES.VERSION_PIN","title":"Pin versions in install commands","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"When providing installation commands, pin versions when reproducibility matters.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["versions","reproducibility"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.SECURITY.REDACT_SECRETS","title":"Redact secrets from code examples","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Do not publish secrets (tokens, keys, credentials) in code examples; use placeholders.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["secrets","redaction"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.SHELL.PROMPTS.CONSISTENT","title":"Use consistent prompt conventions","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"If shell prompts are included, use a consistent prompt convention and avoid copying destructive commands without context.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["shell","prompts"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.TABLES.AVOID_FOR_CODE","title":"Avoid tables for code","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Avoid using tables to display code; code blocks preserve formatting better.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["tables","code"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.TYPED_VALUES.DISTINGUISH","title":"Distinguish user input from placeholders","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"In examples, distinguish typed values from placeholders so readers do not paste placeholders verbatim.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["placeholders","docs"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.URLS.IN_CODE.AVOID_WRAPPING","title":"Avoid wrapping URLs in code blocks","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Avoid manual line breaks inside URLs shown in code blocks; prefer a single line or a shortened, labeled form.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["urls","code"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.CODE.WRAPPING.NO_SOFT_HYPHENS","title":"Do not insert soft hyphens into code","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Do not insert soft hyphens or discretionary breaks into code; keep code literal.","rationale":"Code examples must be readable and reproducible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["soft hyphen","code"],"dependencies":[],"exceptions":[],"status":"active"}
diff --git a/spec/rules/code/v1_code_004.ndjson b/spec/rules/code/v1_code_004.ndjson
new file mode 100644
index 0000000..080e2ab
--- /dev/null
+++ b/spec/rules/code/v1_code_004.ndjson
@@ -0,0 +1,20 @@
+{"id":"HOUSE.CODE.BLOCKS.SPLIT_BY_LANGUAGE","title":"Do not mix languages in a single code block","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"If multiple languages or formats appear in an example, split them into separate code blocks with clear labels.","rationale":"Mixed-language blocks reduce readability and tooling support.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["code blocks","language","separation"],"dependencies":[],"exceptions":["Small inline fragments may remain together if the distinction is obvious."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.ELISION.MARKED","title":"Mark omitted lines in code examples","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"When lines are omitted from a code example, mark the omission explicitly (for example, with a comment or ellipsis marker).","rationale":"Unmarked gaps make examples ambiguous and hard to reproduce.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["elision","examples","omissions"],"dependencies":[],"exceptions":["Very short snippets that are complete as shown do not need elision markers."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.NO_PERSONAL_PATHS","title":"Avoid personal paths and usernames in code","source_refs":["HOUSE §CODE.SECURITY p2"],"category":"code","severity":"should","applies_to":"all","rule_text":"Avoid personal paths, usernames, or machine-specific values in examples; use neutral placeholders instead.","rationale":"Personalized paths reduce portability and may leak information.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","security"],"keywords":["paths","usernames","placeholders"],"dependencies":[],"exceptions":["If a real path is required for clarity, label it as an example path."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.PLATFORM.NOTED","title":"Note platform or shell when commands are platform-specific","source_refs":["HOUSE §CODE.SHELL p2"],"category":"code","severity":"should","applies_to":"all","rule_text":"If a command or snippet is platform-specific, state the OS or shell explicitly near the example.","rationale":"Platform clarity prevents misuse and reduces support issues.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","shell"],"keywords":["platform","shell","commands"],"dependencies":[],"exceptions":["When a document is explicitly scoped to one platform, a single global note may suffice."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.PRECONDITIONS.STATED","title":"State prerequisites for runnable code","source_refs":["HOUSE §CODE.EXAMPLES p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"When code requires prerequisites (versions, tools, environment variables), state them before the snippet or in a short setup section.","rationale":"Unstated prerequisites cause reproducibility failures.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["prerequisites","versions","environment"],"dependencies":[],"exceptions":["Trivial examples may omit prerequisites if the context makes them obvious."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.TESTED_OR_MARKED","title":"Mark untested code as pseudo-code","source_refs":["HOUSE §CODE.EXAMPLES p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"If a snippet has not been tested or is illustrative only, label it explicitly as pseudo-code or illustrative.","rationale":"Readers need to know whether code is copy-pasteable.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["pseudo-code","tested","examples"],"dependencies":[],"exceptions":["If a document is clearly a conceptual overview, a single global note may suffice."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.DETERMINISTIC_OUTPUT","title":"Prefer deterministic outputs in examples","source_refs":["HOUSE §CODE.EXAMPLES p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Example outputs should be deterministic; avoid nondeterministic ordering, random values, or timestamps unless they are labeled as sample output.","rationale":"Deterministic examples are easier to verify and trust.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["deterministic","output","examples"],"dependencies":[],"exceptions":["If nondeterminism is the subject, explain the variability and show a representative sample."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.CONFIG.VALID","title":"Configuration examples must be syntactically valid","source_refs":["HOUSE §CODE.EXAMPLES p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Configuration snippets (JSON, YAML, TOML, etc.) should be syntactically valid as shown.","rationale":"Invalid config examples cause immediate runtime errors.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","config"],"keywords":["config","json","yaml"],"dependencies":[],"exceptions":["If a snippet is partial by design, label it as a fragment."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.NO_LINE_NUMBERS","title":"Avoid inline line numbers inside code blocks","source_refs":["HOUSE §CODE.TYPOGRAPHY p2"],"category":"code","severity":"should","applies_to":"all","rule_text":"Avoid embedding manual line numbers inside code blocks unless they are required for discussion or diff context.","rationale":"Inline numbers reduce copy-paste quality and add noise.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","typography"],"keywords":["line numbers","code blocks"],"dependencies":[],"exceptions":["If a line-by-line walkthrough is required, keep numbering consistent and clearly separated."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.NO_SMART_QUOTES","title":"Avoid smart quotes and typographic substitutions in code","source_refs":["HOUSE §CODE.TYPOGRAPHY p2"],"category":"code","severity":"should","applies_to":"all","rule_text":"Do not use smart quotes, em dashes, or other typographic substitutions inside code examples; keep code literal.","rationale":"Typographic substitutions can break code when copied.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","typography"],"keywords":["smart quotes","typography","copy paste"],"dependencies":[],"exceptions":["Explanatory prose outside code blocks may use typographic punctuation."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.INDENTATION.CONSISTENT","title":"Use consistent indentation within a code block","source_refs":["HOUSE §CODE.TYPOGRAPHY p2"],"category":"code","severity":"should","applies_to":"all","rule_text":"Use a consistent indentation width and style within each code block; avoid mixed indentation levels that obscure structure.","rationale":"Consistent indentation improves readability and prevents misinterpretation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","whitespace"],"keywords":["indentation","whitespace","style"],"dependencies":[],"exceptions":["Some formats (e.g., Makefiles) require specific indentation rules; note them if used."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.TRAILING_WHITESPACE.AVOID","title":"Avoid trailing whitespace in code blocks","source_refs":["HOUSE §CODE.TYPOGRAPHY p2"],"category":"code","severity":"should","applies_to":"all","rule_text":"Avoid trailing spaces in code blocks; trailing whitespace can be significant in some formats and looks unedited.","rationale":"Trailing whitespace can change meaning or cause diffs.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","whitespace"],"keywords":["trailing whitespace","code"],"dependencies":[],"exceptions":["If trailing whitespace is meaningful, annotate it explicitly."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.COMMANDS.PROMPT_FREE_COPY","title":"Provide prompt-free command lines when prompts are shown","source_refs":["HOUSE §CODE.SHELL p2"],"category":"code","severity":"should","applies_to":"all","rule_text":"If shell prompts are included in examples, provide a prompt-free version or clearly indicate which parts are user input.","rationale":"Prompt-free commands are easier to copy and less error-prone.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","shell"],"keywords":["shell prompts","copy paste"],"dependencies":[],"exceptions":["If the prompt conveys necessary context (e.g., root vs user), label it clearly."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.ERROR_OUTPUT.LABELED","title":"Label error output distinctly","source_refs":["HOUSE §CODE.SHELL p2"],"category":"code","severity":"should","applies_to":"all","rule_text":"When showing error output, label it clearly as error or stderr so readers can distinguish it from normal output.","rationale":"Clear labeling reduces confusion and misdiagnosis.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","shell"],"keywords":["stderr","errors","output"],"dependencies":[],"exceptions":["Short examples may prefix error lines with a clear marker instead of a label."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.LINE_BREAKS.SEMANTIC_SAFE","title":"Avoid line breaks that change code meaning","source_refs":["HOUSE §CODE.BLOCKS p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Do not insert manual line breaks inside a token or statement when it changes semantics; use line continuation syntax if needed.","rationale":"Meaning-changing line breaks produce broken examples.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["line breaks","semantics","continuation"],"dependencies":[],"exceptions":["If a line break is required by formatting, add an explicit continuation marker for the language."],"status":"active"}
+{"id":"HOUSE.CODE.BLOCKS.DATA.SYNTHETIC_FOR_SENSITIVE","title":"Use synthetic data for sensitive examples","source_refs":["HOUSE §CODE.SECURITY p2"],"category":"code","severity":"should","applies_to":"all","rule_text":"Use synthetic or anonymized data in code examples when real data could expose sensitive information.","rationale":"Protects privacy and reduces security risk.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","security"],"keywords":["synthetic data","privacy"],"dependencies":[],"exceptions":["If real data must be shown for auditability, document the approval and scrub identifiers."],"status":"active"}
+{"id":"HOUSE.CODE.DIFFS.FILE_HEADERS.PRESENT","title":"Include file headers in unified diffs","source_refs":["HOUSE §CODE.DIFFS p2"],"category":"code","severity":"should","applies_to":"all","rule_text":"Unified diffs should include file headers (---/+++ lines) so context is explicit.","rationale":"File headers make patches unambiguous.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","diff"],"keywords":["diffs","file headers"],"dependencies":[],"exceptions":["Inline diffs used only to highlight a single line may omit headers if the file is named nearby."],"status":"active"}
+{"id":"HOUSE.CODE.DIFFS.CONTEXT_LINES.PRESENT","title":"Provide context lines in diffs","source_refs":["HOUSE §CODE.DIFFS p2"],"category":"code","severity":"should","applies_to":"all","rule_text":"Include sufficient context lines in diffs to understand where changes apply.","rationale":"Context reduces patch ambiguity and misapplication.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","diff"],"keywords":["diffs","context"],"dependencies":[],"exceptions":["Very small patches may use minimal context if the file/section is clearly identified."],"status":"active"}
+{"id":"HOUSE.CODE.SHELL.DESTRUCTIVE.WARN","title":"Warn before destructive commands","source_refs":["HOUSE §CODE.SHELL p2"],"category":"code","severity":"must","applies_to":"all","rule_text":"If a command is destructive or irreversible, warn explicitly and provide safer alternatives or confirmation steps.","rationale":"Destructive commands can cause data loss if copied blindly.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","shell"],"keywords":["destructive commands","warnings","safety"],"dependencies":[],"exceptions":["If the entire document is a controlled runbook, ensure warnings are still explicit."],"status":"active"}
+{"id":"HOUSE.CODE.TYPOGRAPHY.UNICODE.MINIMIZE","title":"Use non-ASCII characters in code only when required","source_refs":["HOUSE §CODE.TYPOGRAPHY p2"],"category":"code","severity":"should","applies_to":"all","rule_text":"Use non-ASCII characters in code examples only when required by the domain; otherwise prefer ASCII-safe representations.","rationale":"ASCII-safe code is more portable across tools and fonts.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","typography"],"keywords":["unicode","ascii","portability"],"dependencies":[],"exceptions":["If a system requires Unicode identifiers, call that requirement out explicitly."],"status":"active"}
diff --git a/spec/rules/code/v1_code_005.ndjson b/spec/rules/code/v1_code_005.ndjson
new file mode 100644
index 0000000..bacf64c
--- /dev/null
+++ b/spec/rules/code/v1_code_005.ndjson
@@ -0,0 +1,4 @@
+{"id":"HOUSE.CODE.EXAMPLES.FILE_PATH.LABEL","title":"Label snippets with filenames or paths","source_refs":["HOUSE §CODE.EXAMPLES p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"When a snippet belongs to a specific file, label it with the filename or path so readers know where it applies.","rationale":"File context improves reproducibility.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["filename","path","context"],"dependencies":[],"exceptions":["Single-file documents may omit labels if the context is unambiguous."],"status":"active"}
+{"id":"HOUSE.CODE.EXAMPLES.MULTI_FILE.SEPARATE","title":"Separate multi-file examples into distinct blocks","source_refs":["HOUSE §CODE.EXAMPLES p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"For multi-file examples, use separate code blocks for each file and label them clearly.","rationale":"Separation reduces confusion and copy errors.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["multi-file","code blocks"],"dependencies":[],"exceptions":["Very small multi-file snippets may be combined if clearly annotated."],"status":"active"}
+{"id":"HOUSE.CODE.EXAMPLES.ENV_VARS.DOCUMENT","title":"Document required environment variables","source_refs":["HOUSE §CODE.EXAMPLES p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"Document required environment variables and expected defaults near the example that depends on them.","rationale":"Hidden environment dependencies break reproducibility.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["environment variables","defaults"],"dependencies":[],"exceptions":["If environment variables are defined in a shared setup section, reference it explicitly."],"status":"active"}
+{"id":"HOUSE.CODE.EXAMPLES.ORDERED_STEPS","title":"Present multi-step sequences in order","source_refs":["HOUSE §CODE.EXAMPLES p1"],"category":"code","severity":"should","applies_to":"all","rule_text":"When a command sequence must be executed in order, label steps or separate them clearly to preserve the sequence.","rationale":"Ordered steps prevent misuse.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code"],"keywords":["steps","sequence"],"dependencies":[],"exceptions":["Single-step commands do not require step labels."],"status":"active"}
diff --git a/spec/rules/code/v1_code_006.ndjson b/spec/rules/code/v1_code_006.ndjson
new file mode 100644
index 0000000..a0749e0
--- /dev/null
+++ b/spec/rules/code/v1_code_006.ndjson
@@ -0,0 +1,6 @@
+{"id":"BRING.CODE.MONO_RAGGED_RIGHT","title":"Set monospaced code ragged-right","source_refs":["BRING §2.1.3 p27"],"category":"code","severity":"should","applies_to":"all","rule_text":"Set monospaced or typewriter-style code ragged-right rather than fully justified.","rationale":"Monospaced text looks uneven when forced into full justification.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","ragged_right"],"keywords":["monospaced","ragged right","code blocks"],"dependencies":[],"exceptions":["If a code listing must be justified for a specific style guide, document the exception."],"status":"active"}
+{"id":"BRING.CODE.RAG.NO_MIN_LINE","title":"Avoid minimum line-length constraints in ragged code","source_refs":["BRING §2.1.3 p27"],"category":"code","severity":"should","applies_to":"all","rule_text":"Do not enforce a minimum line length when setting ragged code; allow natural variation in line endings.","rationale":"Forced minimums create artificial ripples in the rag.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","ragged_right"],"keywords":["rag","line length","code"],"dependencies":[],"exceptions":["Extremely narrow measures may require a minimum to prevent excessive short lines."],"status":"active"}
+{"id":"BRING.CODE.RAG.NO_AUTO_HYPHENATION","title":"Disable automatic hyphenation in code blocks","source_refs":["BRING §2.1.3 p27"],"category":"code","severity":"should","applies_to":"all","rule_text":"Do not allow automatic hyphenation in code blocks; break only at explicit hyphens or by manual intervention.","rationale":"Hyphenation changes literal code and confuses copy/paste.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","hyphenation"],"keywords":["code","hyphenation","ragged"],"dependencies":[],"exceptions":["If a code font lacks required glyphs, replace the font rather than hyphenating."],"status":"active"}
+{"id":"BRING.CODE.RAG.FIXED_WORD_SPACES","title":"Use fixed word spaces in ragged code","source_refs":["BRING §2.1.3 p27"],"category":"code","severity":"should","applies_to":"all","rule_text":"Use fixed word spaces for monospaced code and avoid stretching or shrinking spaces to refine the rag.","rationale":"Variable spacing breaks code alignment and readability.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","spacing"],"keywords":["fixed spaces","code alignment"],"dependencies":[],"exceptions":["If a renderer forces proportional spaces, switch to a true monospaced font."],"status":"active"}
+{"id":"BRING.CODE.RAG.NO_LETTERSPACING","title":"Avoid letterspacing in code blocks","source_refs":["BRING §2.1.3 p27"],"category":"code","severity":"should","applies_to":"all","rule_text":"Do not apply letterspacing or tracking adjustments to monospaced code blocks.","rationale":"Letterspacing disrupts code alignment and scanning.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","tracking"],"keywords":["letterspacing","tracking","code"],"dependencies":[],"exceptions":["If a font renders too tightly, use a different mono font rather than tracking."],"status":"active"}
+{"id":"BRING.CODE.RAG.AVOID_FAKE_JUSTIFY","title":"Avoid typewriter-style justification","source_refs":["BRING §2.1.3 p27"],"category":"code","severity":"should","applies_to":"all","rule_text":"Do not justify monospaced code to imitate typeset text; keep it true to typewriter-style spacing.","rationale":"Justified mono code looks forced and reduces legibility.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","code","justification"],"keywords":["justification","monospaced","code"],"dependencies":[],"exceptions":["None."],"status":"active"}
diff --git a/spec/rules/editorial/v1_editorial_001.ndjson b/spec/rules/editorial/v1_editorial_001.ndjson
new file mode 100644
index 0000000..dcc6e8a
--- /dev/null
+++ b/spec/rules/editorial/v1_editorial_001.ndjson
@@ -0,0 +1,53 @@
+{"id":"HOUSE.EDITORIAL.PLACEHOLDERS.NO_TODO_FIXME","title":"Remove TODO/FIXME markers before publishing","source_refs":["HOUSE §EDITORIAL.PLACEHOLDERS p1"],"category":"editorial","severity":"must","applies_to":"md","rule_text":"Do not ship documents with TODO or FIXME markers in prose; resolve or remove them before publication.","rationale":"Draft markers signal incomplete work.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["editorial","placeholders"],"keywords":["TODO","FIXME","draft"],"dependencies":[],"exceptions":["Allowed inside fenced code examples when the marker is part of the example."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.PLACEHOLDERS.NO_TBD_TKTK","title":"Remove TBD/TKTK placeholders before publishing","source_refs":["HOUSE §EDITORIAL.PLACEHOLDERS p1"],"category":"editorial","severity":"must","applies_to":"md","rule_text":"Do not ship documents with TBD or TKTK placeholders; replace with concrete content or remove.","rationale":"Placeholders undermine credibility.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["editorial","placeholders"],"keywords":["TBD","TKTK","placeholder"],"dependencies":[],"exceptions":["Allowed inside fenced code examples when the marker is part of the example."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.PLACEHOLDERS.NO_LOREM_IPSUM","title":"Avoid lorem ipsum placeholder text","source_refs":["HOUSE §EDITORIAL.PLACEHOLDERS p1"],"category":"editorial","severity":"should","applies_to":"md","rule_text":"Avoid lorem ipsum (or similar filler text) in documents intended for review or publication.","rationale":"Filler text hides missing content.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["editorial","placeholders"],"keywords":["lorem ipsum","filler","placeholder"],"dependencies":[],"exceptions":["If discussing placeholder text explicitly, label the section clearly."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.PLACEHOLDERS.NO_REVIEW_NOTES_INLINE","title":"Do not leave reviewer notes inline in the final output","source_refs":["HOUSE §EDITORIAL.PLACEHOLDERS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Remove inline reviewer notes (e.g., questions to self, review-only callouts) from the published output; move decisions into the text or a change log.","rationale":"Inline notes confuse readers and leak process.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","placeholders"],"keywords":["review notes","comments","draft"],"dependencies":[],"exceptions":["Internal drafts may keep reviewer notes; do not publish them externally."],"status":"active"}
+
+{"id":"HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.PRESENT","title":"Include a single H1 title","source_refs":["HOUSE §EDITORIAL.STRUCTURE p1"],"category":"editorial","severity":"should","applies_to":"md","rule_text":"Include an H1 title for the document so exports have a clear, stable title.","rationale":"A title improves navigation and traceability.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["editorial","structure"],"keywords":["title","H1","heading"],"dependencies":[],"exceptions":["Very short memos may use a first-line title format if agreed by the profile."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.SINGLE","title":"Avoid multiple H1 titles","source_refs":["HOUSE §EDITORIAL.STRUCTURE p1"],"category":"editorial","severity":"should","applies_to":"md","rule_text":"Use only one H1 title per document; use H2+ for sections.","rationale":"Multiple top-level titles confuse structure.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["editorial","structure"],"keywords":["multiple H1","title","structure"],"dependencies":[],"exceptions":["Collections may use a wrapper page; keep the exported unit to one title."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.EARLY","title":"Place the title near the top","source_refs":["HOUSE §EDITORIAL.STRUCTURE p1"],"category":"editorial","severity":"should","applies_to":"md","rule_text":"Place the H1 title at the start of the document or immediately after a brief metadata block.","rationale":"Early titles improve scanability.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["editorial","structure"],"keywords":["title placement","frontmatter","H1"],"dependencies":[],"exceptions":["Cover pages may precede the title when the profile supports it."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.STRUCTURE.SUMMARY.EARLY","title":"Provide an early summary for long documents","source_refs":["HOUSE §EDITORIAL.STRUCTURE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"For long or decision-bearing documents, include a short summary near the start (what, why, decisions, next steps).","rationale":"Summaries reduce review time.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","structure"],"keywords":["summary","executive summary","decisions"],"dependencies":[],"exceptions":["Short notes may skip a summary if the first section is already concise."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.STRUCTURE.SCOPE.STATED","title":"State scope and non-goals","source_refs":["HOUSE §EDITORIAL.STRUCTURE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"State the scope and (when helpful) explicit non-goals so readers know what is included and excluded.","rationale":"Clear scope prevents misinterpretation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","structure"],"keywords":["scope","non-goals","assumptions"],"dependencies":[],"exceptions":["Some narrative documents may embed scope implicitly; ensure it is still clear."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.STRUCTURE.AUDIENCE.STATED","title":"Make the intended audience explicit","source_refs":["HOUSE §EDITORIAL.STRUCTURE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Make the intended audience explicit (operators, reviewers, executives, developers) and write to that audience’s constraints.","rationale":"Audience clarity improves tone and depth.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","structure"],"keywords":["audience","tone","assumptions"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.EDITORIAL.STRUCTURE.DECISIONS.EXPLICIT","title":"Write decisions explicitly","source_refs":["HOUSE §EDITORIAL.STRUCTURE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"When a document contains decisions, write them explicitly (what was decided, by whom, when, and why) rather than implying them.","rationale":"Explicit decisions reduce operational ambiguity.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","structure"],"keywords":["decisions","accountability","rationale"],"dependencies":[],"exceptions":["Exploratory notes may mark decisions as pending."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.STRUCTURE.ACTION_ITEMS.EXPLICIT","title":"List action items with owners and dates","source_refs":["HOUSE §EDITORIAL.STRUCTURE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"When assigning work, list action items with an owner and a target date (or an explicit ‘no date’ rationale).","rationale":"Action items without owners/dates are often dropped.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","structure"],"keywords":["action items","owners","deadlines"],"dependencies":[],"exceptions":["If no owner exists yet, label it explicitly as unassigned."],"status":"active"}
+
+{"id":"HOUSE.EDITORIAL.HEADINGS.NO_TRAILING_PUNCTUATION","title":"Avoid trailing punctuation in headings","source_refs":["HOUSE §EDITORIAL.HEADINGS p1"],"category":"editorial","severity":"should","applies_to":"md","rule_text":"Avoid ending headings with punctuation (especially periods and colons) unless the heading is intentionally a question.","rationale":"Trailing punctuation adds visual noise.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["editorial","headings"],"keywords":["headings","punctuation","titles"],"dependencies":[],"exceptions":["Headings that are questions may end with a question mark."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.HEADINGS.AVOID_ALL_CAPS","title":"Avoid ALL CAPS headings in prose documents","source_refs":["HOUSE §EDITORIAL.HEADINGS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Avoid ALL CAPS headings in prose documents; use normal capitalization for readability.","rationale":"All caps reduces readability.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["editorial","headings"],"keywords":["all caps","headings","readability"],"dependencies":[],"exceptions":["Short labels in UI-like docs may use caps when consistent with the domain."],"status":"active"}
+
+{"id":"HOUSE.EDITORIAL.LISTS.AVOID_SINGLE_ITEM","title":"Avoid single-item lists","source_refs":["HOUSE §EDITORIAL.LISTS p1"],"category":"editorial","severity":"warn","applies_to":"md","rule_text":"Avoid single-item lists; convert to a sentence or add the missing parallel items.","rationale":"Single-item lists often signal incomplete structure.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["editorial","lists"],"keywords":["single-item list","lists","structure"],"dependencies":[],"exceptions":["A single bullet can be acceptable for emphasis when intentional."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.LISTS.PARALLEL_STRUCTURE","title":"Use parallel structure in list items","source_refs":["HOUSE §EDITORIAL.LISTS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Write list items in parallel grammatical form (e.g., all verb phrases or all noun phrases).","rationale":"Parallelism improves scanability.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","lists"],"keywords":["parallel structure","lists","scanability"],"dependencies":[],"exceptions":["If parallelism is impossible, split the list into smaller lists by type."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.LISTS.ORDERED_ONLY_WHEN_ORDERED","title":"Use ordered lists only when order matters","source_refs":["HOUSE §EDITORIAL.LISTS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Use ordered lists only when sequence is meaningful (steps, priority); otherwise use unordered lists.","rationale":"Correct list types improve comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","lists"],"keywords":["ordered lists","steps","priority"],"dependencies":[],"exceptions":["Numbered lists may be required by standards; follow the governing standard."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.LISTS.PUNCTUATION.CONSISTENT","title":"Keep list punctuation consistent","source_refs":["HOUSE §EDITORIAL.LISTS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Within a list, keep punctuation consistent (either all fragments without periods or all full sentences with periods).","rationale":"Consistency reduces editorial noise.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","lists"],"keywords":["list punctuation","periods","consistency"],"dependencies":[],"exceptions":["Lists mixing fragments and sentences should usually be rewritten."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.LISTS.AVOID_DEEP_NESTING","title":"Avoid overly deep list nesting","source_refs":["HOUSE §EDITORIAL.LISTS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Avoid deep list nesting; if nesting goes beyond two levels, consider restructuring into sections or tables.","rationale":"Deep nesting is hard to follow in PDF.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","lists"],"keywords":["nested lists","structure","readability"],"dependencies":[],"exceptions":["Legal or standards text may require deep nesting; keep indentation consistent."],"status":"active"}
+
+{"id":"HOUSE.EDITORIAL.CLARITY.ONE_IDEA_PER_PARAGRAPH","title":"Keep paragraphs focused on one idea","source_refs":["HOUSE §EDITORIAL.CLARITY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Keep paragraphs focused on a single idea; split long paragraphs when they mix multiple topics.","rationale":"Focused paragraphs improve comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","clarity"],"keywords":["paragraphs","focus","structure"],"dependencies":[],"exceptions":["Narrative writing may use long paragraphs intentionally; ensure clarity."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CLARITY.AVOID_AMBIGUOUS_PRONOUNS","title":"Avoid ambiguous pronouns","source_refs":["HOUSE §EDITORIAL.CLARITY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Avoid ambiguous pronouns (it, this, that, they) when the referent could be unclear; repeat the noun or rewrite.","rationale":"Ambiguity causes misreading.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","clarity"],"keywords":["pronouns","ambiguity","clarity"],"dependencies":[],"exceptions":["Short sentences with an obvious referent may be fine."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CLARITY.DEFINE_JARGON_ON_FIRST_USE","title":"Define jargon and uncommon terms on first use","source_refs":["HOUSE §EDITORIAL.CLARITY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Define jargon and uncommon terms on first use, or link to a glossary/definition section.","rationale":"Definitions lower the cost of entry for readers.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","clarity"],"keywords":["jargon","definitions","glossary"],"dependencies":[],"exceptions":["Widely-known terms for the declared audience may not need definition."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CLARITY.AVOID_METACOMMENTARY","title":"Avoid metacommentary like 'as mentioned above'","source_refs":["HOUSE §EDITORIAL.CLARITY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Avoid metacommentary (e.g., 'as mentioned above'); use explicit references (section titles, links) or rewrite to be self-contained.","rationale":"Metacommentary breaks when documents are rearranged.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","clarity"],"keywords":["metacommentary","above/below","self-contained"],"dependencies":[],"exceptions":["If unavoidable, use stable anchors or section identifiers."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CLARITY.EDIT_FOR_BREVITY","title":"Edit for brevity without losing meaning","source_refs":["HOUSE §EDITORIAL.CLARITY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Prefer concise phrasing; remove redundant sentences and filler words while preserving meaning and necessary nuance.","rationale":"Brevity improves review speed.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","clarity"],"keywords":["brevity","redundancy","editing"],"dependencies":[],"exceptions":["Legal and compliance text may require explicit repetition; follow requirements."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CLARITY.AVOID_WEASEL_WORDS","title":"Avoid weasel words and ungrounded certainty","source_refs":["HOUSE §EDITORIAL.CLARITY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Avoid weasel words (e.g., 'clearly', 'obviously') and ungrounded certainty; provide evidence, quantify, or soften appropriately.","rationale":"Unsupported claims reduce trust.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","clarity"],"keywords":["weasel words","certainty","evidence"],"dependencies":[],"exceptions":["When stating a proven fact, cite the proof or standard."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CLARITY.AVOID_DOUBLE_NEGATIVES","title":"Avoid double negatives in instructions","source_refs":["HOUSE §EDITORIAL.CLARITY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Avoid double negatives in instructions and requirements; rewrite to a direct positive requirement when possible.","rationale":"Double negatives cause errors.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","clarity"],"keywords":["double negatives","requirements","instructions"],"dependencies":[],"exceptions":["Quoted requirements may keep original wording; consider annotating with a clearer paraphrase."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CLARITY.EXAMPLES_WHEN_COMPLEX","title":"Use examples for complex procedures","source_refs":["HOUSE §EDITORIAL.CLARITY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"When procedures are complex or error-prone, include a small example (input/output, command, or sample data) to reduce ambiguity.","rationale":"Examples reduce misinterpretation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","clarity"],"keywords":["examples","procedures","clarity"],"dependencies":[],"exceptions":["If examples risk leaking secrets, use synthetic placeholders."],"status":"active"}
+
+{"id":"HOUSE.EDITORIAL.TONE.PROFESSIONAL_AND_RESPECTFUL","title":"Keep tone professional and respectful","source_refs":["HOUSE §EDITORIAL.TONE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Keep tone professional and respectful; avoid insults, sarcasm, or adversarial phrasing in publishable documents.","rationale":"Tone affects trust and adoption.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","tone"],"keywords":["tone","professional","respect"],"dependencies":[],"exceptions":["Direct incident reports may use firm language; keep it factual."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.TONE.INCLUSIVE_LANGUAGE","title":"Use inclusive language","source_refs":["HOUSE §EDITORIAL.TONE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Use inclusive language where feasible; avoid unnecessary gendering and avoid terms widely recognized as derogatory.","rationale":"Inclusive writing broadens accessibility.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","tone"],"keywords":["inclusive language","accessibility","audience"],"dependencies":[],"exceptions":["Quoted historical material may retain original wording; annotate if needed."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.TONE.AVOID_EXCESSIVE_EMPHASIS","title":"Avoid excessive emphasis styling","source_refs":["HOUSE §EDITORIAL.TONE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Avoid excessive emphasis (all caps, repeated exclamation points, excessive bolding); rely on structure and evidence instead.","rationale":"Over-emphasis reads as unprofessional.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","tone"],"keywords":["emphasis","all caps","exclamation"],"dependencies":[],"exceptions":["Short warnings may use strong emphasis when safety-critical."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.TONE.CALIBRATE_CERTAINTY","title":"Calibrate certainty to evidence","source_refs":["HOUSE §EDITORIAL.TONE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Calibrate certainty to evidence: use ‘must’/‘will’ only for guarantees, and use ‘may’/‘typically’ when describing tendencies.","rationale":"Precision prevents overpromising.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","tone"],"keywords":["certainty","guarantees","precision"],"dependencies":[],"exceptions":["Normative specifications may use MUST/SHALL as defined by the standard."],"status":"active"}
+
+{"id":"HOUSE.EDITORIAL.CLAIMS.SUPPORT_WITH_SOURCES","title":"Support factual claims with sources or evidence","source_refs":["HOUSE §EDITORIAL.CLAIMS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Support factual or quantitative claims with citations, data, or a reproducible method; avoid unsupported assertions.","rationale":"Evidence increases trust and auditability.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","claims"],"keywords":["claims","evidence","citations"],"dependencies":[],"exceptions":["Widely-known facts may omit citations, but be conservative in formal outputs."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CLAIMS.DISTINGUISH_FACT_OPINION","title":"Distinguish facts from opinions and proposals","source_refs":["HOUSE §EDITORIAL.CLAIMS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Distinguish factual reporting from opinion or proposals; label recommendations and assumptions explicitly.","rationale":"Clear framing avoids misreading.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","claims"],"keywords":["facts","opinions","recommendations"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CLAIMS.QUANTIFY_WHEN_POSSIBLE","title":"Quantify when it matters","source_refs":["HOUSE §EDITORIAL.CLAIMS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"When describing performance, risk, or scale, quantify (numbers, ranges) when possible and state the measurement conditions.","rationale":"Quantification prevents vague conclusions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","claims"],"keywords":["quantify","metrics","ranges"],"dependencies":[],"exceptions":["If quantification is impossible, say why and what proxy was used."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CLAIMS.AVOID_ABSOLUTES","title":"Avoid absolute claims unless you can prove them","source_refs":["HOUSE §EDITORIAL.CLAIMS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Avoid absolute claims (always, never, impossible) unless you can prove them or you are stating a defined invariant.","rationale":"Absolutes are easy to falsify.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","claims"],"keywords":["absolute claims","always","never"],"dependencies":[],"exceptions":["Security policies may use absolutes as requirements when enforced."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CLAIMS.BASELINE_FOR_COMPARISONS","title":"Define the baseline for comparisons","source_refs":["HOUSE §EDITORIAL.CLAIMS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"When comparing (faster, cheaper, safer), define the baseline and what is being compared; avoid ‘better’ without context.","rationale":"Comparisons require context to be meaningful.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","claims"],"keywords":["baseline","comparisons","context"],"dependencies":[],"exceptions":[],"status":"active"}
+
+{"id":"HOUSE.EDITORIAL.CONSISTENCY.TERMINOLOGY.STABLE","title":"Use stable terminology for the same concept","source_refs":["HOUSE §EDITORIAL.CONSISTENCY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Use the same term for the same concept throughout; avoid switching between synonyms unless you are deliberately distinguishing concepts.","rationale":"Terminology drift confuses readers.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","consistency"],"keywords":["terminology","consistency","definitions"],"dependencies":[],"exceptions":["If renaming is necessary, note the equivalence explicitly."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CONSISTENCY.CAPITALIZATION.STABLE","title":"Keep capitalization consistent for defined terms","source_refs":["HOUSE §EDITORIAL.CONSISTENCY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Keep capitalization consistent for defined terms, product names, and headings; do not alternate between forms without intent.","rationale":"Inconsistent casing looks unedited.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","consistency"],"keywords":["capitalization","defined terms","consistency"],"dependencies":[],"exceptions":["Quoted brand styling may preserve original casing; note it."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CONSISTENCY.SPELLING_VARIANT.CHOOSE_ONE","title":"Choose one spelling variant (US/UK) per document","source_refs":["HOUSE §EDITORIAL.CONSISTENCY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Choose one spelling variant (US/UK) per document unless the audience or quoted material requires mixing; keep it consistent.","rationale":"Mixed spelling distracts reviewers.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","consistency"],"keywords":["spelling","US/UK","locale"],"dependencies":[],"exceptions":["Proper names preserve their original spelling."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CONSISTENCY.TIMEZONE.EXPLICIT","title":"Make time zones explicit for operational times","source_refs":["HOUSE §EDITORIAL.CONSISTENCY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"For operational times (maintenance windows, incidents), specify a time zone or use UTC; avoid ambiguous local times.","rationale":"Ambiguous times cause outages.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","consistency"],"keywords":["time zone","UTC","timestamps"],"dependencies":[],"exceptions":["Purely local events may use local time if the locale is explicit."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CONSISTENCY.NAMES.SAME_FORM","title":"Use a consistent form for names and identifiers","source_refs":["HOUSE §EDITORIAL.CONSISTENCY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Use a consistent form for names and identifiers (people, systems, projects); avoid switching between nicknames and formal names without explanation.","rationale":"Name drift complicates attribution and search.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","consistency"],"keywords":["names","identifiers","consistency"],"dependencies":[],"exceptions":["If multiple aliases exist, list them once and choose a primary form."],"status":"active"}
+
+{"id":"HOUSE.EDITORIAL.REVIEW.SPELLCHECK_AND_READTHROUGH","title":"Run a final spellcheck and read-through","source_refs":["HOUSE §EDITORIAL.REVIEW p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Before publishing, run a spellcheck and do a final read-through for missing words, repeated words, and obvious grammar issues.","rationale":"Basic errors reduce trust.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","review"],"keywords":["spellcheck","proofread","copyedit"],"dependencies":[],"exceptions":["Time-critical incident updates may publish quickly; follow up with a corrected version."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.REVIEW.FACT_CHECK","title":"Fact-check names, numbers, and dates","source_refs":["HOUSE §EDITORIAL.REVIEW p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Fact-check names, numbers, and dates against authoritative sources; correct typos that change meaning (IDs, ports, versions).","rationale":"Small factual errors can be costly.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","review"],"keywords":["fact-check","numbers","dates"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.EDITORIAL.REVIEW.SENSITIVE_INFO.NO_SECRETS","title":"Remove secrets and sensitive data","source_refs":["HOUSE §EDITORIAL.OPSEC p1"],"category":"editorial","severity":"must","applies_to":"all","rule_text":"Do not publish secrets or sensitive data (tokens, private keys, passwords, internal-only hostnames) in outputs intended for sharing.","rationale":"Leaks create security incidents.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","opsec"],"keywords":["secrets","tokens","private keys"],"dependencies":[],"exceptions":["Red-team/internal documents may include secrets only in controlled systems; never publish externally."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.REVIEW.LINKS.VERIFY","title":"Verify outbound links","source_refs":["HOUSE §EDITORIAL.REVIEW p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Verify outbound links (correct target, stable URL, no tracking params) and prefer durable references where available.","rationale":"Broken links degrade trust.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","review"],"keywords":["links","verification","durability"],"dependencies":[],"exceptions":["Some links may be internal-only; label them clearly as such."],"status":"active"}
diff --git a/spec/rules/editorial/v1_editorial_002.ndjson b/spec/rules/editorial/v1_editorial_002.ndjson
new file mode 100644
index 0000000..8f38320
--- /dev/null
+++ b/spec/rules/editorial/v1_editorial_002.ndjson
@@ -0,0 +1,18 @@
+{"id":"HOUSE.EDITORIAL.STRUCTURE.METADATA.OWNER_DATE","title":"Include owner and last-updated metadata","source_refs":["HOUSE §EDITORIAL.STRUCTURE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"For operational or decision documents, include owner/author and last-updated date near the top.","rationale":"Metadata improves accountability and reduces stale guidance.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","structure"],"keywords":["metadata","owner","date"],"dependencies":[],"exceptions":["If the hosting system provides authoritative metadata, a separate section may be unnecessary."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.STRUCTURE.CHANGELOG.LIVING_DOCS","title":"Maintain a changelog for living documents","source_refs":["HOUSE §EDITORIAL.STRUCTURE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"For documents that evolve over time, maintain a brief changelog or revision history so readers can see what changed.","rationale":"Revision context helps reviewers and operators track changes.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","structure"],"keywords":["changelog","revision history"],"dependencies":[],"exceptions":["If readers rely on version control history and it is easily accessible, a changelog may be redundant."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.STRUCTURE.ASSUMPTIONS.EXPLICIT","title":"State assumptions explicitly","source_refs":["HOUSE §EDITORIAL.STRUCTURE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"State key assumptions explicitly, especially when they affect recommendations or conclusions.","rationale":"Hidden assumptions lead to incorrect decisions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","structure"],"keywords":["assumptions","scope"],"dependencies":[],"exceptions":["If assumptions are obvious and trivial, keep them inline rather than as a dedicated section."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.STRUCTURE.RISKS.MITIGATIONS","title":"List risks and mitigations for proposals","source_refs":["HOUSE §EDITORIAL.STRUCTURE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"When proposing changes or plans, list major risks and proposed mitigations.","rationale":"Risk visibility improves decision quality.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","structure"],"keywords":["risks","mitigations","plans"],"dependencies":[],"exceptions":["Purely descriptive reports may omit a risk section if no actions are proposed."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.STRUCTURE.REFERENCES.WHEN_CITED","title":"Provide a references section when citing sources","source_refs":["HOUSE §EDITORIAL.STRUCTURE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"If the document cites external sources, provide a short references section or consistent citation list.","rationale":"A references section improves verification and reuse.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","structure"],"keywords":["references","citations"],"dependencies":[],"exceptions":["Short memos may use inline citations if they are complete and consistent."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.STRUCTURE.GLOSSARY.WHEN_DENSE","title":"Add a glossary when terminology is dense","source_refs":["HOUSE §EDITORIAL.STRUCTURE p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"If a document uses many specialized terms or abbreviations, add a short glossary or definitions section.","rationale":"A glossary reduces reader friction.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","structure"],"keywords":["glossary","definitions"],"dependencies":[],"exceptions":["If each term is defined inline and used only briefly, a glossary may be unnecessary."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.HEADINGS.CASE.CONSISTENT","title":"Keep heading capitalization consistent","source_refs":["HOUSE §EDITORIAL.HEADINGS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Use a consistent heading capitalization style (sentence case or title case) within the document.","rationale":"Inconsistent casing looks unedited and reduces scanability.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","headings"],"keywords":["heading case","consistency"],"dependencies":[],"exceptions":["Proper nouns and official names should keep their original casing."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.HEADINGS.LENGTH.CONCISE","title":"Keep headings concise","source_refs":["HOUSE §EDITORIAL.HEADINGS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Keep headings concise; long headings should be shortened or turned into a short heading plus a summary sentence.","rationale":"Concise headings improve navigation and visual rhythm.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","headings"],"keywords":["headings","concise"],"dependencies":[],"exceptions":["Regulatory or legal headings may need to remain long; consider a short label in addition."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.HEADINGS.NO_DUPLICATE","title":"Avoid duplicate heading text","source_refs":["HOUSE §EDITORIAL.HEADINGS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Avoid repeating the exact same heading text at the same level; add qualifiers to distinguish sections.","rationale":"Duplicate headings confuse readers and anchors.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","headings"],"keywords":["duplicate headings","anchors"],"dependencies":[],"exceptions":["If duplicate labels are required by a standard, add disambiguating prefixes or numbering."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.HEADINGS.AVOID_GENERIC","title":"Avoid generic headings without context","source_refs":["HOUSE §EDITORIAL.HEADINGS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Avoid headings like Misc or Other without descriptive qualifiers; name the section by its content.","rationale":"Generic headings reduce discoverability and scan value.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","headings"],"keywords":["generic headings","structure"],"dependencies":[],"exceptions":["Appendices may use a generic label if the appendix is clearly scoped."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.LISTS.TASKS.CHECKLIST","title":"Use checklists for actionable task lists","source_refs":["HOUSE §EDITORIAL.LISTS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"When listing actionable tasks, use a checklist format so completion status is clear.","rationale":"Checklists reduce missed actions and improve review clarity.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","lists"],"keywords":["checklists","tasks"],"dependencies":[],"exceptions":["If tasks are already tracked elsewhere, an ordered list may be sufficient with a reference."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.LISTS.ITEMS.ACTIONABLE","title":"Start action items with verbs","source_refs":["HOUSE §EDITORIAL.LISTS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Write action items as verb-led phrases (e.g., Update, Verify, Deploy) to make the action explicit.","rationale":"Verb-led items are easier to scan and execute.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","lists"],"keywords":["action items","verbs"],"dependencies":[],"exceptions":["If a task is already captured as a noun phrase in an external system, keep it but add a verb in parentheses."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CLARITY.ACTIVE_VOICE_INSTRUCTIONS","title":"Prefer active voice in instructions","source_refs":["HOUSE §EDITORIAL.CLARITY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Prefer active voice when giving instructions or requirements; specify the actor to reduce ambiguity.","rationale":"Active voice makes ownership and action clear.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","clarity"],"keywords":["active voice","instructions"],"dependencies":[],"exceptions":["Passive voice is acceptable when the actor is unknown or irrelevant."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CLARITY.DEFINE_METRICS","title":"Define metrics and measurement context","source_refs":["HOUSE §EDITORIAL.CLARITY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Define metrics, units, and measurement context before using them in conclusions or claims.","rationale":"Undefined metrics can be misinterpreted or misapplied.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","clarity"],"keywords":["metrics","units","measurement"],"dependencies":[],"exceptions":["Well-known metrics in a narrow domain may need only a brief reminder."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CLAIMS.SCOPE_TIMEBOUND","title":"Scope claims by time and context","source_refs":["HOUSE §EDITORIAL.CLAIMS p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"When making performance or risk claims, state the time frame and context so the claim is not read as universal.","rationale":"Scoped claims reduce overgeneralization.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","claims"],"keywords":["claims","scope","time"],"dependencies":[],"exceptions":["Definitions or invariant requirements may be stated without a time qualifier."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.CONSISTENCY.DATE_FORMAT.SINGLE","title":"Use one date format consistently","source_refs":["HOUSE §EDITORIAL.CONSISTENCY p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Use a single date format throughout the document (prefer an unambiguous form such as YYYY-MM-DD) unless quoting sources.","rationale":"Mixed date formats cause confusion across locales.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","consistency"],"keywords":["dates","format","consistency"],"dependencies":[],"exceptions":["Quoted material may retain original date formats if clearly attributed."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.REVIEW.CROSS_REFERENCES.VERIFY","title":"Verify cross-references and captions","source_refs":["HOUSE §EDITORIAL.REVIEW p1"],"category":"editorial","severity":"should","applies_to":"all","rule_text":"Verify references to figures, tables, and sections so labels and targets match the content.","rationale":"Broken cross-references undermine trust and navigation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","review"],"keywords":["cross-references","figures","tables"],"dependencies":[],"exceptions":["Short documents without cross-references may skip this step."],"status":"active"}
+{"id":"HOUSE.EDITORIAL.OPSEC.REMOVE_PII","title":"Remove personal data from publishable outputs","source_refs":["HOUSE §EDITORIAL.OPSEC p1"],"category":"editorial","severity":"must","applies_to":"all","rule_text":"Remove personal data (emails, phone numbers, addresses) from publishable outputs unless explicit consent and context are documented.","rationale":"Personal data exposure is a privacy and compliance risk.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","editorial","opsec"],"keywords":["PII","privacy","redaction"],"dependencies":[],"exceptions":["Internal-only documents may include PII if access is restricted and logged."],"status":"active"}
diff --git a/spec/rules/figures/v1_figures_003.ndjson b/spec/rules/figures/v1_figures_003.ndjson
new file mode 100644
index 0000000..e67e3b9
--- /dev/null
+++ b/spec/rules/figures/v1_figures_003.ndjson
@@ -0,0 +1,22 @@
+{"id":"CMOS.FIGURES.ACCESSIBILITY.ALT_TEXT","title":"Provide alternative text where possible","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Provide alternative text or a textual summary for figures when the audience includes screen-reader users.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["alt text","accessibility"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.ASPECT_RATIO.PRESERVE","title":"Preserve aspect ratio","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Do not stretch or distort figures; preserve aspect ratios when scaling.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["aspect ratio","scaling"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.CAPTION.LENGTH.REASONABLE","title":"Keep captions concise","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Keep captions concise; if extensive explanation is needed, move detail into the body text.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["captions","concise"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.CAPTION.PLACEMENT.CONSISTENT","title":"Keep caption placement consistent","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Keep caption placement consistent (above or below) based on the chosen style and profile.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["caption placement","layout"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.CAPTION.PUNCTUATION.CONSISTENT","title":"Use consistent caption punctuation","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Keep caption punctuation, capitalization, and end punctuation consistent across figures.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["captions","punctuation"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.CAPTIONS.PRESENT","title":"Provide captions for figures","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Provide a caption for each figure that explains what the reader should take from it; keep caption style consistent.","rationale":"Captions make figures interpretable without guesswork.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures","captions"],"keywords":["captions","figures"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.COLOR.NOT_SOLE_SIGNAL","title":"Do not rely on color alone","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Do not rely on color alone to convey meaning in figures; use labels, patterns, or annotations.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["color","accessibility"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.CONTRAST.SUFFICIENT","title":"Use sufficient contrast","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Use sufficient contrast in figures so content remains readable in grayscale and for low-vision readers.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["contrast","accessibility"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.CREDIT.SOURCE_WHEN_REQUIRED","title":"Credit sources when required","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Credit the source of third-party figures when required, and record permissions/licensing.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["credits","permissions"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.FILENAME.STABLE","title":"Use stable filenames for figure assets","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Use stable figure filenames and paths to support deterministic builds and avoid broken links.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["filenames","assets"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.FORMAT.VECTOR_WHEN_POSSIBLE","title":"Prefer vector formats for diagrams","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Prefer vector formats for diagrams and charts when possible to avoid raster blur in PDF output.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["vector","svg","pdf"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.LEGENDS.EXPLAIN_SYMBOLS","title":"Explain symbols and legend items","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"If a figure uses symbols, colors, or abbreviations, include a legend or explain them in the caption.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["legend","symbols"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.MARGINS.AVOID_CLIPPING","title":"Avoid clipping at page margins","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Ensure figures do not clip into margins or bleed areas unless the profile explicitly supports bleed.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["margins","clipping"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.NUMBERING.SEQUENTIAL","title":"Number figures sequentially","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Number figures sequentially within the chosen scope (document-wide or per chapter) and do not reuse numbers.","rationale":"Consistent numbering supports cross-references.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures","numbering"],"keywords":["figures","numbering","captions"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.NUMBERING.WITHIN_CHAPTERS","title":"If numbering by chapter, keep prefixes consistent","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"If figure numbering is per chapter (e.g., Figure 3.2), keep the prefixing scheme consistent and reflect it in cross-references.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["chapter numbering","figures"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.PLACEMENT.NEAR_MENTION","title":"Place figures near first mention","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Place figures as close as practical to the text that discusses them, subject to layout constraints.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["placement","layout"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.REFERENCES.IN_TEXT","title":"Refer to figures from the text","source_refs":["CMOS18 §3.1 p120"],"category":"figures","severity":"should","applies_to":"all","rule_text":"When figures carry meaning, refer to them from the text (e.g., “see Figure 2”) so readers know when to consult them.","rationale":"Cross-references prevent orphaned visuals.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures","cross_reference"],"keywords":["cross reference","Figure 1"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.RESOLUTION.RASTER_SUFFICIENT","title":"Use sufficient resolution for raster images","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Use raster images at sufficient resolution for the target medium; avoid upscaled low-res images.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["resolution","images"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.SCALE.LEGIBLE","title":"Ensure figure text is legible","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Ensure any text inside figures remains legible at the target page size; avoid tiny labels that disappear when printed.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["legibility","scale"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.SENSITIVE.DATA.REDACT","title":"Redact sensitive data in figures","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Before publication, ensure figures do not expose secrets, internal hostnames, or personal data; redact as required.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["redaction","privacy"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.TABLE_VS_FIGURE.CHOOSE","title":"Choose table vs figure appropriately","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Use tables for precise lookup and figures for patterns/trends; do not duplicate the same information unnecessarily.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["tables","figures"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FIGURES.UNITS.LABEL_AXES","title":"Label axes and units","source_refs":["CMOS18 §3.1 p120","CMOS18 §3.2 p122"],"category":"figures","severity":"should","applies_to":"all","rule_text":"For charts, label axes and units clearly and consistently.","rationale":"Figures should be interpretable, reproducible, and accessible.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["axes","units"],"dependencies":[],"exceptions":[],"status":"active"}
diff --git a/spec/rules/figures/v1_figures_004.ndjson b/spec/rules/figures/v1_figures_004.ndjson
new file mode 100644
index 0000000..c7b17ed
--- /dev/null
+++ b/spec/rules/figures/v1_figures_004.ndjson
@@ -0,0 +1,28 @@
+{"id": "CMOS.FIGURES.CAPTION.PREFIX.CONSISTENT", "title": "Use a consistent figure label", "source_refs": ["CMOS18 \u00a73.5 p64 (scan p1123)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent label format for figures (e.g., Figure, Fig.) and apply it throughout.", "rationale": "Consistent labels aid cross-references.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["figure label", "prefix"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.CAPTION.NUMBER.MATCH_LABEL", "title": "Match caption numbers to figure labels", "source_refs": ["CMOS18 \u00a73.5 p64 (scan p1123)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Ensure the caption number matches the figure label used in text references.", "rationale": "Mismatched numbering confuses readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures", "numbering"], "keywords": ["captions", "numbering"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.CAPTION.ALIGNMENT.CONSISTENT", "title": "Align captions consistently", "source_refs": ["CMOS18 \u00a73.5 p64 (scan p1123)"], "category": "figures", "severity": "should", "applies_to": "pdf", "rule_text": "Keep caption alignment consistent (left, centered, or full width) across figures.", "rationale": "Consistent alignment improves scanning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["caption alignment", "layout"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.CAPTION.FONT.CONSISTENT", "title": "Keep caption typography consistent", "source_refs": ["CMOS18 \u00a73.5 p64 (scan p1123)"], "category": "figures", "severity": "should", "applies_to": "pdf", "rule_text": "Use consistent caption typography (size, weight, and style) for all figures.", "rationale": "Typography consistency improves professionalism.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["caption typography", "consistency"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.CAPTION.CREDITS.INLINE_OR_NOTE", "title": "Place credits consistently", "source_refs": ["CMOS18 \u00a713.109 p836 (scan p858)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "If figure credits are required, place them consistently (in the caption or a note) using one scheme.", "rationale": "Consistent credits simplify review.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures", "credits"], "keywords": ["credits", "permissions"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.PLACEMENT.TOP_OR_BOTTOM.CONSISTENT", "title": "Use consistent figure placement", "source_refs": ["CMOS18 \u00a73.8 p15 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "pdf", "rule_text": "Place figures consistently within the layout (e.g., top or bottom of a page/column) to avoid visual jitter.", "rationale": "Consistent placement improves rhythm.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["placement", "layout"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.PLACEMENT.AVOID_SPLIT", "title": "Avoid splitting figures across pages", "source_refs": ["CMOS18 \u00a73.38 p39 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid splitting a single figure across pages unless it is designed as a multi-page figure.", "rationale": "Split figures are hard to interpret.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["page breaks", "splitting"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.SIZE.MATCH_READABILITY", "title": "Size figures for readability", "source_refs": ["CMOS18 \u00a73.5 p64 (scan p1123)"], "category": "figures", "severity": "should", "applies_to": "pdf", "rule_text": "Size figures so labels and details remain readable at the target output size.", "rationale": "Readable figures preserve meaning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["size", "readability"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.LABELS.FONT.CONSISTENT", "title": "Use consistent label typography", "source_refs": ["CMOS18 \u00a73.12 p24 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Use consistent font family and size for labels within figures.", "rationale": "Consistent labels improve clarity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["labels", "typography"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.LABELS.AVOID_OVERLAP", "title": "Avoid overlapping labels", "source_refs": ["CMOS18 \u00a73.12 p24 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Avoid label overlaps or collisions within figures; adjust layout if needed.", "rationale": "Overlaps reduce legibility.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["labels", "overlap"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.ANNOTATIONS.CONSISTENT_STYLE", "title": "Keep annotation styles consistent", "source_refs": ["CMOS18 \u00a73.12 p24 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent style for callouts, arrows, and annotation boxes within a document.", "rationale": "Consistent annotations improve comprehension.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["annotations", "callouts"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.AXES.UNITS.CONSISTENT", "title": "Use consistent axis units", "source_refs": ["CMOS18 \u00a73.12 p24 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "When charts use axes, keep unit conventions consistent across related figures.", "rationale": "Consistency aids comparison.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["axes", "units"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.CALL_OUTS.AVOID_OVERLAP", "title": "Place callouts without obscuring data", "source_refs": ["CMOS18 \u00a73.38 p39 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Position callouts and annotations so they do not obscure data points or labels.", "rationale": "Obscured data undermines trust.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["callouts", "data"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.COLOR.PALETTE.CONSISTENT", "title": "Use a consistent color palette", "source_refs": ["CMOS18 \u00a73.3 p11 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent color palette across related figures unless a change is meaningful.", "rationale": "Palette consistency helps comparison.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["color", "palette"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.LINE_WEIGHTS.CONSISTENT", "title": "Keep line weights consistent", "source_refs": ["CMOS18 \u00a73.3 p11 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Keep line weights and stroke styles consistent across figures for similar elements.", "rationale": "Consistent strokes improve clarity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["line weights", "strokes"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.SYMBOLS.CONSISTENT", "title": "Use consistent symbols", "source_refs": ["CMOS18 \u00a73.3 p11 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Use consistent symbols and iconography across related figures.", "rationale": "Consistency reduces cognitive load.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["symbols", "icons"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.CROP.AVOID_LOSS", "title": "Avoid cropping that loses meaning", "source_refs": ["CMOS18 \u00a73.38 p39 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Avoid cropping figures in a way that removes important context or labels.", "rationale": "Cropping can distort meaning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["cropping", "context"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.BLEED.ONLY_WHEN_ENABLED", "title": "Use bleed only when supported", "source_refs": ["CMOS18 \u00a73.38 p39 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "pdf", "rule_text": "Use bleed or full-bleed figures only when the output profile and printer support it.", "rationale": "Unsupported bleed can cause clipping.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["bleed", "printing"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.ORIENTATION.CONSISTENT", "title": "Keep orientation consistent", "source_refs": ["CMOS18 \u00a73.38 p39 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "pdf", "rule_text": "Keep figure orientation consistent (portrait vs landscape) within a section unless a change is necessary.", "rationale": "Consistent orientation improves rhythm.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["orientation", "layout"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.SOURCE.DATA.CITED", "title": "Cite data sources for figures", "source_refs": ["CMOS18 \u00a715.12 p29 (scan p1123)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Cite the data source or dataset when a figure summarizes or transforms external data.", "rationale": "Citations support verification.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures", "citations"], "keywords": ["data source", "citation"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.PERMISSIONS.DOCUMENTED", "title": "Document permissions for reused figures", "source_refs": ["CMOS18 \u00a713.109 p836 (scan p858)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Document permissions or licenses for any reused figures and keep records accessible.", "rationale": "Permissions protect against infringement.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures", "permissions"], "keywords": ["permissions", "licenses"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.LIST_OF_FIGURES.WHEN_NEEDED", "title": "Provide a list of figures when numerous", "source_refs": ["CMOS18 \u00a73.34 p33 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Provide a list of figures when a document contains many figures to improve navigation.", "rationale": "Lists improve navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["list of figures", "navigation"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.LIST_ENTRIES.MATCH_CAPTIONS", "title": "Match list-of-figures entries to captions", "source_refs": ["CMOS18 \u00a73.34 p33 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Ensure list-of-figures entries match the figure captions or short titles used in the document.", "rationale": "Matching entries prevents confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["list of figures", "captions"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.KEY.READABLE", "title": "Keep legends and keys readable", "source_refs": ["CMOS18 \u00a73.5 p64 (scan p1123)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Ensure figure legends or keys are large enough to read at output size.", "rationale": "Readable keys preserve meaning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["legend", "keys"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.EMBEDDED_TEXT.MINIMAL", "title": "Avoid excessive text inside figures", "source_refs": ["CMOS18 \u00a73.12 p24 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Avoid packing long paragraphs into figures; move narrative text into the body.", "rationale": "Dense text in figures reduces readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["embedded text", "readability"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.SCALING.UNIFORM", "title": "Scale related figures uniformly", "source_refs": ["CMOS18 \u00a73.5 p64 (scan p1123)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "When comparing related figures, keep scaling consistent so visual comparisons are accurate.", "rationale": "Uniform scaling prevents misinterpretation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["scaling", "comparisons"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.MULTIPART.PANEL_LABELS", "title": "Label multipart figure panels", "source_refs": ["CMOS18 \u00a73.12 p24 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Label multipart figure panels (A, B, C) clearly and reference them consistently.", "rationale": "Panel labels aid navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["panel labels", "multipart"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FIGURES.PANEL_ORDER.LOGICAL", "title": "Order multipart panels logically", "source_refs": ["CMOS18 \u00a73.12 p24 (scan p1122)"], "category": "figures", "severity": "should", "applies_to": "all", "rule_text": "Order multipart panels logically (left-to-right, top-to-bottom) and reflect the order in references.", "rationale": "Logical order reduces confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "figures"], "keywords": ["panel order", "multipart"], "dependencies": [], "exceptions": [], "status": "active"}
diff --git a/spec/rules/figures/v1_figures_005.ndjson b/spec/rules/figures/v1_figures_005.ndjson
new file mode 100644
index 0000000..f218b36
--- /dev/null
+++ b/spec/rules/figures/v1_figures_005.ndjson
@@ -0,0 +1,7 @@
+{"id":"HOUSE.FIGURES.FORMAT.VECTOR_FOR_LINE_ART","title":"Use vector formats for line art and diagrams","source_refs":["HOUSE §FIGURES.FORMAT p1"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Use vector formats for line art, diagrams, and charts when possible to preserve sharpness at any scale.","rationale":"Vector art stays crisp in print and zoom.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["vector","diagrams","format"],"dependencies":[],"exceptions":["Photographs or raster-only sources may remain raster images."],"status":"active"}
+{"id":"HOUSE.FIGURES.RESOLUTION.MINIMUM","title":"Meet minimum resolution for raster figures","source_refs":["HOUSE §FIGURES.FORMAT p1"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Ensure raster figures meet the minimum resolution for the target output profile so labels remain readable.","rationale":"Low-resolution figures become illegible in PDF.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["resolution","raster"],"dependencies":[],"exceptions":["Small decorative images may use lower resolution if they are not informative."],"status":"active"}
+{"id":"HOUSE.FIGURES.AXES.UNITS.LABELED","title":"Label axes with units for quantitative figures","source_refs":["HOUSE §FIGURES.AXES p1"],"category":"figures","severity":"should","applies_to":"all","rule_text":"For charts and plots, label axes with units or scale so numeric values are interpretable.","rationale":"Unlabeled axes reduce clarity and accuracy.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures"],"keywords":["axes","units","charts"],"dependencies":[],"exceptions":["If units are uniform across multiple figures, note them in a shared legend or caption."],"status":"active"}
+{"id":"HOUSE.FIGURES.COLOR.LEGEND.REQUIRED","title":"Provide legends when color encodes meaning","source_refs":["HOUSE §FIGURES.COLOR p1"],"category":"figures","severity":"should","applies_to":"all","rule_text":"When color encodes categories or values, provide a legend or labels that explain the mapping.","rationale":"Legends make color encodings understandable.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures","color"],"keywords":["legend","color encoding"],"dependencies":[],"exceptions":["Single-series charts with direct labels may omit a separate legend."],"status":"active"}
+{"id":"HOUSE.FIGURES.COLOR.CONTRAST_SAFE","title":"Choose color palettes that remain distinguishable","source_refs":["HOUSE §FIGURES.COLOR p1"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Choose color palettes that remain distinguishable in grayscale or for common color-vision deficiencies.","rationale":"Accessible colors improve comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures","accessibility"],"keywords":["colorblind","contrast"],"dependencies":[],"exceptions":["If color is essential, provide redundant encoding such as labels or patterns."],"status":"active"}
+{"id":"HOUSE.FIGURES.TEXT.NOT_RASTERIZED","title":"Avoid rasterized text inside figures","source_refs":["HOUSE §FIGURES.TEXT p1"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Avoid embedding long text as raster images inside figures; keep text selectable and searchable when possible.","rationale":"Rasterized text is hard to read and search.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures","text"],"keywords":["raster text","searchable"],"dependencies":[],"exceptions":["If the source artwork is raster-only, include a text summary in the caption."],"status":"active"}
+{"id":"HOUSE.FIGURES.CAPTIONS.TAKEAWAY","title":"Captions should state the key takeaway","source_refs":["HOUSE §FIGURES.CAPTIONS p1"],"category":"figures","severity":"should","applies_to":"all","rule_text":"Write figure captions that state the key takeaway, not just the label.","rationale":"Takeaway captions improve comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","figures","captions"],"keywords":["captions","summary"],"dependencies":[],"exceptions":["Very small decorative figures may use minimal captions if context is clear."],"status":"active"}
diff --git a/spec/rules/frontmatter/v1_frontmatter_003.ndjson b/spec/rules/frontmatter/v1_frontmatter_003.ndjson
new file mode 100644
index 0000000..2d8d440
--- /dev/null
+++ b/spec/rules/frontmatter/v1_frontmatter_003.ndjson
@@ -0,0 +1,20 @@
+{"id":"CMOS.FRONTMATTER.ABSTRACT.WHEN_APPROPRIATE","title":"Include an abstract/summary when appropriate","source_refs":["CMOS18 §1.1 p5"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"For long or technical documents, include an abstract or executive summary that states scope, audience, and key conclusions.","rationale":"A summary improves scanning and reduces misinterpretation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter","summary"],"keywords":["abstract","executive summary"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.ACCESSIBILITY.NOTES","title":"Include accessibility notes for constrained formats","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"If the output medium imposes constraints (e.g., no color, limited fonts), note accessibility constraints and mitigations.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["accessibility","constraints"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.ACKNOWLEDGMENTS.PLACEMENT","title":"Place acknowledgments consistently","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"Place acknowledgments in a consistent frontmatter location appropriate to the genre (often before the main body).","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["acknowledgments","placement"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.AUDIENCE.SCOPE.STATED","title":"State audience and scope early","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"State intended audience and scope early in the document to set expectations and reduce misuse.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["audience","scope"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.CHANGELOG.LINKS","title":"Link to changelog or repository when available","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"When the doc is maintained in a repository, include a stable link to the source and changelog.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["repository","changelog"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.CITATION_STYLE.DECLARED","title":"Declare the citation style if citations appear","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"If citations are used, declare the citation style (notes-biblio, author-date, house variant) so reviewers know what to expect.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["citation style","notes-biblio"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.CONTACT.OWNERSHIP","title":"Provide a maintenance contact","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"Provide a contact or owner for maintenance and updates so readers can report issues.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["owner","contact"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.DISCLAIMERS.WHEN_REQUIRED","title":"Include disclaimers and limitations","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"Include any required disclaimers, limitations, or legal notices in a visible frontmatter location.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["disclaimer","legal"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.EDITION.VERSION_VISIBLE","title":"Make version/edition visible","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"Make the version/edition visible on the first page for published PDFs.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["version","edition"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.LANGUAGE.NOTICE","title":"Declare primary language when multilingual","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"If the document includes multiple languages, declare the primary language and how translations are handled.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["language","multilingual"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.LICENSE.ATTRIBUTION","title":"Include license/attribution when distributing","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"Include license or attribution details when distributing content that requires it; keep it consistent across versions.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["license","attribution"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.LISTS.OF_FIGURES_TABLES.WHEN_NEEDED","title":"Provide lists of figures/tables when heavily used","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"When figures or tables are numerous, provide a list of figures and/or tables to support navigation.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["list of figures","list of tables"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.NAVIGATION.METADATA","title":"Include metadata needed for distribution","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"Include metadata needed for distribution (document ID, classification, date, owners) according to the publication workflow.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["metadata","classification"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.PREFACE.PURPOSE","title":"Use a preface to explain scope and intent","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"Use a preface or introduction to explain scope, terminology, and how the document should be read.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["preface","introduction"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.READING_TIME.WHEN_HELPFUL","title":"Include reading time/length when helpful","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"For long guides, include approximate length or reading time to set expectations.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["reading time","length"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.REVISION_HISTORY.WHEN_REQUIRED","title":"Include revision history for controlled docs","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"For controlled or audited documents, include a revision history with dates, version identifiers, and change summaries.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["revision history","version"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.SECURITY.CLASSIFICATION","title":"Include security classification when applicable","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"Include security classification markings when applicable; do not rely on filename or storage location alone.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["classification","security"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.TERMS.DEFINITIONS.EARLY","title":"Provide definitions for key terms","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"Provide definitions for key terms and abbreviations early when readers must interpret technical content.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["definitions","terms"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.TITLEPAGE.PRESENT","title":"Include a clear title and author attribution","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"Provide a clear document title and author/owner attribution appropriate to the publication context.","rationale":"Readers need unambiguous identification and provenance.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["title","author","front matter"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.FRONTMATTER.TOC.WHEN_NEEDED","title":"Provide a table of contents when structure is deep","source_refs":["CMOS18 §1.1 p5","CMOS18 §1.2 p7"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"Provide a table of contents when headings are numerous or multi-level; keep it consistent with heading text.","rationale":"Front matter improves navigation and comprehension.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter"],"keywords":["table of contents","headings"],"dependencies":[],"exceptions":[],"status":"active"}
diff --git a/spec/rules/frontmatter/v1_frontmatter_004.ndjson b/spec/rules/frontmatter/v1_frontmatter_004.ndjson
new file mode 100644
index 0000000..7cce7ac
--- /dev/null
+++ b/spec/rules/frontmatter/v1_frontmatter_004.ndjson
@@ -0,0 +1,20 @@
+{"id": "CMOS.FRONTMATTER.TOC.ENTRIES.MATCH_HEADINGS", "title": "Match TOC entries to headings", "source_refs": ["CMOS18 \u00a71.42 p118 (scan p1126)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "Ensure table-of-contents entries match the wording of the corresponding headings.", "rationale": "Accurate TOC entries improve navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["toc", "headings"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.TOC.PAGE_NUMBERS.MATCH", "title": "Keep TOC page numbers accurate", "source_refs": ["CMOS18 \u00a71.42 p118 (scan p1126)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "Verify that TOC page numbers match the actual page locations after final pagination.", "rationale": "Incorrect page numbers break navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["toc", "page numbers"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.TOC.LEVELS.CONSISTENT", "title": "Use consistent TOC depth", "source_refs": ["CMOS18 \u00a71.5 p112 (scan p1129)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent heading depth in the TOC and avoid mixing levels inconsistently.", "rationale": "Consistent depth improves scanning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["toc", "levels"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.TOC.LEADERS.CONSISTENT", "title": "Use consistent TOC leaders", "source_refs": ["CMOS18 \u00a71.5 p112 (scan p1129)"], "category": "frontmatter", "severity": "should", "applies_to": "pdf", "rule_text": "Keep TOC leader dots or spacing consistent across entries.", "rationale": "Consistent leaders improve readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["toc", "leaders"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.TOC.INDENTATION.BY_LEVEL", "title": "Indent TOC entries by level", "source_refs": ["CMOS18 \u00a76.34 p96 (scan p1129)"], "category": "frontmatter", "severity": "should", "applies_to": "pdf", "rule_text": "Indent TOC entries by heading level so hierarchy is visually clear.", "rationale": "Indentation clarifies structure.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["toc", "indentation"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.TOC.ORDER.MATCH_BODY", "title": "Keep TOC order aligned with the body", "source_refs": ["CMOS18 \u00a76.34 p96 (scan p1129)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "Ensure TOC entry order matches the actual order of sections in the document.", "rationale": "Order mismatches confuse readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["toc", "order"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.TOC.SHORT_TITLES.CONSISTENT", "title": "Use consistent short titles in TOC", "source_refs": ["CMOS18 \u00a77.57 p11 (scan p1130)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "If short titles are used in the TOC, apply the same shortening rule throughout.", "rationale": "Consistency prevents ambiguity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["toc", "short titles"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.TOC.FRONT_BACK_MATTER.INCLUDED", "title": "Include front/back sections per policy", "source_refs": ["CMOS18 \u00a77.57 p11 (scan p1130)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "Include frontmatter and backmatter sections in the TOC according to the chosen publication policy.", "rationale": "Readers rely on TOC completeness.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["toc", "frontmatter", "backmatter"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.LIST_OF_FIGURES.SECTION_TITLE", "title": "Title the list of figures clearly", "source_refs": ["CMOS18 \u00a71.42 p118 (scan p1126)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "When a list of figures is present, give it a clear, consistent section title.", "rationale": "Clear titles aid navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["list of figures", "titles"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.LIST_OF_TABLES.SECTION_TITLE", "title": "Title the list of tables clearly", "source_refs": ["CMOS18 \u00a71.42 p118 (scan p1126)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "When a list of tables is present, give it a clear, consistent section title.", "rationale": "Clear titles aid navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["list of tables", "titles"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.SCOPE", "title": "Keep acknowledgments focused", "source_refs": ["CMOS18 \u00a71.22 p76 (scan p1127)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "Keep acknowledgments focused on contributions and avoid mixing them with executive summary or scope statements.", "rationale": "Focus improves reader expectations.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["acknowledgments", "scope"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.ACKNOWLEDGMENTS.NAMES.CONSISTENT", "title": "Use consistent naming in acknowledgments", "source_refs": ["CMOS18 \u00a71.22 p76 (scan p1127)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "Use consistent names and affiliations for acknowledged contributors.", "rationale": "Consistency reduces ambiguity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["acknowledgments", "names"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.FOREWORD.AUTHOR.ATTRIBUTED", "title": "Attribute the foreword", "source_refs": ["CMOS18 \u00a71.53 p53 (scan p1129)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "If a foreword is included, attribute its author clearly.", "rationale": "Attribution clarifies provenance.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["foreword", "author"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.FOREWORD.DATE_IF_PRESENT", "title": "Date the foreword when customary", "source_refs": ["CMOS18 \u00a71.53 p53 (scan p1129)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "When customary for the genre, include a date for the foreword.", "rationale": "Dates help establish context.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["foreword", "date"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.PREFACE.DATE_IF_PRESENT", "title": "Date the preface when customary", "source_refs": ["CMOS18 \u00a711.49 p86 (scan p1127)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "When customary for the genre, include a date or location for the preface.", "rationale": "Dates provide context.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["preface", "date"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.INTRODUCTION.SCOPE", "title": "State introduction scope clearly", "source_refs": ["CMOS18 \u00a75.170 p170 (scan p1129)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "Use the introduction to define scope, background, or approach without duplicating the abstract.", "rationale": "Clarity prevents redundancy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["introduction", "scope"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.EPIGRAPH.ATTRIBUTION", "title": "Attribute epigraphs", "source_refs": ["CMOS18 \u00a712.35 p11 (scan p1130)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "When an epigraph is used, attribute the source clearly.", "rationale": "Attribution preserves provenance.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["epigraph", "attribution"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.EPIGRAPH.PLACEMENT.CONSISTENT", "title": "Place epigraphs consistently", "source_refs": ["CMOS18 \u00a712.35 p11 (scan p1130)"], "category": "frontmatter", "severity": "should", "applies_to": "pdf", "rule_text": "Place epigraphs consistently (location and spacing) relative to the sections they introduce.", "rationale": "Consistent placement improves rhythm.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["epigraph", "placement"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.COPYRIGHT.NOTICES.PRESENT", "title": "Include required copyright notices", "source_refs": ["CMOS18 \u00a71.111 p36 (scan p1129)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "Include required copyright notices and rights statements appropriate to the publication.", "rationale": "Notices protect rights and readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["copyright", "notices"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.FRONTMATTER.COPYRIGHT.RIGHTS.CONTACT", "title": "Provide rights contact when needed", "source_refs": ["CMOS18 \u00a71.112 p112 (scan p1129)"], "category": "frontmatter", "severity": "should", "applies_to": "all", "rule_text": "When reuse is restricted, provide a rights contact or permissions address.", "rationale": "Clear contact info reduces misuse.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "frontmatter"], "keywords": ["copyright", "permissions"], "dependencies": [], "exceptions": [], "status": "active"}
diff --git a/spec/rules/frontmatter/v1_frontmatter_005.ndjson b/spec/rules/frontmatter/v1_frontmatter_005.ndjson
new file mode 100644
index 0000000..4af555c
--- /dev/null
+++ b/spec/rules/frontmatter/v1_frontmatter_005.ndjson
@@ -0,0 +1,7 @@
+{"id":"HOUSE.FRONTMATTER.METADATA.DOC_STATUS","title":"State document status in frontmatter","source_refs":["HOUSE §FRONTMATTER.METADATA p1"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"State the document status (draft, review, final, superseded) near the top when distribution requires clarity.","rationale":"Status prevents readers from relying on stale guidance.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter","metadata"],"keywords":["status","draft","final"],"dependencies":[],"exceptions":["Short internal notes may omit status if the system already surfaces it."],"status":"active"}
+{"id":"HOUSE.FRONTMATTER.METADATA.VERSION","title":"Include a version or edition when changes are expected","source_refs":["HOUSE §FRONTMATTER.METADATA p1"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"Include a version or edition identifier when the document is expected to evolve or be referenced externally.","rationale":"Versioning supports traceability.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter","metadata"],"keywords":["version","edition"],"dependencies":[],"exceptions":["One-off memos may omit versions if not referenced later."],"status":"active"}
+{"id":"HOUSE.FRONTMATTER.METADATA.CONFIDENTIALITY","title":"Include confidentiality or distribution labels when required","source_refs":["HOUSE §FRONTMATTER.DISTRIBUTION p1"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"Include confidentiality or distribution labels in frontmatter when policy requires it.","rationale":"Clear labels reduce accidental disclosure.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter","distribution"],"keywords":["confidential","distribution"],"dependencies":[],"exceptions":["Public documents may omit labels if distribution is already explicit."],"status":"active"}
+{"id":"HOUSE.FRONTMATTER.TOC.AUTO_GENERATED","title":"Generate the TOC from headings","source_refs":["HOUSE §FRONTMATTER.TOC p1"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"Generate the table of contents from document headings to avoid manual drift and mismatches.","rationale":"Automated TOCs reduce errors.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter","toc"],"keywords":["toc","automation"],"dependencies":[],"exceptions":["Short documents may omit a TOC entirely."],"status":"active"}
+{"id":"HOUSE.FRONTMATTER.ABSTRACT.REQUIRED_FOR_LONG_DOCS","title":"Provide an abstract or summary for long technical docs","source_refs":["HOUSE §FRONTMATTER.ABSTRACT p1"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"For long technical documents, include an abstract or summary in the frontmatter that states purpose and key takeaways.","rationale":"Summaries reduce review time.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter","summary"],"keywords":["abstract","summary"],"dependencies":[],"exceptions":["Short documents may use a brief opening paragraph instead."],"status":"active"}
+{"id":"HOUSE.FRONTMATTER.DISTRIBUTION.CONTACT","title":"Provide a contact for external distribution","source_refs":["HOUSE §FRONTMATTER.DISTRIBUTION p1"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"When a document is shared externally, provide a contact for questions, corrections, or permissions.","rationale":"Contact info supports verification and updates.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter","distribution"],"keywords":["contact","external"],"dependencies":[],"exceptions":["If a public issue tracker is the contact point, link to it explicitly."],"status":"active"}
+{"id":"HOUSE.FRONTMATTER.METADATA.LAST_REVIEWED","title":"Include a last-reviewed date for operational docs","source_refs":["HOUSE §FRONTMATTER.METADATA p1"],"category":"frontmatter","severity":"should","applies_to":"all","rule_text":"For operational docs, include a last-reviewed or last-updated date near the top so readers can judge freshness.","rationale":"Freshness is critical for runbooks and policies.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","frontmatter","metadata"],"keywords":["last reviewed","updated"],"dependencies":[],"exceptions":["If an external system surfaces last-updated metadata prominently, this may be omitted."],"status":"active"}
diff --git a/spec/rules/headings/v1_headings_003.ndjson b/spec/rules/headings/v1_headings_003.ndjson
new file mode 100644
index 0000000..219c2e1
--- /dev/null
+++ b/spec/rules/headings/v1_headings_003.ndjson
@@ -0,0 +1,25 @@
+{"id": "BRING.HEADINGS.LENGTH.CONCISE", "title": "Keep headings concise", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Keep headings concise and focused; avoid multi-sentence headings.", "rationale": "Short headings are easier to scan and reinforce hierarchy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings"], "keywords": ["concise headings", "scanability"], "dependencies": [], "exceptions": ["Legal or technical titles may require longer headings; consider a short label plus subtitle."], "status": "active"}
+{"id": "BRING.HEADINGS.NO_TERMINAL_PERIOD", "title": "Avoid periods at the end of headings", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Avoid ending headings with periods unless the heading is a complete quoted sentence.", "rationale": "Terminal periods make headings look like body sentences and reduce hierarchy clarity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "punctuation"], "keywords": ["heading punctuation", "periods"], "dependencies": [], "exceptions": ["Headings that are full sentences may use terminal punctuation by style choice."], "status": "active"}
+{"id": "BRING.HEADINGS.NO_TERMINAL_COLON", "title": "Avoid trailing colons in headings", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Avoid trailing colons in headings; use a subtitle or lead-in line instead.", "rationale": "Trailing colons look unfinished and weaken hierarchy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "punctuation"], "keywords": ["heading punctuation", "colons"], "dependencies": [], "exceptions": ["Run-in headings may end with a colon by design."], "status": "active"}
+{"id": "BRING.HEADINGS.QUESTION_MARK_ONLY_IF_QUESTION", "title": "Use question marks in headings only for real questions", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Use a question mark in a heading only when the heading is phrased as an actual question.", "rationale": "Punctuation should reflect grammar, not tone alone.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "punctuation"], "keywords": ["question marks", "headings"], "dependencies": [], "exceptions": ["Marketing copy may use interrogative tone; keep it consistent within the document."], "status": "active"}
+{"id": "BRING.HEADINGS.NO_HYPHENATION", "title": "Avoid hyphenation in headings", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Avoid hyphenating words at line breaks in headings; reflow or shorten the heading instead.", "rationale": "Hyphenated headings are harder to read and look uneven.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "hyphenation"], "keywords": ["heading line breaks", "hyphenation"], "dependencies": [], "exceptions": ["Extremely narrow columns may force a break; note as a QA exception."], "status": "active"}
+{"id": "BRING.HEADINGS.NO_SINGLE_WORD_LINE", "title": "Avoid single-word final lines in headings", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Avoid line breaks that leave a single short word on its own line in a heading.", "rationale": "Dangling words weaken balance and scanability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "line_breaks"], "keywords": ["heading line breaks", "widow"], "dependencies": [], "exceptions": ["Very short headings may not allow a better break; prefer rephrasing."], "status": "active"}
+{"id": "BRING.HEADINGS.BREAKS.AT_PHRASE_BOUNDARIES", "title": "Break headings at phrase boundaries", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "When a heading must wrap, break at natural phrase boundaries rather than mid-phrase.", "rationale": "Natural breaks preserve meaning and rhythm.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "line_breaks"], "keywords": ["phrase boundaries", "heading wrap"], "dependencies": [], "exceptions": ["If no clean break exists, shorten the heading."], "status": "active"}
+{"id": "BRING.HEADINGS.AVOID_STACKED_LEVELS", "title": "Avoid stacked headings with no text between", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Avoid consecutive headings with no intervening text; insert brief lead-in text or merge levels.", "rationale": "Stacked headings confuse hierarchy and interrupt reading flow.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings"], "keywords": ["stacked headings", "hierarchy"], "dependencies": [], "exceptions": ["Outlines or TOC-like sections may intentionally stack headings."], "status": "active"}
+{"id": "BRING.HEADINGS.RUN_IN.END_PUNCTUATION", "title": "Use clear punctuation for run-in headings", "source_refs": ["BRING \u00a74.2.1 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "For run-in headings, end the heading with a period or colon and follow with a normal word space.", "rationale": "Run-in punctuation clarifies the boundary between heading and text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "run_in"], "keywords": ["run-in heading", "punctuation"], "dependencies": [], "exceptions": ["Some styles use an em dash as a separator; keep the choice consistent."], "status": "active"}
+{"id": "BRING.HEADINGS.RUN_IN.SEPARATION.CONSISTENT", "title": "Keep run-in separation consistent", "source_refs": ["BRING \u00a74.2.1 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent separator (period, colon, or dash) for run-in headings at the same level.", "rationale": "Consistent separators reinforce hierarchy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "run_in"], "keywords": ["run-in heading", "separator"], "dependencies": [], "exceptions": ["A different separator may be used for a distinct heading level if documented."], "status": "active"}
+{"id": "BRING.HEADINGS.NUMBERING.CONSISTENT_STYLE", "title": "Use a consistent numbering style for headings", "source_refs": ["BRING \u00a71.2.2 p20 (scan p19)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "If headings are numbered, use a single numbering style and apply it consistently across levels.", "rationale": "Consistent numbering improves navigation and reduces confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "numbering"], "keywords": ["heading numbers", "consistency"], "dependencies": [], "exceptions": ["Appendices may use a distinct prefix if clearly labeled."], "status": "active"}
+{"id": "BRING.HEADINGS.NUMBERING.NO_GAPS", "title": "Avoid gaps in heading numbering", "source_refs": ["BRING \u00a71.2.2 p20 (scan p19)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Do not skip numbers within a heading sequence unless sections are intentionally omitted and clearly marked.", "rationale": "Numbering gaps confuse navigation and indexing.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "numbering"], "keywords": ["numbering gaps", "headings"], "dependencies": [], "exceptions": ["If a section is removed, note the omission explicitly."], "status": "active"}
+{"id": "BRING.HEADINGS.NUMBERING.PUNCTUATION.CONSISTENT", "title": "Keep punctuation after numbers consistent", "source_refs": ["BRING \u00a71.2.2 p20 (scan p19)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent punctuation pattern after heading numbers (e.g., 1.1 or 1-1) across the document.", "rationale": "Consistent punctuation improves scanning and reduces ambiguity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "numbering"], "keywords": ["numbering punctuation", "headings"], "dependencies": [], "exceptions": ["Legal or technical standards may prescribe a specific pattern."], "status": "active"}
+{"id": "BRING.HEADINGS.NUMBERING.PREFIXES.CONSISTENT", "title": "Use consistent prefixes for special sections", "source_refs": ["BRING \u00a71.2.2 p20 (scan p19)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "If prefixes like Appendix or Part are used in headings, keep their formatting consistent.", "rationale": "Consistent prefixes aid navigation and indexing.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "numbering"], "keywords": ["appendix", "part", "prefix"], "dependencies": [], "exceptions": ["Short documents may omit prefixes entirely."], "status": "active"}
+{"id": "BRING.HEADINGS.SUBHEADS.PARALLEL_GRAMMAR", "title": "Use parallel grammar for peer headings", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Headings at the same level should use parallel grammar and phrasing where possible.", "rationale": "Parallel structure improves scanability and perceived order.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings"], "keywords": ["parallel grammar", "headings"], "dependencies": [], "exceptions": ["Quoted titles may require nonparallel wording."], "status": "active"}
+{"id": "BRING.HEADINGS.WIDTH.BALANCED", "title": "Balance heading width with the text block", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Keep heading line lengths visually balanced with the text block; avoid overly long lines that crowd margins.", "rationale": "Balanced widths preserve page rhythm and hierarchy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings"], "keywords": ["line length", "balance"], "dependencies": [], "exceptions": ["Full-width display headings may be acceptable in design-heavy sections."], "status": "active"}
+{"id": "BRING.HEADINGS.TOC.MATCH", "title": "Match table-of-contents entries to headings", "source_refs": ["BRING \u00a71.2.2 p20 (scan p19)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Ensure table-of-contents entries match the wording and numbering of headings in the document body.", "rationale": "TOC mismatches make navigation unreliable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "toc"], "keywords": ["table of contents", "consistency"], "dependencies": [], "exceptions": ["Short TOCs may use abbreviated labels if clearly scoped."], "status": "active"}
+{"id": "HOUSE.HEADINGS.KEEP_WITH_NEXT", "title": "Keep headings with following text", "source_refs": ["HOUSE \u00a7QA.KEEPS p1"], "category": "headings", "severity": "must", "applies_to": "pdf", "rule_text": "Do not leave a heading stranded at the bottom of a page; keep it with the following text block.", "rationale": "Stranded headings break reading flow and hierarchy.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust keep-with-next tokens and re-render to avoid stranded headings.", "tags": ["headings", "keeps", "typeset"], "keywords": ["keep with next", "stranded heading"], "dependencies": [], "exceptions": ["Very short sections may require a manual layout exception noted in QA."], "status": "active"}
+{"id": "BRING.HEADINGS.AVOID_ABBREVIATIONS", "title": "Avoid abbreviations in headings", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Avoid abbreviations in headings unless they are widely recognized by the audience.", "rationale": "Headings should be immediately understandable without decoding.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "abbreviations"], "keywords": ["abbreviations", "headings"], "dependencies": [], "exceptions": ["Technical documents may use standard abbreviations defined earlier."], "status": "active"}
+{"id": "BRING.HEADINGS.CASE.PROPER_NOUNS_PRESERVE", "title": "Preserve proper-noun capitalization in headings", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Preserve the correct capitalization of proper nouns in headings regardless of heading case style.", "rationale": "Proper nouns should retain their official capitalization.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "capitalization"], "keywords": ["proper nouns", "capitalization"], "dependencies": [], "exceptions": ["Logotypes with unconventional casing may be treated as exceptions."], "status": "active"}
+{"id": "BRING.HEADINGS.NUMBERING.SUBLEVELS.DECIMAL_STYLE", "title": "Keep sublevel numbering consistent", "source_refs": ["BRING \u00a71.2.2 p20 (scan p19)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent sublevel numbering pattern (e.g., 1.1, 1.1.1) once chosen.", "rationale": "Consistent sublevel numbering clarifies hierarchy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "numbering"], "keywords": ["sublevel numbering", "hierarchy"], "dependencies": [], "exceptions": ["Legal standards may prescribe alternate patterns."], "status": "active"}
+{"id": "BRING.HEADINGS.NUMBERING.APPENDIX_LABELS", "title": "Label appendices consistently", "source_refs": ["BRING \u00a71.2.2 p20 (scan p19)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "If appendices are labeled with letters or words, keep the format consistent across the document.", "rationale": "Consistent appendix labels help navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "numbering"], "keywords": ["appendix", "labels"], "dependencies": [], "exceptions": ["Single-appendix documents may omit labels if clearly titled."], "status": "active"}
+{"id": "BRING.HEADINGS.LEADIN_TEXT.BEFORE_LIST", "title": "Provide lead-in text before lists", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "When a section begins with a list, include a brief lead-in sentence to connect the heading to the list.", "rationale": "Lead-in text clarifies why the list appears and improves flow.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "lists"], "keywords": ["lead-in", "lists"], "dependencies": [], "exceptions": ["Very short sections may use a list directly if the heading is descriptive enough."], "status": "active"}
+{"id": "BRING.HEADINGS.HIERARCHY.MAX_DEPTH", "title": "Limit heading depth", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Limit the depth of heading levels to avoid overly complex hierarchies.", "rationale": "Deep hierarchies are hard to navigate.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings", "hierarchy"], "keywords": ["heading depth", "hierarchy"], "dependencies": [], "exceptions": ["Large technical manuals may require deeper hierarchies; document the structure."], "status": "active"}
+{"id": "BRING.HEADINGS.SECTION_OPENING.PARAGRAPH_REQUIRED", "title": "Start sections with narrative text when possible", "source_refs": ["BRING \u00a74.2 p65 (scan p64)"], "category": "headings", "severity": "should", "applies_to": "all", "rule_text": "Start sections with a short narrative paragraph when possible; avoid jumping straight into subheads.", "rationale": "Opening context helps readers orient to the section.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "headings"], "keywords": ["section opening", "orientation"], "dependencies": [], "exceptions": ["Reference sections may open directly with subheads or lists."], "status": "active"}
diff --git a/spec/rules/i18n/v1_i18n_003.ndjson b/spec/rules/i18n/v1_i18n_003.ndjson
new file mode 100644
index 0000000..599f00f
--- /dev/null
+++ b/spec/rules/i18n/v1_i18n_003.ndjson
@@ -0,0 +1,27 @@
+{"id":"CMOS.I18N.ACRONYMS.LANGUAGE_SPECIFIC","title":"Avoid assuming acronyms are shared across languages","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Do not assume an acronym has the same expansion across languages; define it appropriately for the language of the passage.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["acronyms","translation"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.CAPITALIZATION.TITLES.LANGUAGE_RULES","title":"Use language-appropriate title capitalization","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"When writing titles in languages with different capitalization rules, follow the convention of that language rather than forcing English title case.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["capitalization","titles"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.CITATIONS.TITLES.ORIGINAL_OR_TRANSLATED","title":"Be consistent about original vs translated titles","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"In citations, be consistent about whether you use original-language titles, translated titles, or both; follow the selected style guide.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["citations","titles"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.CURRENCY.CODES.LABEL","title":"Label currencies clearly in international contexts","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"In international contexts, label currencies with symbols and/or ISO codes to avoid ambiguity (e.g., $ could refer to multiple currencies).","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["currency","ISO code"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.DATES.FORMAT.CONSISTENT","title":"Use a consistent date format and label when ambiguous","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Use a consistent date format; when the format could be ambiguous across locales, use an unambiguous form or label it.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["dates","ISO 8601"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.DIACRITICS.PRESERVE","title":"Preserve diacritics in names and terms","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Preserve diacritics in personal names, place names, and borrowed terms when they are standard for the referenced language; do not strip accents without a clear reason.","rationale":"Diacritics can change meaning and support accurate attribution.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n","diacritics"],"keywords":["diacritics","names","accents"],"dependencies":[],"exceptions":["Systems that cannot represent diacritics may require fallback forms; document the constraint."],"status":"active"}
+{"id":"CMOS.I18N.GLOSSARY.MULTILINGUAL","title":"Provide a glossary for multilingual technical terms","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"For multilingual technical documents, provide a glossary mapping key terms across languages when readers must correlate terminology.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["glossary","multilingual"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.HYPHENATION.LANGUAGE_TAGS","title":"Hyphenate according to language","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Hyphenation patterns differ by language; ensure hyphenation settings match the language of each passage.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["hyphenation","language"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.ITALICS.FOREIGN_WORDS.SPARE","title":"Use italics for foreign words only when helpful","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674","BRING §5.1 p92"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Use italics for foreign words or phrases only when needed to signal foreignness or for clarity; avoid unnecessary italics for common loanwords.","rationale":"Excess italics create visual noise and inconsistent emphasis.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n","typography"],"keywords":["italics","loanwords","foreign terms"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.LANGUAGE.CONSISTENT_SPELLING","title":"Use consistent spelling conventions by locale","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Choose spelling conventions appropriate to the document locale (e.g., US vs UK) and apply them consistently; avoid mixed spellings unless quoting sources.","rationale":"Mixed locale spellings reduce perceived editorial quality.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n","locale"],"keywords":["locale","spelling","US","UK"],"dependencies":[],"exceptions":["Quoted material may preserve source spelling; mark if necessary."],"status":"active"}
+{"id":"CMOS.I18N.MEANINGFUL_TRANSLATIONS.NOT_LITERAL","title":"Prefer meaning-preserving translations","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"When translating for publication, prefer meaning-preserving wording over overly literal translations that distort tone or intent.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["translation","meaning"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.NAMES.SORTING.COLLATION","title":"Use appropriate collation for indexes and bibliographies","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"When sorting names/terms in indexes or bibliographies, use a collation order appropriate to the language and the publication context.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["collation","index"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.NUMBERS.DECIMAL_SEPARATOR.LOCALE","title":"Follow locale conventions for decimal separators","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Follow locale conventions for decimal and thousands separators and do not mix formats in the same document without explicit labeling.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["decimal separator","thousands separator"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.PARENS.BRACKETS.TRANSLATOR_NOTES","title":"Mark translator/editor notes distinctly","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Mark translator or editor insertions distinctly (e.g., bracketed notes) and do not blur them into the quoted text.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["translator notes","brackets"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.PUNCTUATION.DASHES.MINUS_SIGN","title":"Distinguish hyphen, en dash, em dash, and minus","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Use the correct dash/minus character for the intended meaning, especially in multilingual technical text.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["dashes","minus"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.PUNCTUATION.ELLIPSIS.STYLE","title":"Use a consistent ellipsis style","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Use a consistent ellipsis style and spacing policy; avoid mixing character sequences and single ellipsis glyph styles without reason.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["ellipsis","consistency"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.PUNCTUATION.SPACING.LANGUAGE_RULES","title":"Apply language-specific spacing rules","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Apply language-specific spacing conventions (including before certain punctuation) when setting text in that language.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["spacing","punctuation"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.QUOTES.NESTING.CONSISTENT","title":"Keep nested quotation conventions consistent","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"When quotes are nested in multilingual passages, follow the nesting conventions of the primary language of that passage.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["nested quotes","punctuation"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.QUOTES.STYLE.MATCH_LOCALE","title":"Use quotation style appropriate to the language","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Use quotation marks and nesting appropriate to the language/locale in each passage; avoid mixing quotation styles within a single locale context.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["quotation marks","locale"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.RIGHT_TO_LEFT.MARKUP","title":"Handle right-to-left text explicitly","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"When including right-to-left scripts, use explicit direction handling to prevent punctuation and numerals from reordering unexpectedly.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["RTL","bidirectional"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.ROMANIZATION.DIACRITICS.KEEP","title":"Keep diacritics in romanization when used","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"If romanization includes diacritics, keep them consistently; do not mix diacritic and simplified forms without a policy.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["romanization","diacritics"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.SCRIPT_MIXING.AVOID","title":"Avoid gratuitous script mixing","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Avoid mixing scripts (Latin/Cyrillic/etc.) within a single term unless it is the standard form; mixed scripts can harm readability and security.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["script mixing","homoglyphs"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.SECURITY.HOMOGLYPHS.AWARE","title":"Be aware of homoglyph risks","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"When publishing identifiers or domains that could be confused by homoglyphs, use monospaced formatting and consider an ASCII-safe representation.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["homoglyph","security"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.TRANSLATION.INDICATE","title":"Indicate when text is translated","source_refs":["CMOS18 §11.1 p673"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"When quoting or citing non-English sources in translation, indicate that the wording is translated and provide the original language source details as appropriate.","rationale":"Readers should understand when wording is not original.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n","citations"],"keywords":["translation","non-English","citations"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.TRANSLITERATION.SYSTEM.CONSISTENT","title":"Use a consistent transliteration system","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"If transliteration is required, select a single recognized system and apply it consistently; document the system if readers need to interpret it.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["transliteration","consistency"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.TYPOGRAPHY.FONT_COVERAGE","title":"Use fonts with adequate glyph coverage","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Choose fonts that cover the needed scripts and diacritics; avoid fallback glyph substitution that changes tone or meaning.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["fonts","glyph coverage"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"CMOS.I18N.UNITS.SYMBOLS.STANDARD","title":"Use standard unit symbols for the target locale","source_refs":["CMOS18 §11.1 p673","CMOS18 §11.2 p674"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Use standard unit symbols and abbreviations appropriate to the target locale and technical domain.","rationale":"Internationalized text requires explicit, consistent conventions.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n"],"keywords":["units","symbols"],"dependencies":[],"exceptions":[],"status":"active"}
diff --git a/spec/rules/i18n/v1_i18n_004.ndjson b/spec/rules/i18n/v1_i18n_004.ndjson
new file mode 100644
index 0000000..265947f
--- /dev/null
+++ b/spec/rules/i18n/v1_i18n_004.ndjson
@@ -0,0 +1,2 @@
+{"id":"HOUSE.I18N.NUMBERS.MIXED_DECIMAL_SEPARATORS","title":"Avoid mixing decimal separators within a document","source_refs":["HOUSE §I18N.NUMBERS.MIXED_DECIMAL_SEPARATORS p1"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Do not mix comma and dot decimal separators in the same document; choose the locale-appropriate form and apply consistently.","rationale":"Mixed decimal styles create parsing and comprehension errors.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["numbers","i18n"],"keywords":["decimal separator","locale"],"dependencies":[],"exceptions":["Allow mixed separators inside verbatim quotations when language boundaries are declared."],"status":"active"}
+{"id":"HOUSE.I18N.QUOTES.MIXED_STYLES","title":"Avoid mixing quotation styles across locales","source_refs":["HOUSE §I18N.QUOTES.MIXED_STYLES p1"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Avoid mixing guillemets and curly double quotes in the same document unless a clear language boundary is declared.","rationale":"Mixed quotation styles reduce typographic consistency.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["quotes","i18n"],"keywords":["guillemets","quotation marks"],"dependencies":[],"exceptions":["Allow mixed styles inside verbatim quotations with explicit language labeling."],"status":"active"}
diff --git a/spec/rules/i18n/v1_i18n_005.ndjson b/spec/rules/i18n/v1_i18n_005.ndjson
new file mode 100644
index 0000000..042088f
--- /dev/null
+++ b/spec/rules/i18n/v1_i18n_005.ndjson
@@ -0,0 +1,6 @@
+{"id":"HOUSE.I18N.NUMBERS.GROUPING.CONSISTENT","title":"Use one thousands-grouping style per document","source_refs":["HOUSE §I18N.NUMBERS.GROUPING p1"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Use a single thousands-grouping style (comma, space, thin space, or dot) across the document based on locale conventions.","rationale":"Mixed grouping can change numeric meaning.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n","numbers"],"keywords":["thousands separator","grouping"],"dependencies":[],"exceptions":["Quoted material may retain original grouping if attributed."],"status":"active"}
+{"id":"HOUSE.I18N.NUMBERS.DIGIT_SYSTEM.CONSISTENT","title":"Keep digit systems consistent in numeric contexts","source_refs":["HOUSE §I18N.NUMBERS.DIGIT_SYSTEM p1"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Avoid mixing digit systems (Latin, Arabic-Indic, etc.) within the same numeric context unless the document explicitly requires it.","rationale":"Mixed digit systems can confuse readers.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n","numbers"],"keywords":["digit systems","numerals"],"dependencies":[],"exceptions":["Language-learning material may intentionally show multiple systems with clear labels."],"status":"active"}
+{"id":"HOUSE.I18N.LANGUAGE.SWITCHES.MARK","title":"Mark language switches in multilingual content","source_refs":["HOUSE §I18N.LANGUAGE.SWITCHES p1"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"When passages switch languages, mark the change (language tags in HTML or explicit labels in prose) so readers and tools interpret it correctly.","rationale":"Language metadata improves pronunciation and hyphenation.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n","accessibility"],"keywords":["language tags","multilingual"],"dependencies":[],"exceptions":["Short, well-known phrases may not require explicit marking."],"status":"active"}
+{"id":"HOUSE.I18N.CURRENCY.DISAMBIGUATE","title":"Disambiguate currency symbols in international contexts","source_refs":["HOUSE §I18N.CURRENCY.DISAMBIGUATE p1"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"When using ambiguous currency symbols (e.g., $), disambiguate with ISO codes or currency names in international documents.","rationale":"Ambiguous symbols can be misread across locales.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n","numbers"],"keywords":["currency","ISO codes"],"dependencies":[],"exceptions":["Local-only documents may use symbols without codes when the locale is explicit."],"status":"active"}
+{"id":"HOUSE.I18N.TRANSLATION.LABELS","title":"Label translations and sources when relevant","source_refs":["HOUSE §I18N.TRANSLATION.LABELS p1"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"When a passage is translated, label it as a translation and identify the source language or reference when it matters for interpretation.","rationale":"Translation context preserves accuracy.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n","citations"],"keywords":["translations","source language"],"dependencies":[],"exceptions":["If the document is entirely in translation, a single global note may suffice."],"status":"active"}
+{"id":"HOUSE.I18N.UNITS.SPACING.CONSISTENT","title":"Apply locale-appropriate spacing between numbers and units","source_refs":["HOUSE §I18N.UNITS.SPACING p1"],"category":"i18n","severity":"should","applies_to":"all","rule_text":"Apply a consistent, locale-appropriate spacing convention between numbers and units and prevent undesirable line breaks.","rationale":"Unit spacing affects readability and meaning.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","i18n","units"],"keywords":["units","spacing"],"dependencies":[],"exceptions":["Code or literal data may keep fixed spacing to preserve semantics."],"status":"active"}
diff --git a/spec/rules/layout/v1_layout_004.ndjson b/spec/rules/layout/v1_layout_004.ndjson
new file mode 100644
index 0000000..01ec775
--- /dev/null
+++ b/spec/rules/layout/v1_layout_004.ndjson
@@ -0,0 +1,30 @@
+{"id": "CMOS.LAYOUT.PAGINATION.WIDOWS.AVOID", "title": "Avoid widows at page bottoms", "source_refs": ["CMOS18 \u00a75.16 p81 (scan p1123)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid leaving a single last line of a paragraph at the bottom of a page; reflow so at least two lines stay together.", "rationale": "Widows disrupt reading flow and look careless.", "enforcement": "postrender", "autofix": "reflow", "autofix_notes": "Reflow pagination to eliminate widows; re-render and re-check.", "tags": ["layout", "pagination", "widows_orphans"], "keywords": ["widow", "page break", "paragraph"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PAGINATION.ORPHANS.AVOID", "title": "Avoid orphans at page tops", "source_refs": ["CMOS18 \u00a74.81 p81 (scan p1123)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid starting a page with the final line of a paragraph; reflow to keep the paragraph together.", "rationale": "Orphans interrupt continuity.", "enforcement": "postrender", "autofix": "reflow", "autofix_notes": "Reflow pagination to eliminate orphans; re-render and re-check.", "tags": ["layout", "pagination", "widows_orphans"], "keywords": ["orphan", "page break", "paragraph"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PAGINATION.HEADINGS.KEEP_WITH_TEXT", "title": "Keep headings with following text", "source_refs": ["CMOS18 \u00a73.34 p120 (scan p1122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep headings with a minimum amount of following text; do not leave a heading stranded at a page break.", "rationale": "Headings without text below confuse navigation.", "enforcement": "postrender", "autofix": "reflow", "autofix_notes": "Apply keep-with-next constraints for headings and reflow when violated.", "tags": ["layout", "pagination", "headings", "keep_constraints"], "keywords": ["heading", "keep with next", "pagination"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PAGINATION.HEADINGS.AVOID_BOTTOM_OF_PAGE", "title": "Avoid headings at page bottoms", "source_refs": ["CMOS18 \u00a73.34 p120 (scan p1122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid placing headings at the bottom of a page with only a line or two of text beneath.", "rationale": "Bottom-of-page headings read as orphaned.", "enforcement": "postrender", "autofix": "reflow", "autofix_notes": "Reflow to move the heading to the next page when too little text follows.", "tags": ["layout", "pagination", "headings", "keep_constraints"], "keywords": ["heading", "page bottom", "keep with next"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PAGINATION.HEADINGS.AVOID_TOP_OF_PAGE", "title": "Avoid headings that create excessive white space", "source_refs": ["CMOS18 \u00a73.34 p120 (scan p1122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid pushing a heading to the top of a page if it leaves excessive white space on the preceding page.", "rationale": "Abrupt white space breaks page rhythm.", "enforcement": "postrender", "autofix": "reflow", "autofix_notes": "Reflow pagination to reduce excessive white space before headings.", "tags": ["layout", "pagination", "headings", "keep_constraints"], "keywords": ["heading", "page top", "white space"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PAGINATION.RUNNING_HEADS.PLACEMENT", "title": "Place running heads consistently", "source_refs": ["CMOS18 \u00a73.7 p120 (scan p1122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Place running heads in a consistent position (top margin or header band) across the document.", "rationale": "Consistent placement aids navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "running_heads", "manual_checklist=true"], "keywords": ["running head", "header", "placement"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PAGINATION.RUNNING_HEADS.CONSISTENCY", "title": "Keep running heads consistent", "source_refs": ["CMOS18 \u00a73.7 p120 (scan p1122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep running head content and formatting consistent within a section or part.", "rationale": "Inconsistency confuses orientation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "running_heads", "manual_checklist=true"], "keywords": ["running head", "consistency", "navigation"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PAGINATION.PAGE_NUMBERS.POSITION", "title": "Keep page number placement consistent", "source_refs": ["CMOS18 \u00a71.44 p14 (scan p1123)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Place page numbers in a consistent location (top/bottom, inner/outer) according to the chosen layout.", "rationale": "Consistent placement improves wayfinding.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "page_numbers", "manual_checklist=true"], "keywords": ["page numbers", "position", "pagination"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PAGINATION.PAGE_NUMBERS.STYLE", "title": "Use consistent page number styling", "source_refs": ["CMOS18 \u00a715.117 p117 (scan p1124)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Use a consistent page-number style and formatting throughout the document.", "rationale": "Inconsistent numbering looks unprofessional.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "page_numbers", "manual_checklist=true"], "keywords": ["page numbers", "style", "formatting"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PARAGRAPHS.INDENT_POLICY", "title": "Apply a consistent paragraph indent policy", "source_refs": ["CMOS18 \u00a715.119 p132 (scan p1124)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Apply a consistent first-line indent policy for body paragraphs and omit indents after headings or display elements.", "rationale": "Consistent indents clarify structure.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Apply profile indent tokens and suppress indents after display elements.", "tags": ["layout", "paragraphs", "typeset"], "keywords": ["paragraph indent", "first line", "after heading"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PARAGRAPHS.BLOCK_QUOTE_STYLE", "title": "Set block quotations as display text", "source_refs": ["CMOS18 \u00a715.12 p108 (scan p1124)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Set block quotations as display text with indentation or spacing distinct from body paragraphs.", "rationale": "Display styling distinguishes quoted material.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Apply block-quote indentation and spacing tokens from the profile.", "tags": ["layout", "block_quotes", "typeset"], "keywords": ["block quote", "indentation", "spacing"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PARAGRAPHS.SPACING_POLICY", "title": "Use one paragraph separation method", "source_refs": ["CMOS18 \u00a72.14 p22 (scan p1124)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Use one paragraph separation method within a context (indentation or spacing), not both.", "rationale": "Mixed signals look inconsistent.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Normalize paragraph separation to the chosen profile method.", "tags": ["layout", "paragraphs", "typeset"], "keywords": ["paragraph spacing", "indentation", "consistency"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.SPACING.LINE_SPACING.CONSISTENT", "title": "Keep line spacing consistent", "source_refs": ["CMOS18 \u00a73.45 p130 (scan p1133)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep line spacing consistent within body text; avoid uneven leading within the same context.", "rationale": "Consistent leading stabilizes the text block.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Apply a consistent leading value for body text within the profile.", "tags": ["layout", "spacing", "typeset"], "keywords": ["line spacing", "leading", "consistency"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.SPACING.LEADING.CHOOSE", "title": "Choose appropriate leading", "source_refs": ["CMOS18 \u00a73.45 p130 (scan p1133)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Choose leading appropriate to the type size and measure; avoid cramped or overly loose lines.", "rationale": "Appropriate leading improves readability.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Select a leading value based on type size and measure, then validate in output.", "tags": ["layout", "leading", "typeset"], "keywords": ["leading", "line spacing", "type size"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.SPACING.VERTICAL_RHYTHM", "title": "Maintain vertical rhythm", "source_refs": ["CMOS18 \u00a78.32 p128 (scan p1122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Align added vertical space (around headings, quotes, figures) to a consistent rhythm so the text block returns to its baseline grid.", "rationale": "Rhythm keeps the page texture even.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Use spacing tokens as multiples of base leading to preserve rhythm.", "tags": ["layout", "vertical_rhythm", "typeset"], "keywords": ["vertical rhythm", "baseline grid", "spacing"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.MEASURE.LINE_LENGTH.TARGET_RANGE", "title": "Set a target line length range", "source_refs": ["CMOS18 \u00a78.84 p128 (scan p1122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Set a target line-length range for body text and keep measure within that range.", "rationale": "Stable measure improves readability.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Define a target characters-per-line range and flag deviations.", "tags": ["layout", "measure", "typeset"], "keywords": ["line length", "measure", "body text"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.MEASURE.MAX_LINE_LENGTH", "title": "Avoid overly long lines", "source_refs": ["CMOS18 \u00a72.16 p177 (scan p1122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid overly long lines in continuous text; shorten measure or increase columns when needed.", "rationale": "Long lines hinder tracking.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust measure or column count when lines exceed the target range.", "tags": ["layout", "measure", "typeset"], "keywords": ["long lines", "measure", "columns"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.MEASURE.MIN_LINE_LENGTH", "title": "Avoid overly short lines", "source_refs": ["CMOS18 \u00a75.17 p177 (scan p1122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid overly short lines in continuous text; adjust measure to prevent choppy reading.", "rationale": "Short lines disrupt rhythm.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust measure or column count when lines fall below the target range.", "tags": ["layout", "measure", "typeset"], "keywords": ["short lines", "measure", "rhythm"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PAGINATION.PAGE_BREAKS.BEFORE_PARTS", "title": "Start major divisions on new pages", "source_refs": ["CMOS18 \u00a76.113 p118 (scan p1121)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Start major divisions (parts or chapters) on a new page according to the layout plan.", "rationale": "Clear breaks signal structure.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "pagination", "manual_checklist=true"], "keywords": ["page break", "chapter start", "part break"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PAGINATION.AVOID_SINGLE_LINE_ENDING", "title": "Avoid single-line endings", "source_refs": ["CMOS18 \u00a75.16 p81 (scan p1123)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid leaving a single line of a paragraph at the end of a page or column.", "rationale": "Single-line endings look like widows.", "enforcement": "postrender", "autofix": "reflow", "autofix_notes": "Reflow pagination to avoid single-line endings; re-render and re-check.", "tags": ["layout", "pagination", "widows_orphans"], "keywords": ["single line", "page end", "widow"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PAGINATION.AVOID_SHORT_LAST_LINE", "title": "Avoid very short final lines", "source_refs": ["CMOS18 \u00a75.16 p81 (scan p1123)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid very short final lines (runts) at paragraph endings; reflow to balance line lengths.", "rationale": "Runts create uneven page texture.", "enforcement": "postrender", "autofix": "reflow", "autofix_notes": "Reflow pagination to reduce extreme short last lines; re-render and re-check.", "tags": ["layout", "pagination", "widows_orphans"], "keywords": ["short last line", "runt", "line balance"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PAGINATION.FACING_PAGES.BALANCE", "title": "Balance facing pages", "source_refs": ["CMOS18 \u00a73.34 p120 (scan p1122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Balance facing pages in two-sided layouts so spreads do not look lopsided.", "rationale": "Balanced spreads improve visual cohesion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "pagination", "manual_checklist=true"], "keywords": ["facing pages", "spread", "balance"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PAGINATION.FACING_PAGES.BLANKS", "title": "Handle blank pages intentionally", "source_refs": ["CMOS18 \u00a73.34 p120 (scan p1122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "When a blank page is required in a two-sided layout, handle it intentionally and keep pagination correct.", "rationale": "Intentional blanks avoid confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "pagination", "manual_checklist=true"], "keywords": ["blank page", "pagination", "two-sided"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.PAGINATION.PAGE_SEQUENCE.CONTINUITY", "title": "Keep page sequence and numbering continuous", "source_refs": ["CMOS18 \u00a715.117 p117 (scan p1124)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Ensure page sequence and numbering are continuous and consistent across front matter and main text as specified.", "rationale": "Continuity prevents navigation errors.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "pagination", "manual_checklist=true"], "keywords": ["page sequence", "numbering", "front matter"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.RUNNING_HEADS.CHAPTER_TITLES", "title": "Use chapter titles in running heads consistently", "source_refs": ["CMOS18 \u00a73.7 p120 (scan p1122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Use chapter or part titles in running heads according to the chosen scheme and keep it consistent.", "rationale": "Consistent heads aid navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "running_heads", "manual_checklist=true"], "keywords": ["running head", "chapter title", "consistency"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.RUNNING_HEADS.SECTION_TITLES", "title": "Use section titles in running heads consistently", "source_refs": ["CMOS18 \u00a73.7 p120 (scan p1122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "When running heads use section titles, keep truncation and hierarchy consistent.", "rationale": "Consistent heads reinforce hierarchy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "running_heads", "manual_checklist=true"], "keywords": ["running head", "section title", "hierarchy"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.FOOTNOTES.PLACEMENT", "title": "Place footnotes at the bottom of their page", "source_refs": ["CMOS18 \u00a72.61 p46 (scan p1120)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Place footnotes at the bottom of the page where they are referenced unless the design specifies otherwise.", "rationale": "Footnotes should be close to their references.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "footnotes", "manual_checklist=true"], "keywords": ["footnote", "placement", "page bottom"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.FOOTNOTES.SEQUENCE", "title": "Keep footnotes in sequence", "source_refs": ["CMOS18 \u00a72.61 p46 (scan p1120)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Number footnotes sequentially and present them in the order they appear.", "rationale": "Sequential notes reduce confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "footnotes", "manual_checklist=true"], "keywords": ["footnote", "numbering", "order"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.ILLUSTRATIONS.PLACEMENT_NEAR_REF", "title": "Place figures near their first reference", "source_refs": ["CMOS18 \u00a73.5 p64 (scan p1123)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Place figures or illustrations close to their first reference when possible to preserve reading flow.", "rationale": "Proximity keeps visuals in context.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "figures", "manual_checklist=true"], "keywords": ["figure", "illustration", "placement"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.LAYOUT.TABLES.PLACEMENT_NEAR_REF", "title": "Place tables near their references", "source_refs": ["CMOS18 \u00a73.2 p38 (scan p1123)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Place tables near the text that references them or provide a clear cross-reference if moved.", "rationale": "Proximity keeps tables usable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "tables", "manual_checklist=true"], "keywords": ["table", "placement", "cross-reference"], "dependencies": [], "exceptions": [], "status": "active"}
diff --git a/spec/rules/layout/v1_layout_005.ndjson b/spec/rules/layout/v1_layout_005.ndjson
new file mode 100644
index 0000000..4c255f7
--- /dev/null
+++ b/spec/rules/layout/v1_layout_005.ndjson
@@ -0,0 +1,64 @@
+{"id": "BRING.LAYOUT.MARGINS.PROPORTION.BALANCED", "title": "Balance margins to frame the text block", "source_refs": ["BRING \u00a78.5 p165 (scan p120)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Balance page margins so the text block feels framed rather than crowded.", "rationale": "Balanced margins improve readability and page tone.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "margins", "typeset"], "keywords": ["margins", "text block"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.MARGINS.OUTER_LARGER_THAN_INNER", "title": "Prefer larger outer margins on facing pages", "source_refs": ["BRING \u00a78.5.1 p165 (scan p120)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "On facing pages, prefer a slightly larger outer margin than inner margin to improve balance and thumb space.", "rationale": "Outer margins aid handling and annotations.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "margins", "typeset"], "keywords": ["outer margin", "inner margin", "facing pages"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.MARGINS.GUTTER.ALLOW_BINDING", "title": "Allow for binding in inner margins", "source_refs": ["BRING \u00a78.5.1 p165 (scan p120)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Increase inner margins to allow for binding or gutter loss in print outputs.", "rationale": "Binding loss can make text hard to read.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "margins", "typeset"], "keywords": ["gutter", "binding"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.MARGINS.TOP_BOTTOM.BALANCE", "title": "Balance top and bottom margins", "source_refs": ["BRING \u00a78.5.2 p165 (scan p120)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Balance top and bottom margins so the page feels stable; avoid overly tight bottoms.", "rationale": "Balanced vertical margins improve page rhythm.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "margins", "typeset"], "keywords": ["top margin", "bottom margin"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.MARGINS.CONSISTENT.ACROSS_SECTIONS", "title": "Keep margin proportions consistent", "source_refs": ["BRING \u00a78.5 p165 (scan p120)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep margin proportions consistent across sections unless a deliberate design change is signaled.", "rationale": "Consistency supports navigability.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "margins", "typeset"], "keywords": ["margin consistency", "sections"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.MARGINS.RUNNING_HEAD.CLEARANCE", "title": "Allow clearance for running heads", "source_refs": ["BRING \u00a78.5 p165 (scan p120)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Provide adequate top margin clearance for running heads so they do not crowd the text block.", "rationale": "Clearance improves legibility of headers.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "margins", "typeset"], "keywords": ["running heads", "clearance"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.MARGINS.FOOTNOTE.CLEARANCE", "title": "Allow clearance for footnotes", "source_refs": ["BRING \u00a78.5 p165 (scan p120)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Provide enough bottom margin clearance so footnotes do not crowd body text.", "rationale": "Footnote clearance keeps pages readable.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "margins", "typeset"], "keywords": ["footnotes", "bottom margin"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.MARGINS.AVOID_CROWDING", "title": "Avoid cramped margins", "source_refs": ["BRING \u00a78.5 p165 (scan p120)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid margins so small that text or figures feel cramped against the page edge.", "rationale": "Cramped margins reduce perceived quality.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "margins", "typeset"], "keywords": ["cramped margins", "page edge"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.MARGINS.NOTES.OUTSIDE_TEXTBLOCK", "title": "Keep marginal notes outside the text block", "source_refs": ["BRING \u00a78.5 p165 (scan p120)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "If marginal notes are used, keep them outside the main text block and aligned consistently.", "rationale": "Separation prevents reading confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "margins"], "keywords": ["marginal notes", "alignment"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.MARGINS.BLEED.ONLY_WHEN_ENABLED", "title": "Use bleed only when supported", "source_refs": ["BRING \u00a78.5.2 p165 (scan p120)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Use bleed only when the profile and printer support it; otherwise keep content inside margins.", "rationale": "Unsupported bleed risks clipping.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "margins"], "keywords": ["bleed", "printing"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGE.SHAPE.PROPORTIONATE", "title": "Use a page proportion suited to the content", "source_refs": ["BRING \u00a78.3 p160 (scan p117)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Choose a page proportion that suits the content and intended reading distance.", "rationale": "Page proportion influences readability and tone.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "page", "typeset"], "keywords": ["page proportion", "format"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGE.TEXTBLOCK.POSITION", "title": "Position the text block deliberately", "source_refs": ["BRING \u00a78.3.1 p160 (scan p117)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Position the text block deliberately on the page; avoid drifting placement.", "rationale": "Deliberate placement stabilizes design.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "page", "typeset"], "keywords": ["text block", "placement"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGE.SPREADS.BALANCE_CONTENT", "title": "Balance facing-page spreads", "source_refs": ["BRING \u00a78.8.3 p178 (scan p122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Balance content across facing pages so spreads feel even and intentional.", "rationale": "Balanced spreads improve readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "spreads"], "keywords": ["spreads", "balance"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGE.SPREADS.ALIGN_BASELINES", "title": "Align baselines across facing pages", "source_refs": ["BRING \u00a78.8.3 p178 (scan p122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Align baselines across facing pages when a baseline grid is in use.", "rationale": "Baseline alignment reduces visual jitter.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "baseline_grid", "typeset"], "keywords": ["baseline grid", "facing pages"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGE.ODD_EVEN.CONSISTENT", "title": "Keep odd/even page structure consistent", "source_refs": ["BRING \u00a78.6.1 p166 (scan p121)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep the odd/even page structure consistent; avoid swapping header/footer schemes midstream.", "rationale": "Consistency improves navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["odd page", "even page", "headers"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGE.OPENING_SPREAD.RULE", "title": "Treat opening spreads consistently", "source_refs": ["BRING \u00a78.6.1 p166 (scan p121)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "If opening spreads use a distinct layout, apply the same rule consistently across sections.", "rationale": "Predictable openings aid orientation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "spreads"], "keywords": ["opening spread", "sections"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGE.WHITE_SPACE.DISTRIBUTION", "title": "Distribute white space intentionally", "source_refs": ["BRING \u00a78.3 p160 (scan p117)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Distribute white space intentionally; avoid large accidental voids.", "rationale": "Controlled white space improves page tone.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "white_space"], "keywords": ["white space", "page balance"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGE.HEAD_FOOT_BANDS.CONSISTENT", "title": "Keep header and footer bands consistent", "source_refs": ["BRING \u00a71.2.5 p23 (scan p22)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep header and footer band heights consistent across pages.", "rationale": "Consistent bands improve rhythm.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "headers", "footers", "typeset"], "keywords": ["header band", "footer band"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGE.FACING_ELEMENTS.ALIGN", "title": "Align facing-page elements when paired", "source_refs": ["BRING \u00a78.8.3 p178 (scan p122)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "When elements are paired across a spread, align them to reinforce the relationship.", "rationale": "Alignment helps readers compare content.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "spreads"], "keywords": ["alignment", "spreads"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGE.BLANKS.INTENTIONAL", "title": "Handle blank pages intentionally", "source_refs": ["BRING \u00a71.2.5 p23 (scan p22)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "If a blank page is required, treat it as intentional and keep pagination consistent.", "rationale": "Intentional blanks avoid confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["blank pages", "pagination"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.COLUMNS.COUNT.MODERATE", "title": "Use a moderate column count", "source_refs": ["BRING \u00a74.4.3 p111 (scan p70)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Use a column count that preserves a readable measure; avoid excessive columns.", "rationale": "Too many columns reduce legibility.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "columns", "typeset"], "keywords": ["columns", "measure"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.COLUMNS.WIDTH.CONSISTENT", "title": "Keep column widths consistent", "source_refs": ["BRING \u00a74.4.3 p111 (scan p70)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep column widths consistent within a section unless a design change is intentional.", "rationale": "Consistency aids scanning.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "columns", "typeset"], "keywords": ["column width", "consistency"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.COLUMNS.GUTTER.CONSISTENT", "title": "Keep column gutters consistent", "source_refs": ["BRING \u00a74.4.3 p111 (scan p70)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep gutter spacing consistent between columns.", "rationale": "Consistent gutters improve rhythm.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "columns", "typeset"], "keywords": ["gutter", "spacing"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.COLUMNS.GUTTER.SUFFICIENT", "title": "Use sufficient gutter spacing", "source_refs": ["BRING \u00a74.4.3 p111 (scan p70)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Ensure gutters are wide enough to prevent adjacent columns from visually merging.", "rationale": "Adequate gutters improve readability.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "columns", "typeset"], "keywords": ["gutter", "readability"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.COLUMNS.ALIGN_BASELINES", "title": "Align baselines across columns", "source_refs": ["BRING \u00a74.4.3 p111 (scan p70)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "When using a baseline grid, align text baselines across columns.", "rationale": "Baseline alignment reduces visual drift.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "columns", "baseline_grid", "typeset"], "keywords": ["baseline grid", "columns"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.COLUMNS.SPAN_POLICY.FIGURES", "title": "Define a span policy for figures", "source_refs": ["BRING \u00a74.4.3 p111 (scan p70)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Define when figures should span a single column versus multiple columns, and apply consistently.", "rationale": "A consistent span policy improves layout predictability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "columns"], "keywords": ["figures", "span"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.COLUMNS.SPAN_POLICY.TABLES", "title": "Define a span policy for tables", "source_refs": ["BRING \u00a74.4.3 p111 (scan p70)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Define when tables should span one or more columns and apply the rule consistently.", "rationale": "Consistent spans prevent layout surprises.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "columns"], "keywords": ["tables", "span"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.COLUMNS.SIDEBARS.DISTINCT_MEASURE", "title": "Use a distinct measure for sidebars", "source_refs": ["BRING \u00a74.4.3 p111 (scan p70)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "If sidebars are used, give them a distinct measure and consistent placement.", "rationale": "Distinct measures signal hierarchy.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "columns", "typeset"], "keywords": ["sidebars", "measure"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.COLUMNS.RAGGED_BOTTOM.AVOID", "title": "Avoid ragged bottoms in multi-column layouts", "source_refs": ["BRING \u00a74.4.3 p111 (scan p70)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid extreme ragged bottoms in multi-column layouts; balance columns when possible.", "rationale": "Balanced columns improve visual cohesion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "columns"], "keywords": ["ragged bottom", "balance"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.COLUMNS.USE_FOR_LONG_LISTS", "title": "Use columns for long lists when helpful", "source_refs": ["BRING \u00a74.4.3 p111 (scan p70)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Use columns for long lists only when it improves scanning and the measure remains readable.", "rationale": "Columns can aid scanning when used judiciously.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "columns"], "keywords": ["lists", "columns"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.VERTICAL_RHYTHM.HEADINGS.BEFORE_AFTER", "title": "Use consistent spacing around headings", "source_refs": ["BRING \u00a72.2.3 p39 (scan p38)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Use consistent vertical spacing before and after headings.", "rationale": "Consistent spacing clarifies hierarchy.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "vertical_rhythm", "typeset"], "keywords": ["headings", "spacing"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.VERTICAL_RHYTHM.LISTS.SPACING", "title": "Use consistent spacing around lists", "source_refs": ["BRING \u00a72.2.3 p39 (scan p38)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Use consistent spacing before and after lists to avoid visual clutter.", "rationale": "Consistent list spacing improves readability.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "vertical_rhythm", "typeset"], "keywords": ["lists", "spacing"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.VERTICAL_RHYTHM.TABLES.SPACING", "title": "Use consistent spacing around tables", "source_refs": ["BRING \u00a72.2.3 p39 (scan p38)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Use consistent spacing before and after tables.", "rationale": "Spacing helps tables read as distinct blocks.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "vertical_rhythm", "typeset"], "keywords": ["tables", "spacing"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.VERTICAL_RHYTHM.FIGURES.SPACING", "title": "Use consistent spacing around figures", "source_refs": ["BRING \u00a72.2.3 p39 (scan p38)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Use consistent spacing before and after figures.", "rationale": "Spacing clarifies figure boundaries.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "vertical_rhythm", "typeset"], "keywords": ["figures", "spacing"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.VERTICAL_RHYTHM.CAPTIONS.SPACING", "title": "Keep caption spacing consistent", "source_refs": ["BRING \u00a72.2.3 p39 (scan p38)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep spacing between captions and their content consistent.", "rationale": "Consistent caption spacing improves scanability.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "vertical_rhythm", "typeset"], "keywords": ["captions", "spacing"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.VERTICAL_RHYTHM.FOOTNOTES.SPACING", "title": "Keep footnote spacing consistent", "source_refs": ["BRING \u00a72.2.3 p39 (scan p38)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep spacing between body text and footnotes consistent.", "rationale": "Consistent footnote spacing improves clarity.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "vertical_rhythm", "typeset"], "keywords": ["footnotes", "spacing"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_HEADINGS", "title": "Align headings to the baseline grid", "source_refs": ["BRING \u00a72.2.1 p36 (scan p35)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "When a baseline grid is used, align headings to the grid.", "rationale": "Baseline alignment improves rhythm.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "baseline_grid", "typeset"], "keywords": ["headings", "baseline grid"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_CAPTIONS", "title": "Align captions to the baseline grid", "source_refs": ["BRING \u00a72.2.1 p36 (scan p35)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "When a baseline grid is used, align captions to the grid.", "rationale": "Baseline alignment improves consistency.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "baseline_grid", "typeset"], "keywords": ["captions", "baseline grid"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_TABLES", "title": "Align tables to the baseline grid", "source_refs": ["BRING \u00a72.2.1 p36 (scan p35)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "When a baseline grid is used, align table rows to the grid where practical.", "rationale": "Grid alignment improves table readability.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "baseline_grid", "typeset"], "keywords": ["tables", "baseline grid"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.BASELINE_GRID.APPLY_TO_BLOCK_QUOTES", "title": "Align block quotes to the baseline grid", "source_refs": ["BRING \u00a72.2.1 p36 (scan p35)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "When a baseline grid is used, align block quotes to the grid.", "rationale": "Grid alignment reduces visual drift.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "baseline_grid", "typeset"], "keywords": ["block quotes", "baseline grid"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PARAGRAPH.INDENT.PROPORTIONAL", "title": "Keep indents proportional to text size", "source_refs": ["BRING \u00a72.3.4 p41 (scan p40)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep first-line indents proportional to the text size and measure.", "rationale": "Proportional indents preserve rhythm.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "paragraphs", "typeset"], "keywords": ["indents", "proportion"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PARAGRAPH.INDENT.NOT_TOO_DEEP", "title": "Avoid overly deep indents", "source_refs": ["BRING \u00a72.3.4 p41 (scan p40)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid indents so deep they appear like block quotes or list levels.", "rationale": "Excessive indents confuse structure.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "paragraphs", "typeset"], "keywords": ["indents", "depth"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PARAGRAPH.INDENT.WITHIN_MEASURE", "title": "Keep indents small relative to measure", "source_refs": ["BRING \u00a72.3.4 p41 (scan p40)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep indents small relative to line length so they do not reduce usable measure.", "rationale": "Overly large indents waste space.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "paragraphs", "typeset"], "keywords": ["indents", "measure"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PARAGRAPH.BLOCK_STYLE.CONSISTENT", "title": "If using block paragraphs, keep spacing consistent", "source_refs": ["BRING \u00a72.3.2 p39 (scan p38)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "If paragraphs are separated by space instead of indents, keep the spacing consistent.", "rationale": "Consistent spacing preserves rhythm.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "paragraphs"], "keywords": ["block paragraphs", "spacing"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PARAGRAPH.SECTION_BREAKS.CLEAR", "title": "Make section breaks distinct", "source_refs": ["BRING \u00a72.3.2 p39 (scan p38)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Make section breaks distinct from ordinary paragraph breaks through spacing or symbols.", "rationale": "Clear breaks help navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "paragraphs"], "keywords": ["section breaks", "spacing"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PARAGRAPH.LISTS.HANGING_INDENT", "title": "Use hanging indents for multi-line list items", "source_refs": ["BRING \u00a72.3.4 p41 (scan p40)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Use hanging indents for multi-line list items so labels align and text remains readable.", "rationale": "Hanging indents improve list scanning.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "lists", "typeset"], "keywords": ["hanging indent", "lists"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PARAGRAPH.LISTS.ALIGN_WITH_BODY", "title": "Align list text with body measure", "source_refs": ["BRING \u00a72.3.4 p41 (scan p40)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Align list text with the body text measure to avoid erratic line lengths.", "rationale": "Aligned measures improve rhythm.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "lists", "typeset"], "keywords": ["lists", "measure"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PARAGRAPH.RUN_IN_HEADS.CONSISTENT", "title": "Keep run-in heads consistent", "source_refs": ["BRING \u00a72.3.1 p39 (scan p38)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "If run-in heads are used, keep punctuation, spacing, and styling consistent.", "rationale": "Consistency clarifies structure.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "paragraphs"], "keywords": ["run-in heads", "consistency"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PARAGRAPH.DROP_CAPS.ALIGN_BASELINE", "title": "Align drop caps to the baseline grid", "source_refs": ["BRING \u00a72.3.1 p39 (scan p38)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "If drop caps are used, align them to the baseline grid so text flows cleanly.", "rationale": "Aligned drop caps avoid uneven texture.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the layout constraint.", "tags": ["layout", "drop_caps", "typeset"], "keywords": ["drop caps", "baseline"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PARAGRAPH.AFTER_QUOTE.FLUSH", "title": "Keep paragraphs after quotes consistent", "source_refs": ["BRING \u00a72.3.2 p39 (scan p38)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep paragraph treatment after block quotes consistent (indent or flush) across the document.", "rationale": "Consistency preserves rhythm.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "paragraphs"], "keywords": ["block quotes", "after"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PARAGRAPH.AVOID_WIDOW_START", "title": "Avoid single-line paragraph starts", "source_refs": ["BRING \u00a72.4.9 p44 (scan p43)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid starting a page with a single line of a paragraph when it creates an orphaned line.", "rationale": "Single-line starts reduce readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["orphan", "page start"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PARAGRAPH.AVOID_WIDOW_END", "title": "Avoid single-line paragraph endings", "source_refs": ["BRING \u00a72.4.9 p44 (scan p43)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid ending a page with a single trailing line of a paragraph when it creates a widow.", "rationale": "Single-line endings look accidental.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["widow", "page end"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGINATION.KEEP_FIGURE_WITH_CAPTION", "title": "Keep figures with their captions", "source_refs": ["BRING \u00a72.4.9 p44 (scan p43)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep figures on the same page as their captions when possible.", "rationale": "Separated captions reduce comprehension.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["figures", "captions"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGINATION.KEEP_TABLE_WITH_HEADER", "title": "Keep tables with their header row", "source_refs": ["BRING \u00a72.4.9 p44 (scan p43)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep table header rows with the table body; repeat headers when a table spans pages.", "rationale": "Headers prevent misreading.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["tables", "headers"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGINATION.KEEP_LIST_WITH_INTRO", "title": "Keep list introductions with the list", "source_refs": ["BRING \u00a72.4.9 p44 (scan p43)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Keep a list\u2019s introductory sentence with at least the first list item.", "rationale": "Separated introductions confuse readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["lists", "intro"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGINATION.AVOID_BREAK_AFTER_HEADING", "title": "Avoid breaks immediately after headings", "source_refs": ["BRING \u00a72.4.9 p44 (scan p43)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid page breaks immediately after a heading; keep a minimum amount of text with it.", "rationale": "Headings need supporting text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["headings", "page breaks"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGINATION.AVOID_BREAK_BEFORE_LAST_LINE", "title": "Avoid breaking before the last line of a paragraph", "source_refs": ["BRING \u00a72.4.9 p44 (scan p43)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid breaking a paragraph so only the final line appears on the next page.", "rationale": "This creates an orphaned line.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["orphans", "paragraphs"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGINATION.AVOID_BREAK_IN_EQUATIONS", "title": "Avoid breaking equations across pages", "source_refs": ["BRING \u00a79.4 p42 (scan p41)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid page breaks within displayed equations; keep them intact when possible.", "rationale": "Broken equations are hard to interpret.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["equations", "page breaks"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGINATION.AVOID_BREAK_IN_BLOCK_QUOTES", "title": "Avoid breaking block quotes across pages", "source_refs": ["BRING \u00a79.4 p42 (scan p41)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid splitting block quotations across pages unless they are long.", "rationale": "Split quotes disrupt reading.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["block quotes", "page breaks"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGINATION.BALANCE_FINAL_PAGE", "title": "Balance the final page of a section", "source_refs": ["BRING \u00a79.4 p42 (scan p41)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Balance the final page of a section so it does not look unnaturally sparse.", "rationale": "Balanced endings look intentional.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["final page", "balance"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGINATION.AVOID_LONELY_LINE_IN_LISTS", "title": "Avoid lonely list items at page breaks", "source_refs": ["BRING \u00a72.4.9 p44 (scan p43)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid page breaks that leave a single list item alone at the top or bottom of a page.", "rationale": "Lonely list items reduce readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["lists", "page breaks"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGINATION.AVOID_STRANDED_CAPTIONS", "title": "Avoid captions separated from content", "source_refs": ["BRING \u00a72.4.9 p44 (scan p43)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid leaving a caption separated from its figure or table by a page break.", "rationale": "Separated captions reduce clarity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["captions", "page breaks"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGINATION.AVOID_EXCESS_WHITE_SPACE", "title": "Avoid excessive white space from breaks", "source_refs": ["BRING \u00a79.4 p42 (scan p41)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid page-break decisions that create large accidental white gaps.", "rationale": "Excess white space looks unbalanced.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["white space", "page breaks"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "BRING.LAYOUT.PAGINATION.CLEAR_SECTION_BREAKS", "title": "Use clear section breaks", "source_refs": ["BRING \u00a79.4 p42 (scan p41)"], "category": "layout", "severity": "should", "applies_to": "pdf", "rule_text": "Use clear section breaks rather than relying on subtle spacing changes alone.", "rationale": "Clear breaks improve navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["layout", "manual_checklist=true", "pagination"], "keywords": ["section breaks", "navigation"], "dependencies": [], "exceptions": [], "status": "active"}
diff --git a/spec/rules/layout/v1_layout_006.ndjson b/spec/rules/layout/v1_layout_006.ndjson
new file mode 100644
index 0000000..1e3d91a
--- /dev/null
+++ b/spec/rules/layout/v1_layout_006.ndjson
@@ -0,0 +1,3 @@
+{"id":"HOUSE.LAYOUT.HTML.MEASURE.MAX_WIDTH","title":"Constrain line length in HTML outputs","source_refs":["HOUSE §LAYOUT.HTML.MEASURE p1"],"category":"layout","severity":"should","applies_to":"html","rule_text":"Constrain body text measure in HTML outputs (for example via max-width in ch) so line length stays in a readable range.","rationale":"Readable line length reduces fatigue and improves scanability.","enforcement":"typeset","autofix":"suggest","autofix_notes":"Adjust profile CSS to set a max-width for the main content container.","tags":["layout","measure","typeset"],"keywords":["line length","measure","html"],"dependencies":[],"exceptions":["Full-width layouts for posters or dashboards may intentionally exceed the range; document the choice."],"status":"active"}
+{"id":"HOUSE.LAYOUT.HTML.GUTTERS.MIN_PADDING","title":"Keep minimum side padding on narrow screens","source_refs":["HOUSE §LAYOUT.HTML.GUTTERS p1"],"category":"layout","severity":"should","applies_to":"html","rule_text":"Maintain minimum side padding in HTML outputs so text does not touch the viewport edges on narrow screens.","rationale":"Edge-to-edge text reduces readability and feels cramped.","enforcement":"typeset","autofix":"suggest","autofix_notes":"Set responsive horizontal padding for the content container in the profile CSS.","tags":["layout","gutters","typeset"],"keywords":["padding","responsive","html"],"dependencies":[],"exceptions":["Full-bleed layouts may allow edge-to-edge text for specific components; document the exception."],"status":"active"}
+{"id":"HOUSE.LAYOUT.HTML.SECTION_SPACING.CONSISTENT","title":"Use consistent section spacing in HTML outputs","source_refs":["HOUSE §LAYOUT.HTML.SECTION_SPACING p1"],"category":"layout","severity":"should","applies_to":"html","rule_text":"Use consistent vertical spacing between major sections (headings, lists, figures) in HTML outputs.","rationale":"Consistent spacing clarifies structure and hierarchy.","enforcement":"typeset","autofix":"suggest","autofix_notes":"Set profile spacing tokens for headings, lists, and figures; keep deltas consistent.","tags":["layout","vertical_rhythm","typeset"],"keywords":["spacing","sections","html"],"dependencies":[],"exceptions":["Intentional section breaks may use larger spacing with a clear cue."],"status":"active"}
diff --git a/spec/rules/layout/v1_layout_007.ndjson b/spec/rules/layout/v1_layout_007.ndjson
new file mode 100644
index 0000000..1874fe2
--- /dev/null
+++ b/spec/rules/layout/v1_layout_007.ndjson
@@ -0,0 +1,2 @@
+{"id":"HOUSE.LAYOUT.MD.BLANK_LINES.SPARING","title":"Avoid excessive blank lines in Markdown","source_refs":["HOUSE §LAYOUT.MD.BLANK_LINES.SPARING p1"],"category":"layout","severity":"should","applies_to":"md","rule_text":"Avoid inserting multiple consecutive blank lines between paragraphs unless a clear section break is intended.","rationale":"Excess blank lines fragment the text block and disrupt rhythm.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["layout","spacing"],"keywords":["blank lines","paragraph spacing"],"dependencies":[],"exceptions":["Section breaks may intentionally use extra space; mark with a divider if needed."],"status":"active"}
+{"id":"HOUSE.LAYOUT.MD.HEADINGS.NON_EMPTY_SECTIONS","title":"Avoid headings without content","source_refs":["HOUSE §LAYOUT.MD.HEADINGS.NON_EMPTY_SECTIONS p1"],"category":"layout","severity":"should","applies_to":"md","rule_text":"Headings should introduce content; avoid back-to-back headings or headings followed by no content.","rationale":"Empty sections confuse navigation and review.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["layout","headings"],"keywords":["empty sections","headings"],"dependencies":[],"exceptions":["Section divider pages may use headings alone if explicitly labeled as such."],"status":"active"}
diff --git a/spec/rules/layout/v1_layout_008.ndjson b/spec/rules/layout/v1_layout_008.ndjson
new file mode 100644
index 0000000..b07f976
--- /dev/null
+++ b/spec/rules/layout/v1_layout_008.ndjson
@@ -0,0 +1,4 @@
+{"id":"HOUSE.LAYOUT.PAGINATION.CAPTIONS.KEEP_WITH_CONTENT","title":"Keep captions with their figures or tables","source_refs":["HOUSE §QA.CAPTIONS p2"],"category":"layout","severity":"should","applies_to":"pdf","rule_text":"Keep figure and table captions on the same page as their associated content when possible.","rationale":"Separated captions reduce comprehension and auditability.","enforcement":"postrender","autofix":"reflow","autofix_notes":"Adjust pagination or float placement to keep captions with their content.","tags":["pagination","captions"],"keywords":["captions","figures","tables","pagination"],"dependencies":[],"exceptions":["Very large figures may require captions on adjacent pages; note the exception."],"status":"active"}
+{"id":"HOUSE.LAYOUT.PAGINATION.LISTS.KEEP_INTRO","title":"Keep list introductions with the list","source_refs":["HOUSE §QA.LISTS p2"],"category":"layout","severity":"should","applies_to":"pdf","rule_text":"Keep a list introduction on the same page as the first list item.","rationale":"Separated introductions make lists harder to interpret.","enforcement":"postrender","autofix":"reflow","autofix_notes":"Adjust pagination so the intro and first item appear together.","tags":["pagination","lists"],"keywords":["lists","intro","pagination"],"dependencies":[],"exceptions":["Short preview pages may allow a split if clearly labeled."],"status":"active"}
+{"id":"HOUSE.LAYOUT.PAGINATION.LISTS.AVOID_LONELY_ITEM","title":"Avoid lone list items at page edges","source_refs":["HOUSE §QA.LISTS p2"],"category":"layout","severity":"should","applies_to":"pdf","rule_text":"Avoid pages where a list has a single orphaned item at the top or bottom.","rationale":"Lonely list items reduce readability and signal weak pagination.","enforcement":"postrender","autofix":"reflow","autofix_notes":"Reflow list breaks to avoid single-item pages.","tags":["pagination","lists"],"keywords":["lists","pagination","orphans"],"dependencies":[],"exceptions":["Very short lists may fit on a single page without issue."],"status":"active"}
+{"id":"HOUSE.LAYOUT.PAGINATION.HEADINGS.NO_ADJACENT","title":"Avoid back-to-back headings without body text","source_refs":["HOUSE §QA.HEADINGS p2"],"category":"layout","severity":"should","applies_to":"pdf","rule_text":"Avoid consecutive headings with no intervening body content, especially across page breaks.","rationale":"Adjacent headings weaken hierarchy and confuse navigation.","enforcement":"postrender","autofix":"reflow","autofix_notes":"Reflow or insert body content so headings are not stacked without text.","tags":["pagination","headings"],"keywords":["headings","pagination","stacked headings"],"dependencies":[],"exceptions":["Outline-only sections may stack headings by design; document the exception."],"status":"active"}
diff --git a/spec/rules/layout/v1_layout_009.ndjson b/spec/rules/layout/v1_layout_009.ndjson
new file mode 100644
index 0000000..5c106fe
--- /dev/null
+++ b/spec/rules/layout/v1_layout_009.ndjson
@@ -0,0 +1 @@
+{"id":"HOUSE.LAYOUT.PAGINATION.RUNT_FINAL_PAGE","title":"Avoid runt final pages","source_refs":["HOUSE §LAYOUT.PAGINATION.RUNT_FINAL_PAGE p1"],"category":"layout","severity":"should","applies_to":"pdf","rule_text":"Ensure the final page of a section or document carries enough content to look intentional; avoid leaving only a few lines.","rationale":"Very short final pages look accidental and weaken closure.","enforcement":"postrender","autofix":"none","autofix_notes":"","tags":["layout","pagination","runt_final_page"],"keywords":["final page","copyfitting","pagination"],"dependencies":[],"exceptions":["Very short outputs or title pages may be acceptable with editorial review."],"status":"active"}
diff --git a/spec/rules/links/v1_links_003.ndjson b/spec/rules/links/v1_links_003.ndjson
new file mode 100644
index 0000000..35fb67e
--- /dev/null
+++ b/spec/rules/links/v1_links_003.ndjson
@@ -0,0 +1,16 @@
+{"id":"HOUSE.LINKS.DISALLOW.JAVASCRIPT_URIS","title":"Do not allow javascript: links","source_refs":["HOUSE §QA.LINK_WRAP p2","HOUSE §LINKS.SECURITY p3"],"category":"links","severity":"must","applies_to":"md","rule_text":"Do not emit javascript: URIs in links; they are unsafe and not appropriate for published documents.","rationale":"javascript: links are a security risk.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links","security"],"keywords":["javascript:","links","security"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.LINKS.EMAILS.MAILTO_POLICY","title":"Use mailto: links intentionally","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"all","rule_text":"Use mailto: links intentionally and avoid publishing personal addresses without consent; prefer role-based addresses when possible.","rationale":"Published contact links should not create privacy issues.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","links","privacy"],"keywords":["mailto","email","privacy"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.LINKS.TEXT.NO_CLICK_HERE","title":"Avoid 'click here' link text","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"Avoid link text like 'click here' or 'here'; use descriptive labels.","rationale":"Published links must be durable, readable, and safe.","enforcement":"lint","autofix":"suggest","autofix_notes":"Suggest a safer or cleaner link form when a rewrite is risky.","tags":["links"],"keywords":["click here","accessibility"],"dependencies":[],"exceptions":["Some targets may only exist on internal networks; do not publish externally."],"status":"active"}
+{"id":"HOUSE.LINKS.URLS.ANCHORS.STABLE","title":"Use stable anchors when linking within a document","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"When linking within a document, prefer stable heading anchors; avoid brittle auto-generated IDs when possible.","rationale":"Published links must be durable, readable, and safe.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","links"],"keywords":["anchors","internal links"],"dependencies":[],"exceptions":["Some targets may only exist on internal networks; do not publish externally."],"status":"active"}
+{"id":"HOUSE.LINKS.URLS.AVOID.INTERNAL_HOSTNAMES","title":"Avoid internal hostnames in published docs","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"must","applies_to":"md","rule_text":"Avoid internal-only hostnames in documents intended for external publication; use public equivalents or remove.","rationale":"Published links must be durable, readable, and safe.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","links"],"keywords":["internal hostname","opsec"],"dependencies":[],"exceptions":["Some targets may only exist on internal networks; do not publish externally."],"implementation_notes":"Deprecated: superseded by HOUSE.LINKS.AUTO.INTERNAL_HOSTNAMES.AVOID (lint).","status":"deprecated"}
+{"id":"HOUSE.LINKS.URLS.AVOID.NAKED_URLS_IN_PROSE","title":"Avoid naked URLs in prose","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"In running prose, prefer labeled links instead of exposing long raw URLs unless the URL itself is the subject.","rationale":"Published links must be durable, readable, and safe.","enforcement":"lint","autofix":"suggest","autofix_notes":"Suggest a safer or cleaner link form when a rewrite is risky.","tags":["links"],"keywords":["bare URL","readability"],"dependencies":[],"exceptions":["Some targets may only exist on internal networks; do not publish externally."],"status":"active"}
+{"id":"HOUSE.LINKS.URLS.BARE_DOMAIN.TRAILING_SLASH","title":"Be consistent about trailing slashes","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"Be consistent about trailing slash usage for bare-domain links based on the canonical target.","rationale":"Published links must be durable, readable, and safe.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","links"],"keywords":["trailing slash","canonical"],"dependencies":[],"exceptions":["Some targets may only exist on internal networks; do not publish externally."],"status":"active"}
+{"id":"HOUSE.LINKS.URLS.CANONICAL.NO_TRACKING_PARAMS","title":"Prefer canonical URLs without tracking params","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"Prefer canonical URLs without tracking parameters for publication; remove referrer/utm-style parameters when they are not needed.","rationale":"Published links must be durable, readable, and safe.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","links"],"keywords":["canonical URL","tracking"],"dependencies":[],"exceptions":["Some targets may only exist on internal networks; do not publish externally."],"status":"active"}
+{"id":"HOUSE.LINKS.URLS.DISALLOW.FTP","title":"Avoid ftp: links in published docs","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"Avoid ftp: links for publication; prefer HTTPS equivalents or document the constraint.","rationale":"Published links must be durable, readable, and safe.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","links"],"keywords":["ftp","security"],"dependencies":[],"exceptions":["Some targets may only exist on internal networks; do not publish externally."],"status":"active"}
+{"id":"HOUSE.LINKS.URLS.DISALLOW.LOCALHOST","title":"Avoid localhost links in published docs","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"must","applies_to":"md","rule_text":"Do not publish localhost links as references; they are not usable for readers.","rationale":"Published links must be durable, readable, and safe.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links"],"keywords":["localhost","links"],"dependencies":[],"exceptions":["Some targets may only exist on internal networks; do not publish externally."],"status":"active"}
+{"id":"HOUSE.LINKS.URLS.DOIS.PREFER_DOI_ORG","title":"Prefer doi.org links for DOIs","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"When citing DOIs, prefer the canonical doi.org form and keep it consistent.","rationale":"Published links must be durable, readable, and safe.","enforcement":"lint","autofix":"suggest","autofix_notes":"Suggest a safer or cleaner link form when a rewrite is risky.","tags":["links"],"keywords":["doi","doi.org"],"dependencies":[],"exceptions":["Some targets may only exist on internal networks; do not publish externally."],"status":"active"}
+{"id":"HOUSE.LINKS.URLS.NO_BACKSLASH","title":"Avoid backslashes in URLs","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"Avoid backslashes in URLs; use forward slashes.","rationale":"Published links must be durable, readable, and safe.","enforcement":"lint","autofix":"suggest","autofix_notes":"Suggest a safer or cleaner link form when a rewrite is risky.","tags":["links"],"keywords":["urls","slashes"],"dependencies":[],"exceptions":["Some targets may only exist on internal networks; do not publish externally."],"status":"active"}
+{"id":"HOUSE.LINKS.URLS.NO_TRAILING_PARENS","title":"Avoid stray parentheses in bare URLs","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"When a bare URL appears next to parentheses, ensure the URL does not accidentally include a closing parenthesis.","rationale":"Published links must be durable, readable, and safe.","enforcement":"lint","autofix":"suggest","autofix_notes":"Suggest a safer or cleaner link form when a rewrite is risky.","tags":["links"],"keywords":["urls","punctuation"],"dependencies":[],"exceptions":["Some targets may only exist on internal networks; do not publish externally."],"status":"active"}
+{"id":"HOUSE.LINKS.URLS.NO_WHITESPACE","title":"Do not include whitespace in link targets","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"must","applies_to":"md","rule_text":"Do not include whitespace inside link targets; whitespace breaks URLs and tooling.","rationale":"Published links must be durable, readable, and safe.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links"],"keywords":["urls","whitespace"],"dependencies":[],"exceptions":["Some targets may only exist on internal networks; do not publish externally."],"status":"active"}
+{"id":"HOUSE.LINKS.URLS.NO_ZERO_WIDTH","title":"Avoid zero-width characters in URLs","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"must","applies_to":"md","rule_text":"Avoid zero-width characters in URLs; they can break copying and can be used for deceptive links.","rationale":"Published links must be durable, readable, and safe.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links"],"keywords":["zero width","security"],"dependencies":[],"exceptions":["Some targets may only exist on internal networks; do not publish externally."],"status":"active"}
+{"id":"HOUSE.LINKS.URLS.RELATIVE.REPO_LOCAL","title":"Use relative links for repo-local docs","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"For repo-local documentation, prefer relative links so builds remain portable.","rationale":"Published links must be durable, readable, and safe.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","links"],"keywords":["relative links","repos"],"dependencies":[],"exceptions":["Some targets may only exist on internal networks; do not publish externally."],"status":"active"}
diff --git a/spec/rules/links/v1_links_004.ndjson b/spec/rules/links/v1_links_004.ndjson
new file mode 100644
index 0000000..490c3b5
--- /dev/null
+++ b/spec/rules/links/v1_links_004.ndjson
@@ -0,0 +1,13 @@
+{"id": "HOUSE.LINKS.TEXT.MATCHES_TARGET", "title": "Ensure link text matches destination", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Ensure descriptive link text accurately reflects the destination content.", "rationale": "Mismatched text misleads readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["link text", "accuracy"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.TEXT.AVOID_OVERLONG_LABELS", "title": "Avoid overly long link labels", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Avoid excessively long link labels in running text; shorten or move to footnotes when needed.", "rationale": "Overlong links disrupt reading flow.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["link labels", "readability"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.TEXT.DIFFERENTIATE_REPEATED_LINKS", "title": "Differentiate repeated links", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "If the same link appears multiple times, ensure the label clarifies why it is repeated or consolidate references.", "rationale": "Redundant links clutter prose.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["repeated links", "consistency"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.URLS.NO_EMBEDDED_CREDENTIALS", "title": "Avoid embedded credentials in URLs", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "must", "applies_to": "all", "rule_text": "Do not embed usernames, passwords, or API tokens in URLs.", "rationale": "Embedded credentials are a security risk.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["credentials", "security"], "dependencies": [], "exceptions": [], "implementation_notes": "Deprecated: superseded by HOUSE.LINKS.AUTO.EMBEDDED_CREDENTIALS.AVOID (lint).", "status": "deprecated"}
+{"id": "HOUSE.LINKS.URLS.AVOID_PRIVATE_IPS", "title": "Avoid private IP URLs for public docs", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Avoid links to private IP ranges in documents intended for external audiences.", "rationale": "Private IPs are inaccessible to most readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["private ip", "accessibility"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.URLS.NO_SESSION_PARAMS", "title": "Avoid session or one-time parameters", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Remove session IDs or one-time parameters from published links.", "rationale": "Session links rot quickly.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["session params", "durability"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.URLS.CANONICAL_HOST", "title": "Prefer canonical hostnames", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Prefer canonical hostnames for published links and avoid alternate mirrors unless necessary.", "rationale": "Canonical links are more durable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["canonical", "hostnames"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.URLS.STABLE_ANCHORS", "title": "Use stable anchors for in-page links", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Use stable anchors for in-page links and avoid auto-generated IDs that may change.", "rationale": "Stable anchors prevent link rot.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["anchors", "stability"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.URLS.NO_QUERY_WHEN_NOT_NEEDED", "title": "Avoid unnecessary query strings", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Avoid unnecessary query strings in published URLs when a clean canonical link exists.", "rationale": "Clean URLs are more durable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["query strings", "canonical"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.URLS.SHORTENERS.AVOID", "title": "Avoid link shorteners", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Avoid URL shorteners in published docs; they obscure destinations and can expire.", "rationale": "Shorteners reduce trust and durability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["shorteners", "durability"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.URLS.MAILTO.INTENT", "title": "Use mailto links only when needed", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Use mailto links only when email contact is intended; avoid mailto for general references.", "rationale": "Mailto links can be noisy for readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["mailto", "contact"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.TEXT.NO_EMOJIS", "title": "Avoid emoji-only link text", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Avoid using emoji-only link text; provide readable labels for accessibility.", "rationale": "Emoji-only links are ambiguous.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["emoji", "accessibility"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.TEXT.LINK_TARGET_MISMATCH", "title": "Avoid misleading link labels", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "must", "applies_to": "all", "rule_text": "Do not use labels that imply a different destination than the link target.", "rationale": "Misleading labels break trust.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["misleading", "trust"], "dependencies": [], "exceptions": [], "status": "active"}
diff --git a/spec/rules/links/v1_links_005.ndjson b/spec/rules/links/v1_links_005.ndjson
new file mode 100644
index 0000000..386a99e
--- /dev/null
+++ b/spec/rules/links/v1_links_005.ndjson
@@ -0,0 +1,16 @@
+{"id": "HOUSE.LINKS.URLS.AVOID.STAGING_DOMAINS", "title": "Avoid staging or test hostnames in published docs", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Do not publish links to staging, dev, or test hostnames; replace with production or public equivalents.", "rationale": "Staging links rot and confuse readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["staging", "dev", "test", "hostnames"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.URLS.AVOID.EXPIRING_SIGNED", "title": "Avoid expiring signed URLs", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Avoid signed URLs that include expiry, signature, or token parameters; use stable public links instead.", "rationale": "Expiring links break audits and reviews.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["signed urls", "expires", "tokens"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.URLS.AVOID.ONE_TIME_INVITES", "title": "Avoid one-time invite links", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Avoid one-time or invite-only links in published docs; provide a stable onboarding path instead.", "rationale": "Invite links often expire and leak access.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["invite links", "onboarding"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.URLS.AVOID.PASSWORD_RESET", "title": "Do not publish password-reset or login links", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "must", "applies_to": "all", "rule_text": "Do not publish password-reset, login, or account-recovery links in public documentation.", "rationale": "Security-sensitive links should not be shared broadly.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["password reset", "login", "security"], "dependencies": [], "exceptions": [], "implementation_notes": "Deprecated: superseded by HOUSE.LINKS.AUTO.PASSWORD_RESET.AVOID (lint) and HOUSE.LINKS.AUTO.LOGIN_LINKS.AVOID (lint).", "status": "deprecated"}
+{"id": "HOUSE.LINKS.URLS.AVOID.TEXT_FRAGMENTS", "title": "Avoid text-fragment URLs", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Avoid URLs that include text fragments (e.g., #:~:text=...); they are brittle across browsers and edits.", "rationale": "Text fragments are unstable anchors.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["text fragments", "anchors"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.URLS.NO_PROTOCOL_RELATIVE", "title": "Avoid protocol-relative URLs", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Avoid protocol-relative URLs (//example.com); use explicit https:// links instead.", "rationale": "Explicit schemes reduce ambiguity and enforce HTTPS.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["protocol relative", "https"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.URLS.AVOID.IP_LITERALS", "title": "Avoid literal IP addresses when a domain exists", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Avoid using literal IP addresses in published links when a stable domain name exists.", "rationale": "Domains are more durable and readable than IPs.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["ip addresses", "domains"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.URLS.AVOID.TEMP_FILESHARES", "title": "Avoid temporary file-share links", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Avoid temporary file-share URLs; publish artifacts on stable hosting surfaces instead.", "rationale": "Temporary links expire and break review.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["file sharing", "temporary links"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.TEXT.FILETYPE.LABEL", "title": "Label downloadable file types", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "When linking to a download, label the file type (e.g., PDF, CSV) in the link text or nearby.", "rationale": "Readers should know what they will open.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["downloads", "file type", "labels"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.TEXT.FILESIZE.LABEL", "title": "Label large downloads with file size", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "When linking to large files, note approximate size to set expectations.", "rationale": "Size labeling prevents surprise downloads.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["downloads", "file size"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.TEXT.ACCESS_RESTRICTIONS.NOTE", "title": "Note access restrictions", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "If a link requires authentication or special access, note that in the link text or nearby.", "rationale": "Access notes prevent dead ends for readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["access", "authentication"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.TEXT.LANGUAGE.LABEL", "title": "Label non-default language resources", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "If a link target is in a different language, label the language in the link text or nearby.", "rationale": "Language labels improve accessibility.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["language", "accessibility"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.TEXT.ARCHIVE_AND_HTML.BOTH", "title": "Provide HTML view fallbacks for downloads", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "When linking to downloadable artifacts, provide an HTML view fallback when available.", "rationale": "HTML fallbacks improve review in restricted environments.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["html fallback", "downloads"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.TEXT.PARTIAL_WORD.AVOID", "title": "Avoid linking only part of a word", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "Avoid linking a fragment of a word; link the full word or phrase instead.", "rationale": "Partial-word links are hard to read and click.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["link text", "readability"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.TEXT.MIRROR.LABEL", "title": "Label primary vs mirror links", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "If multiple mirrors are listed, label which link is primary and which are mirrors.", "rationale": "Clear labeling prevents confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["mirrors", "redundancy"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "HOUSE.LINKS.TEXT.STABILITY.NOTE", "title": "Note unstable or moving targets", "source_refs": ["HOUSE \u00a7QA.LINK_WRAP p2"], "category": "links", "severity": "should", "applies_to": "all", "rule_text": "If a link points to a moving target (rolling docs, latest builds), note that in the text.", "rationale": "Readers need to know when a link may change.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "links"], "keywords": ["stability", "moving targets"], "dependencies": [], "exceptions": [], "status": "active"}
diff --git a/spec/rules/links/v1_links_006.ndjson b/spec/rules/links/v1_links_006.ndjson
new file mode 100644
index 0000000..da01472
--- /dev/null
+++ b/spec/rules/links/v1_links_006.ndjson
@@ -0,0 +1,10 @@
+{"id":"HOUSE.LINKS.AUTO.FTP.AVOID","title":"Avoid ftp links","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"Avoid ftp links in published documents; use HTTPS equivalents when possible.","rationale":"FTP links are insecure and unreliable for readers.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links","security"],"keywords":["ftp","security"],"dependencies":[],"exceptions":["Legacy archives may only be available via ftp; note the limitation."],"status":"active"}
+{"id":"HOUSE.LINKS.AUTO.EMBEDDED_CREDENTIALS.AVOID","title":"Avoid embedded credentials in URLs","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"must","applies_to":"md","rule_text":"Do not include usernames or passwords in URLs.","rationale":"Embedded credentials are a security risk and can leak access.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links","security"],"keywords":["credentials","security"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.LINKS.AUTO.TRACKING_PARAMS.AVOID","title":"Avoid tracking parameters in URLs","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"Remove unnecessary tracking parameters (utm, ref, fbclid) from published URLs.","rationale":"Tracking parameters reduce durability and privacy.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links","privacy"],"keywords":["tracking params","utm"],"dependencies":[],"exceptions":["If parameters are required to access a resource, document the reason."],"status":"active"}
+{"id":"HOUSE.LINKS.AUTO.SESSION_PARAMS.AVOID","title":"Avoid session or token parameters in URLs","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"Avoid session IDs or token parameters in published links.","rationale":"Session links expire and break audits.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links"],"keywords":["session","token"],"dependencies":[],"exceptions":["Short-lived access links should be replaced with stable paths before publication."],"status":"active"}
+{"id":"HOUSE.LINKS.AUTO.STAGING_HOSTNAMES.AVOID","title":"Avoid staging or test hostnames","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"Avoid links to staging, dev, test, or preview hostnames in published documents.","rationale":"Non-production hostnames are unstable and confusing for readers.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links"],"keywords":["staging","dev","test"],"dependencies":[],"exceptions":["Internal-only docs may intentionally reference non-prod systems."],"status":"active"}
+{"id":"HOUSE.LINKS.AUTO.INTERNAL_HOSTNAMES.AVOID","title":"Avoid internal hostnames","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"must","applies_to":"md","rule_text":"Do not publish internal-only hostnames in external-facing documents.","rationale":"Internal hostnames are inaccessible and may leak infrastructure details.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links","opsec"],"keywords":["internal hostnames","opsec"],"dependencies":[],"exceptions":["Private docs may allow internal links if the audience is scoped."],"status":"active"}
+{"id":"HOUSE.LINKS.AUTO.PRIVATE_IPS.AVOID","title":"Avoid private IP addresses in links","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"Avoid private IP ranges in published links; use public hostnames instead.","rationale":"Private IPs are not reachable for most readers.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links"],"keywords":["private ip","access"],"dependencies":[],"exceptions":["Internal-only docs may reference private IPs with clear labeling."],"status":"active"}
+{"id":"HOUSE.LINKS.AUTO.INVITE_LINKS.AVOID","title":"Avoid one-time invite links","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"Avoid one-time or invite-only URLs in published documents; use a stable onboarding path.","rationale":"Invite links expire and can leak access.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links","security"],"keywords":["invite links","onboarding"],"dependencies":[],"exceptions":["Short-lived internal notes may include invites if time-bounded and clearly labeled."],"status":"active"}
+{"id":"HOUSE.LINKS.AUTO.PASSWORD_RESET.AVOID","title":"Avoid password reset links","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"must","applies_to":"md","rule_text":"Do not include password reset or recovery links in published documents.","rationale":"Reset links are security-sensitive and usually time-bound.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links","security"],"keywords":["password reset","security"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.LINKS.AUTO.LOGIN_LINKS.AVOID","title":"Avoid login links in public docs","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"Avoid linking directly to login pages in public documentation; link to a stable landing page instead.","rationale":"Login links can leak tenant details and may change paths.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links"],"keywords":["login","signin"],"dependencies":[],"exceptions":["Private/internal docs may link to login pages when appropriate."],"status":"active"}
diff --git a/spec/rules/links/v1_links_007.ndjson b/spec/rules/links/v1_links_007.ndjson
new file mode 100644
index 0000000..50c5b7a
--- /dev/null
+++ b/spec/rules/links/v1_links_007.ndjson
@@ -0,0 +1,4 @@
+{"id":"HOUSE.LINKS.AUTO.FILETYPE_LABEL.REQUIRED","title":"Label downloadable file types in link text","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"When linking to downloadable files, include the file type (PDF, CSV, ZIP, etc.) in the link text or immediately adjacent text.","rationale":"Readers should know what kind of file they will open or download.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links","accessibility"],"keywords":["file type","downloads","labels"],"dependencies":[],"exceptions":["If the file type is already obvious from nearby context, labels may be omitted."],"status":"active"}
+{"id":"HOUSE.LINKS.AUTO.PARTIAL_WORD.AVOID","title":"Avoid linking only part of a word","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"Avoid links that wrap only part of a word; link the full word or phrase instead.","rationale":"Partial-word links are harder to read and click.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links"],"keywords":["link text","readability"],"dependencies":[],"exceptions":[],"status":"active"}
+{"id":"HOUSE.LINKS.AUTO.LABEL_LENGTH.AVOID_OVERLONG","title":"Avoid overly long link labels in running text","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"Avoid excessively long link labels in prose; shorten labels or move the link into a note when needed.","rationale":"Overlong link labels interrupt reading flow.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links"],"keywords":["link labels","readability"],"dependencies":[],"exceptions":["Reference sections may list full titles or longer labels when needed."],"status":"active"}
+{"id":"HOUSE.LINKS.AUTO.HTML_FALLBACK.REQUIRED","title":"Provide HTML view fallbacks for download links","source_refs":["HOUSE §QA.LINK_WRAP p2"],"category":"links","severity":"should","applies_to":"md","rule_text":"When linking to downloadable artifacts, provide an HTML view fallback when available.","rationale":"HTML fallbacks improve review in environments that block or refuse downloads.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links","review"],"keywords":["html fallback","downloads"],"dependencies":[],"exceptions":["If no HTML view exists, note the limitation in nearby text."],"status":"active"}
diff --git a/spec/rules/links/v1_links_008.ndjson b/spec/rules/links/v1_links_008.ndjson
new file mode 100644
index 0000000..14d2f08
--- /dev/null
+++ b/spec/rules/links/v1_links_008.ndjson
@@ -0,0 +1,6 @@
+{"id":"CMOS.LINKS.PUNCTUATE_NORMALLY","title":"Punctuate sentences with URLs and emails normally","source_refs":["CMOS18 §6.8 p381 (scan p403)"],"category":"links","severity":"should","applies_to":"all","rule_text":"Treat URLs and email addresses as normal words in a sentence and keep standard sentence punctuation.","rationale":"Readers should not lose punctuation logic just because a URL appears.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","links"],"keywords":["urls","emails","punctuation"],"dependencies":[],"exceptions":["If a URL is the only content on a line, avoid adding punctuation."],"status":"active"}
+{"id":"CMOS.LINKS.NO_WRAPPERS","title":"Avoid angle brackets or wrappers around URLs","source_refs":["CMOS18 §6.8 p381 (scan p403)"],"category":"links","severity":"should","applies_to":"all","rule_text":"Do not wrap URLs or email addresses in angle brackets or other wrappers in normal prose.","rationale":"Wrappers add visual noise without improving readability.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links"],"keywords":["angle brackets","wrappers","urls"],"dependencies":[],"exceptions":["Literal formats or code samples may require wrappers; mark them as code."],"status":"active"}
+{"id":"CMOS.LINKS.TRAILING_PUNCTUATION_OUTSIDE","title":"Keep trailing punctuation outside link targets","source_refs":["CMOS18 §6.8 p381 (scan p403)"],"category":"links","severity":"should","applies_to":"all","rule_text":"Place trailing sentence punctuation outside the URL or email address.","rationale":"Including punctuation inside the address often breaks the link.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","links"],"keywords":["trailing punctuation","urls"],"dependencies":[],"exceptions":["If a URL genuinely ends with punctuation, clarify with context or rephrase."],"status":"active"}
+{"id":"CMOS.LINKS.HYPERLINK_EXCLUDES_PUNCTUATION","title":"Exclude sentence punctuation from hyperlink markup","source_refs":["CMOS18 §6.8 p381 (scan p403)"],"category":"links","severity":"should","applies_to":"all","rule_text":"When adding hyperlink markup, exclude adjacent sentence punctuation from the link target.","rationale":"This prevents broken URLs and mis-clicks.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","links"],"keywords":["hyperlink","punctuation"],"dependencies":[],"exceptions":["If punctuation is part of the URL, only include that portion in the link."],"status":"active"}
+{"id":"CMOS.LINKS.URL_ONLY_LINE_NO_PUNCT","title":"Avoid terminal punctuation on URL-only lines","source_refs":["CMOS18 §6.8 p381 (scan p403)"],"category":"links","severity":"should","applies_to":"all","rule_text":"If a URL or email address stands alone on its own line, do not add terminal punctuation.","rationale":"Standalone links read better without extra marks.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["links"],"keywords":["standalone url","line"],"dependencies":[],"exceptions":["If the line is part of a sentence, keep punctuation outside the link."],"status":"active"}
+{"id":"CMOS.LINKS.REPHRASE_IF_URL_ENDS_PUNCT","title":"Rephrase when a URL ends with punctuation","source_refs":["CMOS18 §6.8 p381 (scan p403)"],"category":"links","severity":"should","applies_to":"all","rule_text":"If a URL or email address ends with punctuation that could be mistaken for sentence punctuation, rephrase or clarify to avoid confusion.","rationale":"Ambiguous endings cause copy/paste errors.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","links"],"keywords":["url endings","ambiguity"],"dependencies":[],"exceptions":["In code blocks, preserve literal addresses."],"status":"active"}
diff --git a/spec/rules/numbers/v1_numbers_003.ndjson b/spec/rules/numbers/v1_numbers_003.ndjson
new file mode 100644
index 0000000..f3325db
--- /dev/null
+++ b/spec/rules/numbers/v1_numbers_003.ndjson
@@ -0,0 +1,29 @@
+{"id": "CMOS.NUMBERS.DECIMALS.TRAILING_ZEROS.AVOID", "title": "Avoid unnecessary trailing zeros", "source_refs": ["CMOS18 \u00a79.21 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Avoid unnecessary trailing zeros in decimals unless they convey precision required by context.", "rationale": "Extraneous zeros imply false precision.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "decimals"], "keywords": ["trailing zeros", "precision"], "dependencies": [], "exceptions": ["Scientific and technical contexts may require fixed precision; follow domain standards."], "status": "active"}
+{"id": "CMOS.NUMBERS.PERCENTAGES.SYMBOL_OR_WORD.CONSISTENT", "title": "Choose percent symbol or word and keep it consistent", "source_refs": ["CMOS18 \u00a79.20 p599 (scan p621)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Choose either the percent symbol or the word percent and apply the choice consistently within the document.", "rationale": "Mixed percent forms look inconsistent and distract readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "percentages", "consistency"], "keywords": ["percent", "percent sign", "consistency"], "dependencies": [], "exceptions": ["Quoted material may retain its original formatting."], "status": "active"}
+{"id": "CMOS.NUMBERS.PERCENTAGES.SYMBOL_NO_SPACE", "title": "Do not separate the percent symbol from the number", "source_refs": ["CMOS18 \u00a79.20 p599 (scan p621)"], "category": "numbers", "severity": "should", "applies_to": "md", "rule_text": "When using the percent symbol, keep it adjacent to the numeral without a space.", "rationale": "Spacing around percent symbols looks nonstandard and can be misread.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "percentages"], "keywords": ["percent symbol", "spacing"], "dependencies": [], "exceptions": ["Locale-specific formats may allow a space; follow profile locale rules."], "status": "active"}
+{"id": "CMOS.NUMBERS.CURRENCY.SYMBOL_ADJACENT", "title": "Keep currency symbols adjacent to numerals", "source_refs": ["CMOS18 \u00a79.22 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Place currency symbols immediately before the numeral without a space unless a specific standard requires otherwise.", "rationale": "Adjacent symbols are the default convention and reduce ambiguity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "currency"], "keywords": ["currency symbols", "spacing"], "dependencies": [], "exceptions": ["Some locales place the symbol after the number; follow the profile locale."], "status": "active"}
+{"id": "CMOS.NUMBERS.CURRENCY.CODE_POSITION.CONSISTENT", "title": "Keep currency code position consistent", "source_refs": ["CMOS18 \u00a79.25 p602 (scan p624)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When currency codes are used (e.g., ISO codes), keep their position consistent relative to the numeral.", "rationale": "Consistent placement avoids confusion across amounts.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "currency"], "keywords": ["currency codes", "ISO"], "dependencies": [], "exceptions": ["Quoted data may preserve the source formatting."], "status": "active"}
+{"id": "CMOS.NUMBERS.CURRENCY.RANGES.REPEAT_SYMBOL", "title": "Repeat currency symbols in ranges when needed", "source_refs": ["CMOS18 \u00a79.22 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In currency ranges, repeat the symbol if omitting it would be ambiguous or hard to scan.", "rationale": "Clear currency ranges prevent misreading and calculation errors.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "currency", "ranges"], "keywords": ["currency ranges", "symbols"], "dependencies": [], "exceptions": ["Compact tables may omit repeated symbols if column headers make the unit explicit."], "status": "active"}
+{"id": "CMOS.NUMBERS.RANGES.NO_MIXED_FROM_BETWEEN", "title": "Do not mix from/between with dash ranges", "source_refs": ["CMOS18 \u00a79.62 p615 (scan p637)", "CMOS18 \u00a76.83 p415 (scan p437)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Do not combine from/between with a dash range; use either from X to Y or X\u2013Y, not a mixture.", "rationale": "Mixed range constructions are stylistically incorrect and confusing.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ranges"], "keywords": ["ranges", "from to", "between and"], "dependencies": [], "exceptions": ["Quoted material may preserve its original construction."], "status": "active"}
+{"id": "CMOS.NUMBERS.RANGES.REPEAT_UNIT_IF_AMBIG", "title": "Repeat units in ranges when needed for clarity", "source_refs": ["CMOS18 \u00a79.19 p599 (scan p621)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When expressing ranges with units, repeat the unit if omission would be ambiguous.", "rationale": "Readers should not have to infer the unit across a long span.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ranges", "units"], "keywords": ["units", "ranges"], "dependencies": [], "exceptions": ["Short ranges with a clear shared unit may omit repetition."], "status": "active"}
+{"id": "CMOS.NUMBERS.RANGES.UNITS.PLACEMENT_CONSISTENT", "title": "Keep unit placement consistent in ranges", "source_refs": ["CMOS18 \u00a79.19 p599 (scan p621)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Place the unit either after each number or after the range as a whole, and keep the choice consistent.", "rationale": "Consistent unit placement improves scanability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "units", "ranges"], "keywords": ["unit placement", "ranges"], "dependencies": [], "exceptions": ["Tables may use a single unit in the header instead."], "status": "active"}
+{"id": "CMOS.NUMBERS.INCLUSIVE.SHORTEN_SECOND_NUMBER", "title": "Use consistent shortening in inclusive ranges", "source_refs": ["CMOS18 \u00a79.65 p617 (scan p639)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When shortening the second number in an inclusive range, follow the selected shortening rule consistently.", "rationale": "Mixed shortening conventions create confusion in ranges.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "inclusive_numbers"], "keywords": ["inclusive numbers", "shortening"], "dependencies": [], "exceptions": ["Use full numbers when any doubt about clarity exists."], "status": "active"}
+{"id": "CMOS.NUMBERS.INCLUSIVE.YEARS.CENTURY_CROSSING", "title": "Use full years when a range crosses centuries", "source_refs": ["CMOS18 \u00a79.66 p617 (scan p639)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When year ranges cross centuries, use full years rather than abbreviated forms.", "rationale": "Full years prevent ambiguous ranges across century boundaries.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "inclusive_numbers", "dates"], "keywords": ["year ranges", "centuries"], "dependencies": [], "exceptions": ["Tables may use abbreviated forms if the header clarifies the century."], "status": "active"}
+{"id": "CMOS.NUMBERS.DATES.ORDINALS.AVOID", "title": "Avoid ordinal suffixes in dates", "source_refs": ["CMOS18 \u00a79.33 p604 (scan p626)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In running text, write dates without ordinal suffixes (e.g., March 3, not March 3rd).", "rationale": "Ordinal suffixes in dates are nonstandard in formal prose.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["ordinal dates", "March 3rd"], "dependencies": [], "exceptions": ["Quoted speech may preserve conversational date forms."], "status": "active"}
+{"id": "CMOS.NUMBERS.DATES.DAY_MONTH_ORDER.CONSISTENT", "title": "Keep a single date order throughout", "source_refs": ["CMOS18 \u00a79.37 p607 (scan p629)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use a single date order (month-day-year or day-month-year) throughout the document.", "rationale": "Mixing date orders is a frequent source of misreading.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["date order", "consistency"], "dependencies": [], "exceptions": ["Quoted material may preserve the original order; label if ambiguity remains."], "status": "active"}
+{"id": "CMOS.NUMBERS.TIME.LEADING_ZERO_MINUTES", "title": "Use leading zeros in times with minutes", "source_refs": ["CMOS18 \u00a79.39 p607 (scan p629)", "CMOS18 \u00a79.41 p608 (scan p630)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When minutes are shown, use a leading zero (e.g., 9:05) to avoid ambiguity.", "rationale": "Leading zeros prevent misreading times with single-digit minutes.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "time"], "keywords": ["time", "leading zero"], "dependencies": [], "exceptions": ["Informal notes may omit leading zeros; avoid in published output."], "status": "active"}
+{"id": "CMOS.NUMBERS.TIME.RANGES.CONSISTENT_FORMAT", "title": "Use a consistent format for time ranges", "source_refs": ["CMOS18 \u00a79.39 p607 (scan p629)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Express time ranges using a single consistent format (e.g., 9:00-11:00 or 9:00 to 11:00) and do not mix styles.", "rationale": "Mixed range formats reduce scanability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "time", "ranges"], "keywords": ["time ranges", "consistency"], "dependencies": [], "exceptions": ["Tables may use a compact dash style for alignment."], "status": "active"}
+{"id": "CMOS.NUMBERS.TIME.AM_PM.CONSISTENT_SPACING", "title": "Keep spacing around a.m./p.m. consistent", "source_refs": ["CMOS18 \u00a79.39 p607 (scan p629)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "If a.m./p.m. markers are used, keep their spacing and punctuation consistent throughout.", "rationale": "Consistent time markers reduce reader friction.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "time"], "keywords": ["a.m.", "p.m.", "spacing"], "dependencies": [], "exceptions": ["Profiles may standardize marker style; follow the profile."], "status": "active"}
+{"id": "CMOS.NUMBERS.FRACTIONS.ADJECTIVAL.HYPHENATE", "title": "Hyphenate spelled-out fractions used as modifiers", "source_refs": ["CMOS18 \u00a79.16 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When spelled-out fractions are used as adjectives before a noun, hyphenate them for clarity.", "rationale": "Hyphenation keeps compound modifiers readable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["fractions", "compound modifiers"], "dependencies": [], "exceptions": ["If the fraction follows the noun, the hyphen is often unnecessary."], "status": "active"}
+{"id": "CMOS.NUMBERS.ORDINALS.CONSISTENT_FORM", "title": "Keep ordinal formatting consistent", "source_refs": ["CMOS18 \u00a79.6 p592 (scan p614)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent style for ordinals (spelled-out or numeric) within comparable contexts.", "rationale": "Mixed ordinal styles look inconsistent and distract readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ordinals"], "keywords": ["ordinals", "consistency"], "dependencies": [], "exceptions": ["Legal or technical standards may require a specific ordinal style."], "status": "active"}
+{"id": "CMOS.NUMBERS.ROMAN_NUMERALS.CASE_CONSISTENT", "title": "Keep roman numeral case consistent", "source_refs": ["CMOS18 \u00a79.67 p617 (scan p639)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When roman numerals are used, keep case (upper or lower) consistent within a document.", "rationale": "Mixed roman numeral case looks accidental.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "roman_numerals"], "keywords": ["roman numerals", "case"], "dependencies": [], "exceptions": ["Quoted titles may preserve original casing."], "status": "active"}
+{"id": "CMOS.NUMBERS.TIME.ZONE.INCLUDE_WHEN_AMBIGUOUS", "title": "Include time zones when the audience is mixed", "source_refs": ["CMOS18 \u00a79.39 p607 (scan p629)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Include a time zone when the audience spans multiple regions or when the time would otherwise be ambiguous.", "rationale": "Time zones prevent scheduling errors and misinterpretation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "time"], "keywords": ["time zone", "ambiguity"], "dependencies": [], "exceptions": ["Local-only documents may omit time zones if the context is explicit."], "status": "active"}
+{"id": "CMOS.NUMBERS.TIME.SECONDS.OMIT_IF_NOT_NEEDED", "title": "Omit seconds unless precision is required", "source_refs": ["CMOS18 \u00a79.39 p607 (scan p629)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Omit seconds from time expressions unless the extra precision is required by context.", "rationale": "Unnecessary precision can distract readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "time"], "keywords": ["seconds", "precision"], "dependencies": [], "exceptions": ["Scientific and technical logs may require seconds."], "status": "active"}
+{"id": "CMOS.NUMBERS.TIME.SECONDS.INCLUDE_FOR_PRECISION", "title": "Include seconds when precision is meaningful", "source_refs": ["CMOS18 \u00a79.39 p607 (scan p629)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Include seconds when the document requires precise timing or sequence.", "rationale": "Precision should match the purpose of the document.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "time"], "keywords": ["seconds", "precision"], "dependencies": [], "exceptions": ["If seconds are included, ensure they are formatted consistently."], "status": "active"}
+{"id": "CMOS.NUMBERS.TELEPHONE.COUNTRY_CODE.WHEN_INTERNATIONAL", "title": "Include country codes for international audiences", "source_refs": ["CMOS18 \u00a79.59 p614 (scan p636)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Include the country code for telephone numbers when the audience is international.", "rationale": "Country codes are required to make numbers callable across regions.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "telephone"], "keywords": ["country code", "telephone"], "dependencies": [], "exceptions": ["Local-only documents may omit the country code if the locale is explicit."], "status": "active"}
+{"id": "CMOS.NUMBERS.TELEPHONE.SEPARATORS.CONSISTENT", "title": "Keep telephone separators consistent", "source_refs": ["CMOS18 \u00a79.59 p614 (scan p636)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent separator pattern for telephone numbers within the document.", "rationale": "Consistent separators improve readability and reduce dialing errors.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "telephone"], "keywords": ["telephone", "separators"], "dependencies": [], "exceptions": ["Imported contact lists may retain their original formats; note the inconsistency."], "status": "active"}
+{"id": "CMOS.NUMBERS.RATIOS.COLON_SPACING", "title": "Format ratio spacing consistently", "source_refs": ["CMOS18 \u00a79.60 p615 (scan p637)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent spacing convention around the colon in ratios and keep it consistent throughout.", "rationale": "Inconsistent spacing makes ratios harder to scan.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ratios"], "keywords": ["ratios", "spacing"], "dependencies": [], "exceptions": ["Mathematical notation may require tight spacing by convention."], "status": "active"}
+{"id": "CMOS.NUMBERS.SCIENTIFIC.NOTATION.MANTISSA_RANGE", "title": "Keep scientific notation mantissas within standard range", "source_refs": ["CMOS18 \u00a79.10 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When using scientific notation, format values so the mantissa is within the standard range for clarity.", "rationale": "Standardized notation improves comparison and scanning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "scientific_notation"], "keywords": ["scientific notation", "mantissa"], "dependencies": [], "exceptions": ["Engineering notation may use alternative ranges; document the choice."], "status": "active"}
+{"id": "CMOS.NUMBERS.SCIENTIFIC.NOTATION.TIMES_SYMBOL", "title": "Use a consistent multiplication symbol in scientific notation", "source_refs": ["CMOS18 \u00a79.10 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent multiplication symbol or format for scientific notation (e.g., x 10^n) throughout.", "rationale": "Consistent notation reduces ambiguity in data.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "scientific_notation"], "keywords": ["scientific notation", "times symbol"], "dependencies": [], "exceptions": ["If a renderer supports a specific format, follow the renderer's standard."], "status": "active"}
+{"id": "CMOS.NUMBERS.FRACTIONS.SLASH_INLINE", "title": "Use slashed fractions for inline numeric fractions", "source_refs": ["CMOS18 \u00a79.17 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When fractions are expressed numerically in running text, use a simple slash or true fraction glyphs.", "rationale": "Inline fractions should remain compact and readable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["fractions", "slash"], "dependencies": [], "exceptions": ["Math typesetting may use stacked fractions instead."], "status": "active"}
+{"id": "CMOS.NUMBERS.UNITS.SPACE_BETWEEN_NUMBER_UNIT", "title": "Use a space between numbers and units", "source_refs": ["CMOS18 \u00a79.19 p599 (scan p621)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use a space between numerals and unit symbols, and keep the pair from breaking when possible.", "rationale": "Spacing improves legibility and aligns with standard unit formatting.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "units"], "keywords": ["number unit", "spacing"], "dependencies": [], "exceptions": ["Some unit conventions omit the space; follow domain standards when required."], "status": "active"}
diff --git a/spec/rules/numbers/v1_numbers_004.ndjson b/spec/rules/numbers/v1_numbers_004.ndjson
new file mode 100644
index 0000000..831e0da
--- /dev/null
+++ b/spec/rules/numbers/v1_numbers_004.ndjson
@@ -0,0 +1,152 @@
+{"id": "CMOS.NUMBERS.S9_1.OVERVIEW.FACTORS", "title": "Choose numerals versus words based on context factors", "source_refs": ["CMOS18 §9.1 p590 (scan p612)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Choose numerals versus words based on magnitude, approximation versus exactness, the entity described, and the surrounding context.", "rationale": "Number form is a readability choice, not a one-size rule.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["numerals", "words", "context"], "dependencies": [], "exceptions": ["House style may set stronger defaults for specific genres."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_1.READABILITY_OVER_CONSISTENCY", "title": "Let readability override strict consistency when needed", "source_refs": ["CMOS18 §9.1 p590 (scan p612)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "If strict consistency harms readability (such as at sentence starts), prioritize readability and explain the choice.", "rationale": "Readable text beats rigid uniformity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["readability", "consistency"], "dependencies": [], "exceptions": ["Regulated documents may require fixed numeric formats."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_1.GENERAL_WORKS_SCOPE", "title": "Apply general number rules to nontechnical prose", "source_refs": ["CMOS18 §9.1 p590 (scan p612)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Apply the general numbering rules primarily to general and humanities-focused works; technical writing may still require spelled-out numbers in some contexts.", "rationale": "Genre expectations affect number presentation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["genre", "technical writing"], "dependencies": [], "exceptions": ["Follow domain-specific manuals where required."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_2.GENERAL_RULE.ZERO_TO_ONE_HUNDRED", "title": "Spell out zero through one hundred in nontechnical prose", "source_refs": ["CMOS18 §9.2 p590 (scan p612)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In nontechnical contexts, spell out whole numbers from zero through one hundred.", "rationale": "Spelled-out small numbers read more smoothly in narrative prose.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "spelling"], "keywords": ["zero", "one hundred"], "dependencies": [], "exceptions": ["Technical contexts may prefer numerals."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_2.ROUND_MULTIPLES.SPELLED_OUT", "title": "Spell out round multiples of small numbers", "source_refs": ["CMOS18 §9.2 p590 (scan p612)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Spell out round multiples of zero through one hundred (for example, three hundred or two thousand) under the general rule.", "rationale": "Round numbers are easier to read in words.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "spelling"], "keywords": ["round numbers", "multiples"], "dependencies": [], "exceptions": ["Scientific or data-heavy contexts may use numerals."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_2.NONROUND.ABOVE_ONE_HUNDRED", "title": "Use numerals for nonround numbers above one hundred", "source_refs": ["CMOS18 §9.2 p590 (scan p612)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for nonround numbers above one hundred unless a narrative style requires otherwise.", "rationale": "Long spelled-out numbers slow readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "numerals"], "keywords": ["nonround numbers", "above one hundred"], "dependencies": [], "exceptions": ["Spell out if the number begins a sentence."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_3.ALTERNATIVE_RULE.ZERO_TO_NINE", "title": "Alternative rule spells out zero through nine", "source_refs": ["CMOS18 §9.3 p590 (scan p612)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Under the alternative rule used in scientific or journalistic contexts, spell out zero through nine and use numerals for 10 and above.", "rationale": "This rule supports quick scanning in data-heavy prose.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "spelling"], "keywords": ["alternative rule", "zero through nine"], "dependencies": [], "exceptions": ["Apply the same exceptions as the general rule unless house style says otherwise."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_3.ALTERNATIVE_ROUND_MULTIPLES", "title": "Alternative rule favors numerals for round large numbers", "source_refs": ["CMOS18 §9.3 p590 (scan p612)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When the alternative rule is used, express round multiples of hundreds and thousands as numerals.", "rationale": "The alternative rule prioritizes numerals for most values.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "numerals"], "keywords": ["alternative rule", "round numbers"], "dependencies": [], "exceptions": ["Sentence-initial numbers may still be spelled out."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_4.HUNDREDS_THOUSANDS.SPELLED_OUT", "title": "Spell out one hundred to one hundred thousand in nontechnical prose", "source_refs": ["CMOS18 §9.4 p591 (scan p613)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Spell out whole numbers from one hundred through one hundred thousand when they are exact or approximate in nontechnical contexts.", "rationale": "This keeps mid-size quantities readable in narrative prose.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "spelling"], "keywords": ["hundred", "thousand"], "dependencies": [], "exceptions": ["Scientific or monetary contexts may prefer numerals."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_4.NONROUND.LARGE_NUMERALS", "title": "Use numerals for specific nonround large values", "source_refs": ["CMOS18 §9.4 p591 (scan p613)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for specific nonround values (for example, 47,122) even when nearby round values are spelled out.", "rationale": "Precise numbers are harder to read when spelled out.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "numerals"], "keywords": ["nonround numbers", "precision"], "dependencies": [], "exceptions": ["If the number begins a sentence, rephrase where possible."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_4.MIXED_LARGE_CONTEXTS", "title": "Use numerals when large numbers cluster together", "source_refs": ["CMOS18 §9.4 p591 (scan p613)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When many large numbers appear in close proximity, use numerals consistently to prevent a dense block of spelled-out values.", "rationale": "Clusters of spelled-out numbers reduce readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "consistency"], "keywords": ["clusters", "large numbers"], "dependencies": [], "exceptions": ["Narrative emphasis may still call for a spelled-out form."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_4.APPROXIMATIONS.SPELLED_OUT", "title": "Prefer spelled-out approximations in narrative prose", "source_refs": ["CMOS18 §9.4 p591 (scan p613)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use spelled-out approximations (for example, some forty-seven thousand) in narrative prose unless a numeric style is required.", "rationale": "Approximate quantities read more naturally in words.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "approximation"], "keywords": ["approximate numbers"], "dependencies": [], "exceptions": ["Technical summaries may require numerals."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_5.SENTENCE_INITIAL.SPELLED_OUT", "title": "Spell out numbers at the start of a sentence", "source_refs": ["CMOS18 §9.5 p591 (scan p613)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Spell out a number that begins a sentence unless an exception applies.", "rationale": "Sentence-initial numerals can be mistaken for list markers or disrupt flow.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "sentence_start"], "keywords": ["sentence start", "spelling"], "dependencies": [], "exceptions": ["Years and alphanumeric terms may remain numerals when necessary."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_5.SENTENCE_INITIAL.RECAST", "title": "Recast sentences to avoid awkward spelled-out numbers", "source_refs": ["CMOS18 §9.5 p591 (scan p613)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a spelled-out sentence-initial number reads awkwardly, recast the sentence so the number can appear later as a numeral.", "rationale": "Recasting often improves clarity and rhythm.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "sentence_start"], "keywords": ["recast", "sentence start"], "dependencies": [], "exceptions": ["Do not recast if it changes emphasis or meaning."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_5.TWO_NUMBERS.SAME_CATEGORY", "title": "Handle two sentence-initial numbers carefully", "source_refs": ["CMOS18 §9.5 p591 (scan p613)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "If a sentence begins with one number followed by another of the same category, spell out only the first and use numerals for the rest or recast the sentence.", "rationale": "Mixed forms at sentence start reduce confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "sentence_start"], "keywords": ["sentence start", "mixed forms"], "dependencies": [], "exceptions": ["If recasting would be awkward, spell out both numbers."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_5.YEARS.MAY_BEGIN", "title": "Allow years to begin a sentence in numerals", "source_refs": ["CMOS18 §9.5 p591 (scan p613)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Years may begin a sentence in numerals when rewording would be awkward.", "rationale": "Spelled-out years are often clumsy and unclear.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["years", "sentence start"], "dependencies": [], "exceptions": ["Recast if the surrounding text allows it."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_5.ALPHANUMERIC.MAY_BEGIN", "title": "Allow alphanumeric terms to begin sentences", "source_refs": ["CMOS18 §9.5 p591 (scan p613)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Sentence-initial alphanumeric terms (such as 3D or 401(k)) may remain as numerals.", "rationale": "Such terms function as fixed labels.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "sentence_start"], "keywords": ["alphanumeric", "labels"], "dependencies": [], "exceptions": ["Recast only if it improves clarity."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_6.ORDINALS.RULE_PARALLEL", "title": "Apply spelling rules to ordinals", "source_refs": ["CMOS18 §9.6 p592 (scan p614)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Apply the general or alternative spelling rule to ordinal numbers the same way as to cardinals.", "rationale": "Ordinal forms should mirror cardinal style choices.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ordinals"], "keywords": ["ordinals", "spelling"], "dependencies": [], "exceptions": ["Legal style may require different ordinal formats."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.ND_RD", "title": "Use standard ordinal suffixes (nd, rd, th)", "source_refs": ["CMOS18 §9.6 p592 (scan p614)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use standard ordinal suffixes such as nd and rd (for example, 122nd and 123rd) rather than shortened forms like 122d.", "rationale": "Standard suffixes are more readable for general audiences.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ordinals"], "keywords": ["ordinal suffix", "nd", "rd"], "dependencies": [], "exceptions": ["Legal or military style may prefer short suffixes."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_6.ORDINAL_SUFFIX.NO_SUPERSCRIPT", "title": "Do not superscript ordinal suffixes", "source_refs": ["CMOS18 §9.6 p592 (scan p614)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Set ordinal suffixes on the baseline rather than as superscripts.", "rationale": "Superscripts reduce legibility and can be lost in reflow.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ordinals"], "keywords": ["superscript", "ordinals"], "dependencies": [], "exceptions": ["If a house style mandates superscripts, apply consistently."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_6.NTH_DEGREE.ITALIC_N", "title": "Italicize the n in 'nth degree'", "source_refs": ["CMOS18 §9.6 p592 (scan p614)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Italicize the n in the phrase 'nth degree' to indicate a variable.", "rationale": "The italic n signals a variable term rather than a literal letter.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ordinals"], "keywords": ["nth degree", "italics"], "dependencies": [], "exceptions": ["Skip italics in plain-text environments that cannot style characters."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_6.ZERO.ORDINAL_TH", "title": "Use th for the zero ordinal", "source_refs": ["CMOS18 §9.6 p592 (scan p614)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use 'zeroth' as the ordinal form of zero.", "rationale": "Zeroth is the standard ordinal term.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ordinals"], "keywords": ["zeroth"], "dependencies": [], "exceptions": ["Technical contexts may use 0th as a label."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_7.CONSISTENT_CONTEXT", "title": "Keep number forms consistent within a local context", "source_refs": ["CMOS18 §9.7 p592 (scan p614)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Within a paragraph or series, keep number forms consistent for the same category of numbers.", "rationale": "Consistency reduces reader distraction.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "consistency"], "keywords": ["consistency", "categories"], "dependencies": [], "exceptions": ["Sentence-initial numbers may be spelled out as a localized exception."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_7.CATEGORY_TRIGGER", "title": "If one item in a category uses numerals, use numerals for the rest", "source_refs": ["CMOS18 §9.7 p592 (scan p614)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "If one number in a category must be a numeral, treat other numbers in that category as numerals within the same context.", "rationale": "Mixing forms inside a category looks inconsistent.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "consistency"], "keywords": ["numerals", "category"], "dependencies": [], "exceptions": ["Avoid numerals at sentence start by rephrasing."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_7.CROSS_CATEGORY.MIX_OK", "title": "Allow different formats for different categories", "source_refs": ["CMOS18 §9.7 p592 (scan p614)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Different categories of numbers may use different formats within the same sentence or paragraph if it improves clarity.", "rationale": "Mixed categories often read more clearly with distinct forms.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "consistency"], "keywords": ["mixed categories", "clarity"], "dependencies": [], "exceptions": ["Do not mix forms within a single category."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_7.AVOID_DENSE_WORDS", "title": "Switch to numerals to avoid dense spelled-out clusters", "source_refs": ["CMOS18 §9.7 p592 (scan p614)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a passage contains many spelled-out numbers, switch to numerals to keep the text readable.", "rationale": "Long strings of spelled-out numbers are hard to parse.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "readability"], "keywords": ["clusters", "readability"], "dependencies": [], "exceptions": ["Preserve quoted material as written."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_7.SENTENCE_START_EXCEPTION", "title": "Allow sentence-start exceptions while keeping local consistency", "source_refs": ["CMOS18 §9.7 p592 (scan p614)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "If a number at sentence start must be spelled out, keep the remainder of the passage consistent with the chosen number format.", "rationale": "A single exception should not trigger widespread inconsistency.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "consistency"], "keywords": ["sentence start", "exceptions"], "dependencies": [], "exceptions": ["Recast where feasible to avoid the exception."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_7.DOCUMENT_EXCEPTIONS", "title": "Document category-level exceptions in the style sheet", "source_refs": ["CMOS18 §9.7 p592 (scan p614)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "If a document uses numerals for a specific category (for example, ages or centuries), record the exception in the style sheet.", "rationale": "Explicit exceptions prevent drift and reviewer confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "style_sheet"], "keywords": ["style sheet", "exceptions"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.ABBREVIATED_UNITS.NUMERALS", "title": "Use numerals with abbreviated units of measure", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a unit is abbreviated (km, mph, dpi, rpm), use numerals for the quantity.", "rationale": "Abbreviated units pair naturally with numerals.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "units"], "keywords": ["units", "abbreviations"], "dependencies": [], "exceptions": ["Spell out units when the quantity is spelled out by design."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.PERCENT.NUMERALS", "title": "Use numerals with percent expressions", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Percent expressions generally use numerals except at the beginning of a sentence.", "rationale": "Percent values are easier to scan as numerals.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "percentages"], "keywords": ["percent", "numerals"], "dependencies": [], "exceptions": ["Sentence-initial percent values may be spelled out."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.DOC_PARTS.PAGES", "title": "Use numerals for page references", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for page references, including ranges and abbreviated forms (p., pp.).", "rationale": "Readers expect page references in numerals.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "document_parts"], "keywords": ["pages", "references"], "dependencies": [], "exceptions": ["Front-matter pages may use Roman numerals as printed."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.DOC_PARTS.CHAPTERS_PARTS", "title": "Use numerals for parts and chapter references", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals when referring to parts, chapters, and similar divisions (part 5, chap. 1).", "rationale": "Numerals are standard for structural references.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "document_parts"], "keywords": ["chapters", "parts"], "dependencies": [], "exceptions": ["Follow a work's established numbering scheme."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.DOC_PARTS.NOTES", "title": "Use numerals for notes and note ranges", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for notes and note ranges, including abbreviated forms (n., nn.).", "rationale": "Note references are indexing elements.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "document_parts"], "keywords": ["notes", "references"], "dependencies": [], "exceptions": ["Legal documents may use other conventions."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.DOC_PARTS.SECTIONS_PARAS_LINES", "title": "Use numerals for sections, paragraphs, and lines", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for section, paragraph, and line references (sec. 3, para. 5, lines 12-18).", "rationale": "Structured references should be easily scannable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "document_parts"], "keywords": ["sections", "paragraphs", "lines"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.DOC_PARTS.FIGURES_TABLES_EQUATIONS", "title": "Use numerals for figures, tables, and equations", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for figures, tables, equations, columns, and rows (fig. 9, eq. 4, col. 2, row 3).", "rationale": "Numerals standardize navigational references.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "document_parts"], "keywords": ["figures", "tables", "equations"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.DOC_PARTS.BOXES", "title": "Use numerals for boxes and similar elements", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for boxed elements or labeled callouts (box 3).", "rationale": "Box references function like figure references.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "document_parts"], "keywords": ["boxes", "callouts"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.DOC_PARTS.ACT_SCENE", "title": "Use numerals for acts and scenes", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for acts and scenes (act 3, scene 4).", "rationale": "Stage directions and references use numerals for navigation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "document_parts"], "keywords": ["acts", "scenes"], "dependencies": [], "exceptions": ["Follow the cited work's numbering system."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.DOC_PARTS.VOLUMES_ISSUES", "title": "Use numerals for volume and issue references", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for volume, issue, and number references (vol. 3, issue no. 7).", "rationale": "Periodical references rely on numerals for clarity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "document_parts"], "keywords": ["volume", "issue", "number"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.DOC_PARTS.EXAMPLES_QUESTIONS_RULES", "title": "Use numerals for examples, questions, and rules", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for labeled examples, questions, and rules.", "rationale": "Instructional references are easier to scan with numerals.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "document_parts"], "keywords": ["examples", "questions", "rules"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.TITLE_NUMBERS", "title": "Use numerals in formal titles with numbers", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals in formal titles or legal references that include numbers (for example, Title IX).", "rationale": "Such labels are fixed references rather than prose quantities.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "document_parts"], "keywords": ["titles", "legal references"], "dependencies": [], "exceptions": ["Use the official styling of the title when known."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.SYMBOLS.NUMERALS", "title": "Use numerals when symbols are present", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a symbol is used with a quantity (currency, percent, degrees), use numerals.", "rationale": "Symbols pair with numerals and improve scan speed.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "symbols"], "keywords": ["symbols", "numerals"], "dependencies": [], "exceptions": ["Formal narrative may spell out numbers with symbols removed."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.PLACES.STREETS_ROOMS", "title": "Use numerals for streets, rooms, and similar identifiers", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for street numbers, room numbers, suites, and similar place identifiers.", "rationale": "Numeric place identifiers are standard in addresses.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "addresses"], "keywords": ["streets", "rooms", "suites"], "dependencies": [], "exceptions": ["Follow official address formatting when provided."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.DATES.NUMERALS", "title": "Use numerals in date expressions", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals in date expressions (June 1, 1941; May 5).", "rationale": "Dates are standardly numeric regardless of general number rules.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["dates", "numerals"], "dependencies": [], "exceptions": ["Spelled-out dates may appear in ceremonial contexts."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.GRADES_LEVELS.NUMERALS", "title": "Use numerals for grades and levels", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for grades and levels (grade 3, level 6), except where a spelled-out form is conventional.", "rationale": "Grade and level labels function as identifiers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "education"], "keywords": ["grades", "levels"], "dependencies": [], "exceptions": ["Some contexts prefer spelled-out forms like third grade."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.CLOTHING_SIZES.NUMERALS", "title": "Use numerals for clothing sizes", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Express clothing sizes with numerals (size 12, 32 inch waist).", "rationale": "Sizing conventions use numerals as identifiers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "sizes"], "keywords": ["clothing sizes"], "dependencies": [], "exceptions": ["Preserve branded size notation where required."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.SEVERITY_CLASSIFICATIONS", "title": "Use numerals for severity or classification labels", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for severity or classification labels such as type, stage, or category.", "rationale": "These are standardized labels rather than quantities.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "classifications"], "keywords": ["type", "stage", "category"], "dependencies": [], "exceptions": ["If the label uses Roman numerals, keep the published form."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_8.SCORES_VOTES.NUMERALS", "title": "Use numerals for scores and vote tallies", "source_refs": ["CMOS18 §9.8 p593 (scan p615)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Express scores and vote tallies with numerals (34-3, 6 to 3).", "rationale": "Scores and tallies are standard numeric expressions.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "scores"], "keywords": ["scores", "votes"], "dependencies": [], "exceptions": ["Sports or legal style may specify a format; follow it."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_9.MILLIONS_BILLIONS.GENERAL_RULE", "title": "Apply the general rule to million and larger numbers", "source_refs": ["CMOS18 §9.9 p595 (scan p617)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals or words with million, billion, and larger terms according to the general rule for the context.", "rationale": "Large quantities still follow the chosen spelling rule.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "large_numbers"], "keywords": ["million", "billion"], "dependencies": [], "exceptions": ["Monetary amounts may follow money-specific rules."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_9.MIXED_NUMERAL_WORD.FRACTIONS", "title": "Use numerals with words for large fractional quantities", "source_refs": ["CMOS18 §9.9 p595 (scan p617)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "For fractional quantities in the millions or higher, use a numeral plus the word million or billion (2.3 million).", "rationale": "Mixed forms keep large fractions legible.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "large_numbers"], "keywords": ["fractional", "million"], "dependencies": [], "exceptions": ["Scientific notation may be preferable in technical contexts."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_9.CONSISTENCY.WITH_FRACTIONS", "title": "Keep nearby large numbers consistent when mixing fractions", "source_refs": ["CMOS18 §9.9 p595 (scan p617)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a large fractional number is given in numerals, align nearby large whole numbers to numerals for consistency.", "rationale": "Consistency prevents mixed-format confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "consistency"], "keywords": ["large numbers", "consistency"], "dependencies": [], "exceptions": ["Narrative emphasis may warrant spelled-out forms."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_9.BILLION_TRILLION.LOCALE_CHECK", "title": "Verify billion and trillion meanings in non-US contexts", "source_refs": ["CMOS18 §9.9 p595 (scan p617)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Confirm whether billion and trillion follow US or alternate usage when editing international sources.", "rationale": "Different systems attach different magnitudes to these terms.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "large_numbers"], "keywords": ["billion", "trillion", "locale"], "dependencies": [], "exceptions": ["If the document defines the system, follow it."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_10.SCIENTIFIC_NOTATION.USE", "title": "Use scientific notation for large round numbers in technical contexts", "source_refs": ["CMOS18 §9.10 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use scientific notation for large round numbers when technical writing calls for it.", "rationale": "Scientific notation compresses very large values.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "scientific"], "keywords": ["scientific notation"], "dependencies": [], "exceptions": ["Narrative text may still prefer words."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_10.POWERS_OF_TEN", "title": "Express large values as powers of ten when appropriate", "source_refs": ["CMOS18 §9.10 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Large values may be expressed as powers of ten (10^2, 10^6) when clarity or compactness is needed.", "rationale": "Powers of ten are standard in scientific writing.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "scientific"], "keywords": ["powers of ten"], "dependencies": [], "exceptions": ["Avoid in general prose unless required."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_10.NEGATIVE_POWERS", "title": "Use negative powers of ten for very small values", "source_refs": ["CMOS18 §9.10 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Very small numbers may be expressed as negative powers of ten when precision is important.", "rationale": "Negative exponents provide a compact form for tiny values.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "scientific"], "keywords": ["negative exponent"], "dependencies": [], "exceptions": ["Use decimals if required by the audience."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_10.SCI_NOTATION.CONSISTENT", "title": "Keep scientific notation format consistent", "source_refs": ["CMOS18 §9.10 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When scientific notation is used, keep the format consistent (for example, use the same multiplication symbol and exponent style).", "rationale": "Mixed formats look unprofessional and can confuse readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "scientific"], "keywords": ["scientific notation", "consistency"], "dependencies": [], "exceptions": ["Quoted sources may preserve original format."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_11.SI_PREFIXES.LARGE", "title": "Use SI prefixes for large quantities", "source_refs": ["CMOS18 §9.11 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use SI prefixes such as mega-, giga-, and tera- to express large quantities where standard in the field.", "rationale": "SI prefixes provide a compact, standardized scale.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "si_prefixes"], "keywords": ["SI", "mega", "giga", "tera"], "dependencies": [], "exceptions": ["General prose may prefer words or numerals."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_11.SI_PREFIXES.SMALL", "title": "Use SI prefixes for small quantities", "source_refs": ["CMOS18 §9.11 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use SI prefixes such as milli-, micro-, and nano- for small quantities in technical contexts.", "rationale": "Prefixes avoid long strings of zeros.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "si_prefixes"], "keywords": ["milli", "micro", "nano"], "dependencies": [], "exceptions": ["Spell out units for general audiences if needed."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_11.PREFIX_SYMBOLS", "title": "Use standard symbols with SI prefixes", "source_refs": ["CMOS18 §9.11 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When SI prefixes are used with units, use the standard symbols (for example, M, G) as appropriate.", "rationale": "Symbol consistency matters for scientific accuracy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "si_prefixes"], "keywords": ["symbols", "SI units"], "dependencies": [], "exceptions": ["Use spelled-out forms when symbols are not supported."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_11.MYR_GYR", "title": "Use Myr and Gyr for megayear and gigayear when standard", "source_refs": ["CMOS18 §9.11 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In astrophysical contexts, use Myr and Gyr for megayear and gigayear when standard.", "rationale": "Discipline-specific abbreviations improve clarity for expert audiences.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "si_prefixes"], "keywords": ["Myr", "Gyr"], "dependencies": [], "exceptions": ["Define abbreviations on first use for general audiences."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_12.BASE_INDICATOR", "title": "Indicate the base for non-decimal numbers", "source_refs": ["CMOS18 §9.12 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When using binary, octal, or hexadecimal numbers, indicate the base explicitly.", "rationale": "Readers cannot infer the base without a cue.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "number_systems"], "keywords": ["binary", "octal", "hex"], "dependencies": [], "exceptions": ["In code blocks, base notation may be implied."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_12.BASE_PREFIXES", "title": "Use b, o, or h prefixes without spaces", "source_refs": ["CMOS18 §9.12 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use b, o, or h prefixes immediately before numbers to mark binary, octal, or hexadecimal values without a space.", "rationale": "Tight prefixes are a common notation standard.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "number_systems"], "keywords": ["binary", "octal", "hex", "prefix"], "dependencies": [], "exceptions": ["Subscript base notation may be used instead."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_12.BASE_SUBSCRIPT", "title": "Use subscript base notation as an alternative", "source_refs": ["CMOS18 §9.12 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "As an alternative to prefixes, use subscript base notation to show the base of a number.", "rationale": "Subscripts avoid ambiguity in technical writing.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "number_systems"], "keywords": ["subscript", "base notation"], "dependencies": [], "exceptions": ["Plain-text formats may require prefixed notation."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_12.NO_COMMAS.IN_BASE", "title": "Avoid commas in base-indicated numbers", "source_refs": ["CMOS18 §9.12 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a number is expressed in another base, avoid commas or groupings unless the notation standard requires them.", "rationale": "Commas can be misread as decimal groupings.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "number_systems"], "keywords": ["commas", "grouping"], "dependencies": [], "exceptions": ["Use standard grouping conventions for the target base if defined."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_12.BINARY_PREFIXES", "title": "Use binary prefixes for powers of two", "source_refs": ["CMOS18 §9.12 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When binary multiples are intended, use binary prefixes such as kibi-, mebi-, and gibi-.", "rationale": "Binary prefixes distinguish powers of two from decimal powers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "number_systems"], "keywords": ["kibi", "mebi", "gibi"], "dependencies": [], "exceptions": ["If the context defines megabyte as binary, state it clearly."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_12.DECIMAL_PREFIXES", "title": "Use decimal prefixes for powers of ten", "source_refs": ["CMOS18 §9.12 p596 (scan p618)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use standard SI prefixes for powers of ten when describing decimal multiples.", "rationale": "SI prefixes are defined for base-ten quantities.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "number_systems"], "keywords": ["SI prefixes", "decimal"], "dependencies": [], "exceptions": ["Explicitly define exceptions for binary contexts."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_13.DEX.DEFINITION", "title": "Define dex when used in scientific notation", "source_refs": ["CMOS18 §9.13 p597 (scan p619)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When using dex as shorthand for a decimal exponent, define it on first use.", "rationale": "Dex is a specialized term not all readers recognize.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "scientific"], "keywords": ["dex", "exponent"], "dependencies": [], "exceptions": ["Specialist audiences may not need a definition."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.GENERAL_RULE", "title": "Apply the general rule to physical quantities in nontechnical prose", "source_refs": ["CMOS18 §9.14 p597 (scan p619)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In nontechnical prose, apply the general spelling rule to physical quantities such as distance or temperature.", "rationale": "Narrative text favors words for small numbers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "physical_quantities"], "keywords": ["distance", "temperature"], "dependencies": [], "exceptions": ["Technical contexts typically use numerals."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.COMMON_NUMERALS", "title": "Allow numerals for commonly expressed quantities", "source_refs": ["CMOS18 §9.14 p597 (scan p619)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for commonly expressed quantities when they read more naturally (for example, 40-watt bulb, size 14).", "rationale": "Some measurements are conventionally numeric.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "physical_quantities"], "keywords": ["measurements", "numerals"], "dependencies": [], "exceptions": ["Keep the choice consistent within the document."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.EXACT_VALUES", "title": "Use numerals for exact physical quantities", "source_refs": ["CMOS18 §9.14 p597 (scan p619)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "If a physical quantity is exact, express it as a numeral to emphasize precision.", "rationale": "Numerals signal exact measurement.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "physical_quantities"], "keywords": ["exact values"], "dependencies": [], "exceptions": ["Narrative emphasis may still prefer words."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_14.PHYSICAL_QUANTITIES.CONSISTENCY", "title": "Keep physical quantity formatting consistent", "source_refs": ["CMOS18 §9.14 p597 (scan p619)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent numeral-or-word choice for like quantities throughout a document.", "rationale": "Consistency prevents reader confusion across measurements.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "consistency"], "keywords": ["measurements", "consistency"], "dependencies": [], "exceptions": ["Documented style-sheet exceptions are acceptable."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.SPELLED_OUT", "title": "Spell out simple fractions in running text", "source_refs": ["CMOS18 §9.15 p597 (scan p619)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Spell out simple fractions in running text (one-half, three-fourths).", "rationale": "Spelled-out fractions read smoothly in prose.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["simple fractions", "spelled out"], "dependencies": [], "exceptions": ["Use numerals in technical contexts."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.HYPHENATE", "title": "Hyphenate spelled-out fractions in noun and adjective forms", "source_refs": ["CMOS18 §9.15 p597 (scan p619)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Hyphenate spelled-out fractions when used as nouns, adjectives, or adverbs.", "rationale": "Hyphenation clarifies the fraction as a unit.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["hyphenation", "fractions"], "dependencies": [], "exceptions": ["Do not hyphenate when the fraction is used as a noun phrase with of."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_15.SIMPLE_FRACTIONS.EMPHASIS_EXCEPTION", "title": "Use numerals when parts of a fraction are emphasized", "source_refs": ["CMOS18 §9.15 p597 (scan p619)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "If the parts of a fraction are emphasized separately, numerals may be clearer than spelled-out forms.", "rationale": "Emphasis on parts can be obscured by words.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["fractions", "emphasis"], "dependencies": [], "exceptions": ["Avoid in narrative unless clarity demands it."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_15.DECIMAL_FRACTIONS.NUMERALS", "title": "Use numerals for decimal fractions", "source_refs": ["CMOS18 §9.15 p597 (scan p619)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Express decimal fractions as numerals rather than words.", "rationale": "Decimal fractions are standard numeric forms.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["decimals"], "dependencies": [], "exceptions": ["Sentence-initial decimals may be rephrased."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.SHORT_SPELLED_OUT", "title": "Spell out short mixed numbers when readable", "source_refs": ["CMOS18 §9.16 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "For short whole-number plus fraction combinations, spelled-out forms may be used when they read clearly.", "rationale": "Words can be smoother in narrative contexts.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["mixed numbers"], "dependencies": [], "exceptions": ["Use numerals in technical contexts."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.NUMERALS", "title": "Prefer numerals for mixed numbers in measurements", "source_refs": ["CMOS18 §9.16 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for mixed numbers when paired with measurements or when length makes spelled-out forms awkward.", "rationale": "Numerals improve clarity in measurements.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["mixed numbers", "measurements"], "dependencies": [], "exceptions": ["Short narrative phrases may remain spelled out."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.FRACTION_SYMBOLS", "title": "Use fraction symbols for clarity when available", "source_refs": ["CMOS18 §9.16 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "If a clear fraction symbol exists, use it in numerals to improve readability.", "rationale": "Fraction symbols reduce visual clutter.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["fraction symbols"], "dependencies": [], "exceptions": ["Avoid symbols that are unavailable in the target font."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_16.MIXED_NUMBERS.MEASUREMENTS", "title": "Use numerals for mixed-number measurements", "source_refs": ["CMOS18 §9.16 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a mixed number is part of a measurement, numerals are usually preferred.", "rationale": "Measurements are easier to scan in numeric form.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["measurements", "mixed numbers"], "dependencies": [], "exceptions": ["Narrative context may allow spelled-out forms."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_17.FRACTIONS.RUNNING_TEXT.SLASH", "title": "Use a slash for fractions in running text", "source_refs": ["CMOS18 §9.17 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In running text, use a slash to separate numerator and denominator (1/2, 3/4).", "rationale": "Slashes are the standard inline fraction form.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["slash", "fractions"], "dependencies": [], "exceptions": ["Case fractions may be used for common numeric fractions."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_17.CASE_FRACTIONS.USE_WITH_CARE", "title": "Use case fractions only when they are clear", "source_refs": ["CMOS18 §9.17 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Case fractions may be used in text for common numeric fractions when they are clear and supported by the font.", "rationale": "Case fractions can be easier to read than slash forms.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["case fractions"], "dependencies": [], "exceptions": ["Avoid confusion with Unicode vulgar fraction symbols."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_17.FRACTIONS.PARENS_BEFORE_SYMBOLS", "title": "Use parentheses when a fraction is followed by a symbol", "source_refs": ["CMOS18 §9.17 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Enclose a fraction in parentheses when it is followed immediately by a mathematical symbol or expression.", "rationale": "Parentheses prevent misreading of the fraction boundary.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["parentheses", "math symbols"], "dependencies": [], "exceptions": ["Displayed equations may handle grouping differently."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_17.ALGEBRAIC.SLASH", "title": "Use slashes for algebraic fractions in text", "source_refs": ["CMOS18 §9.17 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In running text, use slashes rather than horizontal fraction bars for algebraic fractions.", "rationale": "Horizontal bars are difficult to set inline.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["algebraic fractions", "slash"], "dependencies": [], "exceptions": ["Displayed equations may use fraction bars."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_17.FRACTIONS.IN_NUMERATOR_DENOMINATOR", "title": "Use slashes for fractions inside numerators or denominators", "source_refs": ["CMOS18 §9.17 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a fraction appears inside a numerator or denominator, use a slash to avoid stacked bars.", "rationale": "Nested fraction bars are hard to parse.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["nested fractions"], "dependencies": [], "exceptions": ["Complex display math may use multiline formatting."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_17.EXPONENT_FRACTIONS.SLASH", "title": "Use slashes for fractional exponents", "source_refs": ["CMOS18 §9.17 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Express fractional exponents with slashes rather than stacked fraction bars.", "rationale": "Inline exponents must remain compact and readable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["exponents", "fractions"], "dependencies": [], "exceptions": ["Displayed equations may use full fraction bars."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_17.DISPLAYED_FRACTIONS.BAR", "title": "Use horizontal bars for displayed fractions", "source_refs": ["CMOS18 §9.17 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In displayed equations, set fractions with a horizontal bar unless they appear in subscripts or superscripts.", "rationale": "Displayed math allows clearer fraction layout.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["displayed equations", "fraction bar"], "dependencies": [], "exceptions": ["Fractions in subscripts or superscripts may use slashes."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_17.SLASH_BINDING", "title": "Assume a slash binds only adjacent elements", "source_refs": ["CMOS18 §9.17 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "A slash connects only the symbols immediately adjacent to it; use parentheses to clarify the intended grouping.", "rationale": "Parentheses prevent ambiguous algebra.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "fractions"], "keywords": ["slash", "grouping"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_18.ABBREVIATIONS.NUMERALS_ONLY", "title": "Use numerals with abbreviated units or symbols", "source_refs": ["CMOS18 §9.18 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a unit is abbreviated or expressed as a symbol, use numerals for the quantity.", "rationale": "Abbreviated units assume numeric values.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "units"], "keywords": ["abbreviations", "symbols"], "dependencies": [], "exceptions": ["Spell out units when no numeral is given."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_18.NO_HYPHEN.NUMERAL_UNIT", "title": "Do not hyphenate numerals with abbreviated units", "source_refs": ["CMOS18 §9.18 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Do not insert a hyphen between a numeral and an abbreviated unit, even in adjectival form.", "rationale": "Abbreviated units function as symbols rather than words.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "units"], "keywords": ["hyphenation", "units"], "dependencies": [], "exceptions": ["Use hyphens when the unit is spelled out."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_18.PRIME_SYMBOLS", "title": "Use prime and double prime symbols, not quotes", "source_refs": ["CMOS18 §9.18 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use prime and double prime symbols for feet/inches or minutes/seconds, not apostrophes or quotation marks.", "rationale": "Prime symbols are distinct characters with specific meanings.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "units"], "keywords": ["prime", "double prime"], "dependencies": [], "exceptions": ["Plain-text environments may require a fallback."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_18.SPACING.NUMERAL_UNIT", "title": "Use a space between numerals and units by default", "source_refs": ["CMOS18 §9.18 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Insert a space between the numeral and the unit of measure unless a specific convention omits it.", "rationale": "Spacing improves legibility and matches SI style.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "units"], "keywords": ["spacing", "SI units"], "dependencies": [], "exceptions": ["Degree, percent, and prime symbols typically have no space."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_18.NO_SPACE.DEGREE_PERCENT_PRIME", "title": "Omit spaces for degree, percent, and prime symbols", "source_refs": ["CMOS18 §9.18 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Do not insert a space between numerals and degree, percent, or prime symbols.", "rationale": "These symbols are standardly set closed up to the numeral.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "units"], "keywords": ["degree", "percent", "prime"], "dependencies": [], "exceptions": ["Follow domain-specific conventions if they differ."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_18.UNIT_WITHOUT_NUMERAL.SPELLED_OUT", "title": "Spell out units when no numeral is present", "source_refs": ["CMOS18 §9.18 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a unit of measure appears without a numeral, spell out the unit name.", "rationale": "Abbreviations without numerals can look cryptic.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "units"], "keywords": ["units", "spelled out"], "dependencies": [], "exceptions": ["Tables may use abbreviated units with headers."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_18.SCIENTIFIC_CONTEXT.NUMERALS", "title": "Use numerals for quantities in scientific contexts", "source_refs": ["CMOS18 §9.18 p598 (scan p620)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In scientific and technical writing, express physical quantities and time units with numerals, including fractions.", "rationale": "Technical readers expect numeric precision.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "scientific"], "keywords": ["technical writing", "numerals"], "dependencies": [], "exceptions": ["Narrative sections may follow general rules."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_19.REPEAT_UNITS.CLOSED_UP", "title": "Repeat closed-up unit symbols in ranges", "source_refs": ["CMOS18 §9.19 p599 (scan p621)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a unit symbol is closed up to the number, repeat the symbol for each value in a range (35%-50%).", "rationale": "Repeating the symbol avoids ambiguity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ranges"], "keywords": ["ranges", "symbols"], "dependencies": [], "exceptions": ["House style may allow a single symbol if unambiguous."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_19.UNIT_SPACED.SINGLE", "title": "Use a single unit when separated by a space", "source_refs": ["CMOS18 §9.19 p599 (scan p621)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When the unit is separated by a space, place the unit once after the range (2 x 5 cm).", "rationale": "Repeated units are unnecessary when spacing clarifies the association.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ranges"], "keywords": ["ranges", "units"], "dependencies": [], "exceptions": ["Repeat the unit if ambiguity is possible."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_19.UNIT_REPETITION.CONSISTENT", "title": "Keep unit repetition consistent within a section", "source_refs": ["CMOS18 §9.19 p599 (scan p621)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Choose a unit repetition pattern for ranges and apply it consistently within a section.", "rationale": "Consistency helps readers compare values.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "consistency"], "keywords": ["ranges", "consistency"], "dependencies": [], "exceptions": ["Follow domain conventions when required."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_20.PERCENT.NUMERALS", "title": "Use numerals for percentages in running text", "source_refs": ["CMOS18 §9.20 p599 (scan p621)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Percentages are normally expressed as numerals except at the beginning of a sentence.", "rationale": "Numeric percentages are easier to scan.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "percentages"], "keywords": ["percentages", "numerals"], "dependencies": [], "exceptions": ["Sentence-initial values may be spelled out."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_20.PERCENT.WORD_VS_SYMBOL", "title": "Use percent in prose and % in technical contexts", "source_refs": ["CMOS18 §9.20 p599 (scan p621)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In nontechnical prose, use the word percent; in scientific or statistical contexts, the symbol % is preferred.", "rationale": "Audience expectations differ by genre.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "percentages"], "keywords": ["percent", "symbol"], "dependencies": [], "exceptions": ["House style may standardize one form."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_20.PERCENT.LESS_FREQUENT", "title": "Use less with percentages", "source_refs": ["CMOS18 §9.20 p599 (scan p621)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use less rather than fewer with percentages.", "rationale": "Percentages refer to a proportion rather than countable items.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "percentages"], "keywords": ["less", "fewer"], "dependencies": [], "exceptions": ["Quoted material may preserve original wording."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_20.PERCENT_VS_PERCENTAGE", "title": "Use percent for the value and percentage for the concept", "source_refs": ["CMOS18 §9.20 p599 (scan p621)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use percent for specific values and percentage for the general concept or proportion.", "rationale": "Percent and percentage are not interchangeable parts of speech.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "percentages"], "keywords": ["percent", "percentage"], "dependencies": [], "exceptions": ["House style may allow informal interchange."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_20.PERCENT_RANGES.REPEAT", "title": "Repeat the percent symbol in closed ranges", "source_refs": ["CMOS18 §9.20 p599 (scan p621)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When the percent symbol is closed up to numbers, repeat it for each end of a range (20%-25%).", "rationale": "Repeating the symbol avoids ambiguity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "percentages"], "keywords": ["percent ranges"], "dependencies": [], "exceptions": ["If the range is written with words, use percent once."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_21.DECIMALS.NUMERALS", "title": "Use numerals for decimal fractions", "source_refs": ["CMOS18 §9.21 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Decimal fractions are expressed as numerals regardless of context.", "rationale": "Decimals are numeric forms by definition.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "decimals"], "keywords": ["decimals", "numerals"], "dependencies": [], "exceptions": ["Sentence-initial decimals may be rephrased."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_21.LEADING_ZERO.CONTEXT", "title": "Use a leading zero when context includes values over one", "source_refs": ["CMOS18 §9.21 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When values under one appear alongside values over one, include a leading zero (0.73).", "rationale": "Leading zeros prevent misreading and align decimal places.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "decimals"], "keywords": ["leading zero"], "dependencies": [], "exceptions": ["Probabilities or averages may omit the leading zero by convention."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_21.LEADING_ZERO.OMIT_PROBABILITIES", "title": "Omit the leading zero for probabilities and averages", "source_refs": ["CMOS18 §9.21 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In contexts such as probabilities, batting averages, or correlation coefficients, omit the leading zero (.05, .366).", "rationale": "These fields use a specialized notation convention.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "decimals"], "keywords": ["probabilities", "averages"], "dependencies": [], "exceptions": ["Follow house or discipline standards if different."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_21.LEADING_ZERO.CALIBERS", "title": "Omit the leading zero for firearm calibers", "source_refs": ["CMOS18 §9.21 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Omit the leading zero in firearm calibers expressed as fractions of an inch (.38, .22).", "rationale": "Caliber notation is a fixed convention.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "decimals"], "keywords": ["caliber"], "dependencies": [], "exceptions": ["Do not apply to non-caliber decimals."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_21.UNITS.LESS_THAN_ONE", "title": "Treat units less than one as plural", "source_refs": ["CMOS18 §9.21 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a quantity is less than one, use the plural form of the unit unless a specific convention says otherwise.", "rationale": "English treats sub-unit amounts as plural in measurement contexts.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "decimals"], "keywords": ["plural units"], "dependencies": [], "exceptions": ["Scientific notation may use a fixed unit label."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_21.DECIMAL_CONTEXT.CONSISTENT", "title": "Keep decimal formatting consistent within a context", "source_refs": ["CMOS18 §9.21 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent decimal format within a table, paragraph, or dataset.", "rationale": "Mixed formats reduce clarity and suggest inconsistent precision.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "decimals"], "keywords": ["precision", "consistency"], "dependencies": [], "exceptions": ["Do not pad with zeros unless required."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_22.MONEY.SPELL_OUT_SMALL", "title": "Spell out isolated amounts of one hundred or less", "source_refs": ["CMOS18 §9.22 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In general prose, spell out isolated amounts of money of one hundred or less.", "rationale": "Small amounts read better in words in narrative text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["money", "spelling"], "dependencies": [], "exceptions": ["Technical or tabular contexts may use numerals."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_22.MONEY.NUMERALS_EXACT", "title": "Use numerals for exact monetary amounts", "source_refs": ["CMOS18 §9.22 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals with currency symbols for exact monetary amounts.", "rationale": "Exact amounts are clearer and more standard as numerals.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["currency symbols", "exact amounts"], "dependencies": [], "exceptions": ["Narrative emphasis may still spell out small values."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_22.MONEY.DECIMALS.ONLY_WHEN_MIXED", "title": "Include cents only when mixed with fractional amounts", "source_refs": ["CMOS18 §9.22 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Include decimal zeros in whole-dollar amounts only when the same context includes fractional amounts.", "rationale": "Unneeded zeros imply false precision.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["decimals", "cents"], "dependencies": [], "exceptions": ["Financial statements may require fixed precision."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_22.MONEY.SINGULAR_VERB", "title": "Treat sums of money as singular when used as a unit", "source_refs": ["CMOS18 §9.22 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a sum of money is treated as a unit, use a singular verb.", "rationale": "The sum is a single amount, not multiple items.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["singular verb", "sum"], "dependencies": [], "exceptions": ["Use plural when referring to separate bills or coins."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_22.MONEY.SYMBOL_OR_WORD", "title": "Choose a consistent money format in context", "source_refs": ["CMOS18 §9.22 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Within a context, choose either spelled-out money amounts or symbol-and-numeral format and keep it consistent.", "rationale": "Mixed formats can look inconsistent or confusing.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money", "consistency"], "keywords": ["money format", "consistency"], "dependencies": [], "exceptions": ["Quoted amounts may preserve original formatting."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_22.MONEY.MINIMUM_DECIMALS", "title": "Use the minimum decimals needed for money", "source_refs": ["CMOS18 §9.22 p600 (scan p622)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Avoid adding cents to monetary amounts unless cents are significant or present elsewhere in the context.", "rationale": "Extra decimals suggest precision that may not exist.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["cents", "precision"], "dependencies": [], "exceptions": ["Accounting statements may require fixed decimals."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.DISAMBIGUATE", "title": "Disambiguate non-US dollar amounts", "source_refs": ["CMOS18 §9.23 p601 (scan p623)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When $ does not mean US dollars, identify the currency using a country prefix or code.", "rationale": "The dollar sign is used by multiple currencies.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["dollar sign", "currency"], "dependencies": [], "exceptions": ["If the context makes the currency unambiguous, a prefix may be omitted."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.ISO_CODES", "title": "Use ISO currency codes in formal contexts", "source_refs": ["CMOS18 §9.23 p601 (scan p623)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In formal or technical documents, prefer ISO three-letter currency codes to identify dollar-based currencies.", "rationale": "ISO codes avoid ambiguity across markets.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["ISO codes"], "dependencies": [], "exceptions": ["Public-facing content may prefer country prefixes like C$."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_23.NON_US_DOLLAR.CONTEXT_CLEAR", "title": "Use $ alone only when the currency is clear", "source_refs": ["CMOS18 §9.23 p601 (scan p623)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use a bare dollar sign only when the surrounding context makes the currency unmistakable.", "rationale": "Unlabeled dollar signs can mislead readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["dollar sign", "context"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_24.BRITISH.POUND_SYMBOL", "title": "Use the pound symbol for British currency", "source_refs": ["CMOS18 §9.24 p601 (scan p623)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use the pound sterling symbol (GBP or £) for British currency.", "rationale": "The symbol identifies the unit clearly.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["pound", "sterling"], "dependencies": [], "exceptions": ["Use ISO codes in technical contexts."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_24.BRITISH.PENCE_SYMBOL", "title": "Use p for pence without a period", "source_refs": ["CMOS18 §9.24 p601 (scan p623)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use p to denote pence with no period.", "rationale": "Pence notation follows standard British usage.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["pence"], "dependencies": [], "exceptions": ["Historical documents may use older abbreviations."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_24.BRITISH.DECIMAL_FORMAT", "title": "Use decimal format for pounds and pence", "source_refs": ["CMOS18 §9.24 p601 (scan p623)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Express modern British currency in decimal format (for example, £4.75).", "rationale": "Decimal currency is the current standard.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["decimal currency"], "dependencies": [], "exceptions": ["Historical contexts may use pre-decimal notation."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_25.OTHER_CURRENCIES.DECIMAL", "title": "Use decimal points for most other currencies", "source_refs": ["CMOS18 §9.25 p602 (scan p624)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Most currencies use a decimal point between the main unit and subunit; follow that format.", "rationale": "Decimal notation is standard across modern currencies.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["decimal currency", "subunits"], "dependencies": [], "exceptions": ["Follow local currency standards if different."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_25.CURRENCY_CODES.SPACING", "title": "Insert a space when currency codes are written as letters", "source_refs": ["CMOS18 §9.25 p602 (scan p624)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a currency code is written in letters, separate it from the number with a space.", "rationale": "Spacing improves readability and prevents code-number fusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["currency codes", "spacing"], "dependencies": [], "exceptions": ["Symbols typically sit adjacent to numerals."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_25.CURRENCY_CODES.CONSISTENT", "title": "Keep currency code usage consistent", "source_refs": ["CMOS18 §9.25 p602 (scan p624)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "If currency codes are used, keep them consistent across the document.", "rationale": "Mixed currency labeling confuses readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money", "consistency"], "keywords": ["currency codes", "consistency"], "dependencies": [], "exceptions": ["Quoted material may preserve its original format."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_25.ISO_CODES.FORMAL", "title": "Prefer ISO codes in formal or technical contexts", "source_refs": ["CMOS18 §9.25 p602 (scan p624)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use ISO three-letter currency codes in formal, legal, or technical contexts.", "rationale": "ISO codes are unambiguous and standardized.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["ISO codes"], "dependencies": [], "exceptions": ["Marketing prose may prefer symbols."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_26.LARGE_MONEY.NUMERALS", "title": "Use numerals for large monetary amounts", "source_refs": ["CMOS18 §9.26 p602 (scan p624)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "For monetary amounts above one hundred, use numerals.", "rationale": "Large sums are clearer in numeric form.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["large amounts"], "dependencies": [], "exceptions": ["Narrative emphasis may justify words for small rounded sums."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_26.LARGE_MONEY.MIXED", "title": "Use numerals with million or billion for very large sums", "source_refs": ["CMOS18 §9.26 p602 (scan p624)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "For amounts of a million or more, combine numerals with the word million or billion as appropriate.", "rationale": "Mixed forms keep large sums readable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["million", "billion"], "dependencies": [], "exceptions": ["Use full numerals in tabular data when needed."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_26.K_THOUSANDS", "title": "Use K for thousands only in financial contexts", "source_refs": ["CMOS18 §9.26 p602 (scan p624)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Abbreviate thousands with K only in financial contexts where the audience expects it.", "rationale": "K notation is jargon outside finance.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["K notation", "thousands"], "dependencies": [], "exceptions": ["Define K on first use if the audience may be unfamiliar."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_26.MONEY.COMMAS", "title": "Use standard digit grouping in large sums", "source_refs": ["CMOS18 §9.26 p602 (scan p624)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use standard digit grouping (commas or locale-appropriate separators) for large monetary amounts.", "rationale": "Grouping improves scanability and reduces misreads.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["digit grouping", "commas"], "dependencies": [], "exceptions": ["Follow SI or locale conventions as required."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_27.CURRENCY_YEAR.PARENS_NO_SPACE", "title": "Insert the year in parentheses after a currency symbol", "source_refs": ["CMOS18 §9.27 p602 (scan p624)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When specifying the value of a currency in a given year, put the year in parentheses immediately after the symbol with no space.", "rationale": "The placement keeps the symbol tied to the value.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["currency year", "parentheses"], "dependencies": [], "exceptions": ["Use spaces when a letter code is used instead of a symbol."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_27.CURRENCY_YEAR.CODES_SPACING", "title": "Use spaces around parenthetical years with currency codes", "source_refs": ["CMOS18 §9.27 p602 (scan p624)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When a currency is expressed with letters, place spaces around the parenthetical year.", "rationale": "Spacing keeps letter codes readable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "money"], "keywords": ["currency codes", "spacing"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_28.DIVISIONS.NUMERALS", "title": "Use numerals for book divisions and references", "source_refs": ["CMOS18 §9.28 p603 (scan p625)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use numerals for pages, chapters, parts, volumes, tables, figures, and similar references.", "rationale": "Document navigation expects numeric labels.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "document_parts"], "keywords": ["chapters", "tables", "figures"], "dependencies": [], "exceptions": ["Front matter may use Roman numerals."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_28.FRONT_MATTER.ROMAN", "title": "Use Roman numerals for front-matter pages", "source_refs": ["CMOS18 §9.28 p603 (scan p625)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use lowercase Roman numerals for front-matter pages and Arabic numerals for the main text.", "rationale": "This is standard book pagination practice.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "document_parts"], "keywords": ["front matter", "Roman numerals"], "dependencies": [], "exceptions": ["Follow the published pagination in citations."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_28.BIBLICAL_REFERENCES", "title": "Format biblical references with numerals and colon", "source_refs": ["CMOS18 §9.28 p603 (scan p625)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "For biblical references, use numerals and separate chapter and verse with a colon and no space.", "rationale": "Biblical citations follow a fixed convention.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "citations"], "keywords": ["biblical references", "colon"], "dependencies": [], "exceptions": ["Use the format required by the cited edition."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_29.PERIODICALS.ORDER", "title": "Order periodical references as volume, issue, page", "source_refs": ["CMOS18 §9.29 p603 (scan p625)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Cite periodicals with volume, issue, and page numbers in that order, using numerals.", "rationale": "Standard ordering aids lookup and verification.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "citations"], "keywords": ["periodicals", "volume", "issue"], "dependencies": [], "exceptions": ["Follow citation style guides when required."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_29.PERIODICALS.OMIT_WORDS", "title": "Omit the words volume and page in periodical citations", "source_refs": ["CMOS18 §9.29 p603 (scan p625)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In standard periodical citations, omit the words volume and page and use numerals only.", "rationale": "Compact citations are conventional in journals.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "citations"], "keywords": ["volume", "page", "citations"], "dependencies": [], "exceptions": ["Use explicit labels if required by a publisher."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.NUMERALS", "title": "Use Arabic or Roman numerals for legal divisions", "source_refs": ["CMOS18 §9.30 p603 (scan p625)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Legal instruments commonly use Arabic or Roman numerals to label divisions; follow the document's scheme.", "rationale": "Legal references depend on exact numbering.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "legal"], "keywords": ["legal instruments", "Roman numerals"], "dependencies": [], "exceptions": ["Consult the source document when in doubt."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.PREFER_ARABIC", "title": "Prefer Arabic numerals if legal references are unclear", "source_refs": ["CMOS18 §9.30 p603 (scan p625)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "If a legal reference is ambiguous, prefer Arabic numerals or verify against the source document.", "rationale": "Arabic numerals are the most common and least ambiguous.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "legal"], "keywords": ["legal references", "Arabic numerals"], "dependencies": [], "exceptions": ["Use Roman numerals when the official source requires them."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_30.LEGAL_DIVISIONS.MIXED_LEVELS", "title": "Use mixed numeral systems to distinguish levels when required", "source_refs": ["CMOS18 §9.30 p603 (scan p625)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Some legal documents use Arabic numerals for one level and Roman numerals for another; preserve that distinction.", "rationale": "Mixed systems can encode hierarchy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "legal"], "keywords": ["hierarchy", "legal"], "dependencies": [], "exceptions": ["Do not invent mixed systems; follow the source."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_31.YEAR_STANDALONE", "title": "Use numerals when a year stands alone", "source_refs": ["CMOS18 §9.31 p604 (scan p626)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Express years as numerals when they stand alone.", "rationale": "Year numbers are standardly numeric.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["years", "numerals"], "dependencies": [], "exceptions": ["Spell out only if required by house style."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_31.YEAR_SENTENCE_START_ALLOWED", "title": "Allow numeral years at sentence start", "source_refs": ["CMOS18 §9.31 p604 (scan p626)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "A sentence may begin with a year written as numerals, though rewording may still be preferable.", "rationale": "Spelled-out years are often awkward.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["sentence start", "years"], "dependencies": [], "exceptions": ["Recast if it improves readability."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_32.ABBREVIATED_YEAR.APOSTROPHE", "title": "Use an apostrophe for abbreviated years", "source_refs": ["CMOS18 §9.32 p604 (scan p626)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When abbreviating a year, use an apostrophe (not an opening quote) to replace the omitted digits.", "rationale": "Correct apostrophes signal elision, not quotation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["abbreviated years", "apostrophe"], "dependencies": [], "exceptions": ["Avoid abbreviations in formal writing."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_33.MONTH_DAY.CARDINALS", "title": "Use cardinal numbers in month-day dates", "source_refs": ["CMOS18 §9.33 p604 (scan p626)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In month-day dates, use cardinal numbers (April 11), even if pronounced as ordinals.", "rationale": "Cardinal dates are the standard written form.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["month-day", "cardinals"], "dependencies": [], "exceptions": ["Ordinal forms may appear in informal writing."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_33.DAY_WITHOUT_MONTH.ORDINAL", "title": "Use ordinals when the day stands alone", "source_refs": ["CMOS18 §9.33 p604 (scan p626)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When the day is mentioned without the month or precedes the month, use an ordinal form (the 25th, the 5th of June).", "rationale": "Ordinals are conventional for day-only references.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["ordinals", "day references"], "dependencies": [], "exceptions": ["Formal prose may prefer month-day form."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_33.MONTH_DAY_YEAR.COMMA", "title": "Use commas in month-day-year dates", "source_refs": ["CMOS18 §9.33 p604 (scan p626)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "In month-day-year format, place a comma after the day and after the year if the sentence continues.", "rationale": "Commas separate the date elements clearly.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dates"], "keywords": ["month-day-year", "commas"], "dependencies": [], "exceptions": ["Do not use this rule for day-month-year format."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_34.CENTURIES.ORDINAL_LOWERCASE", "title": "Spell out centuries as lowercase ordinals", "source_refs": ["CMOS18 §9.34 p605 (scan p627)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When referring to centuries as such, spell them out as lowercase ordinals (twenty-first century).", "rationale": "This is the standard narrative form for centuries.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "centuries"], "keywords": ["centuries", "ordinals"], "dependencies": [], "exceptions": ["Numeral century forms may be used if consistent."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_34.CENTURIES.NUMERAL_PLURALS", "title": "Use s without apostrophe for numeric centuries", "source_refs": ["CMOS18 §9.34 p605 (scan p627)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When centuries are expressed as numerals, add s without an apostrophe (1800s).", "rationale": "Apostrophes are not used for simple plurals.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "centuries"], "keywords": ["centuries", "plural"], "dependencies": [], "exceptions": ["Possessive forms still require an apostrophe."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_34.CENTURY_TURN.AVOID_AMBIGUITY", "title": "Avoid ambiguous 'turn of the twenty-first century' phrasing", "source_refs": ["CMOS18 §9.34 p605 (scan p627)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Avoid potentially ambiguous phrases like 'turn of the twenty-first century'; use 'turn of the century' only when the period is clear.", "rationale": "Century turn phrases can be misread.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "centuries"], "keywords": ["turn of the century", "ambiguity"], "dependencies": [], "exceptions": ["Clarify the period explicitly if needed."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_35.DECADES.NO_APOSTROPHE", "title": "Omit apostrophes in decade numerals", "source_refs": ["CMOS18 §9.35 p605 (scan p627)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use no apostrophe between the year and s in decade numerals (1940s).", "rationale": "Decade labels are plurals, not possessives.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "decades"], "keywords": ["decades", "apostrophe"], "dependencies": [], "exceptions": ["Use an apostrophe only when omitting initial digits ('40s)."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_35.DECADES.FIRST_DECADE", "title": "Avoid ambiguous labels for the first decade of a century", "source_refs": ["CMOS18 §9.35 p605 (scan p627)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Do not use decade labels that could be read as a full century (the 2000s); instead specify 2000-2009 or the first decade.", "rationale": "The first decade of a century is easily misread.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "decades"], "keywords": ["first decade", "ambiguity"], "dependencies": [], "exceptions": ["Casual prose may use colloquial terms with clear context."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_35.DECADES.SECOND_DECADE", "title": "Prefer explicit labels for the second decade", "source_refs": ["CMOS18 §9.35 p605 (scan p627)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "For the second decade of a century, prefer explicit labels such as 2010s or 'second decade' in formal contexts.", "rationale": "Clear labels avoid confusion with other periods.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "decades"], "keywords": ["second decade"], "dependencies": [], "exceptions": ["Informal prose may use colloquial terms like 'teens'."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_36.ERAS.ABBREVIATION_PLACEMENT", "title": "Place AD before the year and BC after", "source_refs": ["CMOS18 §9.36 p606 (scan p628)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Place AD before the year and BC after the year; other era abbreviations typically follow the year.", "rationale": "Era abbreviations have conventional placement.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "eras"], "keywords": ["AD", "BC", "placement"], "dependencies": [], "exceptions": ["Follow source conventions if they are explicitly defined."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_36.ERAS.NO_PERIODS", "title": "Use full capitals without periods for era abbreviations", "source_refs": ["CMOS18 §9.36 p606 (scan p628)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "Use full capitals and no periods for era abbreviations (CE, BCE, AD, BC).", "rationale": "This aligns with modern Chicago practice.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "eras"], "keywords": ["CE", "BCE", "AD", "BC"], "dependencies": [], "exceptions": ["Follow discipline-specific conventions when required."], "status": "active"}
+{"id": "CMOS.NUMBERS.S9_36.ERAS.CENTURY_PLACEMENT", "title": "Place era abbreviations after spelled-out centuries", "source_refs": ["CMOS18 §9.36 p606 (scan p628)"], "category": "numbers", "severity": "should", "applies_to": "all", "rule_text": "When an era abbreviation follows a spelled-out century, place the abbreviation after the century phrase.", "rationale": "This ordering matches common historical usage.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "eras"], "keywords": ["centuries", "era abbreviations"], "dependencies": [], "exceptions": ["Use the source's preferred format in quotations."], "status": "active"}
diff --git a/spec/rules/punctuation/v1_punctuation_003.ndjson b/spec/rules/punctuation/v1_punctuation_003.ndjson
new file mode 100644
index 0000000..ffef2be
--- /dev/null
+++ b/spec/rules/punctuation/v1_punctuation_003.ndjson
@@ -0,0 +1,12 @@
+{"id": "CMOS.PUNCTUATION.SEMICOLONS.INDEPENDENT_CLAUSES", "title": "Use semicolons to link related independent clauses", "source_refs": ["CMOS18 \u00a76.63 p408 (scan p430)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use a semicolon to link closely related independent clauses when no conjunction is used.", "rationale": "Semicolons clarify clause boundaries without the finality of a period.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "semicolons"], "keywords": ["semicolons", "independent clauses"], "dependencies": [], "exceptions": ["Short clauses may be separated by a period or conjunction instead."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.SEMICOLONS.AVOID_COMMA_SPLICE", "title": "Avoid comma splices between independent clauses", "source_refs": ["CMOS18 \u00a76.63 p408 (scan p430)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Avoid joining independent clauses with a comma alone; use a semicolon, conjunction, or period.", "rationale": "Comma splices are a high-signal punctuation error in formal text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "semicolons", "commas"], "keywords": ["comma splice", "independent clauses"], "dependencies": [], "exceptions": ["Informal dialogue may accept comma splices; preserve quotations verbatim."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COLONS.COMPLETE_CLAUSE_REQUIRED", "title": "Use colons only after a complete clause", "source_refs": ["CMOS18 \u00a76.68 p410 (scan p432)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use a colon only after a complete clause; do not place a colon after a verb or preposition that directly introduces its object.", "rationale": "Colons should follow a complete thought and introduce what follows.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "colons"], "keywords": ["colon usage", "complete clause"], "dependencies": [], "exceptions": ["Display typography or labels may permit a colon after short fragments."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COLONS.AVOID_AFTER_PREPOSITION", "title": "Avoid colons after prepositions or verbs", "source_refs": ["CMOS18 \u00a76.68 p410 (scan p432)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Avoid placing a colon directly after a preposition or a verb; rewrite so the lead-in is a full clause.", "rationale": "This avoids fragmentary lead-ins and improves readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "colons"], "keywords": ["colon", "preposition", "verb"], "dependencies": [], "exceptions": ["Headings or labels may allow short fragments by design."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COLONS.INTRODUCE_FORMAL_LISTS", "title": "Use colons to introduce formal lists or statements", "source_refs": ["CMOS18 \u00a76.69 p410 (scan p432)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use a colon to introduce a formal list or a quoted statement when the lead-in is complete.", "rationale": "Colons signal that what follows completes the lead-in.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "colons", "lists"], "keywords": ["colon", "list introduction"], "dependencies": [], "exceptions": ["Bulleted lists may use a line break without a colon if the layout already signals the list."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.QUESTION_MARKS.QUOTE_PLACEMENT", "title": "Place question marks with quotes based on meaning", "source_refs": ["CMOS18 \u00a76.122 p428 (scan p450)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Place a question mark inside quotation marks only if it belongs to the quoted material; otherwise place it outside.", "rationale": "Quote punctuation placement should reflect what is actually being questioned.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "quotation_marks", "question_marks"], "keywords": ["question marks", "quotation marks"], "dependencies": [], "exceptions": ["Follow house style for block quotes that include quoted questions."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.PARENS.PUNCTUATION_PLACEMENT", "title": "Place punctuation relative to parentheses by sense", "source_refs": ["CMOS18 \u00a76.101 p422 (scan p444)", "CMOS18 \u00a76.103 p422 (scan p444)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Place punctuation outside a parenthetical unless the punctuation belongs to the parenthetical content itself.", "rationale": "Correct placement clarifies whether the parenthetical is independent.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "parentheses"], "keywords": ["parentheses", "punctuation placement"], "dependencies": [], "exceptions": ["Sentence-length parentheticals may end with internal punctuation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.BRACKETS.EDITORIAL_INSERTIONS", "title": "Use brackets for editorial insertions in quoted material", "source_refs": ["CMOS18 \u00a76.106 p424 (scan p446)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use square brackets to mark editorial insertions or clarifications within quoted material.", "rationale": "Brackets distinguish editor additions from the original source.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "brackets", "quotations"], "keywords": ["brackets", "editorial insertions"], "dependencies": [], "exceptions": ["Translated or adapted quotations may require a note rather than inline brackets."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.SLASHES.NO_SPACES", "title": "Avoid spaces around slashes in simple alternatives", "source_refs": ["CMOS18 \u00a76.113 p426 (scan p448)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a slash indicates a simple alternative, do not add spaces around it; if the expression is complex, use words instead.", "rationale": "Spacing around slashes makes alternatives harder to parse.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "slashes"], "keywords": ["slash", "alternatives", "spacing"], "dependencies": [], "exceptions": ["If the surrounding text already uses spaced slashes by convention, keep it consistent."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.DASHES.EM_DASH.SPARE_USE", "title": "Use em dashes sparingly", "source_refs": ["CMOS18 \u00a76.89 p418 (scan p440)", "CMOS18 \u00a76.91 p418 (scan p440)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use em dashes for emphasis or breaks only when needed; do not rely on them as a default parenthetical style.", "rationale": "Overuse of em dashes makes prose choppy and uneven.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dashes"], "keywords": ["em dash", "parenthetical"], "dependencies": [], "exceptions": ["Some narrative styles intentionally use frequent dashes; follow house profile."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.DASHES.EN_DASH.WORD_RANGES", "title": "Use en dashes for word and phrase ranges", "source_refs": ["CMOS18 \u00a76.83 p415 (scan p437)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use an en dash (not a hyphen) to link word or phrase ranges (e.g., place names) when the range is conceptually between.", "rationale": "En dashes distinguish ranges from compound modifiers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dashes", "ranges"], "keywords": ["en dash", "word ranges"], "dependencies": [], "exceptions": ["Established compound names may keep their standard hyphenation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.HYPHENS.NUMERIC_COMPOUNDS", "title": "Hyphenate numeric compounds used as modifiers", "source_refs": ["CMOS18 \u00a77.91 p476 (scan p498)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Hyphenate numeric compounds used as modifiers before a noun when they would otherwise misread.", "rationale": "Hyphenation clarifies numeric compound meaning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "hyphenation", "numbers"], "keywords": ["numeric compounds", "hyphenation"], "dependencies": [], "exceptions": ["If the compound follows the noun, the hyphen is often unnecessary; follow established usage."], "status": "active"}
diff --git a/spec/rules/punctuation/v1_punctuation_004.ndjson b/spec/rules/punctuation/v1_punctuation_004.ndjson
new file mode 100644
index 0000000..8428a6a
--- /dev/null
+++ b/spec/rules/punctuation/v1_punctuation_004.ndjson
@@ -0,0 +1,211 @@
+{"id": "CMOS.PUNCTUATION.OVERVIEW.FUNCTION.CLARITY", "title": "Use punctuation to clarify relationships in text", "source_refs": ["CMOS18 §6.1 p377 (scan p400)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use punctuation primarily to clarify relationships within and between sentences so reading is easy and unambiguous.", "rationale": "Punctuation is a readability tool, not decoration.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["punctuation", "clarity", "readability"], "dependencies": [], "exceptions": ["Display typography may prioritize visual rhythm; document the choice."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.OVERVIEW.CONSISTENT.PRINCIPLES", "title": "Apply consistent punctuation principles", "source_refs": ["CMOS18 §6.1 p377 (scan p400)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Apply punctuation principles consistently across a document so subjective choices do not obscure meaning.", "rationale": "Consistency reduces reader confusion and review churn.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["punctuation", "consistency"], "dependencies": [], "exceptions": ["Deliberate stylistic shifts must be explicit and localized."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.OVERVIEW.CONTEXT.REGISTER", "title": "Adjust punctuation strictness by register", "source_refs": ["CMOS18 §6.1 p377 (scan p400)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Match punctuation strictness to context: formal prose demands more consistency than conversational or creative writing.", "rationale": "Different registers have different tolerance for variation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "overview"], "keywords": ["register", "context", "punctuation"], "dependencies": [], "exceptions": ["Genre-specific styles may override default norms when documented."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.ITALICS.SURROUNDING_STYLE", "title": "Match punctuation style to surrounding text", "source_refs": ["CMOS18 §6.2 p378 (scan p400)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Punctuation should match the surrounding font style (roman or italic) unless the punctuation belongs to a differently styled element.", "rationale": "Surrounding style is the default for punctuation ownership.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics"], "keywords": ["italics", "roman", "punctuation style"], "dependencies": [], "exceptions": ["See rules for titles and styled terms that own punctuation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.ITALICS.TITLE_OWNERSHIP", "title": "Style punctuation that belongs to a title with the title", "source_refs": ["CMOS18 §6.2 p378 (scan p400)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When punctuation belongs to a styled title (often italic), style that punctuation with the title rather than the surrounding text.", "rationale": "Ownership clarifies meaning and preserves the title’s integrity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics"], "keywords": ["title", "italics", "punctuation ownership"], "dependencies": [], "exceptions": ["If ownership is ambiguous, prefer the surrounding text style."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.BOLD_COLOR.SEMANTIC_OWNERSHIP", "title": "Style punctuation based on semantic ownership in bold/color text", "source_refs": ["CMOS18 §6.3 p379 (scan p401)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When boldface or color is used, style nearby punctuation according to semantic ownership: if it belongs to the bold term, match it; if it belongs to the sentence, use the surrounding style.", "rationale": "Ownership is clearer than purely visual rules.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "boldface", "color"], "keywords": ["boldface", "color", "punctuation ownership"], "dependencies": [], "exceptions": ["House style may standardize a single approach; document the choice."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.BOLD_COLOR.CASE_BY_CASE", "title": "Handle bold/color punctuation case by case", "source_refs": ["CMOS18 §6.3 p379 (scan p401)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Because boldface or color often serves aesthetic purposes, decide punctuation styling case by case rather than applying a rigid rule.", "rationale": "Design intent can vary with emphasis and layout.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "boldface", "color"], "keywords": ["boldface", "color", "aesthetic"], "dependencies": [], "exceptions": ["If a strict system is required, document and enforce it consistently."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.PRINT_ONLY", "title": "Reserve the aesthetic punctuation system for print-only work", "source_refs": ["CMOS18 §6.4 p379 (scan p401)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If you use the traditional aesthetic system that styles punctuation to the immediately preceding styled word, restrict it to print-only contexts.", "rationale": "Electronic formats separate content from styling and favor logical ownership rules.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "style"], "keywords": ["aesthetic system", "print only", "punctuation style"], "dependencies": [], "exceptions": ["Legacy print reissues may follow historical conventions by policy."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.AESTHETIC_SYSTEM.ELECTRONIC_PREFERS_LOGICAL", "title": "Prefer the logical punctuation system in electronic formats", "source_refs": ["CMOS18 §6.4 p379 (scan p401)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In electronic formats, prefer the logical system where punctuation follows the surrounding text style unless it belongs to a styled element.", "rationale": "Markup and tagging separate meaning from appearance.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "style"], "keywords": ["electronic formats", "logical system", "punctuation style"], "dependencies": [], "exceptions": ["If the output format cannot express logical ownership, document the compromise."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.PARENS_BRACKETS.MATCH_SURROUNDING", "title": "Match parentheses and brackets to surrounding style", "source_refs": ["CMOS18 §6.5 p380 (scan p402)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Set parentheses and brackets in the same style as the surrounding text, not the enclosed material.", "rationale": "Surrounding-style parentheses are easier to apply consistently.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "parentheses", "brackets"], "keywords": ["parentheses", "brackets", "style"], "dependencies": [], "exceptions": ["Line-by-line parentheticals may follow the enclosed style."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.PARENS_BRACKETS.LINE_ALONE", "title": "When a parenthetical stands alone, match its style", "source_refs": ["CMOS18 §6.5 p380 (scan p402)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If a phrase in parentheses or brackets appears on its own line, match the parentheses or brackets to the style of the phrase.", "rationale": "Standalone lines read as a self-contained unit.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "parentheses", "brackets"], "keywords": ["parentheses", "brackets", "standalone"], "dependencies": [], "exceptions": ["If the layout treats the line as marginalia, apply the marginal style consistently."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.PARENS_BRACKETS.PRINT_HAIR_SPACE", "title": "Use hair space only for print collisions", "source_refs": ["CMOS18 §6.5 p380 (scan p402)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If italic letters collide visually with roman parentheses or brackets in print, add a thin or hair space; avoid such adjustments in electronic formats.", "rationale": "Print collision fixes do not transfer reliably to devices.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "parentheses", "brackets", "print"], "keywords": ["hair space", "typefitting", "print"], "dependencies": [], "exceptions": ["If the output engine supports deterministic spacing rules, document them."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.QUOTES.MATCH_SURROUNDING", "title": "Match quotation marks to surrounding style", "source_refs": ["CMOS18 §6.6 p380 (scan p402)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Set quotation marks in the same style as surrounding text, even when the quoted material is styled differently.", "rationale": "Quotation marks belong to the sentence structure, not the quoted styling.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "quotation_marks"], "keywords": ["quotation marks", "style", "surrounding text"], "dependencies": [], "exceptions": ["If the quote is itself a styled title, see the italic-title exception rule."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.QUOTES.LINE_ALONE", "title": "Standalone quoted lines match their own style", "source_refs": ["CMOS18 §6.6 p380 (scan p403)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a quoted sentence or phrase appears on a line by itself, quotation marks usually follow the style of that line.", "rationale": "Standalone quotes function as independent units.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "quotation_marks"], "keywords": ["quotation marks", "standalone"], "dependencies": [], "exceptions": ["If the line is a continuation of a styled block quote, follow the block style."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.QUOTES.ITALIC_TITLE_EXCEPTION", "title": "Italic-title exception after closing quotation marks", "source_refs": ["CMOS18 §6.6 p380 (scan p402)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If an italicized title ends in a closing quotation mark, a following comma or period should remain italic to avoid switching styles twice.", "rationale": "The exception preserves readability and avoids style flicker.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "quotation_marks", "italics"], "keywords": ["italic title", "quotation marks", "comma", "period"], "dependencies": [], "exceptions": ["If the punctuation clearly belongs to the surrounding sentence, document the choice."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.SPACING.ONE_SPACE_SENTENCES", "title": "Use one space between sentences in typeset text", "source_refs": ["CMOS18 §6.7 p381 (scan p403)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In typeset matter, use one space (not two) between sentences regardless of the ending mark.", "rationale": "Single spacing is standard in professional typesetting.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "spacing"], "keywords": ["sentence spacing", "one space"], "dependencies": [], "exceptions": ["Monospaced or legacy contexts may require two-space conventions; document the deviation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.SPACING.ONE_SPACE_AFTER_COLON", "title": "Use one space after colons in typeset text", "source_refs": ["CMOS18 §6.7 p381 (scan p403)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use one space (not two) after a colon in typeset matter.", "rationale": "Single-spacing keeps rhythm consistent.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "spacing"], "keywords": ["colon spacing", "one space"], "dependencies": [], "exceptions": ["Design systems that require extra space must specify a precise measure."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.SPACING.DESIGN_SPECIFIED", "title": "If extra spacing is needed, specify exact measure", "source_refs": ["CMOS18 §6.7 p381 (scan p403)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When layout requires extra space between elements, specify the exact measure instead of using ambiguous multiple spaces.", "rationale": "Explicit spacing prevents accidental drift and preserves determinism.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "spacing"], "keywords": ["spacing", "design", "measure"], "dependencies": [], "exceptions": ["Legacy content may preserve multiple spaces only if recorded as a design requirement."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.URLS.PUNCTUATE_NORMALLY", "title": "Punctuate sentences with URLs and emails normally", "source_refs": ["CMOS18 §6.8 p381 (scan p403)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Sentences that include URLs or email addresses should be punctuated normally.", "rationale": "Readers should treat URLs as ordinary sentence elements.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls", "email"], "keywords": ["URL", "email", "punctuation"], "dependencies": [], "exceptions": ["If a URL is the only content on a line, avoid adding punctuation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.URLS.NO_WRAPPERS", "title": "Avoid angle brackets or wrappers around URLs", "source_refs": ["CMOS18 §6.8 p381 (scan p403)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In normal prose, do not wrap URLs or email addresses in angle brackets or other wrappers unless required by a specific medium.", "rationale": "Wrappers add noise without improving readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls", "email"], "keywords": ["angle brackets", "wrappers", "URL"], "dependencies": [], "exceptions": ["Code samples or literal formats may require wrappers; mark them as code."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.URLS.TRAILING_PUNCTUATION", "title": "Treat trailing punctuation as part of the sentence, not the URL", "source_refs": ["CMOS18 §6.8 p381 (scan p403)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Punctuation at the end of a sentence should be understood as part of the sentence, not the URL or email address.", "rationale": "Trailing punctuation avoids truncating links in print and review.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls", "email"], "keywords": ["URL", "email", "trailing punctuation"], "dependencies": [], "exceptions": ["If a URL truly ends with punctuation, clarify with a note or rephrase."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.URLS.HYPERTEXT_EXCLUDES_PUNCTUATION", "title": "Exclude sentence punctuation from hyperlink markup", "source_refs": ["CMOS18 §6.8 p381 (scan p403)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When adding hyperlink markup, exclude surrounding sentence punctuation from the link target.", "rationale": "Including punctuation in links causes broken URLs.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "urls", "email"], "keywords": ["hyperlink", "URL", "punctuation"], "dependencies": [], "exceptions": ["If the URL itself includes punctuation, ensure only that punctuation is linked."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.QUOTES.US_STYLE_PERIODS_COMMAS", "title": "Use US style for periods and commas with closing quotation marks", "source_refs": ["CMOS18 §6.9 p381 (scan p403)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In US style, periods and commas precede closing quotation marks regardless of logic, unless a documented exception applies.", "rationale": "This is the standard convention in US publishing.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "quotation_marks"], "keywords": ["quotation marks", "periods", "commas", "US style"], "dependencies": [], "exceptions": ["Technical or legal contexts may require logical placement by policy."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.QUOTES.APOSTROPHE_NOT_QUOTE", "title": "Do not confuse apostrophes with closing quotation marks", "source_refs": ["CMOS18 §6.9 p381 (scan p403)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Ensure apostrophes at word endings are not mistaken for closing quotation marks.", "rationale": "Misclassification alters meaning and can break quote logic.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "quotation_marks", "apostrophes"], "keywords": ["apostrophe", "quotation mark", "misread"], "dependencies": [], "exceptions": ["In OCR-derived text, flag potential ambiguities for review."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.QUOTES.ALT_STYLE.DOCUMENT", "title": "If an alternate quote style is used, document it", "source_refs": ["CMOS18 §6.9 p381 (scan p403)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If using a non-US quotation style (e.g., British logical placement), document it and apply consistently.", "rationale": "Declared style prevents inconsistent quote placement.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "quotation_marks"], "keywords": ["quotation style", "British style", "consistency"], "dependencies": [], "exceptions": ["Quoted material from external sources may preserve its original style."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.PERIODS.OMIT_DISPLAY_LINES", "title": "Omit periods on display lines and headings", "source_refs": ["CMOS18 §6.14 p384 (scan p405)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Do not add a period at the end of display lines such as titles, headings, or running heads unless the line ends with an abbreviation.", "rationale": "Display typography typically omits terminal punctuation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "periods", "display"], "keywords": ["display lines", "headings", "period omission"], "dependencies": [], "exceptions": ["Captions or run-in heads may use periods by style."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.PARENS.AVOID_MULTIPLE_SENTENCES", "title": "Avoid nesting multiple full sentences inside another sentence", "source_refs": ["CMOS18 §6.14 p384 (scan p405)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Avoid enclosing more than one complete sentence within another sentence; move the parenthetical sentences outside or rephrase.", "rationale": "Nested full sentences reduce clarity and flow.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "parentheses"], "keywords": ["parenthetical sentences", "clarity"], "dependencies": [], "exceptions": ["Short editorial asides may be acceptable if clarity is preserved."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.ELLIPSIS.USE_CASES", "title": "Use ellipses for omission or trailing thought", "source_refs": ["CMOS18 §6.15 p384 (scan p405)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use ellipses to mark omitted material or a trailing, incomplete thought; do not use them as decoration.", "rationale": "Ellipses signal specific kinds of absence.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ellipsis"], "keywords": ["ellipsis", "omission", "trailing thought"], "dependencies": [], "exceptions": ["Quoted material may preserve the source punctuation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.LOGIC_OVER_PAUSE", "title": "Prefer sentence logic over perceived pause", "source_refs": ["CMOS18 §6.16 p384 (scan p405)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In formal prose, comma placement should follow grammatical logic rather than a perceived pause.", "rationale": "Logical punctuation prevents inconsistent pacing.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["commas", "grammar", "logic"], "dependencies": [], "exceptions": ["Creative writing may use commas for rhythm by design."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.REGISTER.FLEX", "title": "Adjust comma density by register", "source_refs": ["CMOS18 §6.16 p384 (scan p405)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Comma density may vary by register: formal prose tends to be more logically punctuated than conversational writing.", "rationale": "Register-sensitive punctuation preserves tone.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "register"], "keywords": ["commas", "register", "tone"], "dependencies": [], "exceptions": ["House style may prescribe a specific comma density."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.EXPLANATORY_ALTERNATIVES", "title": "Set off explanatory alternatives with commas", "source_refs": ["CMOS18 §6.55 p405 (scan p427)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When an explanatory alternative introduced by or interrupts a sentence, set it off with commas; do not add commas when the alternative is not explanatory.", "rationale": "Commas signal whether the alternative is parenthetical.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["explanatory alternatives", "or", "commas"], "dependencies": [], "exceptions": ["If clarity is doubtful, rewrite to remove ambiguity."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.TOO_EITHER.OMIT", "title": "Omit commas with too and either when meaning is also", "source_refs": ["CMOS18 §6.56 p405 (scan p427)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When too or either means also, a preceding comma is usually unnecessary; query before changing if the author prefers commas.", "rationale": "This is a style preference that varies by author.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["too", "either", "commas"], "dependencies": [], "exceptions": ["If too appears mid-clause, commas may aid clarity."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.TOO_MID_SENTENCE", "title": "Mid-clause too may take commas", "source_refs": ["CMOS18 §6.56 p405 (scan p427)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When too appears mid-clause, commas may improve clarity; use them if the sentence reads more cleanly.", "rationale": "Mid-clause adverbs can be harder to parse.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["too", "commas", "clarity"], "dependencies": [], "exceptions": ["If commas feel intrusive, rewrite the clause."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS", "title": "Use commas for direct address", "source_refs": ["CMOS18 §6.57 p405 (scan p427)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Names or words used in direct address should be set off by commas.", "rationale": "Vocative commas clarify who is being addressed.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["direct address", "vocative comma"], "dependencies": [], "exceptions": ["Very short interjections may omit commas by style."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.DIRECT_ADDRESS.GREETINGS", "title": "Use commas in greetings and salutations by style", "source_refs": ["CMOS18 §6.57 p405 (scan p427)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In correspondence, a comma typically follows greetings; a colon may be used for formal letters. If a greeting word like Hello precedes a name, a comma may also precede the name.", "rationale": "Greeting punctuation varies by formality and convention.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "correspondence"], "keywords": ["greetings", "salutations", "comma", "colon"], "dependencies": [], "exceptions": ["House style may specify greeting punctuation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.ELISION", "title": "Use commas to indicate elided words when needed", "source_refs": ["CMOS18 §6.58 p406 (scan p428)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "A comma may indicate omitted words that are easily inferred; omit the comma if the elliptical construction is clear without it.", "rationale": "Ellipsis commas can clarify parallel structures.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["elision", "ellipsis comma"], "dependencies": [], "exceptions": ["If the omission risks ambiguity, rewrite the sentence."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.SEMICOLONS.AVOID_DIALOGUE", "title": "Avoid adding semicolons in dialogue without author approval", "source_refs": ["CMOS18 §6.60 p407 (scan p429)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Many authors avoid semicolons in dialogue; do not add them to dialogue or narrative voice without consulting the author or house style.", "rationale": "Semicolons can alter voice and tone.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "semicolons", "dialogue"], "keywords": ["semicolons", "dialogue", "voice"], "dependencies": [], "exceptions": ["If the text is already formally punctuated, maintain consistency."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COLONS.AMPLIFY_OR_ILLUSTRATE", "title": "Use colons to introduce amplification or illustration", "source_refs": ["CMOS18 §6.65 p409 (scan p431)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use a colon to introduce an element or series that illustrates or amplifies what precedes it.", "rationale": "Colons signal explanatory follow-on content.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "colons"], "keywords": ["colons", "amplification", "illustration"], "dependencies": [], "exceptions": ["If the lead-in is not a complete clause, avoid the colon."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COLONS.EMPHASIS_SECOND_CLAUSE", "title": "Use a colon for emphasis between clauses", "source_refs": ["CMOS18 §6.65 p409 (scan p431)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Between independent clauses, use a colon when the second clause deserves emphasis or explanation beyond a semicolon.", "rationale": "Colons add emphasis to the following clause.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "colons"], "keywords": ["colons", "emphasis"], "dependencies": [], "exceptions": ["If emphasis is not intended, use a semicolon or period."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COLONS.FORMAL_GREETINGS", "title": "Use colons after formal greetings", "source_refs": ["CMOS18 §6.70 p411 (scan p433)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In formal communications or speeches, a colon typically follows the greeting or identification of those addressed.", "rationale": "Formal correspondence conventions differ from casual greetings.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "colons", "correspondence"], "keywords": ["formal greetings", "colon"], "dependencies": [], "exceptions": ["House style may specify commas instead."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COLONS.AVOID_INCOMPLETE_LEADIN", "title": "Avoid colons after incomplete lead-ins", "source_refs": ["CMOS18 §6.71 p411 (scan p433)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Do not use a colon if the words before it do not form a complete sentence; test by reading the lead-in as a full clause.", "rationale": "Colons require a complete lead-in to avoid fragments.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "colons"], "keywords": ["colon misuse", "complete clause"], "dependencies": [], "exceptions": ["Elliptical labels like Pros: or Cons: may allow a colon by design."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.EXCLAMATION.QUOTE_PLACEMENT", "title": "Place exclamation points with the quoted matter they belong to", "source_refs": ["CMOS18 §6.78 p414 (scan p436)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Place an exclamation point inside quotation marks or parentheses only when it belongs to that quoted or parenthetical material.", "rationale": "Placement should reflect meaning, not appearance.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "exclamation_points", "quotation_marks"], "keywords": ["exclamation point", "quote placement"], "dependencies": [], "exceptions": ["Maintain the original punctuation for quoted sources."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.DASHES.DISTINCT_TYPES", "title": "Distinguish hyphens, en dashes, and em dashes by function", "source_refs": ["CMOS18 §6.79 p414 (scan p436)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use hyphens, en dashes, and em dashes according to their distinct functions rather than treating them as interchangeable.", "rationale": "Correct dash usage signals editorial precision.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dashes"], "keywords": ["hyphen", "en dash", "em dash"], "dependencies": [], "exceptions": ["If a platform cannot render en/em dashes, document the fallback."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.HYPHENS.SEPARATORS", "title": "Use hyphens to separate noninclusive numbers and spelled letters", "source_refs": ["CMOS18 §6.81 p415 (scan p437)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use hyphens to separate noninclusive numbers (e.g., phone numbers) and to separate letters when a word is spelled out.", "rationale": "Hyphens are standard separators in such formats.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "hyphens"], "keywords": ["hyphens", "separators", "phone numbers"], "dependencies": [], "exceptions": ["Follow domain-specific formatting (e.g., ISBNs) when prescribed."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.DASHES.EN_DASH.AVOID_FROM_BETWEEN", "title": "Avoid en dashes with from or between", "source_refs": ["CMOS18 §6.83 p415 (scan p437)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a range is introduced by from or between, use to or and rather than an en dash.", "rationale": "Mixing from/between with an en dash is ungrammatical.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dashes", "ranges"], "keywords": ["en dash", "ranges", "from", "between"], "dependencies": [], "exceptions": ["If a source uses mixed forms, preserve quotations verbatim."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.DASHES.EN_DASH.LINE_BREAKS", "title": "Break lines after en dashes, not before", "source_refs": ["CMOS18 §6.88 p418 (scan p440)"], "category": "punctuation", "severity": "should", "applies_to": "pdf", "rule_text": "In print, line breaks should occur after an en dash, not before; avoid carrying a single character to the next line when possible.", "rationale": "En-dash breaks should mirror hyphenation conventions.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust line breaks or spacing to keep en dashes from starting a line.", "tags": ["dashes", "line_breaks"], "keywords": ["en dash", "line breaks"], "dependencies": [], "exceptions": ["Reflowable formats may let the engine decide."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.DASHES.EN_DASH.SPACED_BRITISH", "title": "Use spaced en dashes for British dash style", "source_refs": ["CMOS18 §6.89 p418 (scan p440)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If using British dash style, use a spaced en dash in running text instead of an em dash.", "rationale": "British style prefers spaced en dashes for parenthetical breaks.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dashes"], "keywords": ["British style", "en dash", "spacing"], "dependencies": [], "exceptions": ["Do not mix British and US dash styles in the same document."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.DASHES.EN_DASH.MINUS_SIGN", "title": "Use the correct minus sign in mathematical contexts", "source_refs": ["CMOS18 §6.90 p418 (scan p440)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use the proper minus sign character in mathematical contexts; do not substitute an en dash.", "rationale": "Correct characters improve searchability and clarity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dashes", "math"], "keywords": ["minus sign", "en dash", "math"], "dependencies": [], "exceptions": ["Plain-text environments may require a hyphen-minus by convention."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.DASHES.EM_DASH.ALTERNATIVE_TO_PARENS", "title": "Use em dashes as an alternative to commas or parentheses", "source_refs": ["CMOS18 §6.91 p418 (scan p440)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use em dashes to set off an amplifying or explanatory element when an abrupt break is intended.", "rationale": "Em dashes signal a stronger break than commas.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dashes"], "keywords": ["em dash", "parenthetical"], "dependencies": [], "exceptions": ["Overuse can make prose choppy; prefer commas or parentheses when tone is calm."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.DASHES.EM_DASH.AVOID_NESTED", "title": "Avoid em dashes within em-dash parentheticals", "source_refs": ["CMOS18 §6.95 p419 (scan p441)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Do not place an em dash inside material already set off by em dashes; use commas or parentheses instead.", "rationale": "Nested em dashes are hard to parse.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dashes"], "keywords": ["em dash", "nesting"], "dependencies": [], "exceptions": ["Dialogue may allow extra dashes for interruptions."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.DASHES.EM_DASH.PUNCTUATION_BEFORE", "title": "Do not place commas or colons before em dashes", "source_refs": ["CMOS18 §6.95 p419 (scan p441)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In modern usage, do not place commas, colons, or semicolons before an em dash; only question or exclamation points may precede it when needed.", "rationale": "Stacked punctuation reduces clarity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dashes"], "keywords": ["em dash", "punctuation stacking"], "dependencies": [], "exceptions": ["A period may precede an em dash when it belongs to an abbreviation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.DASHES.EM_DASH.LINE_BREAKS_DETAIL", "title": "Avoid line breaks between em dashes and following punctuation", "source_refs": ["CMOS18 §6.96 p420 (scan p442)"], "category": "punctuation", "severity": "should", "applies_to": "pdf", "rule_text": "Do not allow a line break between an em dash and following punctuation or an attribution that immediately follows it.", "rationale": "Separated marks make the dash read as a hyphen.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust line breaks to keep dash and following punctuation together.", "tags": ["dashes", "line_breaks"], "keywords": ["em dash", "line breaks", "attribution"], "dependencies": [], "exceptions": ["Reflowable formats may rely on engine breaks."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.DASHES.EM_DASH.DIALOGUE_STYLE", "title": "Em dash dialogue style requires a new paragraph and no following space", "source_refs": ["CMOS18 §6.97 p420 (scan p442)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If using em dashes instead of quotation marks for dialogue, start each speech on a new paragraph and do not add a space after the dash.", "rationale": "This convention signals a specific dialogue style.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dashes", "dialogue"], "keywords": ["em dash", "dialogue", "quotation marks"], "dependencies": [], "exceptions": ["Do not mix this style with standard quotation marks."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.DASHES.EM_DASH.LISTS_TABLES", "title": "Avoid em dashes as bullets in formal prose", "source_refs": ["CMOS18 §6.98 p420 (scan p442)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Avoid using em dashes as list bullets in formal prose; use standard list markers instead.", "rationale": "Dash bullets can look informal and inconsistent.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dashes", "lists"], "keywords": ["em dash", "lists"], "dependencies": [], "exceptions": ["Tables may use em dashes to mark empty cells when explained."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.DASHES.TWO_EM.OMISSIONS", "title": "Use 2-em and 3-em dashes for omissions when required", "source_refs": ["CMOS18 §6.99 p421 (scan p443)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use a 2-em or 3-em dash to represent missing words or parts of words when redaction is required; apply spacing rules consistently.", "rationale": "Standard omission marks prevent ambiguity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "dashes", "redaction"], "keywords": ["2-em dash", "3-em dash", "omissions"], "dependencies": [], "exceptions": ["Asterisks may be clearer when censoring expletives."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.APOSTROPHE.USE_CASES", "title": "Use apostrophes for possessives, contractions, and select plurals", "source_refs": ["CMOS18 §6.124 p429 (scan p451)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use apostrophes to mark possessives, to show omitted letters or numerals in contractions, and (rarely) to form plurals of certain expressions.", "rationale": "Apostrophe misuse is a high-visibility error.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "apostrophes"], "keywords": ["apostrophes", "possessive", "contractions"], "dependencies": [], "exceptions": ["Follow house style for pluralizing abbreviations."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.APOSTROPHE.SMART", "title": "Use typographic apostrophes in published text", "source_refs": ["CMOS18 §6.125 p429 (scan p451)"], "category": "punctuation", "severity": "must", "applies_to": "md", "rule_text": "Use typographic apostrophes (right single quotation mark) in published text; avoid straight apostrophes outside code.", "rationale": "Typographic apostrophes are standard in professional typesetting.", "enforcement": "lint", "autofix": "rewrite", "autofix_notes": "Convert straight apostrophes to typographic apostrophes in prose; skip code blocks and inline code.", "tags": ["apostrophes", "degraded_input"], "keywords": ["smart apostrophes", "typography"], "dependencies": [], "exceptions": ["Code and literal strings must preserve straight apostrophes."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.SPACING.WORD_SPACE_DEFAULT", "title": "Use standard word spaces unless a special space is required", "source_refs": ["CMOS18 §6.127 p430 (scan p452)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use the standard word space for most contexts; use special fixed-width spaces only when required by the design or logic.", "rationale": "Special spaces are exceptions, not defaults.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "spacing"], "keywords": ["word space", "spacing"], "dependencies": [], "exceptions": ["Tables or numeric alignment may require fixed-width spaces."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.SPACING.NONBREAKING", "title": "Use nonbreaking spaces to prevent bad breaks", "source_refs": ["CMOS18 §6.127 p430 (scan p452)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use nonbreaking spaces to prevent awkward line breaks between related elements when layout requires control.", "rationale": "Nonbreaking spaces preserve meaning and readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "spacing"], "keywords": ["nonbreaking spaces", "line breaks"], "dependencies": [], "exceptions": ["Let reflowable formats manage breaks unless a specific issue recurs."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.SPACING.FIXED_WIDTHS", "title": "Use fixed-width spaces only when explicitly needed", "source_refs": ["CMOS18 §6.128 p430 (scan p452)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use fixed-width spaces only when explicitly required; do not substitute them for ordinary word spaces.", "rationale": "Fixed-width spaces can disrupt justification and flow.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "spacing"], "keywords": ["fixed-width space", "spacing"], "dependencies": [], "exceptions": ["Equation and typography contexts may require fixed widths."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.PERIODS.NO_DOUBLE_AT_SENTENCE_END", "title": "Do not add an extra period after abbreviations at sentence end", "source_refs": ["CMOS18 §6.132 p432 (scan p454)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When an abbreviation ends with a period at the end of a sentence, do not add another period; add other punctuation only if required.", "rationale": "Double periods are incorrect and distracting.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "periods", "abbreviations"], "keywords": ["abbreviation periods", "sentence end"], "dependencies": [], "exceptions": ["If another mark is required, keep both marks as appropriate."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.PERIODS.NOT_WITH_QM_EXCL", "title": "Do not combine periods with question or exclamation marks", "source_refs": ["CMOS18 §6.133 p433 (scan p454)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "A period does not accompany a question mark or exclamation point; the stronger mark takes precedence.", "rationale": "Stacking terminal marks is unnecessary and informal.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "periods", "question_marks", "exclamation_points"], "keywords": ["period", "question mark", "exclamation point"], "dependencies": [], "exceptions": ["Quoted material may preserve original punctuation if required."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.QUOTE_ENDING_QM_EXCL", "title": "Omit commas when a quote ends with a question or exclamation mark", "source_refs": ["CMOS18 §6.134 p433 (scan p454)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a quoted question or exclamation ends with its own mark, omit the comma that would normally introduce a speech attribution.", "rationale": "The question or exclamation mark replaces the comma.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "quotation_marks"], "keywords": ["commas", "quotation marks", "question mark", "exclamation point"], "dependencies": [], "exceptions": ["Commas may remain after titles that end with a question mark or exclamation point."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.QUESTION_EXCLAMATION.DUAL_MARKS", "title": "Use dual question and exclamation marks only when necessary", "source_refs": ["CMOS18 §6.135 p433 (scan p454)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If a sentence requires both a question mark and an exclamation point, use both only when they are different and essential; otherwise use just one.", "rationale": "Dual marks can confuse readers and look informal.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "question_marks", "exclamation_points"], "keywords": ["question mark", "exclamation point", "dual marks"], "dependencies": [], "exceptions": ["Quoted material may preserve original punctuation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.QUESTION_MARKS.LIST_INTRO", "title": "Question marks take precedence over colons before lists", "source_refs": ["CMOS18 §6.136 p434 (scan p456)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If a question introduces a list, a question mark usually takes precedence over a colon; retain a colon only if the list is part of a sentence.", "rationale": "This keeps punctuation aligned with sentence structure.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "question_marks", "lists"], "keywords": ["question mark", "colon", "lists"], "dependencies": [], "exceptions": ["House style may specify list punctuation rules."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.EMOJIS.PUNCTUATION", "title": "Treat emojis as words in punctuation spacing", "source_refs": ["CMOS18 §6.137 p434 (scan p456)"], "category": "punctuation", "severity": "warn", "applies_to": "all", "rule_text": "If emojis are used, treat a single emoji like a word with spaces around it unless adjacent to punctuation that closes a sentence.", "rationale": "Emoji spacing affects readability and tone.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "emojis"], "keywords": ["emojis", "spacing"], "dependencies": [], "exceptions": ["Fiction and informal contexts may vary; query before changes."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.PARALLEL_ELEMENTS", "title": "List items should be parallel in form", "source_refs": ["CMOS18 §6.138 p435 (scan p456)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "List items should be parallel in form and structure; revise items that break the pattern.", "rationale": "Parallelism improves clarity and scanning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["lists", "parallelism"], "dependencies": [], "exceptions": ["Mixed-form lists may be acceptable if the list is labeled as heterogeneous."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.NUMERALS_ONLY_IF_NEEDED", "title": "Use numerals or letters in lists only when needed", "source_refs": ["CMOS18 §6.138 p435 (scan p456)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use numerals or letters to mark list items only when order, reference, or separation requires them; otherwise omit.", "rationale": "Unnecessary numbering adds clutter.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["lists", "numbering"], "dependencies": [], "exceptions": ["Procedural steps and ranked lists require numbering."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.CONSISTENT_FORMAT", "title": "Keep nearby lists consistent in format", "source_refs": ["CMOS18 §6.138 p435 (scan p456)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When multiple lists appear near each other, keep capitalization, punctuation, and markers consistent.", "rationale": "Consistency prevents visual noise and reader confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["lists", "consistency"], "dependencies": [], "exceptions": ["Lists of different semantic types may use distinct formatting by design."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.RUNIN.SHORT_SIMPLE", "title": "Use run-in lists for short, simple items", "source_refs": ["CMOS18 §6.139 p435 (scan p457)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use run-in lists for short, simple items that read smoothly as part of a sentence.", "rationale": "Run-in lists reduce visual interruption.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["run-in list", "short items"], "dependencies": [], "exceptions": ["If emphasis or hierarchy is needed, use a vertical list."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.VERTICAL.LONG_OR_MULTI", "title": "Use vertical lists for long, prominent, or multi-level items", "source_refs": ["CMOS18 §6.139 p435 (scan p457)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use vertical lists when items are long, need typographic emphasis, or contain multiple levels.", "rationale": "Vertical lists improve scanning for complex content.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["vertical list", "emphasis", "outline"], "dependencies": [], "exceptions": ["If the list is short and sentence-like, prefer run-in."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.RUNIN.MARKERS.PARENS", "title": "Wrap run-in list markers in parentheses", "source_refs": ["CMOS18 §6.140 p435 (scan p457)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When run-in lists use numerals or letters as markers, enclose the markers in parentheses.", "rationale": "Parentheses clarify list boundaries in running text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["run-in list", "parentheses", "markers"], "dependencies": [], "exceptions": ["House style may choose a different enclosure; document it."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.RUNIN.LETTERS.ITALIC_OPTION", "title": "Italicize run-in list letters only if required", "source_refs": ["CMOS18 §6.140 p435 (scan p457)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If letters are used as run-in markers, italicize them only if the style guide specifies; keep the parentheses roman.", "rationale": "Marker styling should be deliberate and consistent.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["run-in list", "letters", "italics"], "dependencies": [], "exceptions": ["If the document uses a different marker style, record it in the style sheet."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.RUNIN.INTRO_COMPLETE_COLON", "title": "Use a colon when a run-in list follows a complete sentence", "source_refs": ["CMOS18 §6.140 p435 (scan p457)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If the introductory text is a complete sentence, place a colon before the first run-in list item.", "rationale": "A colon signals that the list completes the sentence.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists", "colons"], "keywords": ["run-in list", "colon", "intro sentence"], "dependencies": [], "exceptions": ["Avoid a colon after an incomplete lead-in."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.RUNIN.SEPARATORS", "title": "Separate run-in list items with commas or semicolons", "source_refs": ["CMOS18 §6.140 p435 (scan p457)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Separate run-in list items with commas; if any item contains internal commas, use semicolons between all items.", "rationale": "Consistent separators prevent misreading.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["run-in list", "commas", "semicolons"], "dependencies": [], "exceptions": ["If the list is very short, rephrase instead of over-punctuating."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.RUNIN.SENTENCE_ITEMS_VERTICAL", "title": "Set sentence-length items vertically", "source_refs": ["CMOS18 §6.140 p435 (scan p457)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When run-in list items are complete sentences or multiple sentences, switch to a vertical list.", "rationale": "Sentence-length items read better when stacked.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["run-in list", "sentences", "vertical list"], "dependencies": [], "exceptions": ["If the list must remain in running text, reduce item length."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.VERTICAL.INTRO_COLON", "title": "Introduce vertical lists with a complete sentence and a colon", "source_refs": ["CMOS18 §6.141 p436 (scan p458)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Introduce a vertical list with a grammatically complete sentence followed by a colon unless another rule requires different punctuation.", "rationale": "A complete lead-in and colon clarify list structure.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["vertical list", "colon", "lead-in"], "dependencies": [], "exceptions": ["Sentence-style vertical lists may use commas or semicolons instead."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.VERTICAL.UNORDERED_FRAGMENTS", "title": "Unordered lists of fragments use lowercase and no end punctuation", "source_refs": ["CMOS18 §6.141 p436 (scan p458)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In unordered lists where items are fragments, start items lowercase and omit end punctuation except for proper nouns.", "rationale": "Fragment lists read cleanly without terminal marks.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["unordered lists", "fragments", "lowercase"], "dependencies": [], "exceptions": ["If the list is styled for prominence, capitalization may be used consistently."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.VERTICAL.ORDERED_MARKERS", "title": "Use periods after numerals and parentheses around letters", "source_refs": ["CMOS18 §6.141 p436 (scan p458)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In ordered lists, follow numerals with periods; if letters are used, enclose them in parentheses.", "rationale": "Standard markers make hierarchy easier to scan.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["ordered lists", "numerals", "letters"], "dependencies": [], "exceptions": ["Alternate marker systems must be documented."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.VERTICAL.CAPITALIZATION_CONSISTENT", "title": "Keep vertical list capitalization consistent", "source_refs": ["CMOS18 §6.141 p436 (scan p458)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Choose a capitalization scheme for vertical list items and apply it consistently.", "rationale": "Consistency reduces visual noise and editorial drift.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["capitalization", "consistency", "lists"], "dependencies": [], "exceptions": ["Proper nouns remain capitalized regardless of scheme."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.VERTICAL.END_PUNCT_SENTENCES", "title": "Use end punctuation only for sentence items", "source_refs": ["CMOS18 §6.141 p436 (scan p458)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In vertical lists, use end punctuation only when items are complete sentences.", "rationale": "Punctuation should reflect sentence structure.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["lists", "end punctuation", "sentences"], "dependencies": [], "exceptions": ["If a mixed list cannot be revised, punctuate all items consistently."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.VERTICAL.RUNOVER_ALIGN", "title": "Align runover lines with the first word of the item", "source_refs": ["CMOS18 §6.141 p436 (scan p458)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "For vertical lists, align runover lines with the first word after the marker and use a hanging indent or tab as needed.", "rationale": "Aligned runovers keep list structure legible.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists", "layout"], "keywords": ["runover lines", "indentation", "lists"], "dependencies": [], "exceptions": ["Narrow layouts may require alternate indentation choices."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.VERTICAL.MULTI_COLUMN_SHORT_ITEMS", "title": "Use columns for short items to avoid long thin lists", "source_refs": ["CMOS18 §6.141 p436 (scan p458)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When list items are short, consider arranging them in multiple columns to avoid tall, narrow lists.", "rationale": "Columns improve balance and scan speed for short items.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists", "layout"], "keywords": ["lists", "columns", "layout"], "dependencies": [], "exceptions": ["Avoid columns if the reading order could become ambiguous."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.AVOID_VERTICAL_FOR_LONG_SENTENCES", "title": "Use paragraph format for long sentence items without emphasis", "source_refs": ["CMOS18 §6.142 p438 (scan p460)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If list items are long sentences and the list does not need typographic prominence, format them as numbered paragraphs rather than a vertical list.", "rationale": "Paragraph format keeps long items readable without excessive stacking.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["lists", "paragraph format", "long sentences"], "dependencies": [], "exceptions": ["Use vertical lists when emphasis or scanning is required."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.MIXED_SENTENCE_TYPES", "title": "Avoid mixing fragments and full sentences in lists", "source_refs": ["CMOS18 §6.142 p438 (scan p460)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Revise lists so items are all fragments or all sentences; if mixing is unavoidable, punctuate each item with a final mark.", "rationale": "Mixed forms reduce clarity and consistency.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["lists", "fragments", "sentences"], "dependencies": [], "exceptions": ["Preserve original formatting in quoted material."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_PUNCTUATION", "title": "Sentence-style vertical lists use commas or semicolons and a final period", "source_refs": ["CMOS18 §6.142 p438 (scan p460)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a vertical list completes an introductory sentence, separate items with commas or semicolons and end the final item with a period.", "rationale": "Sentence-style lists should read as continuous prose.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["sentence-style list", "commas", "semicolons"], "dependencies": [], "exceptions": ["If items contain internal punctuation, prefer semicolons."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_LOWERCASE", "title": "Sentence-style vertical list items start lowercase", "source_refs": ["CMOS18 §6.142 p438 (scan p460)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In sentence-style vertical lists, begin each item with a lowercase letter even in numbered lists.", "rationale": "Lowercase starts keep the list aligned with the sentence flow.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["sentence-style list", "lowercase"], "dependencies": [], "exceptions": ["Proper nouns remain capitalized."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_CONJUNCTION", "title": "Conjunctions in sentence-style lists are optional", "source_refs": ["CMOS18 §6.142 p438 (scan p460)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In sentence-style vertical lists, a conjunction before the final item is optional; choose one approach and apply it consistently.", "rationale": "Consistency reduces ambiguity in list flow.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["sentence-style list", "conjunctions"], "dependencies": [], "exceptions": ["Legal or formal prose may require an explicit conjunction."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.VERTICAL.SENTENCE_STYLE_USE_ONLY_FOR_EMPHASIS", "title": "Use sentence-style vertical lists only when emphasis is needed", "source_refs": ["CMOS18 §6.142 p438 (scan p460)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If a sentence-style list reads smoothly in running text, keep it run in; set it vertically only when emphasis is required.", "rationale": "Unnecessary vertical lists add visual weight.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["sentence-style list", "emphasis"], "dependencies": [], "exceptions": ["Marketing layouts may choose vertical lists for scanning."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.MULTILEVEL.OUTLINE_MARKERS", "title": "Use structured markers for multilevel lists", "source_refs": ["CMOS18 §6.143 p438 (scan p460)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In multilevel lists, use a structured mix of numerals and letters to distinguish levels and keep the scheme consistent.", "rationale": "Distinct markers clarify hierarchy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["multilevel lists", "outline markers"], "dependencies": [], "exceptions": ["Alternate schemes must be documented in the style sheet."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.MULTILEVEL.RUNOVER_ALIGN", "title": "Align runover lines in multilevel lists", "source_refs": ["CMOS18 §6.143 p438 (scan p460)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In multilevel lists, align runover lines with the first word after the marker and separate markers from text with a tab or fixed space.", "rationale": "Alignment keeps deep outlines readable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists", "layout"], "keywords": ["multilevel lists", "runover lines", "alignment"], "dependencies": [], "exceptions": ["If the layout system handles alignment automatically, verify the output."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.MULTILEVEL.PUNCTUATION_LEVELS", "title": "Differentiate outline levels with punctuation", "source_refs": ["CMOS18 §6.143 p438 (scan p460)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Different outline levels should be distinguished by consistent punctuation or enclosure, such as periods for top levels and parentheses for lower levels.", "rationale": "Distinct punctuation signals level shifts to readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists"], "keywords": ["outline levels", "punctuation", "markers"], "dependencies": [], "exceptions": ["If the outline uses a different system, document it and apply consistently."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.LISTS.MULTILEVEL.MULTI_DIGIT_ALIGN", "title": "Align multi-digit numerals by the last digit", "source_refs": ["CMOS18 §6.143 p438 (scan p460)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When outline numerals have more than one digit, align them on the last digit so text columns line up.", "rationale": "Consistent alignment keeps outlines readable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "lists", "layout"], "keywords": ["outline numerals", "alignment"], "dependencies": [], "exceptions": ["If the layout engine cannot align digits, document the limitation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.PARENS.TRAILING", "title": "Place commas after closing parentheses or brackets", "source_refs": ["CMOS18 §6.18 p384 (scan p407)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When punctuation is needed after parenthetical or bracketed material, place the comma after the closing mark, never before it.", "rationale": "Trailing punctuation belongs to the surrounding sentence.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "parentheses", "brackets"], "keywords": ["parentheses", "brackets", "comma placement"], "dependencies": [], "exceptions": ["Editorial brackets may contain their own punctuation when part of the interpolation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.BRACKETS.EDITORIAL", "title": "Allow editorial commas inside closing brackets only when required", "source_refs": ["CMOS18 §6.18 p384 (scan p407)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "A comma may appear inside and immediately before a closing bracket only when it is part of an editorial interpolation; otherwise it belongs outside.", "rationale": "Editorial insertions can carry their own punctuation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "brackets"], "keywords": ["editorial brackets", "commas"], "dependencies": [], "exceptions": ["If the bracketed material is quoted text, preserve original punctuation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.SERIAL.PAIR_WITH_AND", "title": "Keep the serial comma even if the last element is a pair", "source_refs": ["CMOS18 §6.19 p385 (scan p407)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If the last element in a series is itself a pair joined by and, keep the serial comma before that pair.", "rationale": "Nested conjunctions need clear separators.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["serial comma", "paired items"], "dependencies": [], "exceptions": ["Reword if multiple ands create ambiguity."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.SERIAL.ALL_CONJUNCTIONS_NO_COMMA", "title": "Omit commas when all items are joined by conjunctions", "source_refs": ["CMOS18 §6.19 p385 (scan p407)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When every item in a series is joined by a conjunction, omit commas unless the items are long or clarity requires separators.", "rationale": "Commas are optional in fully conjoined series.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["series", "conjunctions"], "dependencies": [], "exceptions": ["Add commas for long or complex items to aid readability."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.ETC.FINAL_ELEMENT", "title": "Use a comma before etc. and similar terms when final in a series", "source_refs": ["CMOS18 §6.20 p386 (scan p409)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When etc., and so forth, or similar terms end a series, place a comma before the term.", "rationale": "The term functions as the final series element.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["etc", "series"], "dependencies": [], "exceptions": ["If the term follows a single item, the comma is usually unnecessary."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.ETC_ETAL.STYLE", "title": "Treat etc. and et al. as normal text and avoid italics", "source_refs": ["CMOS18 §6.20 p386 (scan p409)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Do not italicize etc. or et al. in normal prose, and prefer limiting etc. to parentheses, notes, or tabular material.", "rationale": "These abbreviations are treated as ordinary terms in Chicago style.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["etc", "et al", "italics"], "dependencies": [], "exceptions": ["Bibliographic styles may impose different conventions."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.CONJUNCTION", "title": "Use a comma before a coordinating conjunction joining independent clauses", "source_refs": ["CMOS18 §6.22 p387 (scan p409)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When independent clauses are joined by a coordinating conjunction, place a comma before the conjunction.", "rationale": "The comma marks the boundary between independent clauses.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["independent clauses", "conjunctions"], "dependencies": [], "exceptions": ["If clauses are very short and closely connected, the comma may be omitted."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.SHORT_OMIT", "title": "Omit commas for very short, closely linked independent clauses", "source_refs": ["CMOS18 §6.22 p387 (scan p409)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If two independent clauses are very short and closely linked, the comma before the conjunction may be omitted unless the clauses form part of a series.", "rationale": "Short clauses can read smoothly without the comma.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["independent clauses", "short clauses"], "dependencies": [], "exceptions": ["Use a comma if omission risks misreading."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.COMMA_SPLICE.AVOID_FORMAL", "title": "Avoid comma splices in formal prose", "source_refs": ["CMOS18 §6.23 p387 (scan p410)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Treat comma splices as errors in formal prose; replace the comma with a conjunction, semicolon, period, dash, or parentheses.", "rationale": "Comma splices weaken clause boundaries in formal contexts.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["comma splice", "run-on"], "dependencies": [], "exceptions": ["Creative or conversational prose may allow occasional splices for effect."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.THEN_SHORTHAND", "title": "Use a comma before then when it stands for and then", "source_refs": ["CMOS18 §6.24 p388 (scan p410)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When then is used as shorthand for and then, a comma usually precedes then; do not add the comma when the phrase is explicitly and then.", "rationale": "The comma clarifies sequencing without repeating the conjunction.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["then", "compound predicate"], "dependencies": [], "exceptions": ["Some genres may omit the comma for a faster rhythm."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.SERIES", "title": "Treat three or more predicate parts as a series", "source_refs": ["CMOS18 §6.24 p388 (scan p410)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a compound predicate has three or more parts, punctuate it like a series, including the serial comma.", "rationale": "Series rules clarify multi-part predicates.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["compound predicate", "series"], "dependencies": [], "exceptions": ["If parts are extremely short, you may omit commas for rhythm."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.IMPERATIVE_CLAUSES.DEFAULT", "title": "Use commas in coordinated imperatives only when needed", "source_refs": ["CMOS18 §6.25 p389 (scan p411)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When two imperative clauses are joined by a coordinating conjunction, add a comma only to prevent ambiguity or when other rules require it.", "rationale": "Imperative clauses can be read as a compound predicate.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["imperatives", "commas"], "dependencies": [], "exceptions": ["Use commas for long or complex clauses."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.DEPENDENT_INTRODUCTORY", "title": "Follow introductory dependent clauses with a comma", "source_refs": ["CMOS18 §6.26 p389 (scan p412)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a dependent clause introduces a sentence, follow it with a comma.", "rationale": "The comma signals the boundary between dependent and main clauses.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["dependent clause", "introductory"], "dependencies": [], "exceptions": ["Very short introductory clauses may omit the comma by house style."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING_RESTRICTIVE", "title": "Do not use commas before restrictive dependent clauses", "source_refs": ["CMOS18 §6.27 p390 (scan p412)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "A dependent clause that follows the main clause should not be preceded by a comma if it is restrictive and essential to meaning.", "rationale": "Restrictive clauses are integral to the main clause.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["dependent clause", "restrictive"], "dependencies": [], "exceptions": ["If meaning is ambiguous, rephrase instead of forcing punctuation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING_NONRESTRICTIVE", "title": "Use commas before nonrestrictive dependent clauses", "source_refs": ["CMOS18 §6.27 p390 (scan p412)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If a dependent clause following the main clause is nonrestrictive, set it off with a comma.", "rationale": "Nonrestrictive clauses are parenthetical.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["dependent clause", "nonrestrictive"], "dependencies": [], "exceptions": ["Creative prose may intentionally blur restrictive status."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.CONSECUTIVE_CONJUNCTIONS.NO_COMMA", "title": "Do not separate consecutive conjunctions by default", "source_refs": ["CMOS18 §6.28 p391 (scan p413)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a dependent clause falls between two clauses so that coordinating and subordinating conjunctions appear consecutively, no comma is usually needed between them.", "rationale": "Consecutive conjunctions can be read without extra punctuation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["conjunctions", "dependent clauses"], "dependencies": [], "exceptions": ["Add a comma for emphasis or in closely punctuated styles."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.RELATIVE_THAT_WHICH", "title": "Use commas with nonrestrictive relative clauses, not restrictive ones", "source_refs": ["CMOS18 §6.29 p391 (scan p414)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Restrictive relative clauses (often introduced by that or who) take no commas; nonrestrictive clauses (often introduced by which or who) take commas.", "rationale": "Comma placement signals whether the clause is essential.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["relative clauses", "that", "which"], "dependencies": [], "exceptions": ["British usage may allow which in restrictive clauses; document the choice."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.RELATIONSHIPS.UNIQUE", "title": "Use commas when a relationship name identifies a unique person", "source_refs": ["CMOS18 §6.31 p393 (scan p415)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a relationship term (spouse, sibling, pet) refers to a unique person, set the name off with commas.", "rationale": "Unique identities are nonrestrictive appositives.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["relationships", "appositives"], "dependencies": [], "exceptions": ["Omit commas when the number of such relations is unknown or irrelevant."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.RELATIONSHIPS.AVOID_POSSESSIVE", "title": "Omit commas to avoid awkward possessives", "source_refs": ["CMOS18 §6.31 p393 (scan p415)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If commas would create an awkward possessive construction, omit them and rephrase if needed.", "rationale": "Awkward possessives signal a structural problem.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["relationships", "possessive"], "dependencies": [], "exceptions": ["If the relationship is clearly unique, consider a full rewrite instead."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASE", "title": "Use commas for nonrestrictive descriptive phrases", "source_refs": ["CMOS18 §6.32 p394 (scan p416)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Descriptive phrases following a noun are set off by commas only when they are nonrestrictive; restrictive phrases take no commas.", "rationale": "Descriptive phrases behave like relative clauses.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["descriptive phrases", "restrictive"], "dependencies": [], "exceptions": ["If ambiguity remains, rephrase instead of forcing commas."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL.NONRESTRICTIVE", "title": "Set off nonrestrictive participial phrases with commas", "source_refs": ["CMOS18 §6.33 p394 (scan p416)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Introductory, medial, or final participial phrases take commas when they are nonrestrictive; restrictive participial phrases do not.", "rationale": "Participial phrases follow the restrictive vs nonrestrictive rule.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["participial phrases", "commas"], "dependencies": [], "exceptions": ["If the phrase modifies a linked subject, avoid the comma."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL.LINKING_VERB", "title": "Do not use commas for participial phrases with linking verbs", "source_refs": ["CMOS18 §6.33 p394 (scan p416)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Do not set off a participial phrase with commas when it modifies the subject through a linking verb, even in inverted sentences.", "rationale": "Linking-verb constructions read as a single unit.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["participial phrases", "linking verbs"], "dependencies": [], "exceptions": ["If the phrase is clearly parenthetical, rephrase."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.ADVERBIAL.INTRO_OPTIONAL", "title": "Use commas after introductory adverbial phrases when needed", "source_refs": ["CMOS18 §6.34 p395 (scan p417)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Introductory adverbial phrases can be followed by a comma when misreading is likely; shorter phrases often omit the comma.", "rationale": "Comma use depends on clarity and length.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["adverbial phrases", "introductory"], "dependencies": [], "exceptions": ["House style may prefer consistent commas after long phrases."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.ADVERBIAL.MID_END", "title": "Set off adverbial phrases when they are parenthetical", "source_refs": ["CMOS18 §6.34 p395 (scan p417)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Adverbial phrases in the middle of a sentence are usually set off with commas; at the end, use a comma only when the phrase is nonrestrictive.", "rationale": "Mid-sentence phrases are more likely to be parenthetical.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["adverbial phrases", "parenthetical"], "dependencies": [], "exceptions": ["Do not use a comma to set off an inverted construction."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.PHRASE_PLUS_CONJUNCTION", "title": "Place commas around phrases after conjunctions based on clause structure", "source_refs": ["CMOS18 §6.35 p395 (scan p418)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If a participial or adverbial phrase follows a conjunction, place commas according to whether the conjunction joins independent clauses; a second comma may be added for emphasis.", "rationale": "Comma placement depends on clause structure, not the phrase alone.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["conjunctions", "participial phrases", "adverbial phrases"], "dependencies": [], "exceptions": ["Closely punctuated styles may retain extra commas."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.DATES.NO_COMMA_OTHER_STYLES", "title": "Omit commas in day-month-year and month-year formats", "source_refs": ["CMOS18 §6.41 p397 (scan p420)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Do not use commas in day-month-year dates, month-year references, or named days with years unless required by a different style system.", "rationale": "Those formats do not take commas in Chicago style.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["dates", "day-month-year"], "dependencies": [], "exceptions": ["Follow ISO date formats in data tables."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.ADDRESSES.MAILING_SPARING", "title": "Use sparse punctuation in mailing addresses", "source_refs": ["CMOS18 §6.42 p397 (scan p420)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In mailing address blocks, use commas sparingly and follow postal conventions, especially for city-state and postal codes.", "rationale": "Postal formats favor minimal punctuation for readability and sorting.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["mailing addresses", "postal"], "dependencies": [], "exceptions": ["Use full punctuation in running prose instead of block formats."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.DIALOGUE_VERB_COMMA", "title": "Use commas to introduce quoted independent clauses", "source_refs": ["CMOS18 §6.43 p398 (scan p421)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Introduce quoted independent clauses with a comma after verbs such as said, replied, asked, or wrote, regardless of quote position.", "rationale": "Dialogue verbs take commas before quotations in Chicago style.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "quotations"], "keywords": ["quotations", "dialogue verbs"], "dependencies": [], "exceptions": ["Do not add a comma when the quotation is introduced by that, whether, or if."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.NO_COMMA_CONJUNCTION", "title": "Omit commas when quotations are introduced by conjunctions", "source_refs": ["CMOS18 §6.43 p398 (scan p421)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Do not use a comma before a quotation introduced by that, whether, if, or similar conjunctions, or when a form of to be intervenes.", "rationale": "These constructions integrate the quotation into the clause.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "quotations"], "keywords": ["quotations", "conjunctions"], "dependencies": [], "exceptions": ["Preserve punctuation in quoted material as written."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.TITLES.APPOSITIVE_RULE", "title": "Treat quoted or italicized titles like nouns for comma use", "source_refs": ["CMOS18 §6.44 p399 (scan p422)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Quoted or italicized titles follow the same comma rules as other nouns; do not insert commas before titles unless they are nonrestrictive appositives.", "rationale": "Comma use depends on restrictive status, not title styling.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "titles"], "keywords": ["titles", "appositives"], "dependencies": [], "exceptions": ["If a title functions as a label, rephrase for clarity."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.QUESTIONS.DIRECT_IN_SENTENCE", "title": "Set off direct questions within sentences like quotations", "source_refs": ["CMOS18 §6.45 p399 (scan p422)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "A direct but unquoted question within a sentence may be introduced by a comma and begins with a capital letter.", "rationale": "Direct questions function like quoted dialogue.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "questions"], "keywords": ["direct questions", "commas"], "dependencies": [], "exceptions": ["If awkward, rewrite as an indirect question."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.QUESTIONS.INDIRECT", "title": "Do not use commas or question marks for indirect questions", "source_refs": ["CMOS18 §6.45 p399 (scan p422)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Indirect questions take no question mark and are not set off by commas or capitalization.", "rationale": "Indirect questions are integrated clauses.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "questions"], "keywords": ["indirect questions"], "dependencies": [], "exceptions": ["If the sentence reads oddly, rewrite."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.JR_SR.NONE", "title": "Do not use commas with Jr., Sr., or numerals in names", "source_refs": ["CMOS18 §6.46 p400 (scan p423)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In running text, do not set off Jr., Sr., II, III, and similar name elements with commas; use commas only in inverted names.", "rationale": "Chicago style treats these as part of the name.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "names"], "keywords": ["names", "jr", "sr"], "dependencies": [], "exceptions": ["If a house style insists on commas, use a second comma and avoid possessives."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.INC_LTD.NONE", "title": "Do not use commas with Inc. or Ltd. in names", "source_refs": ["CMOS18 §6.47 p401 (scan p424)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Do not set off Inc., Ltd., or similar abbreviations with commas in running text; if used, a second comma is required.", "rationale": "Company names should follow a consistent style.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "names"], "keywords": ["company names", "inc", "ltd"], "dependencies": [], "exceptions": ["Preserve legal forms when quoting official company documentation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.NOT_PHRASE", "title": "Set off not-phrases used for clarification", "source_refs": ["CMOS18 §6.48 p401 (scan p424)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use commas to set off a not-phrase that clarifies a noun.", "rationale": "The not-phrase is parenthetical and explanatory.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["not phrases", "clarification"], "dependencies": [], "exceptions": ["If the phrase is essential, rewrite to avoid ambiguity."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.CORRELATIVE.PREDICATE", "title": "Omit commas in correlative pairs that join predicates or phrases", "source_refs": ["CMOS18 §6.49 p401 (scan p424)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In not only...but also and not...but pairs, omit commas when the pair joins a compound predicate or a pair of phrases.", "rationale": "These constructions are not independent clauses.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["correlative conjunctions", "compound predicate"], "dependencies": [], "exceptions": ["If the second element is an independent clause, use a comma."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.CORRELATIVE.INDEPENDENT_CLAUSES", "title": "Use a comma when correlative pairs join independent clauses", "source_refs": ["CMOS18 §6.49 p401 (scan p424)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When correlative conjunctions join two independent clauses, use a comma before the second clause.", "rationale": "Independent clauses require separation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["correlative conjunctions", "independent clauses"], "dependencies": [], "exceptions": ["Informal prose may allow the comma splice for effect."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.PARENTHETICALS.SLIGHT_BREAK", "title": "Use commas for slight parenthetical breaks", "source_refs": ["CMOS18 §6.51 p402 (scan p425)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use commas to set off parenthetical elements when only a slight break is intended.", "rationale": "Commas signal a light interruption.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["parenthetical", "commas"], "dependencies": [], "exceptions": ["If the parenthetical contains commas or needs emphasis, use dashes or parentheses."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.THAT_IS.TRAILING_COMMA", "title": "Follow that is, namely, and similar phrases with a comma", "source_refs": ["CMOS18 §6.54 p403 (scan p426)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Expressions like that is or namely are usually followed by a comma.", "rationale": "The comma signals the explanatory follow-on.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["that is", "namely", "commas"], "dependencies": [], "exceptions": ["If the phrase introduces an independent clause, use a semicolon or dash before it."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.IE_EG.PARENS", "title": "Prefer i.e. and e.g. in parentheses or notes", "source_refs": ["CMOS18 §6.54 p403 (scan p426)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In formal writing, use i.e. and e.g. mainly in parentheses or notes and follow them with a comma.", "rationale": "Chicago treats these abbreviations as parenthetical.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["i.e.", "e.g.", "parentheses"], "dependencies": [], "exceptions": ["Technical fields may use different conventions."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.HOMONYMS.CLARITY", "title": "Use commas between homonyms when needed for clarity", "source_refs": ["CMOS18 §6.59 p406 (scan p429)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If adjacent homonyms or repeated words create confusion, insert a comma to clarify meaning.", "rationale": "A small separator can prevent misreading.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["homonyms", "clarity"], "dependencies": [], "exceptions": ["If the phrase is a known idiom, preserve its form."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.SEMICOLONS.CONJUNCTIVE_ADVERBS", "title": "Use semicolons before conjunctive adverbs joining clauses", "source_refs": ["CMOS18 §6.61 p407 (scan p429)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a conjunctive adverb joins two independent clauses, precede it with a semicolon and usually follow it with a comma.", "rationale": "This avoids comma splices and clarifies clause boundaries.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "semicolons"], "keywords": ["conjunctive adverbs", "semicolons"], "dependencies": [], "exceptions": ["The comma after the adverb may be omitted if the sentence reads cleanly."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.SEMICOLONS.THAT_IS_CLAUSE", "title": "Use semicolons before that is or for example when they introduce clauses", "source_refs": ["CMOS18 §6.62 p407 (scan p430)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When that is, for example, or similar expressions introduce an independent clause, use a semicolon before the expression.", "rationale": "The semicolon keeps the independent clauses distinct.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "semicolons"], "keywords": ["that is", "for example", "semicolons"], "dependencies": [], "exceptions": ["If the expression introduces a phrase rather than a clause, use a comma."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.SEMICOLONS.COMPLEX_SERIES", "title": "Use semicolons to separate items in complex series", "source_refs": ["CMOS18 §6.64 p408 (scan p430)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When items in a series contain internal punctuation, separate the items with semicolons to improve clarity.", "rationale": "Semicolons prevent misgrouping in complex lists.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "semicolons"], "keywords": ["semicolons", "series"], "dependencies": [], "exceptions": ["If the sentence continues beyond the series, do not add an extra semicolon after the series."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COLONS.ONE_SPACE", "title": "Use no more than one space after a colon", "source_refs": ["CMOS18 §6.66 p409 (scan p432)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In typeset text, use one space after a colon; use no space in citations, ratios, or similar technical contexts.", "rationale": "Spacing after colons depends on context.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "colons"], "keywords": ["colons", "spacing"], "dependencies": [], "exceptions": ["Follow domain-specific citation rules if they conflict."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COLONS.QUOTATIONS", "title": "Use colons to introduce dialogue, quotations, or direct questions", "source_refs": ["CMOS18 §6.69 p409 (scan p432)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use a colon to introduce dialogue or a quotation when the lead-in is a complete sentence; it can also introduce a direct question for emphasis.", "rationale": "Colons emphasize the material that follows.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "colons", "quotations"], "keywords": ["colons", "dialogue", "quotations"], "dependencies": [], "exceptions": ["Use a comma with said, asked, or similar verbs unless a block quote is intended."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.QUESTION_MARKS.DIRECT", "title": "Use question marks for direct questions", "source_refs": ["CMOS18 §6.72 p411 (scan p434)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use a question mark to end direct questions; it may also signal editorial doubt or surprise when appropriate.", "rationale": "Question marks indicate interrogative force.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "question_marks"], "keywords": ["question mark", "direct questions"], "dependencies": [], "exceptions": ["Indirect questions do not take question marks."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.QUESTION_MARKS.DIRECT_INDIRECT", "title": "Distinguish direct questions from indirect ones", "source_refs": ["CMOS18 §6.73 p411 (scan p434)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Direct questions within sentences take a question mark; indirect questions do not. Single-word questions may omit the mark, and polite requests may be punctuated as statements.", "rationale": "Punctuation follows the grammatical function of the question.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "question_marks"], "keywords": ["direct questions", "indirect questions"], "dependencies": [], "exceptions": ["If the sentence reads awkwardly, rephrase."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.QUESTION_MARKS.SURROUNDING", "title": "Place question marks inside surrounding punctuation only when needed", "source_refs": ["CMOS18 §6.74 p412 (scan p435)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Place a question mark inside quotation marks, parentheses, or brackets only when it applies to the quoted or parenthetical matter.", "rationale": "Question marks should attach to the material they modify.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "question_marks"], "keywords": ["question marks", "quotation marks", "parentheses"], "dependencies": [], "exceptions": ["If the whole sentence is a question, place the mark outside."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.EXCLAMATION.USE_SPARING", "title": "Use exclamation points sparingly", "source_refs": ["CMOS18 §6.75 p412 (scan p435)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use exclamation points sparingly to mark outcry, strong emphasis, or irony.", "rationale": "Overuse weakens the effect.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "exclamation_points"], "keywords": ["exclamation points", "emphasis"], "dependencies": [], "exceptions": ["Dialogue may intentionally use exclamation points for voice."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.EXCLAMATION.RHETORICAL", "title": "Use exclamation points for rhetorical questions only when needed", "source_refs": ["CMOS18 §6.76 p412 (scan p435)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "A rhetorical question may end with an exclamation point instead of a question mark, but a period can also be effective.", "rationale": "Rhetorical force does not always require an exclamation point.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "exclamation_points"], "keywords": ["rhetorical questions", "exclamation points"], "dependencies": [], "exceptions": ["If emphasis is strong, the exclamation point may be appropriate."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.EXCLAMATION.BRACKETED_AVOID", "title": "Avoid bracketed exclamation points as editorial protest", "source_refs": ["CMOS18 §6.77 p412 (scan p435)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Do not add bracketed exclamation points to quoted material to show editorial protest or amusement; use sic only for actual source errors.", "rationale": "Bracketed exclamation points read as contemptuous and are easily misinterpreted.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "exclamation_points"], "keywords": ["bracketed exclamation", "sic"], "dependencies": [], "exceptions": ["Scholarly editions may use bracketed markers when documented."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.PAIRS.SECOND_REQUIRED", "title": "Use paired commas to set off parenthetical elements", "source_refs": ["CMOS18 §6.17 p385 (scan p407)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a comma opens a parenthetical element, add a second comma if the sentence continues after the element.", "rationale": "Paired commas keep sentence structure clear.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["paired commas", "parenthetical"], "dependencies": [], "exceptions": ["Do not treat commas inside titles of works as paired punctuation for the surrounding sentence."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.PAIRS.TITLES_EXCEPTION", "title": "Do not pair commas inside titles with surrounding text", "source_refs": ["CMOS18 §6.17 p385 (scan p407)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Commas that belong to a title or work name are internal to the title and do not require a matching comma in the surrounding sentence.", "rationale": "Title punctuation should not force extra commas.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "titles"], "keywords": ["titles", "commas"], "dependencies": [], "exceptions": ["If the title is also a parenthetical appositive, edit for clarity."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.PARENS_BRACKETS.AFTER_CLOSING", "title": "Place commas after closing parentheses or brackets", "source_refs": ["CMOS18 §6.18 p385 (scan p407)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a sentence requires a comma after parenthetical or bracketed material, place the comma after the closing mark, not before it.", "rationale": "Closing punctuation belongs outside the enclosure.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "parentheses", "brackets"], "keywords": ["parentheses", "brackets", "comma placement"], "dependencies": [], "exceptions": ["None in standard prose."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.BRACKETS.EDITORIAL_INSERT", "title": "Allow commas inside brackets for editorial inserts", "source_refs": ["CMOS18 §6.18 p385 (scan p407)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If an editorial interpolation inside brackets includes a trailing comma, the comma may appear just before the closing bracket.", "rationale": "Editorial insertions preserve original syntax.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "brackets"], "keywords": ["editorial insert", "brackets"], "dependencies": [], "exceptions": ["Keep such cases rare and well justified."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.SERIAL.REQUIRED", "title": "Use the serial comma before the final conjunction", "source_refs": ["CMOS18 §6.19 p385 (scan p407)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In a series of three or more items, use a comma before the final conjunction.", "rationale": "Serial commas prevent ambiguity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "lists"], "keywords": ["serial comma", "Oxford comma"], "dependencies": [], "exceptions": ["House style may choose a different rule; document it."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.SERIAL.PAIR_LAST_ITEM", "title": "Keep the serial comma when the last item is a pair", "source_refs": ["CMOS18 §6.19 p385 (scan p407)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When the final item in a series is itself a paired element joined by and, keep the serial comma before the pair.", "rationale": "The serial comma clarifies series boundaries.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "lists"], "keywords": ["serial comma", "paired elements"], "dependencies": [], "exceptions": ["If the series is ambiguous, rephrase."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.SERIAL.AMBIGUITY_REWORD", "title": "Reword when a serial comma does not prevent ambiguity", "source_refs": ["CMOS18 §6.19 p385 (scan p407)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If a serial comma still leaves a list ambiguous, rephrase rather than relying on punctuation alone.", "rationale": "Clarity beats punctuation hacks.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "lists"], "keywords": ["ambiguity", "serial comma"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.SERIAL.AS_WELL_AS", "title": "Do not use 'as well as' as a series conjunction", "source_refs": ["CMOS18 §6.19 p385 (scan p407)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Do not treat 'as well as' as a substitute for and in a series; rephrase or separate the addition.", "rationale": "As well as does not behave like a normal series joiner.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "lists"], "keywords": ["as well as", "series"], "dependencies": [], "exceptions": ["Quoted material may preserve original wording."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.SERIAL.ALL_CONJUNCTIONS", "title": "Omit commas when every item is joined by conjunctions", "source_refs": ["CMOS18 §6.19 p385 (scan p407)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When each item in a series is joined by a conjunction, commas are usually unnecessary unless the items are long or complex.", "rationale": "Conjunctions already separate the items.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "lists"], "keywords": ["series", "conjunctions"], "dependencies": [], "exceptions": ["Use commas for clarity in long or nested items."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.ETC.TRAILING", "title": "Treat etc. and similar terms as final series items", "source_refs": ["CMOS18 §6.20 p387 (scan p409)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When etc., and so forth, or and the like ends a series, place a comma before it; add a comma after only if required by the surrounding syntax.", "rationale": "These terms function as final list items.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["etc.", "series"], "dependencies": [], "exceptions": ["If the term follows a single item, no preceding comma is needed."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.ETC_SINGLE_ITEM", "title": "Do not add a comma before etc. or et al. after a single item", "source_refs": ["CMOS18 §6.20 p387 (scan p409)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When etc. or et al. follows a single item, do not add a preceding comma.", "rationale": "A single item is not a series.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["etc.", "et al.", "single item"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.ETC.FORMAL_LIMIT", "title": "Limit etc. in formal prose", "source_refs": ["CMOS18 §6.20 p387 (scan p409)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In formal prose, avoid etc. in running text; reserve it for parentheticals, notes, or tables.", "rationale": "Etc. is often too informal for formal narrative.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "formal_style"], "keywords": ["etc.", "formal prose"], "dependencies": [], "exceptions": ["Quoted material may retain etc."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.AMPERSAND.NO_SERIAL", "title": "Omit the serial comma before ampersands in names", "source_refs": ["CMOS18 §6.21 p387 (scan p409)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When an ampersand replaces and in a name or brand, omit the serial comma before the ampersand.", "rationale": "Ampersands already signal a closed pairing.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["ampersand", "serial comma"], "dependencies": [], "exceptions": ["Follow the official styling of the name when known."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES", "title": "Use commas before conjunctions joining independent clauses", "source_refs": ["CMOS18 §6.22 p387 (scan p409)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When two independent clauses are joined by a coordinating conjunction, place a comma before the conjunction.", "rationale": "The comma signals a full clause boundary.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["independent clauses", "coordinating conjunction"], "dependencies": [], "exceptions": ["If the clauses are very short and tightly linked, the comma may be omitted."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.INDEPENDENT_CLAUSES.SHORT", "title": "Omit commas between very short coordinated clauses", "source_refs": ["CMOS18 §6.22 p387 (scan p409)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If coordinated independent clauses are very short and closely connected, a comma may be omitted unless the clauses are part of a larger series.", "rationale": "Short clauses can read smoothly without a comma.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["short clauses", "coordination"], "dependencies": [], "exceptions": ["Use commas when clarity or series structure requires them."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.SPLICES.AVOID_FORMAL", "title": "Avoid comma splices in formal prose", "source_refs": ["CMOS18 §6.23 p388 (scan p410)"], "category": "punctuation", "severity": "must", "applies_to": "all", "rule_text": "Do not join two independent clauses with a comma alone in formal prose; use a conjunction, semicolon, period, or other acceptable break.", "rationale": "Comma splices are considered errors in formal contexts.", "enforcement": "lint", "autofix": "suggest", "autofix_notes": "Suggest conjunction, semicolon, or sentence break.", "tags": ["commas", "formal_style"], "keywords": ["comma splice", "run-on"], "dependencies": [], "exceptions": ["Creative or conversational prose may allow occasional splices by intent."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.SPLICES.EDITORIAL_DISCRETION", "title": "Allow intentional comma splices in creative or informal prose", "source_refs": ["CMOS18 §6.23 p388 (scan p410)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In creative or conversational writing, an occasional comma splice may be retained if it improves rhythm or voice.", "rationale": "Some styles use splices for effect.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "style"], "keywords": ["comma splice", "voice"], "dependencies": [], "exceptions": ["Do not allow splices that obscure meaning."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.NO_COMMA", "title": "Do not use a comma before conjunctions in compound predicates", "source_refs": ["CMOS18 §6.24 p388 (scan p410)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a single subject shares a compound predicate, do not insert a comma before the coordinating conjunction.", "rationale": "Compound predicates do not create a clause boundary.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["compound predicate", "comma omission"], "dependencies": [], "exceptions": ["A comma may be added to prevent misreading or after a very long first element."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.COMPOUND_PREDICATE.CLARITY", "title": "Use commas in compound predicates only for clarity", "source_refs": ["CMOS18 §6.24 p388 (scan p410)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Add a comma in a compound predicate only when needed to prevent misreading or to mark a clear afterthought.", "rationale": "Extra commas can over-segment a simple predicate.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["compound predicate", "clarity"], "dependencies": [], "exceptions": ["Creative style may allow extra commas for rhythm."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.AND_THEN", "title": "Use a comma before 'then' when it stands for 'and then'", "source_refs": ["CMOS18 §6.24 p388 (scan p410)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When then functions as a shortened 'and then' between clauses, precede it with a comma.", "rationale": "The comma signals the implied conjunction.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["then", "comma"], "dependencies": [], "exceptions": ["Do not add a comma when and then is written explicitly."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.IMPERATIVE_CLAUSES", "title": "Use commas with coordinated imperative clauses only when needed", "source_refs": ["CMOS18 §6.25 p389 (scan p411)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When imperative clauses are joined by a coordinating conjunction, add a comma only if required for clarity or by other comma rules.", "rationale": "Imperatives often function like a single clause with a compound predicate.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["imperative", "coordination"], "dependencies": [], "exceptions": ["Treat three or more imperatives as a series with standard series punctuation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.DEPENDENT_INTRO", "title": "Follow introductory dependent clauses with a comma", "source_refs": ["CMOS18 §6.26 p390 (scan p412)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a dependent clause precedes the main clause, follow it with a comma.", "rationale": "The comma marks the transition to the main clause.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["dependent clause", "introductory"], "dependencies": [], "exceptions": ["Very short lead-ins in informal prose may omit the comma if clear."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING.RESTRICTIVE", "title": "Omit commas before restrictive dependent clauses", "source_refs": ["CMOS18 §6.27 p390 (scan p412)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Do not use a comma before a dependent clause that is essential to the meaning of the main clause.", "rationale": "Restrictive clauses should read as part of the main clause.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["dependent clause", "restrictive"], "dependencies": [], "exceptions": ["If meaning is ambiguous, rephrase rather than forcing punctuation."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.DEPENDENT_FOLLOWING.NONRESTRICTIVE", "title": "Use commas before nonrestrictive dependent clauses", "source_refs": ["CMOS18 §6.27 p390 (scan p412)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use a comma before a dependent clause that is supplementary or parenthetical.", "rationale": "Nonrestrictive clauses should be set off from the main clause.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["dependent clause", "nonrestrictive"], "dependencies": [], "exceptions": ["If the comma changes the meaning, rephrase for clarity."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.CONSECUTIVE_CONJUNCTIONS", "title": "Do not separate consecutive conjunctions unless needed", "source_refs": ["CMOS18 §6.28 p391 (scan p413)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When coordinating and subordinating conjunctions appear consecutively, a comma between them is usually unnecessary unless emphasis or clarity requires it.", "rationale": "Adjacent conjunctions can be read without extra punctuation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["conjunctions", "comma"], "dependencies": [], "exceptions": ["A closely punctuated style may keep the comma for emphasis."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.RELATIVE_RESTRICTIVE", "title": "Do not set off restrictive relative clauses with commas", "source_refs": ["CMOS18 §6.29 p392 (scan p414)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Restrictive relative clauses are not set off by commas; they are integral to the noun they modify.", "rationale": "Commas would wrongly signal a parenthetical clause.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["relative clause", "restrictive"], "dependencies": [], "exceptions": ["House style may allow which in restrictive clauses but still without commas."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.RELATIVE_NONRESTRICTIVE", "title": "Set off nonrestrictive relative clauses with commas", "source_refs": ["CMOS18 §6.29 p392 (scan p414)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Nonrestrictive relative clauses should be enclosed in commas.", "rationale": "Commas signal that the clause is supplemental.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["relative clause", "nonrestrictive"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.APPOSITIVES.NONRESTRICTIVE", "title": "Set off nonrestrictive appositives with commas", "source_refs": ["CMOS18 §6.30 p392 (scan p414)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use commas around an appositive that provides extra, nonessential information about a noun.", "rationale": "Appositives can be parenthetical or identifying.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["appositive", "nonrestrictive"], "dependencies": [], "exceptions": ["Do not add commas when the appositive is essential for identification."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_NAMES", "title": "Use commas with relationship names when unique", "source_refs": ["CMOS18 §6.31 p393 (scan p415)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a relationship term is followed by the only possible name (for example, a sole spouse), set the name off with commas.", "rationale": "Unique relationships behave like nonrestrictive appositives.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["relationships", "appositives"], "dependencies": [], "exceptions": ["Commas may be omitted when the number is unknown, irrelevant, or the tone is casual."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_AWKWARD_POSSESSIVE", "title": "Avoid commas that create awkward possessives", "source_refs": ["CMOS18 §6.31 p393 (scan p415)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Omit commas when they would force an awkward possessive construction; rephrase if needed.", "rationale": "Overpunctuation can make possessives unreadable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["possessive", "awkward"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.RELATIONSHIP_ALWAYS_USE", "title": "Always use commas when the name precedes the relation term", "source_refs": ["CMOS18 §6.31 p393 (scan p415)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use commas when the name comes first and the relationship term follows, or when a modifying adjective makes the relationship term unique.", "rationale": "These constructions are inherently parenthetical.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["relationships", "appositives"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.DESCRIPTIVE_PHRASES.NONRESTRICTIVE", "title": "Use commas with nonrestrictive descriptive phrases", "source_refs": ["CMOS18 §6.32 p394 (scan p416)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Descriptive phrases following a noun are set off with commas only when they are nonrestrictive.", "rationale": "Commas distinguish essential from supplemental description.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["descriptive phrases", "restrictive"], "dependencies": [], "exceptions": ["If meaning is unclear, rephrase."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_INTRO", "title": "Set off introductory participial phrases with commas", "source_refs": ["CMOS18 §6.33 p394 (scan p416)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Introductory participial phrases should be followed by a comma.", "rationale": "The comma marks a leading modifier.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["participial phrase", "introductory"], "dependencies": [], "exceptions": ["If the phrase is very short and unambiguous, some styles omit the comma."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_MID_END", "title": "Set off nonrestrictive participial phrases in mid or final position", "source_refs": ["CMOS18 §6.33 p394 (scan p416)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Participial phrases in the middle or at the end of a sentence take commas unless they are restrictive.", "rationale": "Commas signal that the modifier is supplemental.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["participial phrase", "nonrestrictive"], "dependencies": [], "exceptions": ["Restrictive participial phrases should not be set off."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.PARTICIPIAL_LINKING_VERB", "title": "Do not separate participial phrases after linking verbs", "source_refs": ["CMOS18 §6.33 p394 (scan p416)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Do not use a comma when a participial phrase is linked directly to the subject by a linking verb, even in inverted sentences.", "rationale": "The phrase completes the predicate and should not be separated.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["participial phrase", "linking verb"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_INTRO_OPTIONAL", "title": "Use commas after introductory adverbial phrases only as needed", "source_refs": ["CMOS18 §6.34 p395 (scan p417)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Introductory adverbial phrases may take a comma, but short phrases often do not unless misreading is likely.", "rationale": "Short adverbial phrases usually read smoothly without commas.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["adverbial phrase", "introductory"], "dependencies": [], "exceptions": ["Add a comma when a pause or clarity is needed."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_MID", "title": "Set off mid-sentence adverbial phrases with commas", "source_refs": ["CMOS18 §6.34 p395 (scan p417)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Adverbial phrases placed mid-sentence are normally set off by commas.", "rationale": "Mid-sentence modifiers are usually parenthetical.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["adverbial phrase", "mid-sentence"], "dependencies": [], "exceptions": ["If the phrase is restrictive, omit the commas."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_END", "title": "Use commas before nonrestrictive adverbial phrases at sentence end", "source_refs": ["CMOS18 §6.34 p395 (scan p417)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "At sentence end, use a comma only when an adverbial phrase is nonrestrictive; omit commas when the phrase is essential.", "rationale": "End modifiers often define the action and should not be separated.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["adverbial phrase", "sentence end"], "dependencies": [], "exceptions": ["If emphasis or clarity requires a pause, add the comma."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.ADVERBIAL_INVERTED", "title": "Do not set off adverbial phrases before inverted sentences", "source_refs": ["CMOS18 §6.34 p395 (scan p417)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When an adverbial phrase introduces an inverted sentence, do not separate it with a comma.", "rationale": "The phrase is integral to the inversion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["adverbial phrase", "inversion"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.CONJUNCTION_PLUS_PHRASE.PREDICATE", "title": "Place commas after conjunctions when they are part of the predicate", "source_refs": ["CMOS18 §6.35 p396 (scan p418)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If a participial or adverbial phrase follows a coordinating conjunction that is part of a compound predicate, place the comma after the conjunction.", "rationale": "The conjunction belongs with the predicate, not the preceding clause.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["compound predicate", "conjunction"], "dependencies": [], "exceptions": ["If the conjunction joins independent clauses, place the comma before it."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.CONJUNCTION_PLUS_PHRASE.INDEPENDENT", "title": "Place commas before conjunctions joining independent clauses", "source_refs": ["CMOS18 §6.35 p396 (scan p418)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If a coordinating conjunction joins two independent clauses and a participial or adverbial phrase follows it, place the comma before the conjunction.", "rationale": "The comma marks the clause boundary.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["independent clauses", "conjunction"], "dependencies": [], "exceptions": ["A second comma after the conjunction is optional for emphasis."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.INTRO_PHRASES.GENERAL", "title": "Choose commas for introductory phrases based on type and length", "source_refs": ["CMOS18 §6.36 p396 (scan p418)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use commas with introductory phrases based on their type, relation to the clause, and length; apply the specific rules for the phrase type.", "rationale": "Introductory phrases vary widely in function.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["introductory phrase", "comma choice"], "dependencies": [], "exceptions": ["Follow the rules for dependent, participial, and adverbial phrases first."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.INTRO_YES_NO", "title": "Use commas after introductory yes, no, and similar words", "source_refs": ["CMOS18 §6.37 p397 (scan p419)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use a comma after introductory yes, no, OK, well, and similar terms, except in very informal contexts.", "rationale": "The comma marks a brief introductory pause.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["yes", "no", "introductory"], "dependencies": [], "exceptions": ["Informal dialogue may omit the comma."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.INTRO_OH_AH", "title": "Use commas after exclamatory oh or ah", "source_refs": ["CMOS18 §6.38 p397 (scan p419)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use a comma after exclamatory oh or ah unless followed by a strong mark or forming part of a fixed phrase; do not comma a vocative O.", "rationale": "The comma reflects the interjection’s pause.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["oh", "ah", "interjection"], "dependencies": [], "exceptions": ["No comma when immediately followed by an exclamation point or dash."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.COORDINATE_ADJECTIVES", "title": "Use commas between coordinate adjectives", "source_refs": ["CMOS18 §6.39 p397 (scan p419)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When two or more adjectives independently modify a noun and could be joined by and, separate them with commas.", "rationale": "Coordinate adjectives share equal weight.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["adjectives", "coordinate"], "dependencies": [], "exceptions": ["Do not add commas for cumulative adjectives that form a unit."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.REPEATED_ADJECTIVES.USE_COMMA", "title": "Use commas between repeated adjectives", "source_refs": ["CMOS18 §6.40 p398 (scan p420)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When an adjective is repeated before a noun, separate the repeated forms with a comma.", "rationale": "The comma reflects the pause between repetitions.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["repeated adjectives", "comma"], "dependencies": [], "exceptions": ["In informal or poetic usage, repetition may omit the comma by style."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.DATES.MONTH_DAY_YEAR", "title": "Use commas to set off the year in month-day-year dates", "source_refs": ["CMOS18 §6.41 p398 (scan p420)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In month-day-year dates, use commas to set off the year; separate the day of week with a comma as well.", "rationale": "Commas separate the date components clearly.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["dates", "month-day-year"], "dependencies": [], "exceptions": ["Do not add a comma when only the month and year are given."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.DATES.ALTERNATE_SYSTEMS", "title": "Omit commas in day-month-year and named-day dates", "source_refs": ["CMOS18 §6.41 p398 (scan p420)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In day-month-year formats and in dates that use only a month and year or a named day, omit commas around the year.", "rationale": "Those formats do not require comma separation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["dates", "day-month-year"], "dependencies": [], "exceptions": ["Follow ISO date formatting when specified."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.ADDRESSES.RUN_IN", "title": "Use commas to separate elements in run-in addresses", "source_refs": ["CMOS18 §6.42 p398 (scan p420)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In running text, separate address elements and place-names with commas.", "rationale": "Commas clarify geographic structure.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["addresses", "place-names"], "dependencies": [], "exceptions": ["Use minimal commas in mailing addresses per postal guidelines."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.DIALOGUE", "title": "Introduce direct quotations with a comma after dialogue verbs", "source_refs": ["CMOS18 §6.43 p399 (scan p421)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When a dialogue verb introduces a direct quotation, use a comma before the quotation.", "rationale": "The comma marks the break between narrative and speech.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "quotation_marks"], "keywords": ["quotation", "dialogue verb"], "dependencies": [], "exceptions": ["Do not use a comma when the quotation is introduced by that, whether, or if."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.QUOTATIONS.THAT_WHETHER", "title": "Omit commas before quotations introduced by that or whether", "source_refs": ["CMOS18 §6.43 p399 (scan p421)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Do not use a comma before a quotation that is introduced by a conjunction such as that or whether.", "rationale": "These quotations function as integrated clauses.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "quotation_marks"], "keywords": ["quotation", "that", "whether"], "dependencies": [], "exceptions": ["Quoted material in dialogue follows the dialogue-verb rule."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.TITLES_AND_EXPRESSIONS", "title": "Treat quoted or italic titles like nouns for comma usage", "source_refs": ["CMOS18 §6.44 p400 (scan p422)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Quoted or italicized titles should take commas only when they are nonrestrictive appositives, just like ordinary nouns.", "rationale": "Titles do not automatically require commas.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "titles"], "keywords": ["titles", "appositive"], "dependencies": [], "exceptions": ["Follow the appositive rule for restrictive titles."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.DIRECT_QUESTIONS", "title": "Use commas to introduce direct questions in narrative", "source_refs": ["CMOS18 §6.45 p400 (scan p422)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "A direct question embedded in a sentence is usually introduced by a comma and begins with a capital letter.", "rationale": "Direct questions behave like quoted material.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "question_marks"], "keywords": ["direct question", "comma"], "dependencies": [], "exceptions": ["If the question begins the sentence, no leading comma is needed."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.INDIRECT_QUESTIONS", "title": "Do not punctuate indirect questions as direct questions", "source_refs": ["CMOS18 §6.45 p400 (scan p422)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Indirect questions do not take question marks, commas, or initial capitalization unless they start a sentence.", "rationale": "Indirect questions function as normal clauses.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["indirect question", "punctuation"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.JR_SR.RUNNING", "title": "Do not use commas with Jr. or Sr. in running names", "source_refs": ["CMOS18 §6.46 p401 (scan p423)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In running text, do not set off Jr. or Sr. with commas, and do not use commas before numerals like II or III.", "rationale": "These elements are part of the name.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "names"], "keywords": ["Jr.", "Sr.", "suffixes"], "dependencies": [], "exceptions": ["In inverted names, use a comma before the suffix."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.JR_SR.INVERTED", "title": "Use commas before name suffixes in inverted names", "source_refs": ["CMOS18 §6.46 p401 (scan p423)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "In inverted names (such as indexes), place a comma before suffixes like Jr., Sr., or III.", "rationale": "Inversion requires a clear separator before the suffix.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "names"], "keywords": ["inverted names", "suffix"], "dependencies": [], "exceptions": ["If house style uses commas around suffixes in running text, pair them and avoid awkward possessives."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.CORPORATE_SUFFIX", "title": "Do not use commas with Inc., Ltd., and similar suffixes", "source_refs": ["CMOS18 §6.47 p402 (scan p424)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Company suffixes like Inc. and Ltd. do not take commas in running text; if commas are used by house style, pair them.", "rationale": "Corporate suffixes are part of the name.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas", "names"], "keywords": ["Inc.", "Ltd.", "company names"], "dependencies": [], "exceptions": ["Follow official branding only if it is the document’s explicit style."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.NOT_PHRASES", "title": "Set off clarifying not-phrases with commas", "source_refs": ["CMOS18 §6.48 p402 (scan p424)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use commas to set off a clarifying phrase that begins with not.", "rationale": "The comma signals a corrective aside.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["not phrase", "clarification"], "dependencies": [], "exceptions": ["Avoid commas if the phrase is essential to the predicate."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.CORRELATIVE_PHRASES", "title": "Omit commas when correlative pairs join phrases", "source_refs": ["CMOS18 §6.49 p402 (scan p424)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "With correlative pairs like not only...but also, omit commas when the pairs join phrases or a compound predicate.", "rationale": "Phrase-level pairs do not create a clause boundary.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["correlative conjunctions", "compound predicate"], "dependencies": [], "exceptions": ["Use a comma if the pairs join independent clauses."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.CORRELATIVE_CLAUSES", "title": "Use commas when correlative pairs join independent clauses", "source_refs": ["CMOS18 §6.49 p402 (scan p424)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "When correlative pairs link independent clauses, use a comma before the second clause.", "rationale": "Independent clauses require a boundary marker.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["correlative conjunctions", "independent clauses"], "dependencies": [], "exceptions": ["Informal prose may allow a light splice; use judgment."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.THE_MORE_THE_MORE", "title": "Use commas between the more...the more clauses", "source_refs": ["CMOS18 §6.50 p403 (scan p425)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use a comma between paired clauses of the more...the more type; short phrases may omit the comma.", "rationale": "The comma separates the paired clauses.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["the more", "paired clauses"], "dependencies": [], "exceptions": ["Very short formulas may omit the comma by style."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_ELEMENTS", "title": "Use commas for light parenthetical elements", "source_refs": ["CMOS18 §6.51 p403 (scan p425)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Use commas to set off brief parenthetical elements that add explanation or comment.", "rationale": "Commas signal a slight break without overemphasis.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["parenthetical", "comma"], "dependencies": [], "exceptions": ["If the parenthetical contains commas or needs a stronger break, use em dashes or parentheses."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.PARENTHETICAL_HEAVY", "title": "Use stronger punctuation for heavy parentheticals", "source_refs": ["CMOS18 §6.51 p403 (scan p425)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "If a parenthetical element contains internal commas or needs a stronger break, use em dashes or parentheses instead of commas.", "rationale": "Commas can become confusing when stacked.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["parenthetical", "em dash", "parentheses"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.CONJUNCTIVE_ADVERBS", "title": "Set off conjunctive adverbs with commas when nonessential", "source_refs": ["CMOS18 §6.52 p403 (scan p425)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Conjunctive adverbs such as however and therefore are usually set off with commas unless they are essential to the clause.", "rationale": "Commas signal a parenthetical adverb.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["conjunctive adverbs", "however", "therefore"], "dependencies": [], "exceptions": ["If emphasis is on the adverb itself, omit the commas."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.SUCH_AS_INCLUDING", "title": "Use commas with nonrestrictive such as or including phrases", "source_refs": ["CMOS18 §6.53 p404 (scan p426)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Phrases introduced by such as or including take commas when they are nonrestrictive; omit commas when they are essential.", "rationale": "These phrases follow the same logic as other descriptive phrases.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["such as", "including", "restrictive"], "dependencies": [], "exceptions": ["None."], "status": "active"}
+{"id": "CMOS.PUNCTUATION.COMMAS.THAT_IS_NAMELY", "title": "Punctuate that is, namely, and for example with commas", "source_refs": ["CMOS18 §6.54 p404 (scan p426)"], "category": "punctuation", "severity": "should", "applies_to": "all", "rule_text": "Follow that is, namely, and for example with a comma; prefer a semicolon or em dash before these phrases when they introduce a clause.", "rationale": "These markers introduce clarification and need clear separation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "commas"], "keywords": ["that is", "namely", "for example"], "dependencies": [], "exceptions": ["Parentheses may be used instead when the phrase is fully parenthetical."], "status": "active"}
diff --git a/spec/rules/tables/v1_tables_003.ndjson b/spec/rules/tables/v1_tables_003.ndjson
new file mode 100644
index 0000000..2e88aba
--- /dev/null
+++ b/spec/rules/tables/v1_tables_003.ndjson
@@ -0,0 +1,37 @@
+{"id": "CMOS.TABLES.CAPTIONS.PRESENT", "title": "Provide a caption for each table", "source_refs": ["CMOS18 \u00a73.2 p38 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Provide a caption or title for each table so readers understand its purpose without scanning the body text.", "rationale": "Captions anchor table meaning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["table captions", "context"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.TITLES.PLACEMENT.CONSISTENT", "title": "Place table titles consistently", "source_refs": ["CMOS18 \u00a73.2 p38 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Keep table titles or captions in a consistent position (above or below) across the document.", "rationale": "Consistent placement improves scanability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["table titles", "placement"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.TITLES.NUMBERING.SEQUENTIAL", "title": "Number tables sequentially", "source_refs": ["CMOS18 \u00a73.2 p38 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Number tables sequentially within the chosen scope and avoid reusing numbers.", "rationale": "Sequential numbering supports cross-references.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables", "numbering"], "keywords": ["table numbering", "sequence"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.TITLES.SCOPE.CONSISTENT", "title": "Keep table numbering scope consistent", "source_refs": ["CMOS18 \u00a73.2 p38 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "If tables are numbered per chapter or section, keep the scheme consistent and reflect it in references.", "rationale": "Consistent scope reduces confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables", "numbering"], "keywords": ["chapter numbering", "scope"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.REFERENCES.IN_TEXT", "title": "Refer to tables from the text", "source_refs": ["CMOS18 \u00a73.6 p16 (scan p1122)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "When a table is important, refer to it explicitly from the text so readers know when to consult it.", "rationale": "Cross-references prevent orphaned tables.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables", "cross_reference"], "keywords": ["cross reference", "table mention"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.CAPTIONS.CLARITY", "title": "Write clear table captions", "source_refs": ["CMOS18 \u00a73.2 p38 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Write captions that state what the table shows, not just the topic.", "rationale": "Clear captions speed comprehension.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["captions", "clarity"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.CAPTIONS.BREVITY", "title": "Keep captions concise", "source_refs": ["CMOS18 \u00a73.2 p38 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Keep table captions concise; move extensive explanation into surrounding text.", "rationale": "Concise captions reduce visual clutter.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["captions", "brevity"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.HEADERS.REQUIRED", "title": "Use a header row when it aids interpretation", "source_refs": ["CMOS18 \u00a73.6 p16 (scan p1122)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Use a header row or column labels when they clarify what each column represents.", "rationale": "Headers make tables interpretable.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["headers", "labels"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.HEADERS.ALIGNMENT.CONSISTENT", "title": "Align headers with their columns", "source_refs": ["CMOS18 \u00a73.6 p16 (scan p1122)"], "category": "tables", "severity": "should", "applies_to": "pdf", "rule_text": "Align column headers with the data they label; avoid misalignment caused by decorative spacing.", "rationale": "Alignment reduces misreads.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["header alignment", "columns"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.HEADERS.CAPITALIZATION.CONSISTENT", "title": "Keep header capitalization consistent", "source_refs": ["CMOS18 \u00a73.6 p16 (scan p1122)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Keep capitalization style consistent across table headers within a document.", "rationale": "Consistency improves scanning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["capitalization", "headers"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.STUB_COLUMN.USE", "title": "Use a stub column for row labels", "source_refs": ["CMOS18 \u00a73.6 p16 (scan p1122)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Use a stub (row-header) column when it improves row identification.", "rationale": "Stub columns anchor row meaning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["stub column", "row labels"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.UNITS.IN_HEADERS", "title": "Put units in headers when possible", "source_refs": ["CMOS18 \u00a79.62 p108 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Place units of measure in headers or stub labels rather than repeating them in every cell.", "rationale": "Shared units reduce repetition.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables", "units"], "keywords": ["units", "headers"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.UNITS.CONSISTENT", "title": "Use consistent units within a column", "source_refs": ["CMOS18 \u00a79.62 p108 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Keep units consistent within a column unless variation is meaningful and labeled.", "rationale": "Consistency enables comparison.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables", "units"], "keywords": ["units", "consistency"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.ALIGNMENT.NUMERIC_DECIMAL", "title": "Align numeric columns consistently", "source_refs": ["CMOS18 \u00a79.62 p108 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "pdf", "rule_text": "Align numeric data consistently (right-aligned or decimal-aligned) within a column.", "rationale": "Numeric alignment improves scanability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables", "numbers"], "keywords": ["numeric alignment", "decimal"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.ALIGNMENT.TEXT_LEFT", "title": "Left-align text columns", "source_refs": ["CMOS18 \u00a79.62 p108 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "pdf", "rule_text": "Left-align text columns and avoid centering prose within cells unless it conveys meaning.", "rationale": "Text alignment improves readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["text alignment", "cells"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.ROUNDING.CONSISTENT", "title": "Keep rounding consistent", "source_refs": ["CMOS18 \u00a79.62 p108 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Apply a consistent rounding policy within a table unless precision differences are meaningful and labeled.", "rationale": "Consistent rounding prevents false precision.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables", "numbers"], "keywords": ["rounding", "precision"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.PRECISION.CONSISTENT", "title": "Use consistent numeric precision", "source_refs": ["CMOS18 \u00a79.62 p108 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Keep numeric precision consistent within a column unless variation is required.", "rationale": "Consistent precision aids comparison.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables", "numbers"], "keywords": ["precision", "numeric columns"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.MISSING_VALUES.EXPLAIN", "title": "Explain missing values", "source_refs": ["CMOS18 \u00a75.207 p207 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Explain missing or not-applicable values with a note or symbol legend.", "rationale": "Unexplained blanks cause confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["missing values", "notes"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.NOTES.ORDERED_MARKERS", "title": "Order table note markers consistently", "source_refs": ["CMOS18 \u00a75.207 p207 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Order table notes and their markers consistently (e.g., a\u2013z, *, \u2020) and keep the scheme stable.", "rationale": "Consistent markers prevent misreads.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["table notes", "markers"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.SOURCE.NOTES.DISTINCT", "title": "Separate source notes from data", "source_refs": ["CMOS18 \u00a75.207 p207 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Separate source notes and explanatory notes from the data body with spacing or a clear separator.", "rationale": "Separation prevents misinterpretation.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["table notes", "sources"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.FOOTNOTES.PLACEMENT", "title": "Place table notes immediately below the table", "source_refs": ["CMOS18 \u00a75.207 p207 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Place table notes directly below the table they describe, before any surrounding body text resumes.", "rationale": "Close proximity clarifies meaning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["table notes", "placement"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.ABBREVIATIONS.EXPLAIN", "title": "Explain abbreviations used in tables", "source_refs": ["CMOS18 \u00a75.207 p207 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Explain any abbreviations or symbols used within a table in a note or legend.", "rationale": "Unexplained abbreviations slow reading.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["abbreviations", "legend"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.ROW_SPACING.READABLE", "title": "Maintain readable row spacing", "source_refs": ["CMOS18 \u00a75.254 p84 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "pdf", "rule_text": "Maintain adequate row spacing; avoid crowding rows to fit width or height.", "rationale": "Crowded rows reduce legibility.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["row spacing", "legibility"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.COLUMN_SPACING.READABLE", "title": "Maintain readable column spacing", "source_refs": ["CMOS18 \u00a75.254 p84 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "pdf", "rule_text": "Maintain adequate spacing between columns so values do not visually merge.", "rationale": "Spacing improves scanning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["column spacing", "legibility"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.RULES.MINIMAL", "title": "Use rules sparingly", "source_refs": ["CMOS18 \u00a75.254 p84 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "pdf", "rule_text": "Use grid lines sparingly; prefer whitespace and alignment to create groupings.", "rationale": "Heavy rules add visual noise.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["rules", "gridlines"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.GRIDLINES.LIGHT", "title": "Keep gridlines light", "source_refs": ["CMOS18 \u00a75.254 p84 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "pdf", "rule_text": "When gridlines are necessary, keep them light and unobtrusive.", "rationale": "Light rules preserve readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["gridlines", "weight"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.GROUPING.WHITESPACE", "title": "Group data with whitespace", "source_refs": ["CMOS18 \u00a75.254 p84 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "pdf", "rule_text": "Use whitespace to group related rows or columns instead of extra rules when possible.", "rationale": "Whitespace communicates structure cleanly.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["grouping", "whitespace"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.SHADING.SPARING", "title": "Use shading sparingly", "source_refs": ["CMOS18 \u00a75.254 p84 (scan p1123)"], "category": "tables", "severity": "should", "applies_to": "pdf", "rule_text": "Use shading sparingly for emphasis and ensure it does not reduce readability when printed.", "rationale": "Overuse of shading reduces clarity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["shading", "emphasis"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.WIDTH.FIT_PAGE", "title": "Keep tables within page margins", "source_refs": ["CMOS18 \u00a71.42 p48 (scan p1122)"], "category": "tables", "severity": "should", "applies_to": "pdf", "rule_text": "Ensure tables fit within the page or column measure; avoid clipping or overflow.", "rationale": "Overflow tables are a layout failure.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["overflow", "margins"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.ROTATION.LANDSCAPE.WHEN_NEEDED", "title": "Rotate tables only when required", "source_refs": ["CMOS18 \u00a71.42 p48 (scan p1122)"], "category": "tables", "severity": "should", "applies_to": "pdf", "rule_text": "Use landscape or rotated tables only when necessary; prefer redesign or splitting first.", "rationale": "Rotation disrupts reading flow.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["landscape", "rotation"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.SPLITS.AVOID_ROW_BREAKS", "title": "Avoid breaking rows across pages", "source_refs": ["CMOS18 \u00a71.42 p48 (scan p1122)"], "category": "tables", "severity": "should", "applies_to": "pdf", "rule_text": "Avoid splitting a single row across pages whenever possible.", "rationale": "Row breaks make tables hard to read.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["page breaks", "rows"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.SPLITS.REPEAT_HEADERS", "title": "Repeat headers on continued tables", "source_refs": ["CMOS18 \u00a71.42 p48 (scan p1122)"], "category": "tables", "severity": "should", "applies_to": "pdf", "rule_text": "When a table continues on a new page, repeat the header row to preserve context.", "rationale": "Repeated headers prevent reader confusion.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["continued tables", "headers"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.COLUMN_ORDER.LOGICAL", "title": "Order columns logically", "source_refs": ["CMOS18 \u00a71.82 p82 (scan p1122)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Order columns logically (by time, magnitude, or grouping) and document the scheme if not obvious.", "rationale": "Logical order helps scanning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["column order", "logic"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.ROW_ORDER.LOGICAL", "title": "Order rows logically", "source_refs": ["CMOS18 \u00a71.82 p82 (scan p1122)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Order rows logically (alphabetical, chronological, or by magnitude) and keep the scheme consistent.", "rationale": "Consistent order aids lookup.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["row order", "logic"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.SORTING.LOGICAL", "title": "Avoid mixed sorting schemes", "source_refs": ["CMOS18 \u00a71.82 p82 (scan p1122)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Avoid mixing different sorting schemes within the same table unless clearly labeled.", "rationale": "Mixed ordering confuses readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["sorting", "consistency"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.DATA_TYPES.NOT_MIXED", "title": "Avoid mixing data types in a column", "source_refs": ["CMOS18 \u00a71.82 p82 (scan p1122)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Avoid mixing text and numeric values within a single column unless clearly indicated.", "rationale": "Mixed types are harder to scan.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["data types", "columns"], "dependencies": [], "exceptions": [], "status": "active"}
+{"id": "CMOS.TABLES.SUBTOTALS.CLEAR", "title": "Label subtotals and totals clearly", "source_refs": ["CMOS18 \u00a71.82 p82 (scan p1122)"], "category": "tables", "severity": "should", "applies_to": "all", "rule_text": "Label subtotals and totals clearly and separate them visually from regular rows.", "rationale": "Clear totals prevent misreading.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "tables"], "keywords": ["totals", "subtotals"], "dependencies": [], "exceptions": [], "status": "active"}
diff --git a/spec/rules/tables/v1_tables_004.ndjson b/spec/rules/tables/v1_tables_004.ndjson
new file mode 100644
index 0000000..52f26bb
--- /dev/null
+++ b/spec/rules/tables/v1_tables_004.ndjson
@@ -0,0 +1,6 @@
+{"id":"HOUSE.TABLES.UNITS.IN_HEADERS","title":"Include units in column headers","source_refs":["HOUSE §TABLES.UNITS p1"],"category":"tables","severity":"should","applies_to":"all","rule_text":"Include units in column headers (e.g., ms, %, USD) so numeric values are interpretable.","rationale":"Unit labels reduce ambiguity.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","tables"],"keywords":["units","headers"],"dependencies":[],"exceptions":["If a unit applies to an entire table, a single note may suffice."],"status":"active"}
+{"id":"HOUSE.TABLES.NUMERIC.ALIGN_DECIMALS","title":"Align numeric columns by decimal","source_refs":["HOUSE §TABLES.ALIGNMENT p1"],"category":"tables","severity":"should","applies_to":"pdf","rule_text":"Align numeric columns on the decimal point or right-align integers to improve scanning.","rationale":"Aligned numbers are easier to compare.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","tables"],"keywords":["numeric alignment","decimals"],"dependencies":[],"exceptions":["If alignment is controlled by the renderer, document the limitation."],"status":"active"}
+{"id":"HOUSE.TABLES.MISSING_DATA.CONSISTENT_MARK","title":"Use a consistent marker for missing data","source_refs":["HOUSE §TABLES.MISSING_DATA p1"],"category":"tables","severity":"should","applies_to":"all","rule_text":"Use a consistent marker for missing data (e.g., em dash, N/A) and explain the marker when ambiguity is possible.","rationale":"Consistent markers avoid misreads.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","tables"],"keywords":["missing data","markers"],"dependencies":[],"exceptions":["If a standard for the domain exists, follow it."],"status":"active"}
+{"id":"HOUSE.TABLES.SOURCE.NOTES","title":"Provide source notes for data tables","source_refs":["HOUSE §TABLES.SOURCES p1"],"category":"tables","severity":"should","applies_to":"all","rule_text":"When tables summarize external data, include a source note or citation adjacent to the table.","rationale":"Sources support verification.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","tables","citations"],"keywords":["table sources","notes"],"dependencies":[],"exceptions":["If the data source is defined in a methods section, a short reference may be sufficient."],"status":"active"}
+{"id":"HOUSE.TABLES.NUMERIC.PRECISION.CONSISTENT","title":"Keep numeric precision consistent within columns","source_refs":["HOUSE §TABLES.ALIGNMENT p1"],"category":"tables","severity":"should","applies_to":"all","rule_text":"Use consistent numeric precision within each column unless differences are meaningful and explained.","rationale":"Inconsistent precision distracts and can imply false accuracy.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","tables"],"keywords":["precision","decimals"],"dependencies":[],"exceptions":["If values are inherently mixed precision, include a note or rounding policy."],"status":"active"}
+{"id":"HOUSE.TABLES.COLUMN_WIDTHS.BALANCED","title":"Balance column widths to avoid cramped cells","source_refs":["HOUSE §TABLES.ALIGNMENT p1"],"category":"tables","severity":"should","applies_to":"all","rule_text":"Balance column widths so text does not become excessively cramped or overly sparse.","rationale":"Balanced widths improve readability.","enforcement":"manual","autofix":"none","autofix_notes":"","tags":["manual_checklist=true","tables"],"keywords":["column widths","layout"],"dependencies":[],"exceptions":["If a narrow column is intentional, explain it with a note or header."],"status":"active"}
diff --git a/spec/rules/typography/v1_typography_003.ndjson b/spec/rules/typography/v1_typography_003.ndjson
new file mode 100644
index 0000000..9338546
--- /dev/null
+++ b/spec/rules/typography/v1_typography_003.ndjson
@@ -0,0 +1,90 @@
+{"id": "BRING.TYPOGRAPHY.TYPEFACE.PURPOSE_MATCH_CONTENT", "title": "Match typeface to document purpose", "source_refs": ["BRING \u00a71.2.4 p22 (scan p21)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Select typefaces whose tone and historical feel suit the document's subject and audience.", "rationale": "A mismatch between type and content reduces credibility.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "typeface", "selection"], "keywords": ["typeface", "tone", "audience", "purpose"], "dependencies": [], "exceptions": ["Brand requirements may limit choices; document the tradeoff."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.TYPEFACE.TEXT_FACES_FOR_BODY", "title": "Use text faces for body copy", "source_refs": ["BRING \u00a76.1.1 p93 (scan p92)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Set long-form body text in a face designed for continuous reading rather than a display face.", "rationale": "Text faces are optimized for legibility at small sizes.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "typeface", "body_text"], "keywords": ["text face", "body", "legibility"], "dependencies": [], "exceptions": ["Short callouts or posters may use display faces by design."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.TYPEFACE.DISPLAY_FACES_FOR_DISPLAY", "title": "Reserve display faces for display use", "source_refs": ["BRING \u00a76.1.1 p93 (scan p92)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use display faces for headings or short labels only; do not set body paragraphs in display cuts.", "rationale": "Display faces can fatigue readers in long passages.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "typeface", "display"], "keywords": ["display face", "heading", "body"], "dependencies": [], "exceptions": ["Very short documents may accept a single display face."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.TYPEFACE.LIMIT_NUMBER", "title": "Limit the number of distinct typefaces", "source_refs": ["BRING \u00a71.2.4 p22 (scan p21)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Limit the document to a small, intentional set of typefaces.", "rationale": "Too many faces dilute hierarchy and coherence.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "typeface", "consistency"], "keywords": ["typefaces", "consistency", "hierarchy"], "dependencies": [], "exceptions": ["Brand systems may prescribe more faces; keep usage scoped by role."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.TYPEFACE.SIMILAR_FACES_AVOID", "title": "Avoid pairing nearly identical faces", "source_refs": ["BRING \u00a71.2.4 p22 (scan p21)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid pairing two faces that are too similar to distinguish; either match closely or contrast clearly.", "rationale": "Near-duplicate faces create tension without structure.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "typeface", "pairing"], "keywords": ["pairing", "contrast", "typefaces"], "dependencies": [], "exceptions": ["Subtle pairings may work in expert typographic systems; document rationale."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.TYPEFACE.CONTRAST_INTENTIONAL", "title": "Make contrasts intentional when mixing faces", "source_refs": ["BRING \u00a71.2.4 p22 (scan p21)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "When mixing faces, ensure each has a clear role and visible contrast in structure or weight.", "rationale": "Intentional contrast signals hierarchy and improves scanning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "typeface", "contrast"], "keywords": ["contrast", "structure", "roles"], "dependencies": [], "exceptions": ["Subtle contrast may be acceptable in minimalist designs."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.TYPEFACE.FALLBACKS_COMPATIBLE_METRICS", "title": "Choose compatible fallback fonts", "source_refs": ["BRING \u00a76.1.1 p93 (scan p92)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Choose fallback fonts with compatible metrics and x-height to minimize reflow.", "rationale": "Mismatched fallbacks cause layout shifts and uneven color.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["typeface", "fallbacks", "typeset"], "keywords": ["fallback", "x-height", "metrics"], "dependencies": [], "exceptions": ["If fallbacks are constrained by platform, document the limitation."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.TYPEFACE.GLYPH_COVERAGE_REQUIRED", "title": "Confirm glyph coverage", "source_refs": ["BRING \u00a76.1.1 p93 (scan p92)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Confirm the chosen face covers required glyphs such as diacritics, symbols, and currencies.", "rationale": "Missing glyphs lead to substitutions and errors.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "typeface", "glyphs"], "keywords": ["glyph coverage", "diacritics", "symbols"], "dependencies": [], "exceptions": ["If a rare glyph is missing, provide a documented fallback."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.TYPEFACE.OPTICAL_SIZES_USE", "title": "Use optical sizes when available", "source_refs": ["BRING \u00a76.1.1 p93 (scan p92)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use optical sizes or text cuts when provided, matching the intended point size.", "rationale": "Optical sizes improve legibility and overall text color.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["typeface", "optical_sizes", "typeset"], "keywords": ["optical size", "text cut", "legibility"], "dependencies": [], "exceptions": ["If optical sizes are unavailable, use the standard cut."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.TYPEFACE.MIXING_BY_ROLE_ONLY", "title": "Mix faces only by role", "source_refs": ["BRING \u00a71.2.4 p22 (scan p21)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Mix typefaces only for distinct structural roles (e.g., display vs body), not within a single role.", "rationale": "Role-based mixing preserves coherence.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "typeface", "roles"], "keywords": ["roles", "display", "body"], "dependencies": [], "exceptions": ["Charts and UI components may require dedicated faces."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.TYPEFACE.FAMILY_WITH_VARIANTS", "title": "Prefer families with coherent variants", "source_refs": ["BRING \u00a76.1.1 p93 (scan p92)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Prefer a family that includes roman, italic, and bold variants instead of mixing unrelated faces.", "rationale": "A coherent family simplifies hierarchy and maintenance.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "typeface", "family"], "keywords": ["family", "roman", "italic", "bold"], "dependencies": [], "exceptions": ["Brand systems may prescribe separate display and text families."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.TYPEFACE.LEGIBILITY_AT_SIZE", "title": "Verify legibility at target size", "source_refs": ["BRING \u00a76.1.1 p93 (scan p92)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Verify the face remains legible at the intended size and line length; avoid overly delicate designs.", "rationale": "Legibility drives reading comfort and trust.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "typeface", "legibility"], "keywords": ["legibility", "size", "line length"], "dependencies": [], "exceptions": ["Display-only materials may accept lower legibility for effect."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.FAMILY.SINGLE_FAMILY_BODY", "title": "Keep body text within one family", "source_refs": ["BRING \u00a76.5.1 p102 (scan p101)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use a single family for body text and its immediate variants (roman, italic, bold, small caps).", "rationale": "A single family keeps color and rhythm consistent.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "family", "consistency"], "keywords": ["family", "roman", "italic", "bold"], "dependencies": [], "exceptions": ["Display headings may use a separate family."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.FAMILY.TRUE_ITALICS", "title": "Use true italics from the family", "source_refs": ["BRING \u00a76.5.2 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use the designed italic of the family rather than slanting the roman.", "rationale": "True italics have different letterforms and spacing optimized for readability.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["family", "italics", "typeset"], "keywords": ["true italics", "oblique", "slant"], "dependencies": [], "exceptions": ["If no italic exists, document the fallback behavior."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.FAMILY.TRUE_SMALL_CAPS", "title": "Use designed small caps", "source_refs": ["BRING \u00a76.5.2 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use designed small caps from the family; do not scale down full capitals.", "rationale": "Scaled capitals have incorrect weight and spacing.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["family", "small_caps", "typeset"], "keywords": ["small caps", "scaled caps"], "dependencies": [], "exceptions": ["If true small caps are unavailable, avoid small caps entirely."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.FAMILY.AVOID_FAUX_BOLD", "title": "Avoid synthetic bold", "source_refs": ["BRING \u00a76.5.3 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid synthetic emboldening; use the family's bold weight.", "rationale": "Synthetic bold distorts letterforms and spacing.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["family", "bold", "typeset"], "keywords": ["bold", "synthetic", "embolden"], "dependencies": [], "exceptions": ["If no bold exists, prefer a different family or other emphasis."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.FAMILY.METRICS_MATCH_WHEN_MIXING", "title": "Match metrics when mixing families", "source_refs": ["BRING \u00a76.5.1 p102 (scan p101)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "When mixing families, match x-height and overall color so body text stays even.", "rationale": "Mismatched metrics make text blocks look uneven.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "family", "metrics"], "keywords": ["x-height", "metrics", "color"], "dependencies": [], "exceptions": ["Display contrasts may intentionally break this rule."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.FAMILY.LIMIT_STYLE_VARIANTS", "title": "Limit the number of style variants", "source_refs": ["BRING \u00a76.5.1 p102 (scan p101)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Limit the number of weights and widths in use to keep the hierarchy clear.", "rationale": "Too many variants weaken hierarchy and consistency.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "family", "weights"], "keywords": ["weights", "widths", "hierarchy"], "dependencies": [], "exceptions": ["Large design systems may allow more variants with strict roles."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.FAMILY.USE_DESIGNED_WEIGHTS", "title": "Use designed weights, not synthetic extremes", "source_refs": ["BRING \u00a76.5.3 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Select from the family's designed weights rather than stretching a variable font to extremes.", "rationale": "Extreme synthetic weights can reduce readability and consistency.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["family", "weights", "typeset"], "keywords": ["variable font", "weights", "extremes"], "dependencies": [], "exceptions": ["Display settings may accept larger deviations with review."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.FAMILY.SMALL_CAPS_SPARE", "title": "Use small caps sparingly", "source_refs": ["BRING \u00a76.5.2 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use small caps for short labels or abbreviations, not long passages.", "rationale": "Long small-cap passages reduce readability and color consistency.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "small_caps", "usage"], "keywords": ["small caps", "labels", "abbreviations"], "dependencies": [], "exceptions": ["Formal front matter may permit short small-cap lines."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.FAMILY.ITALIC_FOR_SUBTLE_EMPHASIS", "title": "Prefer italics for subtle emphasis", "source_refs": ["BRING \u00a76.5.2 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "For subtle emphasis in body text, prefer italics over bold.", "rationale": "Italics preserve text color while signaling emphasis.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics", "emphasis"], "keywords": ["italics", "emphasis", "body text"], "dependencies": [], "exceptions": ["Accessibility requirements may prefer bold; follow profile."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.FAMILY.BOLD_FOR_STRONG_EMPHASIS", "title": "Use bold only for strong emphasis", "source_refs": ["BRING \u00a76.5.3 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Reserve bold for strong emphasis or interface-like labels; keep it brief.", "rationale": "Excess bold disrupts rhythm and hierarchy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "bold", "emphasis"], "keywords": ["bold", "emphasis", "labels"], "dependencies": [], "exceptions": ["Callout blocks may use bold for scanning."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.FAMILY.WEIGHT_CONTRAST_CLEAR", "title": "Ensure bold weight contrast is clear", "source_refs": ["BRING \u00a76.5.3 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Bold text should be clearly darker than roman; avoid barely heavier weights.", "rationale": "Clear contrast is necessary for hierarchy.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["bold", "weights", "typeset"], "keywords": ["bold contrast", "weight", "hierarchy"], "dependencies": [], "exceptions": ["Some minimalist designs use subtle contrast; document the choice."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.FAMILY.ITALIC_PUNCTUATION_MATCH", "title": "Match punctuation styling in italic runs", "source_refs": ["BRING \u00a76.5.2 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Keep punctuation within italicized phrases styled consistently with the surrounding italics.", "rationale": "Mixed styles inside a word or title look broken.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics", "punctuation"], "keywords": ["italics", "punctuation", "consistency"], "dependencies": [], "exceptions": ["House style may require roman punctuation in specific cases."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.ITALICS.SPARING", "title": "Use italics sparingly", "source_refs": ["BRING \u00a77.2.1 p122 (scan p121)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use italics sparingly; they should not become a second body style.", "rationale": "Frequent italics reduce clarity and emphasis.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics", "emphasis"], "keywords": ["italics", "emphasis", "readability"], "dependencies": [], "exceptions": ["Scholarly editions may require more italic usage; document the reason."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.ITALICS.LONG_SPANS_AVOID", "title": "Avoid long spans of italics", "source_refs": ["BRING \u00a77.2.1 p122 (scan p121)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid long paragraphs set in italics; prefer structural changes or other emphasis.", "rationale": "Long italic passages are hard to read.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics", "readability"], "keywords": ["italics", "paragraphs", "readability"], "dependencies": [], "exceptions": ["Quoted material may require italics; keep it short and distinct."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.ITALICS.TITLES_STANDALONE_WORKS", "title": "Italicize titles of standalone works", "source_refs": ["BRING \u00a77.2.2 p124 (scan p123)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "When a title style is required, use italics for standalone works and apply it consistently.", "rationale": "Consistent title styling aids recognition.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics", "titles"], "keywords": ["titles", "books", "journals"], "dependencies": [], "exceptions": ["Some house styles use quotation marks instead; follow profile."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.ITALICS.TERMS_INTRODUCED_SPARE", "title": "Italicize introduced terms only when needed", "source_refs": ["BRING \u00a77.2.1 p122 (scan p121)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Italicize introduced or defined terms only when necessary; remove emphasis once the term is established.", "rationale": "Over-italicizing definitions adds noise.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics", "definitions"], "keywords": ["definitions", "terms", "emphasis"], "dependencies": [], "exceptions": ["Glossaries may use consistent emphasis for headwords."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.ITALICS.CONSISTENT_TITLE_TREATMENT", "title": "Keep title treatment consistent", "source_refs": ["BRING \u00a77.2.2 p124 (scan p123)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Do not mix italics and quotation marks for the same class of titles within a document.", "rationale": "Inconsistent title treatment confuses readers.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics", "consistency"], "keywords": ["titles", "consistency", "quotation marks"], "dependencies": [], "exceptions": ["Quoted material may preserve original styling."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.ITALICS.AVOID_IN_ALL_CAPS_HEADINGS", "title": "Avoid italics in all-caps headings", "source_refs": ["BRING \u00a77.2.7 p130 (scan p129)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid setting all-caps headings in italics because legibility suffers.", "rationale": "All-caps italics are difficult to parse quickly.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics", "headings"], "keywords": ["all caps", "italics", "headings"], "dependencies": [], "exceptions": ["Short stylized headings may be acceptable with review."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.ITALICS.PUNCTUATION_FOLLOWS_STYLE", "title": "Keep punctuation in the same italic style", "source_refs": ["BRING \u00a77.2.1 p122 (scan p121)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Punctuation that belongs to an italicized word or title should follow the same style.", "rationale": "Mixed punctuation styles look broken.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics", "punctuation"], "keywords": ["punctuation", "italics", "consistency"], "dependencies": [], "exceptions": ["House styles may require roman punctuation in specific contexts."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.ITALICS.EMPHASIS_NOT_UNDERLINE", "title": "Prefer italics over underlining", "source_refs": ["BRING \u00a77.2.1 p122 (scan p121)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use italics rather than underlining for emphasis in running text.", "rationale": "Underlines interfere with descenders and readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics", "emphasis"], "keywords": ["underlining", "emphasis", "readability"], "dependencies": [], "exceptions": ["Links may be underlined in web contexts for accessibility."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.ITALICS.AVOID_STACKED_EMPHASIS", "title": "Avoid stacked emphasis styles", "source_refs": ["BRING \u00a77.2.1 p122 (scan p121)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid stacking italics with bold or caps for extended emphasis; choose one emphasis method.", "rationale": "Stacked emphasis reduces legibility and looks heavy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics", "emphasis"], "keywords": ["italics", "bold", "caps"], "dependencies": [], "exceptions": ["Short warnings may combine styles sparingly."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.ITALICS.HEADINGS_AVOID", "title": "Avoid italicizing headings by default", "source_refs": ["BRING \u00a77.2.7 p130 (scan p129)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid italicizing headings by default; use size and weight for hierarchy.", "rationale": "Italic headings are harder to scan quickly.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics", "headings"], "keywords": ["headings", "hierarchy", "italics"], "dependencies": [], "exceptions": ["Short display headings may be italicized intentionally."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.ITALICS.RUNNING_HEADS_AVOID", "title": "Keep running heads in roman", "source_refs": ["BRING \u00a77.2.7 p130 (scan p129)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Keep running heads and page headers in roman for clarity; avoid italics.", "rationale": "Roman headers scan faster at small sizes.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics", "running_heads"], "keywords": ["running heads", "headers", "roman"], "dependencies": [], "exceptions": ["Design-driven headers may use italics with review."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.ITALICS.AVOID_NUMERAL_ITALICS", "title": "Avoid italicizing numerals", "source_refs": ["BRING \u00a77.2.1 p122 (scan p121)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Do not italicize numerals or measurements unless they are part of an italicized title.", "rationale": "Italic numerals can reduce clarity in data.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "italics", "numerals"], "keywords": ["numerals", "italics", "measurements"], "dependencies": [], "exceptions": ["Mathematical notation may follow different conventions."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_AVOID_LONG_RUNS", "title": "Avoid long all-caps runs", "source_refs": ["BRING \u00a73.2.1 p46 (scan p45)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid long runs of all-caps text in body copy.", "rationale": "All caps reduce word shape recognition.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "caps", "readability"], "keywords": ["all caps", "readability", "body"], "dependencies": [], "exceptions": ["Short headings and labels may use all caps."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.CAPS.ALL_CAPS_SHORT_LABELS_ONLY", "title": "Reserve all caps for short labels", "source_refs": ["BRING \u00a73.2.1 p46 (scan p45)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Reserve all caps for short labels or acronyms rather than sentences.", "rationale": "Short caps can work; long caps reduce scanning speed.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "caps", "labels"], "keywords": ["labels", "acronyms", "all caps"], "dependencies": [], "exceptions": ["Short, formal titles may use all caps by design."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_FOR_ACRONYMS", "title": "Use small caps for acronyms when available", "source_refs": ["BRING \u00a73.2.1 p46 (scan p45)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "If available, use small caps for acronyms to reduce visual shouting.", "rationale": "Small caps integrate better with mixed-case text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "caps", "small_caps"], "keywords": ["acronyms", "small caps", "all caps"], "dependencies": [], "exceptions": ["Some acronyms are standard in full caps; follow house style."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.CAPS.SMALL_CAPS_NOT_FOR_LONG_PASSAGES", "title": "Avoid long passages in small caps", "source_refs": ["BRING \u00a73.2.1 p46 (scan p45)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Do not set long passages in small caps; readability drops quickly.", "rationale": "Small caps reduce word shape cues in continuous text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "small_caps", "readability"], "keywords": ["small caps", "long passages", "readability"], "dependencies": [], "exceptions": ["Short front matter lines may use small caps."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.CAPS.MIXED_CAPS_CONSISTENT", "title": "Keep capitalization style consistent", "source_refs": ["BRING \u00a73.2.1 p46 (scan p45)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Keep capitalization style consistent within headings and labels; avoid mixing styles on the same level.", "rationale": "Consistent caps support hierarchy and scanning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "caps", "consistency"], "keywords": ["capitalization", "headings", "consistency"], "dependencies": [], "exceptions": ["Quoted titles may preserve original capitalization."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.CAPS.AVOID_FOR_EMPHASIS", "title": "Avoid all caps for emphasis", "source_refs": ["BRING \u00a73.2.1 p46 (scan p45)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid using all caps as a default emphasis mechanism; use italics or bold instead.", "rationale": "All caps read as shouting and slow scanning.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "caps", "emphasis"], "keywords": ["emphasis", "all caps", "readability"], "dependencies": [], "exceptions": ["Short warnings may use caps with review."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.CAPS.TRACKING_REVIEW", "title": "Review spacing in caps", "source_refs": ["BRING \u00a72.1.6 p30 (scan p29)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Review spacing in all-caps and small-caps text and add tracking if it looks tight.", "rationale": "Caps often need extra spacing to read well.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["caps", "tracking", "typeset"], "keywords": ["tracking", "caps", "spacing"], "dependencies": [], "exceptions": ["Very short labels may not need extra tracking."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.CAPS.ROMAN_NUMERALS_SPACING", "title": "Space Roman numerals for clarity", "source_refs": ["BRING \u00a73.2.1 p46 (scan p45)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "When Roman numerals appear in caps, ensure spacing and weight keep them distinct and readable.", "rationale": "Dense Roman numerals can become ambiguous.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "caps", "roman_numerals"], "keywords": ["Roman numerals", "spacing", "caps"], "dependencies": [], "exceptions": ["Short regnal numbers may be acceptable without adjustments."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.LIGATURES.STANDARD_ON_BODY", "title": "Enable standard ligatures in body text", "source_refs": ["BRING \u00a73.3 p50 (scan p49)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Enable standard ligatures in body text when the face provides them.", "rationale": "Standard ligatures prevent collisions and improve texture.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["ligatures", "typeset"], "keywords": ["ligatures", "fi", "fl"], "dependencies": [], "exceptions": ["Monospaced or code faces may disable ligatures."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_SPARING", "title": "Use discretionary ligatures sparingly", "source_refs": ["BRING \u00a73.3.1 p50 (scan p49)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use discretionary ligatures sparingly and primarily in display text.", "rationale": "Overuse of discretionary ligatures draws attention away from content.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ligatures", "display"], "keywords": ["discretionary ligatures", "display"], "dependencies": [], "exceptions": ["Logotypes may use discretionary ligatures as a design feature."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ALL_CAPS", "title": "Avoid ligatures in all caps", "source_refs": ["BRING \u00a73.3.2 p52 (scan p51)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid ligatures in all-caps or small-caps settings if they distort letter recognition.", "rationale": "Ligatures in caps can reduce clarity.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ligatures", "caps"], "keywords": ["ligatures", "all caps", "small caps"], "dependencies": [], "exceptions": ["Short logotypes may permit ligatures with review."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_CODE_URLS", "title": "Disable ligatures in code and URLs", "source_refs": ["BRING \u00a73.3 p50 (scan p49)"], "category": "typography", "severity": "should", "applies_to": "md", "rule_text": "Disable ligatures in code, URLs, and file paths to preserve literal strings.", "rationale": "Ligatures can change the perceived characters in technical strings.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["ligatures", "code", "typeset"], "keywords": ["code", "URLs", "file paths"], "dependencies": [], "exceptions": ["Display-only snippets may ignore this rule if clearly labeled."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.LIGATURES.AVOID_IN_ACRONYMS", "title": "Avoid ligatures in acronyms", "source_refs": ["BRING \u00a73.3.2 p52 (scan p51)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid ligatures in acronyms or initialisms.", "rationale": "Ligatures can obscure letter boundaries in abbreviations.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ligatures", "acronyms"], "keywords": ["acronyms", "initialisms", "ligatures"], "dependencies": [], "exceptions": ["Brand acronyms may use custom ligatures by design."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.LIGATURES.FI_FL_COLLISIONS", "title": "Use standard fi/fl ligatures to prevent collisions", "source_refs": ["BRING \u00a73.3 p50 (scan p49)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use standard fi/fl ligatures when available to prevent collisions in text sizes.", "rationale": "Common f combinations often collide without ligatures.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["ligatures", "typeset"], "keywords": ["fi", "fl", "collisions"], "dependencies": [], "exceptions": ["If a face has poor ligatures, disable and review spacing."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.LIGATURES.DISCRETIONARY_IN_DISPLAY", "title": "Allow discretionary ligatures in display text", "source_refs": ["BRING \u00a73.3.1 p50 (scan p49)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Allow discretionary ligatures in display type only when they improve rhythm and do not confuse word shape.", "rationale": "Display settings can benefit from selective ligatures.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ligatures", "display"], "keywords": ["display", "discretionary", "ligatures"], "dependencies": [], "exceptions": ["Avoid in captions and footnotes."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.LIGATURES.DO_NOT_USE_IF_AMBIGUOUS", "title": "Avoid ambiguous ligatures", "source_refs": ["BRING \u00a73.3.2 p52 (scan p51)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Do not use ligatures that obscure letter identity at small sizes.", "rationale": "Ambiguous ligatures hurt readability and accuracy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ligatures", "readability"], "keywords": ["ligatures", "readability", "small sizes"], "dependencies": [], "exceptions": ["Large display settings may tolerate more decorative ligatures."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.LIGATURES.KEEP_CONSISTENT", "title": "Keep ligature usage consistent", "source_refs": ["BRING \u00a73.3 p50 (scan p49)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Keep ligature usage consistent across similar text blocks such as body and captions.", "rationale": "Inconsistent ligatures look uneven and accidental.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ligatures", "consistency"], "keywords": ["ligatures", "consistency", "captions"], "dependencies": [], "exceptions": ["Different typefaces may require different ligature behavior."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.LIGATURES.REVIEW_FOR_LANGUAGE", "title": "Review ligatures for language suitability", "source_refs": ["BRING \u00a73.3.2 p52 (scan p51)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Review ligature behavior in languages where letter combinations differ; disable if it harms readability.", "rationale": "Language-specific letterforms can be distorted by ligatures.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "ligatures", "i18n"], "keywords": ["ligatures", "language", "i18n"], "dependencies": [], "exceptions": ["Purely decorative headings may be exempt with review."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.NUMERALS.OLDSTYLE_FOR_TEXT", "title": "Use oldstyle figures in running text", "source_refs": ["BRING \u00a74.4.4 p72 (scan p71)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use oldstyle figures in running text when available; they blend with lowercase forms.", "rationale": "Oldstyle figures reduce visual disruption in prose.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["numerals", "oldstyle", "typeset"], "keywords": ["oldstyle figures", "prose", "numerals"], "dependencies": [], "exceptions": ["Technical documents may require lining figures throughout."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.NUMERALS.LINING_FOR_CAPS_AND_DISPLAY", "title": "Use lining figures with caps and display", "source_refs": ["BRING \u00a74.4.4 p72 (scan p71)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use lining figures in all-caps settings and large display headings.", "rationale": "Lining figures align with capital height and feel balanced.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["numerals", "lining", "typeset"], "keywords": ["lining figures", "caps", "display"], "dependencies": [], "exceptions": ["Oldstyle figures may be acceptable in display typography if intentional."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.NUMERALS.TABULAR_FOR_TABLES", "title": "Use tabular figures in tables", "source_refs": ["BRING \u00a74.4.3 p111 (scan p110)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use tabular figures for columns of numbers to align widths.", "rationale": "Tabular figures improve column alignment.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["numerals", "tabular", "typeset"], "keywords": ["tabular figures", "tables", "alignment"], "dependencies": [], "exceptions": ["Narrow tables may require proportional figures with manual alignment."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.NUMERALS.PROPORTIONAL_FOR_PROSE", "title": "Use proportional figures in prose", "source_refs": ["BRING \u00a74.4.4 p72 (scan p71)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use proportional figures in prose and narrative text.", "rationale": "Proportional figures create a smoother text color in running copy.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["numerals", "proportional", "typeset"], "keywords": ["proportional figures", "prose"], "dependencies": [], "exceptions": ["Data-heavy prose may prefer tabular figures."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.NUMERALS.CONSISTENT_STYLE_WITHIN_SECTION", "title": "Keep numeral style consistent within a section", "source_refs": ["BRING \u00a74.4.4 p72 (scan p71)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Keep numeral style (oldstyle/lining, proportional/tabular) consistent within a section.", "rationale": "Mixed figure styles look accidental and distract.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "numerals", "consistency"], "keywords": ["numeral style", "consistency"], "dependencies": [], "exceptions": ["Tables may use tabular figures while body uses proportional figures."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.NUMERALS.MIXED_STYLE_AVOID", "title": "Avoid mixed figure styles in a paragraph", "source_refs": ["BRING \u00a74.4.4 p72 (scan p71)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid mixing oldstyle and lining figures within the same paragraph.", "rationale": "Mixed figure styles disrupt line texture.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "numerals", "consistency"], "keywords": ["oldstyle", "lining", "paragraph"], "dependencies": [], "exceptions": ["Quoted material may preserve original styling."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.NUMERALS.SLASHED_ZERO_IF_CONFUSION", "title": "Use slashed zero when confusion is likely", "source_refs": ["BRING \u00a74.4.3 p111 (scan p110)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use slashed or dotted zero when confusion with letter O is likely in codes or IDs.", "rationale": "Clear distinction reduces transcription errors.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "numerals", "clarity"], "keywords": ["slashed zero", "IDs", "codes"], "dependencies": [], "exceptions": ["If the face lacks a distinct zero, document the limitation."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.NUMERALS.FIGURE_STYLE_FOR_CAPTIONS", "title": "Match figure style in captions", "source_refs": ["BRING \u00a74.4.4 p72 (scan p71)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Match figure style in captions to the body text unless a table requires tabular figures.", "rationale": "Caption typography should feel integrated with the text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "numerals", "captions"], "keywords": ["captions", "figures", "style"], "dependencies": [], "exceptions": ["Table captions may inherit tabular figures."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.NUMERALS.SMALL_CAPS_AND_FIGURES", "title": "Match figures to small caps", "source_refs": ["BRING \u00a74.4.4 p72 (scan p71)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "When using small caps, choose a figure style that matches cap height and overall color.", "rationale": "Mismatched figures stand out in small-cap settings.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "numerals", "small_caps"], "keywords": ["small caps", "figures", "cap height"], "dependencies": [], "exceptions": ["If the face lacks matching figures, consider alternate styling."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.NUMERALS.FRACTIONS_TRUE_GLYPHS", "title": "Use true fraction glyphs when available", "source_refs": ["BRING \u00a74.4.3 p111 (scan p110)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use true fraction glyphs or proper fraction styling instead of stacked numerals when available.", "rationale": "True fractions are clearer and more balanced.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["numerals", "fractions", "typeset"], "keywords": ["fractions", "glyphs", "styling"], "dependencies": [], "exceptions": ["Plain-text contexts may require numeric fractions."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.NUMERALS.SUPERIOR_INFERIOR_FOR_NOTES", "title": "Use designed superior/inferior figures for notes", "source_refs": ["BRING \u00a74.4.3 p111 (scan p110)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use designed superior/inferior figures for footnote markers when available.", "rationale": "Properly designed note markers keep text color consistent.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["numerals", "footnotes", "typeset"], "keywords": ["superior", "inferior", "footnotes"], "dependencies": [], "exceptions": ["If the face lacks these, use a dedicated note style."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.NUMERALS.AVOID_LINING_IN_LOWERCASE", "title": "Avoid lining figures in lowercase text", "source_refs": ["BRING \u00a74.4.4 p72 (scan p71)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid forcing lining figures into lowercase body text unless required by data alignment.", "rationale": "Lining figures can disrupt the texture of lowercase text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "numerals", "texture"], "keywords": ["lining figures", "lowercase", "texture"], "dependencies": [], "exceptions": ["Data-heavy sections may prefer lining figures for clarity."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.SIZE.SCALE_CONSISTENT", "title": "Use a consistent size scale", "source_refs": ["BRING \u00a74.3.3 p69 (scan p68)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use a consistent size scale for headings and subheads rather than arbitrary jumps.", "rationale": "A consistent scale improves hierarchy and rhythm.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "size", "hierarchy"], "keywords": ["size scale", "headings", "hierarchy"], "dependencies": [], "exceptions": ["Special display spreads may use bespoke sizes."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.SIZE.AVOID_TOO_MANY_SIZES", "title": "Limit the number of type sizes", "source_refs": ["BRING \u00a74.3.3 p69 (scan p68)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Limit the number of type sizes used in a document.", "rationale": "Too many sizes weaken hierarchy and consistency.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "size", "consistency"], "keywords": ["type sizes", "consistency"], "dependencies": [], "exceptions": ["Complex manuals may require more sizes with strict role mapping."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.SIZE.BODY_SIZE_MATCH_MEASURE", "title": "Match body size to line length", "source_refs": ["BRING \u00a72.5 p41 (scan p40)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Choose body text size in balance with line length; avoid tiny type on long measures.", "rationale": "Size and measure must work together for readability.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "size", "measure"], "keywords": ["measure", "line length", "body size"], "dependencies": [], "exceptions": ["Tables may use smaller sizes when labeled clearly."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.SIZE.LEADING_RELATION", "title": "Adjust leading relative to size", "source_refs": ["BRING \u00a72.5 p41 (scan p40)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Adjust line spacing in proportion to size; avoid cramped leading.", "rationale": "Proper leading improves readability and texture.", "enforcement": "typeset", "autofix": "suggest", "autofix_notes": "Adjust profile tokens and re-render to satisfy the typography constraint.", "tags": ["size", "leading", "typeset"], "keywords": ["leading", "line spacing", "readability"], "dependencies": [], "exceptions": ["Tight leading may be used in short display blocks."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.SIZE.SMALL_TEXT_MINIMUM", "title": "Respect a minimum body size", "source_refs": ["BRING \u00a74.3.3 p69 (scan p68)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Do not set body text below a legible minimum for the medium.", "rationale": "Too-small type undermines accessibility.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "size", "accessibility"], "keywords": ["minimum size", "accessibility", "body text"], "dependencies": [], "exceptions": ["Footnotes may be smaller but must remain readable."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.SIZE.DISPLAY_SIZE_BALANCE", "title": "Balance display size against body", "source_refs": ["BRING \u00a74.3.3 p69 (scan p68)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Ensure display type is large enough to be distinct but not overpowering.", "rationale": "Balanced display size supports hierarchy without noise.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "size", "display"], "keywords": ["display size", "hierarchy", "balance"], "dependencies": [], "exceptions": ["Posters may intentionally exaggerate display sizes."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.WEIGHT.HIERARCHY_CLEAR", "title": "Use weight to signal hierarchy clearly", "source_refs": ["BRING \u00a74.3.2 p68 (scan p67)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use weight changes to signal hierarchy clearly; avoid subtle weight shifts that are hard to see.", "rationale": "Clear weight steps help readers scan structure.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "weight", "hierarchy"], "keywords": ["weight", "hierarchy", "contrast"], "dependencies": [], "exceptions": ["Minimalist designs may use subtle weight shifts intentionally."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.WEIGHT.AVOID_TOO_MANY_WEIGHTS", "title": "Limit the number of weights", "source_refs": ["BRING \u00a74.3.2 p68 (scan p67)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Limit the number of different weights in use; too many weakens hierarchy.", "rationale": "Excess weights make the system hard to read and maintain.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "weight", "consistency"], "keywords": ["weights", "consistency", "hierarchy"], "dependencies": [], "exceptions": ["Large editorial systems may allow more weights with strict rules."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.WEIGHT.BOLD_IN_LONG_PASSAGES_AVOID", "title": "Avoid bold in long passages", "source_refs": ["BRING \u00a74.3.2 p68 (scan p67)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid setting long passages in bold; it slows reading and adds noise.", "rationale": "Extended bold blocks are harder to read than roman.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "weight", "bold"], "keywords": ["bold", "passages", "readability"], "dependencies": [], "exceptions": ["Short callouts may use bold for emphasis."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.WEIGHT.HEAVY_WEIGHTS_SHORT_LABELS", "title": "Use heavy weights for short labels", "source_refs": ["BRING \u00a74.3.2 p68 (scan p67)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use heavy weights primarily for short labels or headings, not running text.", "rationale": "Heavy weights overpower continuous text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "weight", "labels"], "keywords": ["heavy weight", "labels", "headings"], "dependencies": [], "exceptions": ["Short marketing headlines may use heavy weights by design."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.CONTRAST.FONT_PAIRING_MATCH", "title": "Match contrast when pairing faces", "source_refs": ["BRING \u00a78.4.2 p163 (scan p162)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "When pairing typefaces, match contrast and stroke modulation so they feel compatible.", "rationale": "Compatible contrast keeps mixed typography cohesive.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "contrast", "pairing"], "keywords": ["contrast", "stroke", "pairing"], "dependencies": [], "exceptions": ["High-contrast pairings may be used for strong design statements."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.CONTRAST.AVOID_EXTREME_MIX", "title": "Avoid extreme contrast mixes", "source_refs": ["BRING \u00a78.4.2 p163 (scan p162)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid pairing faces with extreme contrast differences unless the design intent is explicit.", "rationale": "Extreme contrast mixes can feel unbalanced and reduce legibility.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "contrast", "pairing"], "keywords": ["contrast", "pairing", "balance"], "dependencies": [], "exceptions": ["Editorial spreads may allow extreme contrast with review."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.SERIF.BODY_TEXT_DEFAULT", "title": "Prefer serif for long-form body text", "source_refs": ["BRING \u00a76.5.5 p105 (scan p104)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Prefer serif faces for long-form body text when a traditional reading tone is desired.", "rationale": "Serif faces often read comfortably in long passages.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "serif", "body_text"], "keywords": ["serif", "body text", "tone"], "dependencies": [], "exceptions": ["Sans serif may be preferred for modern or screen-first profiles."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.SERIF.SANS_FOR_DISPLAY", "title": "Use sans serif for display contrast", "source_refs": ["BRING \u00a76.5.5 p105 (scan p104)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use sans serif for headings or UI elements when contrast is needed; avoid using it for both body and headings without reason.", "rationale": "Controlled contrast clarifies structure.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "serif", "sans"], "keywords": ["sans serif", "headings", "contrast"], "dependencies": [], "exceptions": ["All-sans documents are acceptable when the face is designed for text."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.SERIF.AVOID_MIX_SAME_ROLE", "title": "Avoid serif/sans mixing within the same role", "source_refs": ["BRING \u00a76.5.5 p105 (scan p104)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid mixing serif and sans serif for the same textual role.", "rationale": "Role mixing confuses hierarchy and texture.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "serif", "sans"], "keywords": ["serif", "sans", "roles"], "dependencies": [], "exceptions": ["Pull quotes may use a different face to signal separation."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.SERIF.PAIR_WITH_COMPATIBLE_XHEIGHT", "title": "Pair serif and sans with compatible x-height", "source_refs": ["BRING \u00a78.4.2 p163 (scan p162)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "When pairing serif and sans serif, match x-height and weight to avoid mismatch.", "rationale": "Compatible metrics keep mixed typography coherent.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "serif", "pairing"], "keywords": ["x-height", "pairing", "metrics"], "dependencies": [], "exceptions": ["Intentional contrast pairings may be acceptable with review."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.SERIF.STROKE_CONTRAST_COMPATIBLE", "title": "Match stroke contrast in serif/sans pairs", "source_refs": ["BRING \u00a78.4.2 p163 (scan p162)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Pair faces with compatible stroke contrast and axis to maintain harmony.", "rationale": "Mismatch in contrast makes pairing look accidental.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "serif", "pairing"], "keywords": ["stroke contrast", "axis", "pairing"], "dependencies": [], "exceptions": ["Graphic posters may break this rule intentionally."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.SERIF.SERIF_SANS_BALANCE", "title": "Balance serif and sans tone", "source_refs": ["BRING \u00a76.5.5 p105 (scan p104)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Ensure serif and sans choices balance in tone; do not let one dominate without reason.", "rationale": "Balanced tone keeps the document cohesive.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "serif", "tone"], "keywords": ["tone", "balance", "pairing"], "dependencies": [], "exceptions": ["A deliberate brand voice may favor one voice strongly."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.BOLD.SPARING_USE", "title": "Use bold sparingly", "source_refs": ["BRING \u00a76.5.3 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use bold sparingly; reserve it for clear emphasis or labels.", "rationale": "Excess bold disrupts rhythm and hierarchy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "bold", "emphasis"], "keywords": ["bold", "emphasis", "labels"], "dependencies": [], "exceptions": ["Short callouts may use bold for scanning."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.BOLD.AVOID_LONG_PASSAGES", "title": "Avoid long bold passages", "source_refs": ["BRING \u00a76.5.3 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid bolding full sentences or paragraphs in body text.", "rationale": "Long bold passages are harder to read than roman.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "bold", "readability"], "keywords": ["bold", "paragraphs", "readability"], "dependencies": [], "exceptions": ["Warning blocks may use bold for short spans."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ALL_CAPS", "title": "Avoid bold all caps", "source_refs": ["BRING \u00a76.5.3 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid combining bold with all caps for extended text; it reads as shouting.", "rationale": "Bold all caps can overpower the page.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "bold", "caps"], "keywords": ["bold", "all caps", "emphasis"], "dependencies": [], "exceptions": ["Short labels may use bold caps when clarity requires it."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.BOLD.NOT_WITH_ITALICS_LONG", "title": "Avoid long bold italic runs", "source_refs": ["BRING \u00a76.5.3 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Avoid long runs of bold italics; use a single emphasis mode instead.", "rationale": "Bold italics reduce legibility in long spans.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "bold", "italics"], "keywords": ["bold italic", "legibility", "emphasis"], "dependencies": [], "exceptions": ["Short warnings may combine styles with review."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.BOLD.LABELS_SHORT", "title": "Keep bold labels short", "source_refs": ["BRING \u00a76.5.3 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use bold primarily for short labels, not for narrative content.", "rationale": "Short bold labels aid scanning without overwhelming the text.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "bold", "labels"], "keywords": ["labels", "bold", "scanning"], "dependencies": [], "exceptions": ["Short lead-ins may use bold when clearly separated."], "status": "active"}
+{"id": "BRING.TYPOGRAPHY.BOLD.HEADING_HIERARCHY_BALANCE", "title": "Balance bold with size in headings", "source_refs": ["BRING \u00a76.5.3 p103 (scan p102)"], "category": "typography", "severity": "should", "applies_to": "all", "rule_text": "Use size and spacing to establish heading hierarchy before adding bold weight.", "rationale": "Weight alone can flatten hierarchy.", "enforcement": "manual", "autofix": "none", "autofix_notes": "", "tags": ["manual_checklist=true", "bold", "headings"], "keywords": ["headings", "hierarchy", "weight"], "dependencies": [], "exceptions": ["Condensed layouts may require bold to differentiate levels."], "status": "active"}
diff --git a/spec/rules/typography/v1_typography_004.ndjson b/spec/rules/typography/v1_typography_004.ndjson
new file mode 100644
index 0000000..8cd180c
--- /dev/null
+++ b/spec/rules/typography/v1_typography_004.ndjson
@@ -0,0 +1,3 @@
+{"id":"HOUSE.TYPOGRAPHY.HTML.LINE_HEIGHT.MINIMUM","title":"Keep body line-height at a readable minimum","source_refs":["HOUSE §TYPOGRAPHY.HTML.LINE_HEIGHT p1"],"category":"typography","severity":"should","applies_to":"html","rule_text":"Set body text line-height to a readable minimum (for example 1.4) to avoid cramped lines in HTML outputs.","rationale":"Adequate leading improves legibility and scanning.","enforcement":"typeset","autofix":"suggest","autofix_notes":"Adjust profile CSS line-height for body text to meet the minimum.","tags":["typography","line_height","typeset"],"keywords":["line height","leading","html"],"dependencies":[],"exceptions":["Dense tables or code blocks may use tighter line-height if readability remains acceptable."],"status":"active"}
+{"id":"HOUSE.TYPOGRAPHY.HTML.JUSTIFICATION.RAGGED_RIGHT","title":"Avoid full justification in HTML outputs","source_refs":["HOUSE §TYPOGRAPHY.HTML.JUSTIFICATION p1"],"category":"typography","severity":"should","applies_to":"html","rule_text":"Avoid full justification in HTML outputs unless spacing and hyphenation are controlled; prefer ragged-right body text.","rationale":"Web justification often produces rivers and uneven spacing.","enforcement":"typeset","autofix":"suggest","autofix_notes":"Set text alignment to left/ start in profile CSS for body text.","tags":["typography","justification","typeset"],"keywords":["ragged right","justification","html"],"dependencies":[],"exceptions":["Print-like HTML outputs with controlled hyphenation may use justification with review."],"status":"active"}
+{"id":"HOUSE.TYPOGRAPHY.HTML.LINK_DECORATION.CONSISTENT","title":"Use consistent link decoration","source_refs":["HOUSE §TYPOGRAPHY.HTML.LINK_DECORATION p1"],"category":"typography","severity":"should","applies_to":"html","rule_text":"Use consistent link decoration (such as underline) in HTML outputs so links remain distinguishable in body text.","rationale":"Consistent decoration improves readability and reduces ambiguity.","enforcement":"typeset","autofix":"suggest","autofix_notes":"Set link styles in profile CSS and keep them consistent across states.","tags":["typography","links","typeset"],"keywords":["links","underline","css"],"dependencies":[],"exceptions":["If a design system uses an alternative cue, ensure it remains obvious and accessible."],"status":"active"}
diff --git a/spec/rules/typography/v1_typography_005.ndjson b/spec/rules/typography/v1_typography_005.ndjson
new file mode 100644
index 0000000..5670829
--- /dev/null
+++ b/spec/rules/typography/v1_typography_005.ndjson
@@ -0,0 +1,4 @@
+{"id":"HOUSE.TYPOGRAPHY.EMPHASIS.ITALIC_LONG.AVOID","title":"Avoid long runs of italics","source_refs":["HOUSE §TYPOGRAPHY.MD.EMPHASIS.BALANCE p1"],"category":"typography","severity":"should","applies_to":"md","rule_text":"Avoid long italic spans in body text; prefer short, targeted emphasis.","rationale":"Extended italics reduce legibility and weaken emphasis.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["typography","italics","emphasis"],"keywords":["italics","emphasis","readability"],"dependencies":[],"exceptions":["Quoted material may require italics; keep it short and distinct."],"status":"active"}
+{"id":"HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_LONG.AVOID","title":"Avoid long runs of bold text","source_refs":["HOUSE §TYPOGRAPHY.MD.EMPHASIS.BALANCE p1"],"category":"typography","severity":"should","applies_to":"md","rule_text":"Avoid long bold spans in paragraphs; reserve bold for brief labels or emphasis.","rationale":"Excess bold disrupts hierarchy and reading flow.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["typography","bold","emphasis"],"keywords":["bold","emphasis","readability"],"dependencies":[],"exceptions":["Short callouts may use bold for scanning."],"status":"active"}
+{"id":"HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ITALIC_LONG.AVOID","title":"Avoid long bold-italic runs","source_refs":["HOUSE §TYPOGRAPHY.MD.EMPHASIS.BALANCE p1"],"category":"typography","severity":"warn","applies_to":"md","rule_text":"Avoid long runs of combined bold italics; use a single emphasis mode.","rationale":"Bold italics reduce legibility in longer spans.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["typography","bold","italics","emphasis"],"keywords":["bold italics","emphasis"],"dependencies":[],"exceptions":["Short warnings may combine styles with review."],"status":"active"}
+{"id":"HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ALL_CAPS.AVOID","title":"Avoid bold all-caps in prose","source_refs":["HOUSE §TYPOGRAPHY.MD.EMPHASIS.BALANCE p1"],"category":"typography","severity":"should","applies_to":"md","rule_text":"Avoid bold all-caps text in running prose; use case and weight sparingly.","rationale":"Bold all-caps reads as shouting and overpowers the page.","enforcement":"lint","autofix":"none","autofix_notes":"","tags":["typography","bold","caps"],"keywords":["all caps","bold","emphasis"],"dependencies":[],"exceptions":["Short labels may use bold caps when clarity requires it."],"status":"active"}
diff --git a/src/iftypeset/cli.py b/src/iftypeset/cli.py
index fbc1a29..468639c 100644
--- a/src/iftypeset/cli.py
+++ b/src/iftypeset/cli.py
@@ -1,18 +1,61 @@
import argparse
+import glob
+import io
import json
+import os
import sys
+from contextlib import redirect_stdout
+from datetime import datetime, timezone
from dataclasses import asdict
from pathlib import Path
from iftypeset import __version__
+from iftypeset.config import apply_config
from iftypeset.css_gen import generate_profile_css
from iftypeset.index_builder import build_indexes, write_indexes
from iftypeset.linting import collect_input_paths, lint_paths, manual_checklist
-from iftypeset.qa import analyze_html, evaluate_gates, layout_report_dict
+from iftypeset.qa import LayoutReport, analyze_html, analyze_pdf, evaluate_gates, layout_report_dict
from iftypeset.rendering import render_html, render_pdf, renderer_info
-from iftypeset.reporting import CoverageError, CoverageReport, build_coverage_report
+from iftypeset.reporting import (
+ CoverageError,
+ CoverageReport,
+ build_coverage_report,
+ build_doctor_report,
+ build_bundle,
+ build_run_index,
+ build_report_index,
+ build_trust_contract,
+)
from iftypeset.spec_loader import SpecError, load_spec
+EXIT_OK = 0
+EXIT_GATE_FAIL = 1
+EXIT_CONFIG = 2
+EXIT_RENDER = 3
+EXIT_NONDET = 4
+
+QA_RULE_MAP = {
+ "link_wrap": "HOUSE.LINKS.WRAP.SAFE_BREAKS",
+ "code_overflow": "HOUSE.CODE.BLOCKS.NO_CLIPPING",
+ "table_overflow": "HOUSE.TABLES.OVERFLOW.NO_CLIPPING",
+ "overfull_token": "HOUSE.LAYOUT.OVERFLOW.OVERFULL_LINES.REPORT",
+ "overfull_line_pdf": "HOUSE.LAYOUT.OVERFLOW.OVERFULL_LINES.REPORT",
+ "overfull_bbox_pdf": "HOUSE.LAYOUT.OVERFLOW.OVERFULL_LINES.REPORT",
+ "stranded_heading": "HOUSE.HEADINGS.KEEPS.AVOID_STRANDED",
+ "stranded_heading_pdf": "HOUSE.HEADINGS.KEEPS.AVOID_STRANDED",
+ "widow_pdf": "BRING.LAYOUT.PAGINATION.WIDOWS_AVOID",
+ "orphan_pdf": "BRING.LAYOUT.PAGINATION.ORPHANS_AVOID",
+}
+
+_BANNED_ENGINES = {"chromium", "chrome", "google-chrome"}
+
+
+def _parse_engine_arg(value: str) -> str:
+ normalized = str(value).strip().lower()
+ if normalized in _BANNED_ENGINES:
+ raise argparse.ArgumentTypeError("Chromium engine is banned; use --engine playwright.")
+ return normalized
+
def _cmd_validate_spec(args: argparse.Namespace) -> int:
try:
@@ -20,7 +63,7 @@ def _cmd_validate_spec(args: argparse.Namespace) -> int:
except SpecError as e:
_write_json(Path(args.out) / "spec-validation.json", {"ok": False, "error": str(e)})
print(json.dumps({"ok": False, "error": str(e)}))
- return 4
+ return EXIT_CONFIG
out: dict[str, object] = {
"ok": True,
@@ -38,7 +81,7 @@ def _cmd_validate_spec(args: argparse.Namespace) -> int:
out_dir.mkdir(parents=True, exist_ok=True)
_write_json(out_dir / "spec-validation.json", out)
print(json.dumps(out, indent=2, sort_keys=True))
- return 0
+ return EXIT_OK
def _cmd_report(args: argparse.Namespace) -> int:
@@ -46,13 +89,13 @@ def _cmd_report(args: argparse.Namespace) -> int:
spec = load_spec(Path(args.spec))
except SpecError as e:
print(json.dumps({"ok": False, "error": str(e)}))
- return 4
+ return EXIT_CONFIG
try:
report: CoverageReport = build_coverage_report(spec, strict=args.strict)
except CoverageError as e:
print(json.dumps({"ok": False, "error": str(e)}))
- return 2
+ return EXIT_GATE_FAIL
out_dir = Path(args.out)
out_dir.mkdir(parents=True, exist_ok=True)
@@ -60,13 +103,363 @@ def _cmd_report(args: argparse.Namespace) -> int:
json.dumps(asdict(report), indent=2, sort_keys=True) + "\n", encoding="utf-8"
)
(out_dir / "coverage-summary.md").write_text(report.to_markdown(), encoding="utf-8")
+ trust = build_trust_contract(spec, report)
+ (out_dir / "trust-contract.json").write_text(
+ json.dumps(asdict(trust), indent=2, sort_keys=True) + "\n", encoding="utf-8"
+ )
+ (out_dir / "trust-contract.md").write_text(trust.to_markdown(), encoding="utf-8")
+
+ report_dir = out_dir / "report"
+ report_dir.mkdir(parents=True, exist_ok=True)
+ (report_dir / "index.html").write_text(build_report_index(out_dir), encoding="utf-8")
if args.build_indexes:
indexes = build_indexes(spec.rules)
write_indexes(indexes, Path(args.spec) / "indexes")
print(json.dumps({"ok": True, "out_dir": str(out_dir.resolve())}, indent=2, sort_keys=True))
- return 0
+ return EXIT_OK
+
+
+def _cmd_doctor(args: argparse.Namespace) -> int:
+ try:
+ spec = load_spec(Path(args.spec))
+ except SpecError as e:
+ print(json.dumps({"ok": False, "error": str(e)}))
+ return EXIT_CONFIG
+
+ report = build_doctor_report(spec)
+ out_dir = Path(args.out)
+ out_dir.mkdir(parents=True, exist_ok=True)
+ (out_dir / "doctor.json").write_text(json.dumps(asdict(report), indent=2, sort_keys=True) + "\n", encoding="utf-8")
+ (out_dir / "doctor.md").write_text(report.to_markdown(), encoding="utf-8")
+ print(json.dumps({"ok": True, "out_dir": str(out_dir.resolve())}, indent=2, sort_keys=True))
+ return EXIT_OK
+
+
+def _cmd_bundle(args: argparse.Namespace) -> int:
+ out_dir = Path(args.out)
+ bundle_path = Path(args.bundle) if args.bundle else (out_dir / "iftypeset-bundle.tar.gz")
+ max_bytes = int(args.max_size_mb * 1024 * 1024)
+ manifest = build_bundle(out_dir, bundle_path, max_bytes=max_bytes)
+ print(
+ json.dumps(
+ {
+ "ok": True,
+ "bundle": str(bundle_path.resolve()),
+ "manifest": str((out_dir / "bundle-manifest.json").resolve()),
+ "included": len(manifest.get("included", []) if isinstance(manifest, dict) else []),
+ },
+ indent=2,
+ sort_keys=True,
+ )
+ )
+ return EXIT_OK
+
+
+def _has_glob(value: str) -> bool:
+ return any(ch in value for ch in ("*", "?", "["))
+
+
+def _resolve_run_inputs(input_value: str) -> tuple[list[Path], Path]:
+ if _has_glob(input_value):
+ matches = [Path(p) for p in glob.glob(input_value, recursive=True)]
+ paths = sorted([p for p in matches if p.is_file() and p.suffix.lower() == ".md"])
+ if not paths:
+ raise ValueError(f"No markdown files matched: {input_value}")
+ base_dir = Path(os.path.commonpath([str(p.resolve()) for p in paths]))
+ return paths, base_dir
+
+ input_path = Path(input_value)
+ if input_path.is_dir():
+ paths = collect_input_paths(input_path)
+ if not paths:
+ raise ValueError(f"No markdown files found under {input_path}")
+ return paths, input_path
+ if input_path.exists():
+ return [input_path], input_path.parent
+ raise ValueError(f"Input path not found: {input_path}")
+
+
+def _run_pipeline(
+ args: argparse.Namespace,
+ *,
+ input_path: Path,
+ out_dir: Path,
+ emit_stdout: bool,
+) -> tuple[dict[str, object], int]:
+ started = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
+ out_dir.mkdir(parents=True, exist_ok=True)
+
+ steps: list[dict[str, object]] = []
+ warnings: list[str] = []
+
+ def run_step(name: str, func, ns: argparse.Namespace) -> int:
+ buf = io.StringIO()
+ with redirect_stdout(buf):
+ rc = func(ns)
+ entry: dict[str, object] = {"name": name, "rc": rc, "ok": rc == EXIT_OK}
+ output = buf.getvalue().strip()
+ if rc != 0 and output:
+ entry["stdout"] = output
+ steps.append(entry)
+ return rc
+
+ def record_skip(name: str, reason: str) -> None:
+ steps.append({"name": name, "rc": None, "ok": False, "skipped": True, "reason": reason})
+
+ validate_args = argparse.Namespace(spec=args.spec, out=str(out_dir), build_indexes=True)
+ rc_validate = run_step("validate-spec", _cmd_validate_spec, validate_args)
+ if rc_validate == EXIT_CONFIG:
+ summary = _finalize_run(
+ args,
+ steps,
+ warnings,
+ started,
+ EXIT_CONFIG,
+ input_path=input_path,
+ out_dir=out_dir,
+ emit_stdout=emit_stdout,
+ )
+ return summary, EXIT_CONFIG
+
+ lint_args = argparse.Namespace(
+ spec=args.spec,
+ input=str(input_path),
+ out=str(out_dir),
+ profile=args.profile,
+ format=args.format,
+ fail_on=args.fail_on,
+ degraded_ok=args.degraded_ok,
+ fix=args.fix,
+ fix_mode=args.fix_mode,
+ lint_fixed=args.lint_fixed,
+ )
+ rc_lint = run_step("lint", _cmd_lint, lint_args)
+ if rc_lint == EXIT_CONFIG:
+ summary = _finalize_run(
+ args,
+ steps,
+ warnings,
+ started,
+ EXIT_CONFIG,
+ input_path=input_path,
+ out_dir=out_dir,
+ emit_stdout=emit_stdout,
+ )
+ return summary, EXIT_CONFIG
+
+ render_html_args = argparse.Namespace(
+ spec=args.spec,
+ input=str(input_path),
+ out=str(out_dir),
+ profile=args.profile,
+ self_contained=args.self_contained,
+ degraded_ok=args.degraded_ok,
+ )
+ rc_html = run_step("render-html", _cmd_render_html, render_html_args)
+ if rc_html == EXIT_CONFIG:
+ summary = _finalize_run(
+ args,
+ steps,
+ warnings,
+ started,
+ EXIT_CONFIG,
+ input_path=input_path,
+ out_dir=out_dir,
+ emit_stdout=emit_stdout,
+ )
+ return summary, EXIT_CONFIG
+
+ if args.skip_pdf:
+ record_skip("render-pdf", "skip_pdf")
+ rc_pdf = EXIT_OK
+ else:
+ render_pdf_args = argparse.Namespace(
+ spec=args.spec,
+ input=str(input_path),
+ out=str(out_dir),
+ profile=args.profile,
+ engine=getattr(args, "engine", None),
+ self_contained=args.self_contained,
+ font_dir=getattr(args, "font_dir", None),
+ strict_fonts=getattr(args, "strict_fonts", False),
+ )
+ rc_pdf = run_step("render-pdf", _cmd_render_pdf, render_pdf_args)
+ if rc_pdf == EXIT_CONFIG:
+ summary = _finalize_run(
+ args,
+ steps,
+ warnings,
+ started,
+ EXIT_CONFIG,
+ input_path=input_path,
+ out_dir=out_dir,
+ emit_stdout=emit_stdout,
+ )
+ return summary, EXIT_CONFIG
+ if rc_pdf == EXIT_RENDER:
+ if getattr(args, "require_pdf", False):
+ warnings.append("render-pdf failed and require-pdf is set")
+ else:
+ warnings.append("render-pdf failed or renderer missing; continuing with HTML QA")
+
+ if (out_dir / "render.html").exists():
+ qa_args = argparse.Namespace(
+ spec=args.spec,
+ out=str(out_dir),
+ profile=args.profile,
+ strict=args.strict,
+ html=None,
+ pdf=None,
+ format="json",
+ )
+ rc_qa = run_step("qa", _cmd_qa, qa_args)
+ else:
+ record_skip("qa", "render-html missing")
+ rc_qa = EXIT_CONFIG
+
+ report_args = argparse.Namespace(spec=args.spec, out=str(out_dir), strict=args.strict, build_indexes=True)
+ rc_report = run_step("report", _cmd_report, report_args)
+
+ exit_code = EXIT_OK
+ if EXIT_CONFIG in {rc_validate, rc_lint, rc_html, rc_pdf, rc_qa, rc_report}:
+ exit_code = EXIT_CONFIG
+ elif EXIT_RENDER in {rc_pdf} and getattr(args, "require_pdf", False):
+ exit_code = EXIT_RENDER
+ elif EXIT_GATE_FAIL in {rc_lint, rc_html, rc_qa, rc_report}:
+ exit_code = EXIT_GATE_FAIL
+
+ summary = _finalize_run(
+ args,
+ steps,
+ warnings,
+ started,
+ exit_code,
+ input_path=input_path,
+ out_dir=out_dir,
+ emit_stdout=emit_stdout,
+ )
+ return summary, exit_code
+
+
+def _cmd_run(args: argparse.Namespace) -> int:
+ if getattr(args, "skip_pdf", False) and getattr(args, "require_pdf", False):
+ print(json.dumps({"ok": False, "error": "--skip-pdf and --require-pdf cannot be used together"}))
+ return EXIT_CONFIG
+
+ try:
+ input_paths, base_dir = _resolve_run_inputs(args.input)
+ except ValueError as e:
+ print(json.dumps({"ok": False, "error": str(e)}))
+ return EXIT_CONFIG
+
+ out_root = Path(args.out)
+ if len(input_paths) == 1:
+ _, exit_code = _run_pipeline(
+ args,
+ input_path=input_paths[0],
+ out_dir=out_root,
+ emit_stdout=True,
+ )
+ return exit_code
+
+ started = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
+ out_root.mkdir(parents=True, exist_ok=True)
+ documents: list[dict[str, object]] = []
+ warnings: list[str] = []
+
+ for path in input_paths:
+ try:
+ rel = path.resolve().relative_to(base_dir.resolve())
+ except ValueError:
+ rel = Path(path.name)
+ rel = rel.with_suffix("")
+ doc_out = out_root / "docs" / rel
+ doc_out.mkdir(parents=True, exist_ok=True)
+
+ summary, exit_code = _run_pipeline(
+ args,
+ input_path=path,
+ out_dir=doc_out,
+ emit_stdout=False,
+ )
+
+ report_index = doc_out / "report" / "index.html"
+ doc_entry = {
+ "input": str(path.resolve()),
+ "rel_input": rel.as_posix(),
+ "out_dir": str(doc_out.resolve()),
+ "exit_code": exit_code,
+ "ok": exit_code == EXIT_OK,
+ "summary": str((doc_out / "run-summary.json").resolve()),
+ "report_index": str(report_index.resolve()) if report_index.exists() else None,
+ }
+ documents.append(doc_entry)
+ for warning in summary.get("warnings", []) if isinstance(summary, dict) else []:
+ warnings.append(f"{rel.as_posix()}: {warning}")
+
+ finished = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
+ codes = [int(doc.get("exit_code", EXIT_OK)) for doc in documents]
+ exit_code = EXIT_OK
+ if EXIT_CONFIG in codes:
+ exit_code = EXIT_CONFIG
+ elif EXIT_RENDER in codes:
+ exit_code = EXIT_RENDER
+ elif EXIT_GATE_FAIL in codes:
+ exit_code = EXIT_GATE_FAIL
+
+ summary = {
+ "ok": exit_code == EXIT_OK,
+ "exit_code": exit_code,
+ "mode": "multi",
+ "started_at_utc": started,
+ "finished_at_utc": finished,
+ "spec_root": str(Path(args.spec).resolve()),
+ "input": str(args.input),
+ "profile": str(args.profile),
+ "out_dir": str(out_root.resolve()),
+ "documents": documents,
+ "warnings": warnings,
+ }
+ _write_json(out_root / "run-summary.json", summary)
+
+ report_dir = out_root / "report"
+ report_dir.mkdir(parents=True, exist_ok=True)
+ (report_dir / "index.html").write_text(build_run_index(out_root, documents), encoding="utf-8")
+
+ print(json.dumps({"ok": summary["ok"], "out_dir": summary["out_dir"], "exit_code": exit_code}, indent=2))
+ return exit_code
+
+
+def _finalize_run(
+ args: argparse.Namespace,
+ steps: list[dict[str, object]],
+ warnings: list[str],
+ started: str,
+ exit_code: int,
+ *,
+ input_path: Path,
+ out_dir: Path,
+ emit_stdout: bool,
+) -> dict[str, object]:
+ finished = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
+ summary = {
+ "ok": exit_code == 0,
+ "exit_code": exit_code,
+ "started_at_utc": started,
+ "finished_at_utc": finished,
+ "spec_root": str(Path(args.spec).resolve()),
+ "input": str(input_path.resolve()),
+ "profile": str(args.profile),
+ "out_dir": str(out_dir.resolve()),
+ "steps": steps,
+ "warnings": warnings,
+ }
+ _write_json(out_dir / "run-summary.json", summary)
+ if emit_stdout:
+ print(json.dumps({"ok": summary["ok"], "out_dir": summary["out_dir"], "exit_code": exit_code}, indent=2))
+ return summary
def _cmd_emit_css(args: argparse.Namespace) -> int:
@@ -74,12 +467,12 @@ def _cmd_emit_css(args: argparse.Namespace) -> int:
spec = load_spec(Path(args.spec))
except SpecError as e:
print(json.dumps({"ok": False, "error": str(e)}))
- return 4
+ return EXIT_CONFIG
profile = spec.profiles.get(str(args.profile))
if not profile:
print(json.dumps({"ok": False, "error": f"Unknown profile_id: {args.profile}"}))
- return 4
+ return EXIT_CONFIG
out_dir = Path(args.out)
out_dir.mkdir(parents=True, exist_ok=True)
@@ -90,7 +483,93 @@ def _cmd_emit_css(args: argparse.Namespace) -> int:
json.dumps(css_out.report, indent=2, sort_keys=True) + "\n", encoding="utf-8"
)
print(json.dumps({"ok": True, "out_dir": str(out_dir.resolve())}, indent=2, sort_keys=True))
- return 0
+ return EXIT_OK
+
+
+def _cmd_profiles_list(args: argparse.Namespace) -> int:
+ try:
+ spec = load_spec(Path(args.spec))
+ except SpecError as e:
+ print(json.dumps({"ok": False, "error": str(e)}))
+ return EXIT_CONFIG
+ profiles = sorted(spec.profiles.keys())
+ print(json.dumps({"ok": True, "profiles": profiles}, indent=2, sort_keys=True))
+ return EXIT_OK
+
+
+def _cmd_gates_show(args: argparse.Namespace) -> int:
+ try:
+ spec = load_spec(Path(args.spec))
+ except SpecError as e:
+ print(json.dumps({"ok": False, "error": str(e)}))
+ return EXIT_CONFIG
+ profile_id = str(args.profile)
+ gates_all = spec.quality_gates.get("profiles", {}).get(profile_id)
+ if not gates_all:
+ print(json.dumps({"ok": False, "error": f"Missing quality gates for profile {profile_id}"}))
+ return EXIT_CONFIG
+ mode = "strict" if args.strict else "default"
+ gates = gates_all.get(mode) or {}
+ print(json.dumps({"ok": True, "profile": profile_id, "mode": mode, "gates": gates}, indent=2, sort_keys=True))
+ return EXIT_OK
+
+
+def _cmd_rules_list(args: argparse.Namespace) -> int:
+ try:
+ spec = load_spec(Path(args.spec))
+ except SpecError as e:
+ print(json.dumps({"ok": False, "error": str(e)}))
+ return EXIT_CONFIG
+
+ categories = set(args.category or [])
+ enforcements = set(args.enforcement or [])
+ severities = set(args.severity or [])
+ tags_filter = set(args.tag or [])
+
+ items: list[dict[str, object]] = []
+ for rule in spec.rules:
+ raw = rule.raw
+ if categories and rule.category not in categories:
+ continue
+ if enforcements and rule.enforcement not in enforcements:
+ continue
+ if severities and rule.severity not in severities:
+ continue
+ tags = [str(t) for t in (raw.get("tags") or [])]
+ if tags_filter and not tags_filter.issubset(set(tags)):
+ continue
+ items.append(
+ {
+ "id": rule.id,
+ "title": raw.get("title", ""),
+ "category": rule.category,
+ "severity": rule.severity,
+ "enforcement": rule.enforcement,
+ "manual_checklist": "manual_checklist=true" in tags,
+ "tags": tags,
+ }
+ )
+ print(json.dumps({"ok": True, "count": len(items), "rules": items}, indent=2, sort_keys=True))
+ return EXIT_OK
+
+
+def _cmd_rules_show(args: argparse.Namespace) -> int:
+ try:
+ spec = load_spec(Path(args.spec))
+ except SpecError as e:
+ print(json.dumps({"ok": False, "error": str(e)}))
+ return EXIT_CONFIG
+
+ target = str(args.rule_id)
+ for rule in spec.rules:
+ if rule.id == target:
+ out = dict(rule.raw)
+ out["source_path"] = rule.source_path
+ out["line_no"] = rule.line_no
+ print(json.dumps({"ok": True, "rule": out}, indent=2, sort_keys=True))
+ return EXIT_OK
+ print(json.dumps({"ok": False, "error": f"Rule not found: {target}"}))
+ return EXIT_CONFIG
def _cmd_lint(args: argparse.Namespace) -> int:
@@ -98,26 +577,27 @@ def _cmd_lint(args: argparse.Namespace) -> int:
spec = load_spec(Path(args.spec))
except SpecError as e:
print(json.dumps({"ok": False, "error": str(e)}))
- return 4
+ return EXIT_CONFIG
profile = spec.profiles.get(str(args.profile))
if not profile:
print(json.dumps({"ok": False, "error": f"Unknown profile_id: {args.profile}"}))
- return 4
+ return EXIT_CONFIG
input_path = Path(args.input)
if not input_path.exists():
print(json.dumps({"ok": False, "error": f"Input path not found: {input_path}"}))
- return 4
+ return EXIT_CONFIG
paths = collect_input_paths(input_path)
if not paths:
print(json.dumps({"ok": False, "error": f"No markdown files found under {input_path}"}))
- return 4
+ return EXIT_CONFIG
result = lint_paths(
paths,
profile_id=str(args.profile),
fix=args.fix,
fix_mode=args.fix_mode,
+ lint_fixed=getattr(args, "lint_fixed", False),
degraded_ok=args.degraded_ok,
fail_on=args.fail_on,
)
@@ -153,7 +633,7 @@ def _cmd_lint(args: argparse.Namespace) -> int:
if args.format == "text":
print(_lint_text_summary(result.report))
- return 0 if result.report.get("ok") else 2
+ return EXIT_OK if result.report.get("ok") else EXIT_GATE_FAIL
def _cmd_render_html(args: argparse.Namespace) -> int:
@@ -161,17 +641,17 @@ def _cmd_render_html(args: argparse.Namespace) -> int:
spec = load_spec(Path(args.spec))
except SpecError as e:
print(json.dumps({"ok": False, "error": str(e)}))
- return 4
+ return EXIT_CONFIG
profile = spec.profiles.get(str(args.profile))
if not profile:
print(json.dumps({"ok": False, "error": f"Unknown profile_id: {args.profile}"}))
- return 4
+ return EXIT_CONFIG
input_path = Path(args.input)
if not input_path.exists() or input_path.is_dir():
print(json.dumps({"ok": False, "error": f"Input markdown file not found: {input_path}"}))
- return 4
+ return EXIT_CONFIG
out_dir = Path(args.out)
out_dir.mkdir(parents=True, exist_ok=True)
@@ -192,8 +672,8 @@ def _cmd_render_html(args: argparse.Namespace) -> int:
print(json.dumps(summary, indent=2, sort_keys=True))
if result.degraded and not args.degraded_ok:
- return 2
- return 0
+ return EXIT_GATE_FAIL
+ return EXIT_OK
def _cmd_render_pdf(args: argparse.Namespace) -> int:
@@ -201,27 +681,35 @@ def _cmd_render_pdf(args: argparse.Namespace) -> int:
spec = load_spec(Path(args.spec))
except SpecError as e:
print(json.dumps({"ok": False, "error": str(e)}))
- return 4
+ return EXIT_CONFIG
profile = spec.profiles.get(str(args.profile))
if not profile:
print(json.dumps({"ok": False, "error": f"Unknown profile_id: {args.profile}"}))
- return 4
+ return EXIT_CONFIG
input_path = Path(args.input)
if not input_path.exists() or input_path.is_dir():
print(json.dumps({"ok": False, "error": f"Input markdown file not found: {input_path}"}))
- return 4
+ return EXIT_CONFIG
out_dir = Path(args.out)
- result = render_pdf(input_path, profile, out_dir, self_contained=args.self_contained)
+ result = render_pdf(
+ input_path,
+ profile,
+ out_dir,
+ engine_name=getattr(args, "engine", None),
+ self_contained=args.self_contained,
+ font_dirs=[Path(p) for p in (getattr(args, "font_dir", None) or [])],
+ strict_fonts=bool(getattr(args, "strict_fonts", False)),
+ )
_write_json(out_dir / "render-log.json", result.log)
if result.ok:
print(json.dumps({"ok": True, "engine": result.engine, "pdf": result.pdf_path}, indent=2, sort_keys=True))
- return 0
+ return EXIT_OK
print(json.dumps({"ok": False, "engine": result.engine, "error": result.log.get("error")}, indent=2, sort_keys=True))
- return 3
+ return EXIT_RENDER
def _cmd_qa(args: argparse.Namespace) -> int:
@@ -229,40 +717,88 @@ def _cmd_qa(args: argparse.Namespace) -> int:
spec = load_spec(Path(args.spec))
except SpecError as e:
print(json.dumps({"ok": False, "error": str(e)}))
- return 4
+ return EXIT_CONFIG
profile = spec.profiles.get(str(args.profile))
if not profile:
print(json.dumps({"ok": False, "error": f"Unknown profile_id: {args.profile}"}))
- return 4
+ return EXIT_CONFIG
out_dir = Path(args.out)
- html_path = out_dir / "render.html"
+ html_path = Path(args.html) if getattr(args, "html", None) else (out_dir / "render.html")
+ pdf_path = Path(args.pdf) if getattr(args, "pdf", None) else (out_dir / "render.pdf")
+
if not html_path.exists():
- print(json.dumps({"ok": False, "error": f"Missing render.html at {html_path}"}))
- return 4
+ print(json.dumps({"ok": False, "error": f"Missing HTML input at {html_path}"}))
+ return EXIT_CONFIG
html_text = html_path.read_text(encoding="utf-8")
layout = analyze_html(html_text, profile, analysis_mode="html")
+ metrics = dict(layout.metrics)
+ incidents = list(layout.incidents)
+ warnings = list(layout.warnings)
+ analysis_mode = layout.analysis_mode
+
+ if pdf_path.exists():
+ pdf_result = analyze_pdf(pdf_path, profile, analysis_mode="pdf")
+ if pdf_result.ok:
+ metrics["max_widows_per_10_pages"] = pdf_result.metrics.get("max_widows_per_10_pages", 0)
+ metrics["max_orphans_per_10_pages"] = pdf_result.metrics.get("max_orphans_per_10_pages", 0)
+ if "max_overfull_lines" in pdf_result.metrics:
+ metrics["max_overfull_lines"] = max(
+ metrics.get("max_overfull_lines", 0),
+ pdf_result.metrics.get("max_overfull_lines", 0),
+ )
+ if "max_stranded_headings" in pdf_result.metrics:
+ metrics["max_stranded_headings"] = max(
+ metrics.get("max_stranded_headings", 0),
+ pdf_result.metrics.get("max_stranded_headings", 0),
+ )
+ for key in (
+ "max_caption_separation_incidents",
+ "max_list_break_incidents",
+ "max_heading_proximity_incidents",
+ "max_runt_final_page",
+ ):
+ if key in pdf_result.metrics:
+ metrics[key] = max(metrics.get(key, 0), pdf_result.metrics.get(key, 0))
+ incidents.extend(pdf_result.incidents)
+ warnings.extend(pdf_result.warnings)
+ analysis_mode = "html+pdf"
+ else:
+ warnings.extend(pdf_result.warnings or ["PDF analysis failed; HTML-only analysis used"])
+ else:
+ warnings.append("PDF not available; HTML-only analysis used")
+
+ layout = LayoutReport(
+ metrics=metrics,
+ incidents=incidents,
+ warnings=warnings,
+ profile_id=layout.profile_id,
+ analysis_mode=analysis_mode,
+ )
gates_all = spec.quality_gates.get("profiles", {}).get(str(args.profile))
if not gates_all:
print(json.dumps({"ok": False, "error": f"Missing quality gates for profile {args.profile}"}))
- return 4
+ return EXIT_CONFIG
gates = gates_all.get("strict" if args.strict else "default") or {}
qa_report = evaluate_gates(layout.metrics, gates, profile_id=str(args.profile), strict=args.strict)
qa_report["metrics"] = layout.metrics
layout_dict = layout_report_dict(layout)
- if not (out_dir / "render.pdf").exists():
- layout_dict.setdefault("warnings", []).append("PDF not available; HTML-only analysis used")
+ layout_dict.setdefault("inputs", {})["html"] = str(html_path.resolve())
+ if pdf_path.exists():
+ layout_dict.setdefault("inputs", {})["pdf"] = str(pdf_path.resolve())
_write_json(out_dir / "layout-report.json", layout_dict)
_write_json(out_dir / "qa-report.json", qa_report)
+ if args.format == "sarif":
+ _write_json(out_dir / "qa-report.sarif", _qa_to_sarif(layout_dict, qa_report))
print(json.dumps({"ok": qa_report.get("ok"), "out_dir": str(out_dir.resolve())}, indent=2, sort_keys=True))
- return 0 if qa_report.get("ok") else 2
+ return EXIT_OK if qa_report.get("ok") else EXIT_GATE_FAIL
def build_parser() -> argparse.ArgumentParser:
@@ -270,6 +806,7 @@ def build_parser() -> argparse.ArgumentParser:
prog="iftypeset",
description="Publication-quality typesetting runtime (spec tooling).",
)
+ parser.add_argument("--config", help="Path to iftypeset.yaml (defaults to ./iftypeset.yaml when present).")
parser.add_argument("--version", action="store_true", help="Print tool version and exit.")
sub = parser.add_subparsers(dest="command")
@@ -286,29 +823,121 @@ def build_parser() -> argparse.ArgumentParser:
report.add_argument("--build-indexes", action="store_true", help="Build and write indexes into spec/indexes/.")
report.set_defaults(func=_cmd_report)
+ doctor = sub.add_parser("doctor", help="Emit environment + determinism report.")
+ doctor.add_argument("--spec", default="spec", help="Spec root directory (default: ./spec).")
+ doctor.add_argument("--out", default="out", help="Output directory (default: ./out).")
+ doctor.set_defaults(func=_cmd_doctor)
+
+ bundle = sub.add_parser("bundle", help="Create a portable review bundle from out/ artifacts.")
+ bundle.add_argument("--out", default="out", help="Output directory (default: ./out).")
+ bundle.add_argument("--bundle", help="Bundle output path (default: /iftypeset-bundle.tar.gz).")
+ bundle.add_argument(
+ "--max-size-mb",
+ type=float,
+ default=50.0,
+ help="Skip artifacts larger than this size (default: 50).",
+ )
+ bundle.set_defaults(func=_cmd_bundle)
+
+ run = sub.add_parser("run", help="Run a CI-style pipeline: validate → lint → render → qa → report.")
+ run.add_argument("--spec", default="spec", help="Spec root directory (default: ./spec).")
+ run.add_argument("--input", required=True, help="Markdown file.")
+ run.add_argument("--out", default="out", help="Output directory (default: ./out).")
+ run.add_argument("--profile", help="Profile id (default: web_pdf or config).")
+ run.add_argument("--strict", action="store_true", help="Use strict QA/report thresholds.")
+ run.add_argument("--format", default="json", choices=["json", "sarif", "text"], help="Lint output format.")
+ run.add_argument("--fail-on", default="must", choices=["must", "should", "warn"], help="Lint fail threshold.")
+ run.add_argument("--degraded-ok", action="store_true", help="Allow degraded mode without failing.")
+ run.add_argument("--fix", action="store_true", help="Apply safe deterministic fixes.")
+ run.add_argument("--fix-mode", default="suggest", choices=["suggest", "rewrite"], help="Fix mode.")
+ run.add_argument(
+ "--lint-fixed",
+ action="store_true",
+ help="When rewriting fixes, lint the fixed output instead of the original.",
+ )
+ run.add_argument("--self-contained", action="store_true", help="Embed local images as data URIs.")
+ run.add_argument(
+ "--font-dir",
+ action="append",
+ default=[],
+ help="Additional font directory (e.g., corporate fonts); can be repeated.",
+ )
+ run.add_argument(
+ "--strict-fonts",
+ action="store_true",
+ help="Fail PDF rendering if primary profile fonts are missing or if PDF embeds fallback fonts.",
+ )
+ run.add_argument(
+ "--engine",
+ default="playwright",
+ type=_parse_engine_arg,
+ help="Preferred PDF engine (default: playwright; auto is treated as playwright; chromium is banned).",
+ )
+ run.add_argument(
+ "--require-pdf",
+ action="store_true",
+ help="Fail the run if PDF rendering fails.",
+ )
+ run.add_argument("--skip-pdf", action="store_true", help="Skip PDF rendering.")
+ run.set_defaults(func=_cmd_run)
+
emit_css = sub.add_parser("emit-css", help="Emit deterministic CSS for a given typeset profile.")
emit_css.add_argument("--spec", default="spec", help="Spec root directory (default: ./spec).")
- emit_css.add_argument("--profile", required=True, help="Profile id (e.g., web_pdf, print_pdf).")
+ emit_css.add_argument("--profile", help="Profile id (default: web_pdf or config).")
emit_css.add_argument("--out", default="out", help="Output directory (default: ./out).")
emit_css.set_defaults(func=_cmd_emit_css)
+ profiles = sub.add_parser("profiles", help="Inspect available profiles.")
+ profiles_sub = profiles.add_subparsers(dest="profiles_cmd", required=True)
+ profiles_list = profiles_sub.add_parser("list", help="List profiles in the current spec.")
+ profiles_list.add_argument("--spec", default="spec", help="Spec root directory (default: ./spec).")
+ profiles_list.set_defaults(func=_cmd_profiles_list)
+
+ gates = sub.add_parser("gates", help="Inspect QA gates.")
+ gates_sub = gates.add_subparsers(dest="gates_cmd", required=True)
+ gates_show = gates_sub.add_parser("show", help="Show QA gates for a profile.")
+ gates_show.add_argument("--spec", default="spec", help="Spec root directory (default: ./spec).")
+ gates_show.add_argument("--profile", help="Profile id (default: web_pdf or config).")
+ gates_show.add_argument("--strict", action="store_true", help="Use strict thresholds.")
+ gates_show.set_defaults(func=_cmd_gates_show)
+
+ rules = sub.add_parser("rules", help="Inspect rule registry.")
+ rules_sub = rules.add_subparsers(dest="rules_cmd", required=True)
+ rules_list = rules_sub.add_parser("list", help="List rules (optional filters).")
+ rules_list.add_argument("--spec", default="spec", help="Spec root directory (default: ./spec).")
+ rules_list.add_argument("--category", action="append", help="Filter by category.")
+ rules_list.add_argument("--enforcement", action="append", help="Filter by enforcement.")
+ rules_list.add_argument("--severity", action="append", help="Filter by severity.")
+ rules_list.add_argument("--tag", action="append", help="Filter by tag (can be repeated).")
+ rules_list.set_defaults(func=_cmd_rules_list)
+
+ rules_show = rules_sub.add_parser("show", help="Show a rule by id.")
+ rules_show.add_argument("rule_id", help="Rule identifier.")
+ rules_show.add_argument("--spec", default="spec", help="Spec root directory (default: ./spec).")
+ rules_show.set_defaults(func=_cmd_rules_show)
+
lint = sub.add_parser("lint", help="Run Markdown lint rules and emit diagnostics.")
lint.add_argument("--spec", default="spec", help="Spec root directory (default: ./spec).")
lint.add_argument("--input", required=True, help="Markdown file or directory.")
lint.add_argument("--out", default="out", help="Output directory (default: ./out).")
- lint.add_argument("--profile", required=True, help="Profile id.")
+ lint.add_argument("--profile", help="Profile id (default: web_pdf or config).")
lint.add_argument("--format", default="json", choices=["json", "sarif", "text"], help="Output format.")
lint.add_argument("--fail-on", default="must", choices=["must", "should", "warn"], help="Fail threshold.")
lint.add_argument("--degraded-ok", action="store_true", help="Allow degraded mode without failing.")
lint.add_argument("--fix", action="store_true", help="Apply safe deterministic fixes.")
lint.add_argument("--fix-mode", default="suggest", choices=["suggest", "rewrite"], help="Fix mode.")
+ lint.add_argument(
+ "--lint-fixed",
+ action="store_true",
+ help="When rewriting fixes, lint the fixed output instead of the original.",
+ )
lint.set_defaults(func=_cmd_lint)
render_html_cmd = sub.add_parser("render-html", help="Render Markdown to deterministic HTML + CSS.")
render_html_cmd.add_argument("--spec", default="spec", help="Spec root directory (default: ./spec).")
render_html_cmd.add_argument("--input", required=True, help="Markdown file.")
render_html_cmd.add_argument("--out", default="out", help="Output directory (default: ./out).")
- render_html_cmd.add_argument("--profile", required=True, help="Profile id.")
+ render_html_cmd.add_argument("--profile", help="Profile id (default: web_pdf or config).")
render_html_cmd.add_argument("--self-contained", action="store_true", help="Embed local images as data URIs.")
render_html_cmd.add_argument("--degraded-ok", action="store_true", help="Allow degraded mode without failing.")
render_html_cmd.set_defaults(func=_cmd_render_html)
@@ -317,15 +946,35 @@ def build_parser() -> argparse.ArgumentParser:
render_pdf_cmd.add_argument("--spec", default="spec", help="Spec root directory (default: ./spec).")
render_pdf_cmd.add_argument("--input", required=True, help="Markdown file.")
render_pdf_cmd.add_argument("--out", default="out", help="Output directory (default: ./out).")
- render_pdf_cmd.add_argument("--profile", required=True, help="Profile id.")
+ render_pdf_cmd.add_argument("--profile", help="Profile id (default: web_pdf or config).")
render_pdf_cmd.add_argument("--self-contained", action="store_true", help="Embed local images as data URIs.")
+ render_pdf_cmd.add_argument(
+ "--font-dir",
+ action="append",
+ default=[],
+ help="Additional font directory (e.g., corporate fonts); can be repeated.",
+ )
+ render_pdf_cmd.add_argument(
+ "--strict-fonts",
+ action="store_true",
+ help="Fail PDF rendering if primary profile fonts are missing or if PDF embeds fallback fonts.",
+ )
+ render_pdf_cmd.add_argument(
+ "--engine",
+ default="playwright",
+ type=_parse_engine_arg,
+ help="Preferred PDF engine (default: playwright; auto is treated as playwright; chromium is banned).",
+ )
render_pdf_cmd.set_defaults(func=_cmd_render_pdf)
qa = sub.add_parser("qa", help="Run post-render QA gates.")
qa.add_argument("--spec", default="spec", help="Spec root directory (default: ./spec).")
qa.add_argument("--out", default="out", help="Output directory (default: ./out).")
- qa.add_argument("--profile", required=True, help="Profile id.")
+ qa.add_argument("--html", help="HTML file to analyze (default: /render.html).")
+ qa.add_argument("--pdf", help="Optional PDF path for reporting (default: /render.pdf).")
+ qa.add_argument("--profile", help="Profile id (default: web_pdf or config).")
qa.add_argument("--strict", action="store_true", help="Use strict thresholds.")
+ qa.add_argument("--format", default="json", choices=["json", "sarif"], help="Output format.")
qa.set_defaults(func=_cmd_qa)
return parser
@@ -402,9 +1051,94 @@ def _to_sarif(report: dict[str, object]) -> dict[str, object]:
}
+def _qa_to_sarif(layout: dict[str, object], qa_report: dict[str, object]) -> dict[str, object]:
+ incidents = layout.get("incidents", []) or []
+ inputs = layout.get("inputs", {}) if isinstance(layout.get("inputs"), dict) else {}
+ html_uri = inputs.get("html")
+ pdf_uri = inputs.get("pdf")
+
+ results: list[dict[str, object]] = []
+
+ def _artifact_for_kind(kind: str) -> str | None:
+ if kind.endswith("_pdf"):
+ return pdf_uri or html_uri
+ return html_uri
+
+ for incident in incidents:
+ if not isinstance(incident, dict):
+ continue
+ kind = str(incident.get("kind") or "qa_incident")
+ rule_id = QA_RULE_MAP.get(kind, f"QA.{kind}")
+ detail = str(incident.get("detail") or kind)
+ context = str(incident.get("context") or "").strip()
+ message = detail if not context else f"{detail} ({context})"
+ artifact = _artifact_for_kind(kind)
+ locations = []
+ if artifact:
+ locations.append(
+ {
+ "physicalLocation": {
+ "artifactLocation": {"uri": artifact},
+ "region": {"startLine": 1},
+ }
+ }
+ )
+ results.append(
+ {
+ "ruleId": rule_id,
+ "level": "warning",
+ "message": {"text": message},
+ "locations": locations,
+ "properties": {"incident_kind": kind},
+ }
+ )
+
+ gates = qa_report.get("gates", {}) if isinstance(qa_report.get("gates"), dict) else {}
+ for metric, gate in gates.items():
+ if not isinstance(gate, dict):
+ continue
+ if gate.get("status") != "fail":
+ continue
+ count = gate.get("count")
+ maximum = gate.get("max")
+ rule_id = f"QA_GATE.{metric}"
+ message = f"QA gate failed: {metric} count {count} > max {maximum}"
+ locations = []
+ if html_uri:
+ locations.append(
+ {
+ "physicalLocation": {
+ "artifactLocation": {"uri": html_uri},
+ "region": {"startLine": 1},
+ }
+ }
+ )
+ results.append(
+ {
+ "ruleId": rule_id,
+ "level": "error",
+ "message": {"text": message},
+ "locations": locations,
+ "properties": {"metric": metric, "count": count, "max": maximum},
+ }
+ )
+
+ return {
+ "version": "2.1.0",
+ "$schema": "https://json.schemastore.org/sarif-2.1.0.json",
+ "runs": [
+ {
+ "tool": {"driver": {"name": "iftypeset", "version": __version__}},
+ "results": results,
+ }
+ ],
+ }
+
+
def main(argv: list[str] | None = None) -> None:
parser = build_parser()
- args = parser.parse_args(argv)
+ raw_argv = list(argv) if argv is not None else sys.argv[1:]
+ args = parser.parse_args(raw_argv)
if args.version:
print(
json.dumps(
@@ -420,10 +1154,15 @@ def main(argv: list[str] | None = None) -> None:
raise SystemExit(0)
if not getattr(args, "func", None):
parser.error("Command required")
+ try:
+ args = apply_config(args, raw_argv)
+ except Exception as exc:
+ print(json.dumps({"ok": False, "error": str(exc)}))
+ raise SystemExit(EXIT_CONFIG)
try:
rc = int(args.func(args))
except BrokenPipeError:
- rc = 1
+ rc = EXIT_CONFIG
raise SystemExit(rc)
diff --git a/src/iftypeset/config.py b/src/iftypeset/config.py
new file mode 100644
index 0000000..a3cd178
--- /dev/null
+++ b/src/iftypeset/config.py
@@ -0,0 +1,97 @@
+from __future__ import annotations
+
+from pathlib import Path
+from typing import Any
+
+import yaml
+
+
+def _argv_has_flag(argv: list[str], flag: str) -> bool:
+ prefix = f"{flag}="
+ return any(arg == flag or arg.startswith(prefix) for arg in argv)
+
+
+def _get_section(config: dict[str, Any], command: str | None) -> dict[str, Any]:
+ if not command:
+ return {}
+ key = command.replace("-", "_")
+ section = config.get(key)
+ if isinstance(section, dict):
+ return section
+ if key in {"render_html", "render_pdf"}:
+ section = config.get("render")
+ if isinstance(section, dict):
+ return section
+ return {}
+
+
+def find_config_path(spec_root: Path | None, cwd: Path, explicit: Path | None) -> Path | None:
+ if explicit:
+ return explicit
+ candidates: list[Path] = []
+ candidates.append(cwd / "iftypeset.yaml")
+ if spec_root is not None:
+ candidates.append(spec_root.parent / "iftypeset.yaml")
+ for path in candidates:
+ if path.exists():
+ return path
+ return None
+
+
+def load_config(path: Path | None) -> dict[str, Any]:
+ if not path:
+ return {}
+ if not path.exists():
+ raise ValueError(f"Config not found: {path}")
+ raw = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
+ if not isinstance(raw, dict):
+ raise ValueError("Config must be a mapping at the top level.")
+ return raw
+
+
+def apply_config(args: Any, argv: list[str]) -> Any:
+ spec_root = Path(getattr(args, "spec", "spec"))
+ explicit = Path(args.config) if getattr(args, "config", None) else None
+ config_path = find_config_path(spec_root if spec_root else None, Path.cwd(), explicit)
+ if not config_path:
+ if hasattr(args, "profile") and not getattr(args, "profile"):
+ setattr(args, "profile", "web_pdf")
+ return args
+ config = load_config(config_path)
+
+ defaults = config.get("defaults") if isinstance(config.get("defaults"), dict) else {}
+ section = _get_section(config, getattr(args, "command", None))
+
+ def get_value(key: str) -> Any:
+ if key in section:
+ return section.get(key)
+ return defaults.get(key)
+
+ def maybe_set(attr: str, flag: str, key: str) -> None:
+ if not hasattr(args, attr):
+ return
+ if _argv_has_flag(argv, flag):
+ return
+ value = get_value(key)
+ if value is not None:
+ setattr(args, attr, value)
+
+ maybe_set("spec", "--spec", "spec")
+ maybe_set("out", "--out", "out")
+ maybe_set("profile", "--profile", "profile")
+ maybe_set("strict", "--strict", "strict")
+ maybe_set("format", "--format", "format")
+ maybe_set("fail_on", "--fail-on", "fail_on")
+ maybe_set("degraded_ok", "--degraded-ok", "degraded_ok")
+ maybe_set("fix", "--fix", "fix")
+ maybe_set("fix_mode", "--fix-mode", "fix_mode")
+ maybe_set("lint_fixed", "--lint-fixed", "lint_fixed")
+ maybe_set("self_contained", "--self-contained", "self_contained")
+ maybe_set("engine", "--engine", "engine")
+ maybe_set("require_pdf", "--require-pdf", "require_pdf")
+ maybe_set("skip_pdf", "--skip-pdf", "skip_pdf")
+
+ if hasattr(args, "profile") and not getattr(args, "profile"):
+ setattr(args, "profile", get_value("profile") or "web_pdf")
+
+ return args
diff --git a/src/iftypeset/css_gen.py b/src/iftypeset/css_gen.py
index 13db100..e32c96e 100644
--- a/src/iftypeset/css_gen.py
+++ b/src/iftypeset/css_gen.py
@@ -2,6 +2,7 @@ from __future__ import annotations
from dataclasses import dataclass
from typing import Any
+import re
@dataclass(frozen=True)
@@ -17,12 +18,19 @@ def generate_profile_css(profile: dict[str, Any]) -> CssOutput:
page = profile.get("page") or {}
fonts = profile.get("fonts") or {}
+ colors = profile.get("colors") or {}
paragraphs = profile.get("paragraphs") or {}
hyphenation = profile.get("hyphenation") or {}
widows_orphans = profile.get("widows_orphans") or {}
headings = profile.get("headings") or {}
+ heading_sizes_cfg = headings.get("sizes") or {}
+ heading_spacing = headings.get("spacing") or {}
code = profile.get("code") or {}
tables = profile.get("tables") or {}
+ figures = profile.get("figures") or {}
+ typography = profile.get("typography") or {}
+ lists = profile.get("lists") or {}
+ layout = profile.get("layout") or {}
page_size = str(page.get("size") or "Letter")
orientation = str(page.get("orientation") or "portrait")
@@ -41,7 +49,15 @@ def generate_profile_css(profile: dict[str, Any]) -> CssOutput:
heading_family = _font_stack(heading_font.get("family") or [])
mono_family = _font_stack(mono_font.get("family") or [])
- body_size = str(body_font.get("size") or "11pt")
+ body_color = str(colors.get("body") or "#111827")
+ accent_color = str(colors.get("accent") or body_color)
+ heading_color = str(colors.get("heading") or accent_color)
+ link_color = str(colors.get("link") or accent_color)
+ citation_color = str(colors.get("citation") or link_color)
+ table_rule_color = str(colors.get("table_rule") or "#e5e7eb")
+ table_stripe_bg = str(colors.get("table_stripe") or "transparent")
+
+ body_size = str(body_font.get("size") or "12pt")
body_line_height = body_font.get("line_height") or 1.45
heading_size = str(heading_font.get("size") or body_size)
mono_size = str(mono_font.get("size") or "10pt")
@@ -50,6 +66,8 @@ def generate_profile_css(profile: dict[str, Any]) -> CssOutput:
indent = str(paragraphs.get("indent") or "0")
first_paragraph_indent = str(paragraphs.get("first_paragraph_indent") or "0")
block_spacing = str(paragraphs.get("block_paragraph_spacing") or "0")
+ density_overrides = layout.get("density_overrides") or {}
+ use_density_vars = bool(density_overrides)
hyphens_enabled = bool(hyphenation.get("enabled") or False)
widows = int(widows_orphans.get("widow_lines") or 2)
@@ -57,14 +75,71 @@ def generate_profile_css(profile: dict[str, Any]) -> CssOutput:
keep_with_next_lines = int(headings.get("keep_with_next_lines") or 2)
avoid_stranded = bool(headings.get("avoid_stranded_headings") or False)
+ heading_rule = headings.get("rule") or {}
+ heading_rule_enabled = bool(heading_rule.get("enabled") or False)
+ heading_rule_position = str(heading_rule.get("position") or "under")
+ heading_rule_thickness = str(heading_rule.get("thickness") or "1px")
+ heading_rule_color = str(heading_rule.get("color") or heading_color)
+ heading_rule_spacing = str(heading_rule.get("spacing") or "0.2em")
+ h1_size = str(heading_sizes_cfg.get("h1") or "1.8em")
+ h2_size = str(heading_sizes_cfg.get("h2") or "1.5em")
+ h3_size = str(heading_sizes_cfg.get("h3") or "1.25em")
+ h4_size = str(heading_sizes_cfg.get("h4") or "1.1em")
+ heading_margin_top = heading_spacing.get("top")
+ heading_margin_bottom = heading_spacing.get("bottom")
code_block = (code.get("block") or {}) if isinstance(code, dict) else {}
code_block_size = str(code_block.get("font_size") or mono_size)
code_block_line_height = code_block.get("line_height") or mono_line_height
code_block_wrap = bool(code_block.get("wrap") or False)
+ code_block_padding = str(code_block.get("padding") or "0.4em 0.6em")
+ code_block_background = str(code_block.get("background") or "transparent")
+ code_block_border = str(code_block.get("border") or "none")
+ code_block_radius = str(code_block.get("radius") or "0")
table_padding = str(tables.get("cell_padding") or "3pt 6pt")
table_header_repeat = bool(tables.get("header_repeat") or False)
+ table_layout = str(tables.get("layout") or "auto")
+ table_cell_wrap = bool(tables.get("cell_wrap") or False)
+ table_keep_together = bool(tables.get("keep_together") or False)
+ table_row_keep = bool(tables.get("row_keep_together") or False)
+ table_header_align = str(tables.get("header_align") or "left")
+ table_cell_align = str(tables.get("cell_align") or "left")
+ table_numeric_align = str(tables.get("numeric_align") or "right")
+ table_boolean_align = str(tables.get("boolean_align") or "center")
+ table_grid_style = str(tables.get("grid_style") or "boxed")
+
+ figure_max_width = str(figures.get("max_width") or "100%")
+ figure_margin = str(figures.get("margin") or "0.6em auto")
+
+ small_caps_cfg = typography.get("small_caps_acronyms") or {}
+ if isinstance(small_caps_cfg, dict):
+ small_caps_enabled = bool(small_caps_cfg.get("enabled") or False)
+ small_caps_tracking = str(small_caps_cfg.get("letter_spacing") or "0.04em")
+ else:
+ small_caps_enabled = bool(small_caps_cfg)
+ small_caps_tracking = "0.04em"
+
+ drop_caps_cfg = typography.get("drop_caps") or {}
+ drop_caps_enabled = bool(drop_caps_cfg.get("enabled") or False)
+ drop_caps_size = str(drop_caps_cfg.get("size") or "2.8em")
+ drop_caps_padding_right = str(drop_caps_cfg.get("padding_right") or "0.08em")
+ drop_caps_padding_top = str(drop_caps_cfg.get("padding_top") or "0.02em")
+ drop_caps_weight = str(drop_caps_cfg.get("weight") or "").strip()
+ text_wrap_cfg = typography.get("text_wrap") or {}
+ body_text_wrap = str(text_wrap_cfg.get("body") or "").strip()
+ heading_text_wrap = str(text_wrap_cfg.get("headings") or "").strip()
+
+ hanging_cfg = lists.get("hanging_punctuation") or {}
+ list_text_wrap = str(lists.get("text_wrap") or "").strip()
+ if isinstance(hanging_cfg, dict):
+ hanging_enabled = bool(hanging_cfg.get("enabled") or False)
+ hanging_indent = str(hanging_cfg.get("indent") or "1.2em")
+ hanging_hang = str(hanging_cfg.get("hang") or "0.4em")
+ else:
+ hanging_enabled = bool(hanging_cfg)
+ hanging_indent = str(lists.get("indent") or "1.2em")
+ hanging_hang = str(lists.get("hang") or "0.4em")
# Build CSS deterministically.
css: list[str] = []
@@ -79,6 +154,27 @@ def generate_profile_css(profile: dict[str, Any]) -> CssOutput:
css.append(f" --if-body-size: {body_size};")
css.append(f" --if-heading-size: {heading_size};")
css.append(f" --if-mono-size: {mono_size};")
+ css.append(f" --if-body-color: {body_color};")
+ css.append(f" --if-accent-color: {accent_color};")
+ css.append(f" --if-heading-color: {heading_color};")
+ css.append(f" --if-link-color: {link_color};")
+ css.append(f" --if-citation-color: {citation_color};")
+ css.append(f" --if-table-rule-color: {table_rule_color};")
+ css.append(f" --if-table-stripe-bg: {table_stripe_bg};")
+ css.append(f" --if-small-caps-tracking: {small_caps_tracking};")
+ css.append(f" --if-code-block-padding: {code_block_padding};")
+ css.append(f" --if-code-block-bg: {code_block_background};")
+ css.append(f" --if-code-block-border: {code_block_border};")
+ css.append(f" --if-code-block-radius: {code_block_radius};")
+ css.append(f" --if-figure-max-width: {figure_max_width};")
+ css.append(f" --if-figure-margin: {figure_margin};")
+ if use_density_vars:
+ css.append(f" --if-body-line-height: {body_line_height};")
+ css.append(f" --if-paragraph-spacing: {block_spacing};")
+ if heading_margin_top:
+ css.append(f" --if-heading-margin-top: {heading_margin_top};")
+ if heading_margin_bottom:
+ css.append(f" --if-heading-margin-bottom: {heading_margin_bottom};")
css.append("}")
css.append("")
@@ -111,23 +207,64 @@ def generate_profile_css(profile: dict[str, Any]) -> CssOutput:
css.append("body {")
css.append(" font-family: var(--if-body-font);")
css.append(f" font-size: var(--if-body-size);")
- css.append(f" line-height: {body_line_height};")
- css.append(" color: #111827;")
+ if use_density_vars:
+ css.append(" line-height: var(--if-body-line-height);")
+ else:
+ css.append(f" line-height: {body_line_height};")
+ if body_text_wrap:
+ css.append(f" text-wrap: {body_text_wrap};")
+ css.append(" color: var(--if-body-color);")
css.append("}")
css.append("")
+ if use_density_vars:
+ for name, cfg in density_overrides.items():
+ if not isinstance(cfg, dict):
+ continue
+ line_height = cfg.get("body_line_height")
+ spacing = cfg.get("paragraph_spacing")
+ heading_top = cfg.get("heading_margin_top")
+ heading_bottom = cfg.get("heading_margin_bottom")
+ if not line_height and not spacing and not heading_top and not heading_bottom:
+ continue
+ css.append(f"body.if-density-{name} {{")
+ if line_height:
+ css.append(f" --if-body-line-height: {line_height};")
+ if spacing:
+ css.append(f" --if-paragraph-spacing: {spacing};")
+ if heading_top:
+ css.append(f" --if-heading-margin-top: {heading_top};")
+ if heading_bottom:
+ css.append(f" --if-heading-margin-bottom: {heading_bottom};")
+ css.append("}")
+ css.append("")
css.append("h1, h2, h3, h4, h5, h6 {")
css.append(" font-family: var(--if-heading-font);")
css.append(" font-weight: 650;")
- css.append(" break-after: avoid;")
+ css.append(" color: var(--if-heading-color);")
+ if heading_text_wrap:
+ css.append(f" text-wrap: {heading_text_wrap};")
+ css.append(" break-after: avoid-page;")
+ css.append(" page-break-after: avoid;")
if avoid_stranded:
css.append(" break-inside: avoid;")
+ if use_density_vars:
+ if heading_margin_top:
+ css.append(" margin-top: var(--if-heading-margin-top);")
+ if heading_margin_bottom:
+ css.append(" margin-bottom: var(--if-heading-margin-bottom);")
+ else:
+ if heading_margin_top:
+ css.append(f" margin-top: {heading_margin_top};")
+ if heading_margin_bottom:
+ css.append(f" margin-bottom: {heading_margin_bottom};")
css.append("}")
css.append("")
- css.append("h1 { font-size: 1.8em; }")
- css.append("h2 { font-size: 1.5em; }")
- css.append("h3 { font-size: 1.25em; }")
+ css.append(f"h1 {{ font-size: {h1_size}; }}")
+ css.append(f"h2 {{ font-size: {h2_size}; }}")
+ css.append(f"h3 {{ font-size: {h3_size}; }}")
+ css.append(f"h4 {{ font-size: {h4_size}; }}")
css.append("")
css.append("p {")
@@ -137,12 +274,53 @@ def generate_profile_css(profile: dict[str, Any]) -> CssOutput:
css.append(f" orphans: {orphans};")
if indent != "0":
css.append(f" text-indent: {indent};")
- if block_spacing != "0":
+ if use_density_vars:
+ css.append(" margin-top: var(--if-paragraph-spacing);")
+ css.append(" margin-bottom: var(--if-paragraph-spacing);")
+ elif block_spacing != "0":
css.append(f" margin-top: {block_spacing};")
css.append(f" margin-bottom: {block_spacing};")
css.append("}")
css.append("")
+ css.append("li {")
+ css.append(" break-inside: avoid;")
+ css.append(" page-break-inside: avoid;")
+ if hanging_enabled:
+ css.append(f" text-indent: -{hanging_hang};")
+ css.append(f" padding-left: {hanging_hang};")
+ if list_text_wrap:
+ css.append(f" text-wrap: {list_text_wrap};")
+ if hyphens_enabled:
+ css.append(" hyphens: auto;")
+ css.append("}")
+ css.append("")
+ if hanging_enabled:
+ css.append("ul {")
+ css.append(" list-style-position: outside;")
+ css.append(f" padding-left: {hanging_indent};")
+ css.append("}")
+ css.append("")
+
+ css.append("a {")
+ css.append(" color: var(--if-link-color);")
+ css.append(" text-decoration: underline;")
+ css.append(" text-underline-offset: 0.12em;")
+ css.append("}")
+ css.append("")
+ css.append(".if-citation {")
+ css.append(" color: var(--if-citation-color);")
+ css.append(" font-weight: 600;")
+ css.append(" white-space: nowrap;")
+ css.append("}")
+ css.append("")
+ if small_caps_enabled:
+ css.append(".if-sc {")
+ css.append(" font-variant-caps: all-small-caps;")
+ css.append(" letter-spacing: var(--if-small-caps-tracking);")
+ css.append("}")
+ css.append("")
+
# First paragraph in a section: no indent when configured.
if first_paragraph_indent == "0" and indent != "0":
css.append("main > p:first-of-type, section > p:first-of-type {")
@@ -160,6 +338,11 @@ def generate_profile_css(profile: dict[str, Any]) -> CssOutput:
css.append("pre {")
css.append(f" font-size: {code_block_size};")
css.append(f" line-height: {code_block_line_height};")
+ css.append(" max-width: 100%;")
+ css.append(" padding: var(--if-code-block-padding);")
+ css.append(" background: var(--if-code-block-bg);")
+ css.append(" border: var(--if-code-block-border);")
+ css.append(" border-radius: var(--if-code-block-radius);")
css.append(" white-space: pre;")
if code_block_wrap:
css.append(" white-space: pre-wrap;")
@@ -172,17 +355,77 @@ def generate_profile_css(profile: dict[str, Any]) -> CssOutput:
css.append("table {")
css.append(" border-collapse: collapse;")
css.append(" width: 100%;")
+ css.append(f" table-layout: {table_layout};")
+ if table_keep_together:
+ css.append(" break-inside: avoid;")
+ css.append(" page-break-inside: avoid;")
css.append("}")
css.append("")
css.append("th, td {")
css.append(f" padding: {table_padding};")
- css.append(" border: 1px solid #e5e7eb;")
+ if table_grid_style in {"rules", "rules_minimal"}:
+ css.append(" border: none;")
+ if table_grid_style == "rules":
+ css.append(" border-bottom: 1px solid var(--if-table-rule-color);")
+ else:
+ css.append(" border: 1px solid var(--if-table-rule-color);")
css.append(" vertical-align: top;")
+ if table_cell_wrap:
+ css.append(" overflow-wrap: anywhere;")
+ css.append(" word-break: break-word;")
css.append("}")
css.append("")
+ if table_grid_style in {"rules", "rules_minimal"}:
+ header_top = "1.5px"
+ header_bottom = "1.5px"
+ tail_bottom = "1.5px"
+ if table_grid_style == "rules_minimal":
+ header_bottom = "0.5px"
+ css.append("thead th {")
+ css.append(f" border-top: {header_top} solid var(--if-table-rule-color);")
+ css.append(f" border-bottom: {header_bottom} solid var(--if-table-rule-color);")
+ css.append(" background: var(--if-table-stripe-bg);")
+ css.append("}")
+ css.append("")
+ css.append("tbody tr:last-child td {")
+ css.append(f" border-bottom: {tail_bottom} solid var(--if-table-rule-color);")
+ css.append("}")
+ css.append("")
+ css.append(f"th {{ text-align: {table_header_align}; }}")
+ css.append(f"td {{ text-align: {table_cell_align}; }}")
+ css.append(f".if-num {{ text-align: {table_numeric_align}; font-variant-numeric: tabular-nums; }}")
+ css.append(f".if-bool {{ text-align: {table_boolean_align}; }}")
+ css.append("")
+ css.append("tbody tr:nth-child(even) {")
+ css.append(" background: var(--if-table-stripe-bg);")
+ css.append("}")
+ css.append("")
+ if table_row_keep:
+ css.append("tr, th, td {")
+ css.append(" break-inside: avoid;")
+ css.append(" page-break-inside: avoid;")
+ css.append("}")
+ css.append("")
if table_header_repeat:
css.append("thead { display: table-header-group; }")
css.append("")
+ css.append("figure.if-figure {")
+ css.append(" margin: var(--if-figure-margin);")
+ css.append(" break-inside: avoid;")
+ css.append(" page-break-inside: avoid;")
+ css.append("}")
+ css.append("")
+ css.append("figure.if-figure img {")
+ css.append(" display: block;")
+ css.append(" max-width: var(--if-figure-max-width);")
+ css.append(" height: auto;")
+ css.append("}")
+ css.append("")
+ css.append("img {")
+ css.append(" max-width: 100%;")
+ css.append(" height: auto;")
+ css.append("}")
+ css.append("")
# Approximation: keep headings with at least N following lines by avoiding breaks after heading.
# CSS cannot express "keep_with_next_lines" precisely; this is a pragmatic guard.
@@ -192,6 +435,120 @@ def generate_profile_css(profile: dict[str, Any]) -> CssOutput:
css.append("}")
css.append("")
+ if heading_rule_enabled:
+ selector = "h1, h2" if heading_rule_position == "under" else "h1, h2"
+ css.append(f"{selector} {{")
+ if heading_rule_position == "over":
+ css.append(f" border-top: {heading_rule_thickness} solid {heading_rule_color};")
+ css.append(f" padding-top: {heading_rule_spacing};")
+ else:
+ css.append(f" border-bottom: {heading_rule_thickness} solid {heading_rule_color};")
+ css.append(f" padding-bottom: {heading_rule_spacing};")
+ css.append("}")
+ css.append("")
+ if drop_caps_enabled:
+ selector = (
+ "main > p:first-of-type::first-letter, "
+ "h1 + p::first-letter, "
+ "h2 + p::first-letter, "
+ "h3 + p::first-letter"
+ )
+ css.append(f"{selector} {{")
+ css.append(" float: left;")
+ css.append(" line-height: 1;")
+ css.append(f" font-size: {drop_caps_size};")
+ css.append(f" padding-right: {drop_caps_padding_right};")
+ css.append(f" padding-top: {drop_caps_padding_top};")
+ if drop_caps_weight:
+ css.append(f" font-weight: {drop_caps_weight};")
+ css.append("}")
+ css.append("")
+
+ section_overrides = layout.get("section_overrides") or {}
+ for key, cfg in section_overrides.items():
+ if not isinstance(cfg, dict):
+ continue
+ slug = _slugify(str(key))
+ if not slug:
+ continue
+ selector = f".if-section-{slug}"
+ content_max_width = cfg.get("content_max_width")
+ content_margin_left = cfg.get("content_margin_left")
+ content_margin_right = cfg.get("content_margin_right")
+ content_padding_left = cfg.get("content_padding_left")
+ content_padding_right = cfg.get("content_padding_right")
+ list_max_width = cfg.get("list_max_width")
+ list_padding_right = cfg.get("list_padding_right")
+ list_padding_left = cfg.get("list_padding_left")
+ list_margin_left = cfg.get("list_margin_left")
+ list_margin_right = cfg.get("list_margin_right")
+ item_width = cfg.get("list_item_width")
+ item_max_width = cfg.get("list_item_max_width")
+ item_padding_right = cfg.get("list_item_padding_right")
+ item_padding_left = cfg.get("list_item_padding_left")
+ item_margin_left = cfg.get("list_item_margin_left")
+ item_margin_right = cfg.get("list_item_margin_right")
+ if (
+ content_max_width
+ or content_margin_left
+ or content_margin_right
+ or content_padding_left
+ or content_padding_right
+ ):
+ targets = f"{selector} > :not(h2)"
+ css.append(f"{targets} {{")
+ if content_max_width:
+ css.append(f" max-width: {content_max_width};")
+ if content_margin_left:
+ css.append(f" margin-left: {content_margin_left};")
+ if content_margin_right:
+ css.append(f" margin-right: {content_margin_right};")
+ if content_padding_left:
+ css.append(f" padding-left: {content_padding_left};")
+ if content_padding_right:
+ css.append(f" padding-right: {content_padding_right};")
+ css.append("}")
+ css.append("")
+ if list_max_width or list_padding_right or list_padding_left or list_margin_left or list_margin_right:
+ targets = f"{selector} ul, {selector} ol"
+ css.append(f"{targets} {{")
+ if list_max_width:
+ css.append(f" max-width: {list_max_width};")
+ if list_padding_left:
+ css.append(f" padding-left: {list_padding_left};")
+ if list_padding_right:
+ css.append(f" padding-right: {list_padding_right};")
+ if list_margin_left:
+ css.append(f" margin-left: {list_margin_left};")
+ if list_margin_right:
+ css.append(f" margin-right: {list_margin_right};")
+ css.append("}")
+ css.append("")
+ if (
+ item_width
+ or item_max_width
+ or item_padding_right
+ or item_padding_left
+ or item_margin_left
+ or item_margin_right
+ ):
+ targets = f"{selector} li"
+ css.append(f"{targets} {{")
+ if item_width:
+ css.append(f" width: {item_width};")
+ if item_max_width:
+ css.append(f" max-width: {item_max_width};")
+ if item_padding_left:
+ css.append(f" padding-left: {item_padding_left};")
+ if item_padding_right:
+ css.append(f" padding-right: {item_padding_right};")
+ if item_margin_left:
+ css.append(f" margin-left: {item_margin_left};")
+ if item_margin_right:
+ css.append(f" margin-right: {item_margin_right};")
+ css.append("}")
+ css.append("")
+
report = {
"profile_id": profile_id,
"page": {
@@ -205,8 +562,55 @@ def generate_profile_css(profile: dict[str, Any]) -> CssOutput:
"heading": {"family": heading_family, "size": heading_size},
"mono": {"family": mono_family, "size": mono_size, "line_height": mono_line_height},
},
+ "colors": {
+ "body": body_color,
+ "accent": accent_color,
+ "heading": heading_color,
+ "link": link_color,
+ "citation": citation_color,
+ "table_rule": table_rule_color,
+ "table_stripe": table_stripe_bg,
+ },
"hyphenation": {"enabled": hyphens_enabled},
"widows_orphans": {"widows": widows, "orphans": orphans},
+ "code": {
+ "block": {
+ "font_size": code_block_size,
+ "line_height": code_block_line_height,
+ "wrap": code_block_wrap,
+ "padding": code_block_padding,
+ "background": code_block_background,
+ "border": code_block_border,
+ "radius": code_block_radius,
+ }
+ },
+ "tables": {
+ "cell_padding": table_padding,
+ "header_repeat": table_header_repeat,
+ "layout": table_layout,
+ "grid_style": table_grid_style,
+ "keep_together": table_keep_together,
+ "row_keep_together": table_row_keep,
+ },
+ "figures": {"max_width": figure_max_width, "margin": figure_margin},
+ "typography": {
+ "small_caps_acronyms": {
+ "enabled": small_caps_enabled,
+ "letter_spacing": small_caps_tracking,
+ },
+ "drop_caps": {
+ "enabled": drop_caps_enabled,
+ "size": drop_caps_size,
+ "weight": drop_caps_weight or "inherit",
+ },
+ },
+ "lists": {
+ "hanging_punctuation": {
+ "enabled": hanging_enabled,
+ "indent": hanging_indent,
+ "hang": hanging_hang,
+ }
+ },
}
return CssOutput(css="\n".join(css).rstrip() + "\n", report=report)
@@ -240,3 +644,9 @@ def _font_stack(family: list[Any]) -> str:
else:
parts.append(s)
return ", ".join(parts) if parts else "serif"
+
+
+def _slugify(value: str) -> str:
+ slug = re.sub(r"[^a-z0-9\\s-]", "", value.lower())
+ slug = re.sub(r"\\s+", "-", slug.strip())
+ return slug
diff --git a/src/iftypeset/linting.py b/src/iftypeset/linting.py
index f784d28..a2615e4 100644
--- a/src/iftypeset/linting.py
+++ b/src/iftypeset/linting.py
@@ -3,8 +3,12 @@ from __future__ import annotations
from dataclasses import asdict, dataclass
from datetime import datetime, timezone
from pathlib import Path
+import ipaddress
import re
from typing import Any
+from urllib.parse import parse_qs, urlparse
+
+import yaml
from iftypeset import __version__
from iftypeset.md_parser import MdDocument, code_fence_lines, parse_markdown, read_markdown
@@ -52,6 +56,7 @@ def lint_paths(
*,
fix: bool = False,
fix_mode: str = "suggest",
+ lint_fixed: bool = False,
degraded_ok: bool = False,
fail_on: str = "must",
) -> LintResult:
@@ -67,12 +72,15 @@ def lint_paths(
if reasons:
degraded[str(path)] = reasons
- diagnostics.extend(_lint_document(doc))
if fix:
fixed_text, applied = apply_fixes(raw_text, fix_mode=fix_mode)
if applied:
fixes.extend(applied)
fixed_outputs[str(path)] = fixed_text
+ if fix_mode == "rewrite" and lint_fixed:
+ doc = parse_markdown(path, fixed_text)
+
+ diagnostics.extend(_lint_document(doc))
report = _build_report(
diagnostics=diagnostics,
@@ -90,6 +98,8 @@ def lint_paths(
def manual_checklist(spec: LoadedSpec) -> list[dict[str, Any]]:
items: list[dict[str, Any]] = []
for rule in spec.rules:
+ if str(rule.raw.get("status", "active")) != "active":
+ continue
tags = [str(t) for t in (rule.raw.get("tags") or [])]
if "manual_checklist=true" not in tags:
continue
@@ -114,6 +124,13 @@ def apply_fixes(text: str, *, fix_mode: str) -> tuple[str, list[LintFix]]:
new_lines, trailing_count = _strip_trailing_whitespace(lines, fenced)
new_lines, link_count = _normalize_link_spacing(new_lines, fenced)
+ new_lines, sentence_space_count = _normalize_sentence_spacing(new_lines, fenced)
+ new_lines, colon_space_count = _normalize_colon_spacing(new_lines, fenced)
+ new_lines, em_dash_count = _normalize_em_dashes(new_lines, fenced)
+ new_lines, leading_zero_count = _normalize_leading_zero_decimals(new_lines, fenced)
+ new_lines, decade_plural_count = _normalize_decade_plurals(new_lines, fenced)
+ new_lines, link_trailing_punct_count = _normalize_markdown_link_trailing_punct(new_lines, fenced)
+ new_lines, smart_quotes_count = _normalize_smart_quotes(new_lines, fenced)
fixes: list[LintFix] = []
if trailing_count:
@@ -134,6 +151,69 @@ def apply_fixes(text: str, *, fix_mode: str) -> tuple[str, list[LintFix]]:
mode=fix_mode,
)
)
+ if sentence_space_count:
+ fixes.append(
+ LintFix(
+ code="TYPO.SENTENCE_SPACE",
+ description="Normalize sentence spacing to single spaces",
+ count=sentence_space_count,
+ mode=fix_mode,
+ )
+ )
+ if colon_space_count:
+ fixes.append(
+ LintFix(
+ code="PUNCT.COLON_SPACE",
+ description="Normalize spaces after colons",
+ count=colon_space_count,
+ mode=fix_mode,
+ )
+ )
+ if em_dash_count:
+ fixes.append(
+ LintFix(
+ code="PUNCT.EM_DASH",
+ description="Normalize em dash formatting (US style)",
+ count=em_dash_count,
+ mode=fix_mode,
+ )
+ )
+ if leading_zero_count:
+ fixes.append(
+ LintFix(
+ code="NUM.LEADING_ZERO",
+ description="Add leading zero to decimals < 1",
+ count=leading_zero_count,
+ mode=fix_mode,
+ )
+ )
+ if decade_plural_count:
+ fixes.append(
+ LintFix(
+ code="NUM.DECADE_PLURAL",
+ description="Normalize decade plurals (no apostrophe)",
+ count=decade_plural_count,
+ mode=fix_mode,
+ )
+ )
+ if link_trailing_punct_count:
+ fixes.append(
+ LintFix(
+ code="LINK.TRAILING_PUNCT",
+ description="Move trailing punctuation outside Markdown link targets",
+ count=link_trailing_punct_count,
+ mode=fix_mode,
+ )
+ )
+ if smart_quotes_count:
+ fixes.append(
+ LintFix(
+ code="PUNCT.SMART_QUOTES",
+ description="Convert straight quotes to typographic quotes",
+ count=smart_quotes_count,
+ mode=fix_mode,
+ )
+ )
out_text = "\n".join(new_lines)
if text.endswith("\n"):
@@ -175,10 +255,28 @@ def _lint_document(doc: MdDocument) -> list[LintDiagnostic]:
diagnostics: list[LintDiagnostic] = []
lines = doc.normalized_source.splitlines()
fenced = code_fence_lines(doc.normalized_source)
+ masked_lines: list[str] = []
+ link_keys: set[str] = set()
+ file_ignores = _parse_front_matter_ignore(doc.normalized_source)
+ line_ignores = _collect_line_ignores(doc.normalized_source, fenced)
+ reference_ranges = _reference_section_ranges(doc.blocks, len(lines))
+
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ masked_lines.append(line)
+ continue
+ masked = _mask_inline_code(line)
+ masked_lines.append(masked)
+ for _label, url, _start, _end in _iter_markdown_link_spans(masked):
+ link_keys.add(_canonical_link_key(url))
for idx, line in enumerate(lines, start=1):
if idx in fenced:
continue
+ clean = _strip_inline_code(line)
+ clean_no_links = _strip_markdown_links(clean)
+ masked = masked_lines[idx - 1]
+
if line.rstrip() != line:
diagnostics.append(
LintDiagnostic(
@@ -190,51 +288,596 @@ def _lint_document(doc: MdDocument) -> list[LintDiagnostic]:
column=len(line),
)
)
+ if re.match(r"^\s*(?:[-*+]\s*|\d+\.\s*)$", line):
+ diagnostics.append(
+ LintDiagnostic(
+ code="A11Y.LIST_EMPTY_ITEM",
+ message="Avoid empty list items",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=1,
+ rule_id="HOUSE.ACCESSIBILITY.LISTS.NO_EMPTY_ITEMS",
+ )
+ )
- for block in doc.blocks:
- if block.type in {"paragraph", "blockquote"}:
- if re.search(r"\S \S", block.text):
+ if _has_double_sentence_space(clean):
+ diagnostics.append(
+ LintDiagnostic(
+ code="TYPO.SENTENCE_SPACE",
+ message="Use a single space between sentences",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=1,
+ rule_id="BRING.TYPOGRAPHY.SPACING.SENTENCE_SPACE.SINGLE",
+ )
+ )
+ if _colon_spacing_violation(clean):
+ diagnostics.append(
+ LintDiagnostic(
+ code="PUNCT.COLON_SPACE",
+ message="Use a single space after a colon in prose",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=1,
+ rule_id="CMOS.PUNCTUATION.COLONS.SPACE_AFTER",
+ )
+ )
+ if re.search(r"\s—\s|\s--\s", clean):
+ diagnostics.append(
+ LintDiagnostic(
+ code="PUNCT.EM_DASH",
+ message="Use em dashes without surrounding spaces (US style)",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=1,
+ rule_id="CMOS.PUNCTUATION.DASHES.EM_DASH.USE_WITHOUT_SPACES_US",
+ )
+ )
+ if '"' in clean:
+ diagnostics.append(
+ LintDiagnostic(
+ code="PUNCT.SMART_QUOTES",
+ message="Use typographic quotation marks (avoid straight double quotes)",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=clean.find('"') + 1,
+ rule_id="CMOS.PUNCTUATION.QUOTES.SMART_QUOTES",
+ )
+ )
+ if "file://" in clean:
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.FILE_URI",
+ message="file:// links are not allowed in published outputs",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=clean.find("file://") + 1,
+ rule_id="HOUSE.LINKS.DISALLOW.FILE_URIS",
+ )
+ )
+ js_match = re.search(r"\bjavascript\s*:", clean, flags=re.IGNORECASE)
+ if js_match:
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.JAVASCRIPT_URI",
+ message="javascript: links are not allowed",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=js_match.start() + 1,
+ rule_id="HOUSE.LINKS.DISALLOW.JAVASCRIPT_URIS",
+ )
+ )
+ if re.search(r"https?://(?:localhost|127\.0\.0\.1|0\.0\.0\.0)(?:\b|/)", clean, flags=re.IGNORECASE):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.LOCALHOST",
+ message="Do not publish localhost/loopback links",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=1,
+ rule_id="HOUSE.LINKS.URLS.DISALLOW.LOCALHOST",
+ )
+ )
+ if _contains_zero_width(clean):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.ZERO_WIDTH",
+ message="Zero-width characters detected (can break or disguise links)",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=1,
+ rule_id="HOUSE.LINKS.URLS.NO_ZERO_WIDTH",
+ )
+ )
+ if re.search(r"(? 1 and not _prior_heading_level(doc, block.level, block.start_line):
+
+ todo_match = re.search(r"\b(?:TODO|FIXME)\b", clean, flags=re.IGNORECASE)
+ if todo_match:
+ diagnostics.append(
+ LintDiagnostic(
+ code="EDITORIAL.TODO_FIXME",
+ message="Remove TODO/FIXME markers before publishing",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=todo_match.start() + 1,
+ rule_id="HOUSE.EDITORIAL.PLACEHOLDERS.NO_TODO_FIXME",
+ )
+ )
+ tbd_match = re.search(r"\b(?:TBD|TKTK)\b", clean, flags=re.IGNORECASE)
+ if tbd_match:
+ diagnostics.append(
+ LintDiagnostic(
+ code="EDITORIAL.TBD_TKTK",
+ message="Remove TBD/TKTK placeholders before publishing",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=tbd_match.start() + 1,
+ rule_id="HOUSE.EDITORIAL.PLACEHOLDERS.NO_TBD_TKTK",
+ )
+ )
+ lorem_match = re.search(r"lorem\s+ipsum", clean, flags=re.IGNORECASE)
+ if lorem_match:
+ diagnostics.append(
+ LintDiagnostic(
+ code="EDITORIAL.LOREM_IPSUM",
+ message="Avoid lorem ipsum placeholder text",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=lorem_match.start() + 1,
+ rule_id="HOUSE.EDITORIAL.PLACEHOLDERS.NO_LOREM_IPSUM",
+ )
+ )
+
+ for m in re.finditer(r"\b10\.\d{4,9}/[^\s\])>]+", clean_no_links, flags=re.IGNORECASE):
+ prefix = clean_no_links[max(0, m.start() - 20) : m.start()].lower()
+ if prefix.endswith(("doi.org/", "dx.doi.org/")):
+ continue
+ diagnostics.append(
+ LintDiagnostic(
+ code="CITATION.DOI_PREFERRED",
+ message="Prefer canonical doi.org links for DOI references",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=m.start() + 1,
+ rule_id="CMOS.CITATIONS.DOI.PREFERRED_OVER_URL",
+ )
+ )
+
+ for label, url, col in _iter_markdown_links(clean):
+ if re.search(r"\s", url):
diagnostics.append(
LintDiagnostic(
- code="HEADING.SKIP",
- message="Heading level skips a level",
+ code="LINK.URL_WHITESPACE",
+ message="Whitespace in Markdown link target",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.URLS.NO_WHITESPACE",
+ )
+ )
+ if re.match(r"https?://", url, flags=re.IGNORECASE) and url.endswith((".", ",", ";", ":")):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.TRAILING_PUNCT",
+ message="Trailing punctuation should not be inside link URLs",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.PUNCTUATION.NO_TRAILING_PUNCT",
+ )
+ )
+ if re.match(r"http://", url, flags=re.IGNORECASE):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.PREFER_HTTPS",
+ message="Prefer HTTPS URLs when available",
severity="should",
path=str(doc.path),
- line=block.start_line,
- column=1,
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.URLS.PREFER_HTTPS",
)
)
- if block.type == "table":
- if not any(h for h in block.headers):
+ if "\\" in url:
diagnostics.append(
LintDiagnostic(
- code="TABLE.HEADER.MISSING",
- message="Table header row is empty",
- severity="warn",
+ code="LINK.URL_BACKSLASH",
+ message="Avoid backslashes in URLs",
+ severity="should",
path=str(doc.path),
- line=block.start_line,
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.URLS.NO_BACKSLASH",
+ )
+ )
+ if url.lower().startswith("ftp://"):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.FTP",
+ message="Avoid ftp: links in published docs",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.AUTO.FTP.AVOID",
+ )
+ )
+ if _url_has_embedded_credentials(url):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.CREDENTIALS",
+ message="Do not embed credentials in URLs",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.AUTO.EMBEDDED_CREDENTIALS.AVOID",
+ )
+ )
+ if url.startswith("//"):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.PROTOCOL_RELATIVE",
+ message="Avoid protocol-relative URLs; use explicit https://",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.URLS.NO_PROTOCOL_RELATIVE",
+ )
+ )
+ if re.search(r"dx\.doi\.org/", url, flags=re.IGNORECASE) or url.lower().startswith("http://doi.org/"):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.DOI_CANONICAL",
+ message="Prefer canonical https://doi.org/ DOI links",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.URLS.DOIS.PREFER_DOI_ORG",
+ )
+ )
+ if _has_text_fragment(url):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.TEXT_FRAGMENT",
+ message="Avoid text-fragment URLs in published links",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.URLS.AVOID.TEXT_FRAGMENTS",
+ )
+ )
+ if _url_has_signed_params(url):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.EXPIRING_SIGNED",
+ message="Avoid expiring signed URLs in published docs",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.URLS.AVOID.EXPIRING_SIGNED",
+ )
+ )
+ if _url_has_tracking_params(url):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.TRACKING_PARAMS",
+ message="Avoid tracking parameters in published URLs",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.AUTO.TRACKING_PARAMS.AVOID",
+ )
+ )
+ if _url_has_session_params(url):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.SESSION_PARAMS",
+ message="Avoid session or token parameters in published URLs",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.AUTO.SESSION_PARAMS.AVOID",
+ )
+ )
+ host = _extract_url_host(url)
+ if host and host in _SHORTENER_HOSTS:
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.SHORTENER",
+ message="Avoid opaque link shorteners in published docs",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.ACCESSIBILITY.LINKS.AVOID_SHORTENERS",
+ )
+ )
+ if host and _host_looks_staging(host):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.STAGING_HOST",
+ message="Avoid staging or test hostnames in published docs",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.AUTO.STAGING_HOSTNAMES.AVOID",
+ )
+ )
+ if host and _host_looks_internal(host):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.INTERNAL_HOST",
+ message="Avoid internal-only hostnames in published docs",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.AUTO.INTERNAL_HOSTNAMES.AVOID",
+ )
+ )
+ if host and _is_ip_literal(host) and host not in {"127.0.0.1", "0.0.0.0", "localhost"}:
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.IP_LITERAL",
+ message="Avoid literal IP addresses in published links",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.URLS.AVOID.IP_LITERALS",
+ )
+ )
+ if host and _is_private_ip_literal(host):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.PRIVATE_IP",
+ message="Avoid private IP addresses in published links",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.AUTO.PRIVATE_IPS.AVOID",
+ )
+ )
+ if _url_looks_invite(url):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.INVITE",
+ message="Avoid one-time or invite-only links in published docs",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.AUTO.INVITE_LINKS.AVOID",
+ )
+ )
+ if _url_looks_password_reset(url):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.PASSWORD_RESET",
+ message="Do not publish password reset or recovery links",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.AUTO.PASSWORD_RESET.AVOID",
+ )
+ )
+ if _url_looks_login(url):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.LOGIN",
+ message="Avoid publishing login links in public docs",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.LINKS.AUTO.LOGIN_LINKS.AVOID",
+ )
+ )
+ if _is_low_information_link_text(label):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.TEXT_DESCRIPTIVE",
+ message="Link text should be descriptive",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
column=1,
+ rule_id="HOUSE.LINKS.TEXT.DESCRIPTIVE",
+ )
+ )
+
+ for label, url, start, end in _iter_markdown_link_spans(masked):
+ if start > 0 and masked[start - 1] == "!":
+ continue
+ if (
+ (start > 0 and _is_word_char(masked[start - 1]))
+ or (end < len(masked) and _is_word_char(masked[end]))
+ ):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.PARTIAL_WORD",
+ message="Avoid linking only part of a word",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=start + 1,
+ rule_id="HOUSE.LINKS.AUTO.PARTIAL_WORD.AVOID",
+ )
+ )
+ ext = _extract_download_extension(url)
+ if ext and not _label_mentions_filetype(label, ext):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.FILETYPE_LABEL",
+ message="Label downloadable file types in the link text",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=start + 1,
+ rule_id="HOUSE.LINKS.AUTO.FILETYPE_LABEL.REQUIRED",
+ )
+ )
+ if _label_is_overlong(label):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.LABEL_OVERLONG",
+ message="Avoid overly long link labels in running text",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=start + 1,
+ rule_id="HOUSE.LINKS.AUTO.LABEL_LENGTH.AVOID_OVERLONG",
+ )
+ )
+ if ext and not _has_html_fallback(url, link_keys):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.HTML_FALLBACK",
+ message="Provide an HTML view fallback for download links when available",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=start + 1,
+ rule_id="HOUSE.LINKS.AUTO.HTML_FALLBACK.REQUIRED",
+ )
+ )
+
+ for alt, _url, col in _iter_markdown_images(clean):
+ if not alt.strip():
+ diagnostics.append(
+ LintDiagnostic(
+ code="A11Y.IMG_ALT",
+ message="Image alt text is required (or explicit empty alt only for decorative images)",
+ severity="must",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.A11Y.IMAGES.ALT_REQUIRED",
+ )
+ )
+ elif _alt_text_looks_like_filename(alt):
+ diagnostics.append(
+ LintDiagnostic(
+ code="A11Y.IMG_ALT_QUALITY",
+ message="Alt text should describe content, not a filename or generic label",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.ACCESSIBILITY.IMAGES.ALT_TEXT.QUALITY.NO_FILENAME",
)
)
for idx, line in enumerate(lines, start=1):
if idx in fenced:
continue
- for match in re.finditer(r"(https?://\S+|www\.\S+)", line):
+ clean = _strip_inline_code(line)
+ angle_link = re.search(r"<\s*(https?://[^>]+|mailto:[^>]+)\s*>", clean, flags=re.IGNORECASE)
+ if angle_link:
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.ANGLE_WRAPPER",
+ message="Avoid angle-bracketed URLs in prose",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=angle_link.start(0) + 1,
+ rule_id="CMOS.LINKS.NO_WRAPPERS",
+ )
+ )
+ in_reference_section = _line_in_ranges(idx, reference_ranges)
+ for match in re.finditer(r"(https?://\S+|www\.\S+)", clean):
token = match.group(1)
- if _long_unbroken(token, 80):
+ if line.strip() == token and token.endswith((".", ",", ";", ":")):
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.URL_ONLY_TRAILING_PUNCT",
+ message="Avoid terminal punctuation on URL-only lines",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=match.start(1) + 1,
+ rule_id="CMOS.LINKS.URL_ONLY_LINE_NO_PUNCT",
+ )
+ )
+ if _long_unbroken(token, 80) and not in_reference_section:
diagnostics.append(
LintDiagnostic(
code="LINK.WRAP.RISK",
@@ -245,6 +888,19 @@ def _lint_document(doc: MdDocument) -> list[LintDiagnostic]:
column=match.start(1) + 1,
)
)
+ if _looks_like_bare_url(token) and "](" not in clean and not in_reference_section:
+ diagnostics.append(
+ LintDiagnostic(
+ code="LINK.BARE_URL",
+ message="Avoid naked URLs in prose when a labeled link will do",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=match.start(1) + 1,
+ rule_id="HOUSE.LINKS.URLS.AVOID.NAKED_URLS_IN_PROSE",
+ )
+ )
+ break
link_spacing = re.compile(r"\]\s+\(\s*([^)]+?)\s*\)")
for idx, line in enumerate(lines, start=1):
@@ -263,6 +919,172 @@ def _lint_document(doc: MdDocument) -> list[LintDiagnostic]:
)
break
+ for block in doc.blocks:
+ if block.type == "heading" and block.level:
+ if block.level > 1 and not _prior_heading_level(doc, block.level, block.start_line):
+ diagnostics.append(
+ LintDiagnostic(
+ code="A11Y.HEADINGS.NO_SKIPS",
+ message="Heading level skips a level",
+ severity="must",
+ path=str(doc.path),
+ line=block.start_line,
+ column=1,
+ rule_id="HOUSE.A11Y.HEADINGS.NO_SKIPS",
+ )
+ )
+ stripped = block.text.rstrip()
+ if stripped.endswith((".", ":", ";")):
+ diagnostics.append(
+ LintDiagnostic(
+ code="EDITORIAL.HEADING_TRAILING_PUNCT",
+ message="Avoid trailing punctuation in headings",
+ severity="should",
+ path=str(doc.path),
+ line=block.start_line,
+ column=1,
+ rule_id="HOUSE.EDITORIAL.HEADINGS.NO_TRAILING_PUNCTUATION",
+ )
+ )
+ heading_text = _strip_markdown_links(_strip_inline_code(block.text))
+ if _is_effectively_empty_text(heading_text):
+ diagnostics.append(
+ LintDiagnostic(
+ code="A11Y.HEADING_EMPTY",
+ message="Avoid empty or decorative headings",
+ severity="should",
+ path=str(doc.path),
+ line=block.start_line,
+ column=1,
+ rule_id="HOUSE.ACCESSIBILITY.HEADINGS.NO_EMPTY",
+ )
+ )
+ if _is_all_caps_heading(heading_text):
+ diagnostics.append(
+ LintDiagnostic(
+ code="EDITORIAL.HEADING_ALL_CAPS",
+ message="Avoid all caps headings in prose documents",
+ severity="should",
+ path=str(doc.path),
+ line=block.start_line,
+ column=1,
+ rule_id="HOUSE.EDITORIAL.HEADINGS.AVOID_ALL_CAPS",
+ )
+ )
+ if block.type == "table":
+ if not any(h for h in block.headers):
+ diagnostics.append(
+ LintDiagnostic(
+ code="TABLE.HEADER.MISSING",
+ message="Table header row is empty",
+ severity="should",
+ path=str(doc.path),
+ line=block.start_line,
+ column=1,
+ rule_id="HOUSE.ACCESSIBILITY.TABLES.HEADER_ROW.REQUIRED",
+ )
+ )
+ if block.type == "blockquote":
+ if block.text.lstrip().startswith(("\"", "“", "”")):
+ diagnostics.append(
+ LintDiagnostic(
+ code="PUNCT.BLOCKQUOTE.NO_QUOTES",
+ message="Block quotes should omit surrounding quotation marks",
+ severity="must",
+ path=str(doc.path),
+ line=block.start_line,
+ column=1,
+ rule_id="CMOS.PUNCTUATION.BLOCK_QUOTES.NO_QUOTE_MARKS",
+ )
+ )
+ if block.type in {"paragraph", "heading", "blockquote"}:
+ if _unbalanced_delimiters(_strip_markdown_links(_strip_inline_code(block.text))):
+ diagnostics.append(
+ LintDiagnostic(
+ code="PUNCT.BALANCE",
+ message="Parentheses/brackets appear unbalanced",
+ severity="must",
+ path=str(doc.path),
+ line=block.start_line,
+ column=1,
+ rule_id="CMOS.PUNCTUATION.PARENS_BRACKETS.BALANCE",
+ )
+ )
+ if block.type == "list":
+ if len(block.items) == 1:
+ diagnostics.append(
+ LintDiagnostic(
+ code="EDITORIAL.LIST_SINGLE_ITEM",
+ message="Avoid single-item lists",
+ severity="warn",
+ path=str(doc.path),
+ line=block.start_line,
+ column=1,
+ rule_id="HOUSE.EDITORIAL.LISTS.AVOID_SINGLE_ITEM",
+ )
+ )
+
+ h1s = [b for b in doc.blocks if b.type == "heading" and b.level == 1]
+ if not h1s:
+ diagnostics.append(
+ LintDiagnostic(
+ code="EDITORIAL.TITLE.MISSING",
+ message="Include an H1 title",
+ severity="should",
+ path=str(doc.path),
+ line=1,
+ column=1,
+ rule_id="HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.PRESENT",
+ )
+ )
+ if len(h1s) > 1:
+ diagnostics.append(
+ LintDiagnostic(
+ code="EDITORIAL.TITLE.MULTIPLE",
+ message="Avoid multiple H1 titles",
+ severity="should",
+ path=str(doc.path),
+ line=h1s[1].start_line,
+ column=1,
+ rule_id="HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.SINGLE",
+ )
+ )
+ if h1s:
+ first_idx = next((i for i, b in enumerate(doc.blocks) if b.type == "heading" and b.level == 1), 0)
+ if first_idx > 2:
+ diagnostics.append(
+ LintDiagnostic(
+ code="EDITORIAL.TITLE.LATE",
+ message="Place the title near the top",
+ severity="should",
+ path=str(doc.path),
+ line=h1s[0].start_line,
+ column=1,
+ rule_id="HOUSE.EDITORIAL.STRUCTURE.H1_TITLE.EARLY",
+ )
+ )
+
+ diagnostics.extend(_lint_layout_spacing(doc))
+ diagnostics.extend(_lint_empty_sections(doc))
+ diagnostics.extend(_lint_emphasis_spans(doc))
+ diagnostics.extend(_lint_accessibility_links(doc))
+ diagnostics.extend(_lint_footnote_marker_sequence(doc))
+ diagnostics.extend(_lint_citations_bracketed_numbers(doc))
+ diagnostics.extend(_lint_citations_heading_note_markers(doc))
+ diagnostics.extend(_lint_citations_ibid(doc))
+ diagnostics.extend(_lint_citations_notes_bibliography_required(doc))
+ diagnostics.extend(_lint_code_blocks(doc))
+ diagnostics.extend(_lint_acronyms(doc))
+ diagnostics.extend(_lint_citations_author_date(doc))
+ diagnostics.extend(_lint_i18n_consistency(doc))
+
+ if file_ignores or line_ignores:
+ diagnostics = [
+ d
+ for d in diagnostics
+ if not _should_ignore_diagnostic(d, file_ignores, line_ignores)
+ ]
+
return diagnostics
@@ -277,6 +1099,25 @@ def _prior_heading_level(doc: MdDocument, level: int, line_no: int) -> bool:
return level == 1
+def _is_all_caps_heading(text: str) -> bool:
+ clean = re.sub(r"[\s\u00a0]+", " ", text.strip())
+ if not clean:
+ return False
+ letters = [ch for ch in clean if ch.isalpha()]
+ if len(letters) < 4:
+ return False
+ if any(ch.islower() for ch in letters):
+ return False
+ words = [w for w in re.split(r"\s+", clean) if w]
+ if len(words) == 1 and len(letters) <= 6:
+ return False
+ return True
+
+
+def _is_effectively_empty_text(text: str) -> bool:
+ return not bool(re.search(r"[A-Za-z0-9]", text))
+
+
def _long_unbroken(text: str, threshold: int) -> bool:
for token in re.findall(r"\S+", text):
if len(token) >= threshold:
@@ -284,6 +1125,1411 @@ def _long_unbroken(text: str, threshold: int) -> bool:
return False
+def _split_inline_code(text: str) -> list[tuple[bool, str]]:
+ parts: list[tuple[bool, str]] = []
+ buf: list[str] = []
+ in_code = False
+ delimiter = ""
+ i = 0
+ while i < len(text):
+ if not in_code and text[i] == "`":
+ j = i
+ while j < len(text) and text[j] == "`":
+ j += 1
+ if buf:
+ parts.append((False, "".join(buf)))
+ buf.clear()
+ delimiter = text[i:j]
+ buf.append(delimiter)
+ in_code = True
+ i = j
+ continue
+ if in_code and delimiter and text.startswith(delimiter, i):
+ buf.append(delimiter)
+ parts.append((True, "".join(buf)))
+ buf.clear()
+ in_code = False
+ i += len(delimiter)
+ delimiter = ""
+ continue
+ buf.append(text[i])
+ i += 1
+ if buf:
+ parts.append((in_code, "".join(buf)))
+ return parts
+
+
+def _strip_inline_code(text: str) -> str:
+ return "".join(seg for is_code, seg in _split_inline_code(text) if not is_code)
+
+
+def _strip_markdown_links(text: str) -> str:
+ return re.sub(r"\[[^\]]*\]\([^)]+\)", " ", text)
+
+
+def _has_double_sentence_space(text: str) -> bool:
+ return bool(re.search(r"[.!?][\]\)\"']? {2,}", text))
+
+
+def _unbalanced_delimiters(text: str) -> bool:
+ stack: list[str] = []
+ pairs = {")": "(", "]": "["}
+ for idx, ch in enumerate(text):
+ if ch in "([":
+ stack.append(ch)
+ elif ch in ")]":
+ if ch == ")" and not stack and _looks_like_enumeration_close(text, idx):
+ continue
+ if not stack or stack[-1] != pairs[ch]:
+ return True
+ stack.pop()
+ return bool(stack)
+
+
+def _looks_like_enumeration_close(text: str, idx: int) -> bool:
+ if idx <= 0 or text[idx] != ")":
+ return False
+ j = idx - 1
+ while j >= 0 and text[j].isalnum():
+ j -= 1
+ token = text[j + 1 : idx]
+ if not token:
+ return False
+ if not (token.isdigit() or (len(token) == 1 and token.isalpha())):
+ return False
+ if j >= 0 and not text[j].isspace():
+ return False
+ if idx + 1 < len(text) and not text[idx + 1].isspace():
+ return False
+ return True
+
+
+def _contains_zero_width(text: str) -> bool:
+ return any(ch in text for ch in ("\u200b", "\u200c", "\u200d", "\ufeff"))
+
+
+def _expected_ordinal_suffix(number: int) -> str:
+ if 10 <= (number % 100) <= 20:
+ return "th"
+ last = number % 10
+ if last == 1:
+ return "st"
+ if last == 2:
+ return "nd"
+ if last == 3:
+ return "rd"
+ return "th"
+
+
+def _colon_spacing_violation(text: str) -> bool:
+ # Space-after-colon rule (skip URLs, time, ratios).
+ if "://" in text:
+ return False
+ if re.search(r": {2,}", text):
+ return True
+ return bool(re.search(r":(?!\s)(?=[A-Za-z])", text))
+
+
+def _iter_markdown_links(line: str) -> list[tuple[str, str, int]]:
+ out: list[tuple[str, str, int]] = []
+ for m in re.finditer(r"\[([^\]]+)\]\(([^)]+)\)", line):
+ label = m.group(1)
+ url = m.group(2).strip()
+ out.append((label, url, m.start(2) + 1))
+ return out
+
+
+def _iter_markdown_link_spans(line: str) -> list[tuple[str, str, int, int]]:
+ out: list[tuple[str, str, int, int]] = []
+ for m in re.finditer(r"\[([^\]]+)\]\(([^)]+)\)", line):
+ label = m.group(1)
+ url = m.group(2).strip()
+ out.append((label, url, m.start(), m.end()))
+ return out
+
+
+def _mask_inline_code(text: str) -> str:
+ parts = _split_inline_code(text)
+ masked: list[str] = []
+ for is_code, seg in parts:
+ if is_code:
+ masked.append(" " * len(seg))
+ else:
+ masked.append(seg)
+ return "".join(masked)
+
+
+def _normalize_ignore_list(value: Any) -> set[str]:
+ if value is None:
+ return set()
+ if isinstance(value, str):
+ return {v for v in re.split(r"[,\s]+", value) if v}
+ if isinstance(value, list):
+ out: set[str] = set()
+ for item in value:
+ if isinstance(item, str):
+ out.update({v for v in re.split(r"[,\s]+", item) if v})
+ return out
+ return set()
+
+
+def _parse_front_matter_ignore(text: str) -> set[str]:
+ lines = text.splitlines()
+ if not lines or lines[0].strip() != "---":
+ return set()
+ end_idx = None
+ for i in range(1, min(len(lines), 200)):
+ if lines[i].strip() in {"---", "..."}:
+ end_idx = i
+ break
+ if end_idx is None:
+ return set()
+ raw = "\n".join(lines[1:end_idx])
+ try:
+ data = yaml.safe_load(raw) or {}
+ except yaml.YAMLError:
+ return set()
+ if not isinstance(data, dict):
+ return set()
+ ignores: set[str] = set()
+ ignores |= _normalize_ignore_list(data.get("iftypeset_ignore"))
+ if isinstance(data.get("iftypeset"), dict):
+ ignores |= _normalize_ignore_list(data["iftypeset"].get("ignore"))
+ return ignores
+
+
+def _collect_line_ignores(text: str, fenced: set[int]) -> dict[int, set[str]]:
+ lines = text.splitlines()
+ ignores_by_line: dict[int, set[str]] = {}
+ pending: set[str] = set()
+ directive = re.compile(r"")
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ continue
+ match = directive.search(line)
+ if match:
+ tokens = _normalize_ignore_list(match.group(1))
+ if tokens:
+ ignores_by_line.setdefault(idx, set()).update(tokens)
+ remainder = directive.sub("", line).strip()
+ if remainder:
+ continue
+ pending |= tokens
+ continue
+ if pending and line.strip():
+ ignores_by_line.setdefault(idx, set()).update(pending)
+ pending = set()
+ return ignores_by_line
+
+
+def _should_ignore_diagnostic(
+ diag: LintDiagnostic, file_ignores: set[str], line_ignores: dict[int, set[str]]
+) -> bool:
+ candidates: set[str] = set()
+ if diag.rule_id:
+ candidates.add(diag.rule_id)
+ if diag.code:
+ candidates.add(diag.code)
+ if not candidates:
+ return False
+ if candidates & file_ignores:
+ return True
+ if diag.line is None:
+ return False
+ if candidates & line_ignores.get(diag.line, set()):
+ return True
+ return False
+
+
+def _reference_section_ranges(blocks: list[MdBlock], total_lines: int) -> list[tuple[int, int]]:
+ headings = [b for b in blocks if b.type == "heading" and b.start_line]
+ headings.sort(key=lambda b: b.start_line)
+ ranges: list[tuple[int, int]] = []
+ for i, heading in enumerate(headings):
+ end_line = total_lines
+ if i + 1 < len(headings):
+ end_line = headings[i + 1].start_line - 1
+ if _is_reference_heading(heading.text):
+ ranges.append((heading.start_line, end_line))
+ return ranges
+
+
+def _is_reference_heading(text: str) -> bool:
+ cleaned = re.sub(r"[^a-z0-9]+", " ", text.lower())
+ tokens = cleaned.split()
+ keywords = {
+ "references",
+ "reference",
+ "bibliography",
+ "sources",
+ "source",
+ "links",
+ "resources",
+ "appendix",
+ "appendices",
+ "data",
+ "datasets",
+ "citations",
+ }
+ return any(token in keywords for token in tokens)
+
+
+def _line_in_ranges(line_no: int, ranges: list[tuple[int, int]]) -> bool:
+ for start, end in ranges:
+ if start <= line_no <= end:
+ return True
+ return False
+
+
+def _iter_markdown_images(line: str) -> list[tuple[str, str, int]]:
+ out: list[tuple[str, str, int]] = []
+ for m in re.finditer(r"!\[([^\]]*)\]\(([^)]+)\)", line):
+ alt = m.group(1)
+ url = m.group(2).strip()
+ out.append((alt, url, m.start(2) + 1))
+ return out
+
+
+_SHORTENER_HOSTS = {
+ "bit.ly",
+ "buff.ly",
+ "goo.gl",
+ "is.gd",
+ "lnkd.in",
+ "ow.ly",
+ "rb.gy",
+ "rebrand.ly",
+ "t.co",
+ "tiny.cc",
+ "tinyurl.com",
+}
+
+_FILETYPE_LABELS: dict[str, set[str]] = {
+ ".tar.gz": {"tar.gz", "tar", "tgz", "archive"},
+ ".tgz": {"tgz", "tar.gz", "archive"},
+ ".tar": {"tar", "archive"},
+ ".zip": {"zip", "archive"},
+ ".gz": {"gz", "gzip", "archive"},
+ ".pdf": {"pdf"},
+ ".csv": {"csv"},
+ ".tsv": {"tsv"},
+ ".xlsx": {"xlsx", "excel"},
+ ".xls": {"xls", "excel"},
+ ".docx": {"docx", "word"},
+ ".doc": {"doc", "word"},
+ ".pptx": {"pptx", "powerpoint"},
+ ".ppt": {"ppt", "powerpoint"},
+ ".md": {"md", "markdown"},
+ ".json": {"json"},
+ ".py": {"py", "python"},
+}
+
+_HTML_FALLBACK_EXTS = {".md", ".tar.gz", ".tgz", ".zip", ".gz", ".py"}
+_LINK_LABEL_MAX_CHARS = 80
+_LINK_LABEL_MAX_WORDS = 12
+
+_STAGING_TOKENS = {"staging", "stage", "dev", "test", "qa", "sandbox", "preview"}
+_INTERNAL_TLDS = {".local", ".internal", ".intranet", ".corp", ".lan", ".home", ".private"}
+_TRACKING_PARAMS = {
+ "utm_source",
+ "utm_medium",
+ "utm_campaign",
+ "utm_term",
+ "utm_content",
+ "ref",
+ "referrer",
+ "source",
+ "fbclid",
+ "gclid",
+ "mc_cid",
+ "mc_eid",
+}
+_SESSION_PARAMS = {"session", "sessionid", "sid", "phpsessid", "jsessionid", "token", "auth", "access_token"}
+_INVITE_PATH_TOKENS = {"invite", "invitation", "join", "signup", "register"}
+_INVITE_PARAMS = {"invite", "invitation", "invite_code", "join", "signup", "register", "code"}
+_TOKEN_PARAMS = {"token", "code", "key", "auth", "access_token"}
+_PASSWORD_RESET_TOKENS = {"reset", "forgot", "recover", "password"}
+_LOGIN_TOKENS = {"login", "signin", "sign-in", "auth", "session"}
+
+
+def _normalize_url_for_parse(url: str) -> str:
+ if url.startswith("//"):
+ return f"https:{url}"
+ if url.startswith("www."):
+ return f"https://{url}"
+ return url
+
+
+def _parse_url(url: str):
+ try:
+ return urlparse(_normalize_url_for_parse(url))
+ except ValueError:
+ return None
+
+
+def _url_has_tracking_params(url: str) -> bool:
+ parsed = _parse_url(url)
+ if not parsed or not parsed.query:
+ return False
+ keys = {k.lower() for k in parse_qs(parsed.query, keep_blank_values=True)}
+ return any(k.startswith("utm_") or k in _TRACKING_PARAMS for k in keys)
+
+
+def _url_has_session_params(url: str) -> bool:
+ parsed = _parse_url(url)
+ if not parsed or not parsed.query:
+ return False
+ keys = {k.lower() for k in parse_qs(parsed.query, keep_blank_values=True)}
+ return bool(keys & _SESSION_PARAMS)
+
+
+def _url_has_embedded_credentials(url: str) -> bool:
+ parsed = _parse_url(url)
+ if not parsed:
+ return False
+ return bool(parsed.username or parsed.password)
+
+
+def _host_looks_staging(host: str | None) -> bool:
+ if not host:
+ return False
+ parts = host.split(".")
+ for part in parts:
+ if part in _STAGING_TOKENS:
+ return True
+ for token in _STAGING_TOKENS:
+ if part.startswith(token) or part.endswith(token):
+ return True
+ return False
+
+
+def _host_looks_internal(host: str | None) -> bool:
+ if not host:
+ return False
+ if any(host.endswith(tld) for tld in _INTERNAL_TLDS):
+ return True
+ parts = host.split(".")
+ return any(part in {"internal", "intranet", "corp", "lan", "local"} for part in parts)
+
+
+def _is_private_ip_literal(host: str | None) -> bool:
+ if not host:
+ return False
+ try:
+ ip = ipaddress.ip_address(host)
+ except ValueError:
+ return False
+ return ip.is_private
+
+
+def _url_looks_invite(url: str) -> bool:
+ parsed = _parse_url(url)
+ if not parsed:
+ return False
+ path = (parsed.path or "").lower()
+ has_invite_path = any(token in path for token in _INVITE_PATH_TOKENS)
+ keys = {k.lower() for k in parse_qs(parsed.query, keep_blank_values=True)}
+ has_invite_key = bool(keys & _INVITE_PARAMS)
+ has_token = bool(keys & _TOKEN_PARAMS)
+ return (has_invite_path or has_invite_key) and (has_token or has_invite_key)
+
+
+def _url_looks_password_reset(url: str) -> bool:
+ parsed = _parse_url(url)
+ if not parsed:
+ return False
+ path = (parsed.path or "").lower()
+ if any(token in path for token in _PASSWORD_RESET_TOKENS):
+ return True
+ keys = {k.lower() for k in parse_qs(parsed.query, keep_blank_values=True)}
+ return bool(keys & {"reset", "password", "recover", "forgot"})
+
+
+def _url_looks_login(url: str) -> bool:
+ parsed = _parse_url(url)
+ if not parsed:
+ return False
+ path = (parsed.path or "").lower()
+ if any(token in path for token in _LOGIN_TOKENS):
+ return True
+ keys = {k.lower() for k in parse_qs(parsed.query, keep_blank_values=True)}
+ return bool(keys & {"login", "signin", "auth"})
+
+
+def _extract_url_host(url: str) -> str | None:
+ try:
+ parsed = urlparse(_normalize_url_for_parse(url))
+ except ValueError:
+ return None
+ host = parsed.netloc
+ if not host:
+ return None
+ host = host.split("@")[-1]
+ if host.startswith("["):
+ host = host.split("]")[0].lstrip("[")
+ elif ":" in host:
+ host = host.split(":", 1)[0]
+ return host.lower()
+
+
+def _is_ipv4_literal(host: str) -> bool:
+ if not re.match(r"^(?:\d{1,3}\.){3}\d{1,3}$", host):
+ return False
+ return all(0 <= int(part) <= 255 for part in host.split("."))
+
+
+def _is_ip_literal(host: str) -> bool:
+ if _is_ipv4_literal(host):
+ return True
+ return ":" in host
+
+
+def _url_has_signed_params(url: str) -> bool:
+ parsed = urlparse(_normalize_url_for_parse(url))
+ if not parsed.query:
+ return False
+ keys = {k.lower() for k in parse_qs(parsed.query, keep_blank_values=True)}
+ if {"x-amz-signature", "x-amz-credential", "x-amz-expires"} & keys:
+ return True
+ if {"x-goog-signature", "x-goog-credential", "x-goog-expires"} & keys:
+ return True
+ if {"x-ms-signature", "x-ms-expires", "x-ms-date"} & keys:
+ return True
+ if "signature" in keys and "expires" in keys:
+ return True
+ return False
+
+
+def _has_text_fragment(url: str) -> bool:
+ return "#:~:text=" in url
+
+
+def _extract_download_extension(url: str) -> str | None:
+ parsed = _parse_url(url)
+ path = parsed.path if parsed else url
+ lower_path = path.lower()
+ for ext in sorted(_FILETYPE_LABELS.keys(), key=len, reverse=True):
+ if lower_path.endswith(ext):
+ return ext
+ return None
+
+
+def _label_mentions_filetype(label: str, ext: str) -> bool:
+ tokens = _FILETYPE_LABELS.get(ext, set())
+ if not tokens:
+ return True
+ label_lower = label.lower()
+ if any(token in label_lower for token in tokens):
+ return True
+ label_compact = re.sub(r"[^a-z0-9]+", "", label_lower)
+ for token in tokens:
+ token_compact = re.sub(r"[^a-z0-9]+", "", token)
+ if token_compact and token_compact in label_compact:
+ return True
+ return False
+
+
+def _label_is_overlong(label: str) -> bool:
+ if len(label) >= _LINK_LABEL_MAX_CHARS:
+ return True
+ words = re.findall(r"[A-Za-z0-9]+", label)
+ return len(words) >= _LINK_LABEL_MAX_WORDS
+
+
+def _canonical_link_key(url: str) -> str:
+ parsed = _parse_url(url)
+ if not parsed:
+ return url.strip().lower()
+ path = parsed.path or ""
+ if parsed.scheme and parsed.netloc:
+ return f"{parsed.scheme.lower()}://{parsed.netloc.lower()}{path}".rstrip("/")
+ return path.lower().rstrip("/")
+
+
+def _possible_html_fallback_keys(url: str) -> set[str]:
+ parsed = _parse_url(url)
+ path = parsed.path if parsed else url
+ ext = _extract_download_extension(url)
+ if not ext or ext not in _HTML_FALLBACK_EXTS:
+ return set()
+ base = path[: -len(ext)]
+ prefix = ""
+ if parsed and parsed.scheme and parsed.netloc:
+ prefix = f"{parsed.scheme.lower()}://{parsed.netloc.lower()}"
+ candidates = {
+ f"{prefix}{base}",
+ f"{prefix}{base}/",
+ f"{prefix}{base}.html",
+ f"{prefix}{base}/index.html",
+ }
+ return {_canonical_link_key(c) for c in candidates if c}
+
+
+def _has_html_fallback(url: str, link_keys: set[str]) -> bool:
+ candidates = _possible_html_fallback_keys(url)
+ if not candidates:
+ return True
+ return bool(candidates & link_keys)
+
+
+def _is_word_char(ch: str) -> bool:
+ return bool(re.match(r"[A-Za-z0-9_]", ch))
+
+def _is_low_information_link_text(label: str) -> bool:
+ s = " ".join(label.strip().lower().split())
+ if not s:
+ return True
+ if s in {"click here", "here", "this", "link", "more", "read more"}:
+ return True
+ if s.startswith("http://") or s.startswith("https://") or s.startswith("www."):
+ return True
+ return False
+
+
+def _is_symbol_only_text(label: str) -> bool:
+ s = label.strip()
+ if not s:
+ return True
+ return not bool(re.search(r"[A-Za-z0-9]", s))
+
+
+def _normalize_label(label: str) -> str:
+ return " ".join(label.strip().lower().split())
+
+
+def _looks_like_bare_url(token: str) -> bool:
+ return token.startswith("http://") or token.startswith("https://") or token.startswith("www.")
+
+
+def _alt_text_looks_like_filename(alt: str) -> bool:
+ s = alt.strip().lower()
+ if not s:
+ return False
+ if s in {"image", "photo", "screenshot", "figure"}:
+ return True
+ return bool(re.search(r"\b[\w.-]+\.(png|jpe?g|gif|svg|webp|pdf)\b", s))
+
+
+def _lint_footnote_marker_sequence(doc: MdDocument) -> list[LintDiagnostic]:
+ diagnostics: list[LintDiagnostic] = []
+ text = doc.normalized_source
+ fenced = code_fence_lines(text)
+
+ refs: list[tuple[int, int]] = []
+ defs: set[int] = set()
+ for idx, line in enumerate(text.splitlines(), start=1):
+ if idx in fenced:
+ continue
+ for m in re.finditer(r"\[\^(\d+)\]", line):
+ refs.append((idx, int(m.group(1))))
+ mdef = re.match(r"^\[\^(\d+)\]:\s+", line.strip())
+ if mdef:
+ defs.add(int(mdef.group(1)))
+
+ if not refs:
+ return diagnostics
+
+ seen_numbers: list[int] = [n for _, n in refs]
+ counts: dict[int, int] = {}
+ for n in seen_numbers:
+ counts[n] = counts.get(n, 0) + 1
+ dupes = sorted(n for n, c in counts.items() if c > 1)
+ expected = list(range(1, max(seen_numbers) + 1))
+ if sorted(set(seen_numbers)) != expected or seen_numbers != sorted(seen_numbers):
+ diagnostics.append(
+ LintDiagnostic(
+ code="CITATION.NOTE_SEQUENCE",
+ message="Footnote markers should be continuous and ordered",
+ severity="must",
+ path=str(doc.path),
+ line=refs[0][0],
+ column=1,
+ rule_id="CMOS.CITATIONS.NOTES.NOTE_MARKERS.SEQUENCE_CONTINUOUS",
+ )
+ )
+ if dupes:
+ diagnostics.append(
+ LintDiagnostic(
+ code="CITATION.NOTE_DUPLICATE",
+ message=f"Duplicate footnote markers found: {', '.join(str(n) for n in dupes)}",
+ severity="must",
+ path=str(doc.path),
+ line=refs[0][0],
+ column=1,
+ rule_id="CMOS.CITATIONS.NOTES.NOTE_MARKERS.SEQUENCE_CONTINUOUS",
+ )
+ )
+
+ missing_defs = [n for n in set(seen_numbers) if n not in defs]
+ if missing_defs:
+ diagnostics.append(
+ LintDiagnostic(
+ code="CITATION.NOTE_DEFINITION",
+ message=f"Missing footnote definitions for: {', '.join(str(n) for n in sorted(missing_defs))}",
+ severity="should",
+ path=str(doc.path),
+ line=refs[0][0],
+ column=1,
+ rule_id="HOUSE.CITATIONS.NOTES.DEFINITIONS.REQUIRED",
+ )
+ )
+
+ for idx, line in enumerate(text.splitlines(), start=1):
+ if idx in fenced:
+ continue
+ if re.match(r"^\[\^\d+\]:\s+", line.strip()):
+ continue
+ for m in re.finditer(r"\[\^\d+\][,.;:!?]", line):
+ diagnostics.append(
+ LintDiagnostic(
+ code="CITATION.NOTE_PLACEMENT",
+ message="Place note markers after related punctuation",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=m.start() + 1,
+ rule_id="CMOS.CITATIONS.NOTES.NOTE_MARKERS.PLACEMENT_AFTER_PUNCT",
+ )
+ )
+ break
+ return diagnostics
+
+
+def _lint_layout_spacing(doc: MdDocument) -> list[LintDiagnostic]:
+ diagnostics: list[LintDiagnostic] = []
+ lines = doc.normalized_source.splitlines()
+ fenced = code_fence_lines(doc.normalized_source)
+ blank_run = 0
+ run_start: int | None = None
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ blank_run = 0
+ run_start = None
+ continue
+ if not line.strip():
+ if blank_run == 0:
+ run_start = idx
+ blank_run += 1
+ continue
+ if blank_run >= 2 and run_start is not None:
+ diagnostics.append(
+ LintDiagnostic(
+ code="LAYOUT.EXTRA_BLANK_LINES",
+ message="Avoid extra blank lines between paragraphs unless a section break is intended",
+ severity="warn",
+ path=str(doc.path),
+ line=run_start,
+ column=1,
+ rule_id="HOUSE.LAYOUT.MD.BLANK_LINES.SPARING",
+ )
+ )
+ blank_run = 0
+ run_start = None
+ if blank_run >= 2 and run_start is not None:
+ diagnostics.append(
+ LintDiagnostic(
+ code="LAYOUT.EXTRA_BLANK_LINES",
+ message="Avoid extra blank lines between paragraphs unless a section break is intended",
+ severity="warn",
+ path=str(doc.path),
+ line=run_start,
+ column=1,
+ rule_id="HOUSE.LAYOUT.MD.BLANK_LINES.SPARING",
+ )
+ )
+ return diagnostics
+
+
+def _lint_empty_sections(doc: MdDocument) -> list[LintDiagnostic]:
+ diagnostics: list[LintDiagnostic] = []
+ blocks = doc.blocks
+ for i, block in enumerate(blocks):
+ if block.type != "heading":
+ continue
+ has_content = False
+ for nxt in blocks[i + 1 :]:
+ if nxt.type == "heading":
+ break
+ if nxt.type in {"paragraph", "list", "code", "table", "blockquote"}:
+ if nxt.type == "paragraph" and not nxt.text.strip():
+ continue
+ has_content = True
+ break
+ if not has_content:
+ diagnostics.append(
+ LintDiagnostic(
+ code="LAYOUT.EMPTY_SECTION",
+ message="Headings should be followed by content, not another heading or EOF",
+ severity="should",
+ path=str(doc.path),
+ line=block.start_line,
+ column=1,
+ rule_id="HOUSE.LAYOUT.MD.HEADINGS.NON_EMPTY_SECTIONS",
+ )
+ )
+ return diagnostics
+
+
+def _span_overlaps(existing: list[tuple[int, int]], start: int, end: int) -> bool:
+ for s, e in existing:
+ if start < e and end > s:
+ return True
+ return False
+
+
+def _collect_emphasis_spans(text: str) -> list[tuple[str, str, int]]:
+ spans: list[tuple[str, str, int]] = []
+ used: list[tuple[int, int]] = []
+ patterns = [
+ ("bold_italic", r"\*\*\*([^*]+)\*\*\*"),
+ ("bold_italic", r"___([^_]+)___"),
+ ("bold", r"\*\*([^*]+)\*\*"),
+ ("bold", r"__([^_]+)__"),
+ ("italic", r"(? bool:
+ letters = [ch for ch in text if ch.isalpha()]
+ if len(letters) < 4:
+ return False
+ return all(ch.isupper() for ch in letters)
+
+
+def _lint_emphasis_spans(doc: MdDocument) -> list[LintDiagnostic]:
+ diagnostics: list[LintDiagnostic] = []
+ lines = doc.normalized_source.splitlines()
+ fenced = code_fence_lines(doc.normalized_source)
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ continue
+ clean = _strip_inline_code(line)
+ for kind, content, col in _collect_emphasis_spans(clean):
+ words = len(re.findall(r"[A-Za-z0-9]+", content))
+ chars = len(content)
+ if kind == "italic" and (words >= 20 or chars >= 120):
+ diagnostics.append(
+ LintDiagnostic(
+ code="TYPO.ITALIC_LONG",
+ message="Avoid long runs of italics in body text",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col + 1,
+ rule_id="HOUSE.TYPOGRAPHY.EMPHASIS.ITALIC_LONG.AVOID",
+ )
+ )
+ if kind == "bold" and (words >= 12 or chars >= 80):
+ diagnostics.append(
+ LintDiagnostic(
+ code="TYPO.BOLD_LONG",
+ message="Avoid long runs of bold text in body paragraphs",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col + 1,
+ rule_id="HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_LONG.AVOID",
+ )
+ )
+ if kind == "bold_italic" and (words >= 8 or chars >= 60):
+ diagnostics.append(
+ LintDiagnostic(
+ code="TYPO.BOLD_ITALIC_LONG",
+ message="Avoid long runs of bold italics",
+ severity="warn",
+ path=str(doc.path),
+ line=idx,
+ column=col + 1,
+ rule_id="HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ITALIC_LONG.AVOID",
+ )
+ )
+ if kind in {"bold", "bold_italic"} and _is_all_caps_text(content):
+ diagnostics.append(
+ LintDiagnostic(
+ code="TYPO.BOLD_ALL_CAPS",
+ message="Avoid bold all-caps text in running prose",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col + 1,
+ rule_id="HOUSE.TYPOGRAPHY.EMPHASIS.BOLD_ALL_CAPS.AVOID",
+ )
+ )
+ return diagnostics
+
+
+def _lint_accessibility_links(doc: MdDocument) -> list[LintDiagnostic]:
+ diagnostics: list[LintDiagnostic] = []
+ lines = doc.normalized_source.splitlines()
+ fenced = code_fence_lines(doc.normalized_source)
+ label_targets: dict[str, set[str]] = {}
+ label_first_line: dict[str, int] = {}
+
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ continue
+ for label, url, col in _iter_markdown_links(line):
+ norm_label = _normalize_label(label)
+ if norm_label:
+ label_targets.setdefault(norm_label, set()).add(url.strip())
+ label_first_line.setdefault(norm_label, idx)
+ if _is_symbol_only_text(label):
+ diagnostics.append(
+ LintDiagnostic(
+ code="A11Y.LINK_TEXT.SYMBOL_ONLY",
+ message="Avoid symbol-only link text; provide a readable label",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=col,
+ rule_id="HOUSE.ACCESSIBILITY.LINK_TEXT.SYMBOL_ONLY.AVOID",
+ )
+ )
+
+ for label, targets in sorted(label_targets.items()):
+ if len(targets) <= 1:
+ continue
+ line_no = label_first_line.get(label, 1)
+ diagnostics.append(
+ LintDiagnostic(
+ code="A11Y.LINK_TEXT.DUPLICATE_LABELS",
+ message="Identical link text should not point to different destinations",
+ severity="should",
+ path=str(doc.path),
+ line=line_no,
+ column=1,
+ rule_id="HOUSE.ACCESSIBILITY.LINK_TEXT.UNIQUE_TARGETS",
+ )
+ )
+ return diagnostics
+def _lint_citations_bracketed_numbers(doc: MdDocument) -> list[LintDiagnostic]:
+ diagnostics: list[LintDiagnostic] = []
+ lines = doc.normalized_source.splitlines()
+ fenced = code_fence_lines(doc.normalized_source)
+ pattern = re.compile(r"\[(\d{1,3})\]")
+
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ continue
+ if re.match(r"^\s*\[\d+\]:\s+", line) or re.match(r"^\s*\[\^\d+\]:\s+", line):
+ continue
+ clean = _strip_inline_code(line)
+ for m in pattern.finditer(clean):
+ if m.start() > 0 and clean[m.start() - 1] == "]":
+ continue
+ if m.end() < len(clean) and clean[m.end()] == "(":
+ continue
+ diagnostics.append(
+ LintDiagnostic(
+ code="CITATION.BRACKETED_NUMERIC",
+ message="Avoid bracketed numeric citations in prose; use Markdown footnotes",
+ severity="warn",
+ path=str(doc.path),
+ line=idx,
+ column=m.start() + 1,
+ rule_id="HOUSE.CITATIONS.NOTES.MARKERS.BRACKETED_NUMBERS.AVOID",
+ )
+ )
+ break
+ return diagnostics
+
+
+def _lint_citations_heading_note_markers(doc: MdDocument) -> list[LintDiagnostic]:
+ diagnostics: list[LintDiagnostic] = []
+ pattern = re.compile(r"\[\^\d+\]")
+ for block in doc.blocks:
+ if block.type != "heading":
+ continue
+ matches = list(pattern.finditer(block.text))
+ if not matches:
+ continue
+ last = matches[-1]
+ trailing = block.text[last.end() :]
+ if trailing.strip():
+ diagnostics.append(
+ LintDiagnostic(
+ code="CITATION.HEADING_NOTE_PLACEMENT",
+ message="Place note markers at the end of headings",
+ severity="should",
+ path=str(doc.path),
+ line=block.start_line,
+ column=1,
+ rule_id="CMOS.CITATIONS.NOTES.NOTE_MARKERS.HEADINGS_END",
+ )
+ )
+ return diagnostics
+
+
+def _lint_citations_ibid(doc: MdDocument) -> list[LintDiagnostic]:
+ diagnostics: list[LintDiagnostic] = []
+ lines = doc.normalized_source.splitlines()
+ fenced = code_fence_lines(doc.normalized_source)
+ ibid_re = re.compile(r"\bibid\.?\b", flags=re.IGNORECASE)
+
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ continue
+ if not re.match(r"^\s*\[\^\d+\]:\s+", line):
+ continue
+ if ibid_re.search(line):
+ diagnostics.append(
+ LintDiagnostic(
+ code="CITATION.IBID",
+ message="Avoid ibid in notes; prefer unambiguous short forms",
+ severity="warn",
+ path=str(doc.path),
+ line=idx,
+ column=1,
+ rule_id="HOUSE.CITATIONS.NOTES.IBID.AVOID",
+ )
+ )
+ return diagnostics
+
+
+def _lint_citations_notes_bibliography_required(doc: MdDocument) -> list[LintDiagnostic]:
+ diagnostics: list[LintDiagnostic] = []
+ lines = doc.normalized_source.splitlines()
+ fenced = code_fence_lines(doc.normalized_source)
+ ref_heading = re.compile(r"^#{1,6}\s*(references|bibliography|works cited)\b", flags=re.IGNORECASE)
+ notes_present = False
+ ref_heading_found = False
+
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ continue
+ if re.search(r"\[\^\d+\]", line) or re.match(r"^\s*\[\^\d+\]:\s+", line):
+ notes_present = True
+ if ref_heading.match(line.strip()):
+ ref_heading_found = True
+
+ if notes_present and not ref_heading_found:
+ diagnostics.append(
+ LintDiagnostic(
+ code="CITATION.BIBLIOGRAPHY_REQUIRED",
+ message="Include a bibliography or references section when using footnote citations",
+ severity="should",
+ path=str(doc.path),
+ line=1,
+ column=1,
+ rule_id="HOUSE.CITATIONS.NOTES.BIBLIOGRAPHY.REQUIRED",
+ )
+ )
+ return diagnostics
+
+
+def _lint_code_blocks(doc: MdDocument) -> list[LintDiagnostic]:
+ diagnostics: list[LintDiagnostic] = []
+ for block in doc.blocks:
+ if block.type != "code":
+ continue
+ if not (block.info or "").strip():
+ diagnostics.append(
+ LintDiagnostic(
+ code="CODE.LANG_INFO",
+ message="Consider adding a language identifier to fenced code blocks",
+ severity="should",
+ path=str(doc.path),
+ line=block.start_line,
+ column=1,
+ rule_id="HOUSE.CODE.FENCES.LANGUAGE_INFO.SUGGEST",
+ )
+ )
+ max_len = max((len(ln) for ln in block.text.splitlines()), default=0)
+ if max_len >= 100:
+ diagnostics.append(
+ LintDiagnostic(
+ code="CODE.LONG_LINES",
+ message="Code block contains very long lines that may overflow in PDF",
+ severity="should",
+ path=str(doc.path),
+ line=block.start_line,
+ column=1,
+ rule_id="HOUSE.CODE.BLOCKS.LONG_LINES.AVOID",
+ )
+ )
+ if "\t" in block.text:
+ diagnostics.append(
+ LintDiagnostic(
+ code="CODE.TABS",
+ message="Code block contains tab characters",
+ severity="should",
+ path=str(doc.path),
+ line=block.start_line,
+ column=1,
+ rule_id="HOUSE.CODE.BLOCKS.TABS.AVOID",
+ )
+ )
+ return diagnostics
+
+
+def _lint_acronyms(doc: MdDocument) -> list[LintDiagnostic]:
+ diagnostics: list[LintDiagnostic] = []
+ text = doc.normalized_source
+ fenced = code_fence_lines(text)
+ allow = {
+ "AI",
+ "API",
+ "CLI",
+ "CPU",
+ "CSS",
+ "DNS",
+ "EU",
+ "GPU",
+ "HTML",
+ "HTTP",
+ "HTTPS",
+ "ID",
+ "IP",
+ "ISO",
+ "JSON",
+ "JWT",
+ "PDF",
+ "QA",
+ "RFC",
+ "SQL",
+ "SSH",
+ "SSL",
+ "TLS",
+ "UI",
+ "UK",
+ "US",
+ "UTC",
+ "UUID",
+ "URI",
+ "URL",
+ "VM",
+ "YAML",
+ }
+ defined: set[str] = set()
+ first_seen: dict[str, int] = {}
+ for idx, line in enumerate(text.splitlines(), start=1):
+ if idx in fenced:
+ continue
+ clean = _strip_inline_code(line)
+ for m in re.finditer(r"\(([A-Z]{2,8})\)", clean):
+ defined.add(m.group(1))
+ for m in re.finditer(r"\b([A-Z]{2,8})\b", clean):
+ ac = m.group(1)
+ if ac in allow:
+ continue
+ first_seen.setdefault(ac, idx)
+
+ for ac, line_no in sorted(first_seen.items(), key=lambda kv: kv[1]):
+ if ac in defined:
+ continue
+ diagnostics.append(
+ LintDiagnostic(
+ code="ABBREV.DEFINE_FIRST_USE",
+ message=f"Acronym '{ac}' may need definition on first use",
+ severity="should",
+ path=str(doc.path),
+ line=line_no,
+ column=1,
+ rule_id="CMOS.ABBREVIATIONS.ACRONYMS.DEFINE_FIRST_USE",
+ )
+ )
+ return diagnostics
+
+
+def _lint_citations_author_date(doc: MdDocument) -> list[LintDiagnostic]:
+ diagnostics: list[LintDiagnostic] = []
+ lines = doc.normalized_source.splitlines()
+ fenced = code_fence_lines(doc.normalized_source)
+ author_date_present = False
+
+ author_date_inline = re.compile(
+ r"\b[A-Z][A-Za-z-]+(?:\s+[A-Z][A-Za-z-]+)*\s*\((?:19|20)\d{2}[a-z]?\)"
+ )
+ author_date_paren = re.compile(r"\([A-Z][A-Za-z-]+[^)]*(?:19|20)\d{2}[a-z]?\)")
+ year_only_paren = re.compile(r"\((?:19|20)\d{2}[a-z]?\)")
+ year_pattern = re.compile(r"\b(1[89]\d{2}|20\d{2})\b")
+ nd_pattern = re.compile(r"\b(n\.d\.|forthcoming|in press)\b", flags=re.IGNORECASE)
+ ref_heading = re.compile(r"^#{1,6}\s*(references|bibliography|works cited)\b", flags=re.IGNORECASE)
+
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ continue
+ clean = _strip_inline_code(line)
+ clean = _strip_markdown_links(clean)
+ if author_date_inline.search(clean) or author_date_paren.search(clean):
+ author_date_present = True
+ for m in year_only_paren.finditer(clean):
+ diagnostics.append(
+ LintDiagnostic(
+ code="CITATION.AUTHOR_DATE.PAREN_YEAR_ONLY",
+ message="Year-only parenthetical citations are ambiguous in author-date style",
+ severity="warn",
+ path=str(doc.path),
+ line=idx,
+ column=m.start() + 1,
+ rule_id="HOUSE.CITATIONS.AUTHOR_DATE.PAREN_YEAR_ONLY",
+ )
+ )
+
+ if not author_date_present:
+ return diagnostics
+
+ in_refs = False
+ ref_heading_found = False
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ continue
+ clean = _strip_inline_code(line)
+ if ref_heading.match(clean):
+ ref_heading_found = True
+ in_refs = True
+ continue
+ if in_refs and clean.lstrip().startswith("#"):
+ break
+ if not in_refs:
+ continue
+ entry = clean.strip()
+ if not entry:
+ continue
+ entry = entry.lstrip("-*0123456789. ").strip()
+ if not entry:
+ continue
+ if year_pattern.search(entry) or nd_pattern.search(entry):
+ continue
+ diagnostics.append(
+ LintDiagnostic(
+ code="CITATION.AUTHOR_DATE.MISSING_YEAR",
+ message="Author-date references should include a year (or n.d.)",
+ severity="should",
+ path=str(doc.path),
+ line=idx,
+ column=1,
+ rule_id="HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.YEAR_REQUIRED",
+ )
+ )
+
+ if author_date_present and not ref_heading_found:
+ diagnostics.append(
+ LintDiagnostic(
+ code="CITATION.AUTHOR_DATE.REFLIST_REQUIRED",
+ message="Provide a reference list when using author-date citations",
+ severity="should",
+ path=str(doc.path),
+ line=1,
+ column=1,
+ rule_id="HOUSE.CITATIONS.AUTHOR_DATE.REFLIST.REQUIRED",
+ )
+ )
+
+ return diagnostics
+
+
+def _lint_i18n_consistency(doc: MdDocument) -> list[LintDiagnostic]:
+ diagnostics: list[LintDiagnostic] = []
+ lines = doc.normalized_source.splitlines()
+ fenced = code_fence_lines(doc.normalized_source)
+ comma_decimal = re.compile(r"\b\d+,\d{1,2}\b")
+ dot_decimal = re.compile(r"\b\d+\.\d{1,2}\b")
+
+ comma_line = None
+ dot_line = None
+ guillemet_line = None
+ curly_line = None
+
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ continue
+ clean = _strip_inline_code(line)
+ if comma_line is None and comma_decimal.search(clean):
+ comma_line = idx
+ if dot_line is None and dot_decimal.search(clean):
+ dot_line = idx
+ if guillemet_line is None and ("«" in clean or "»" in clean):
+ guillemet_line = idx
+ if curly_line is None and ("“" in clean or "”" in clean):
+ curly_line = idx
+
+ if comma_line is not None and dot_line is not None:
+ diagnostics.append(
+ LintDiagnostic(
+ code="I18N.MIXED_DECIMAL_SEPARATORS",
+ message="Avoid mixing decimal separators within the same document",
+ severity="should",
+ path=str(doc.path),
+ line=comma_line,
+ column=1,
+ rule_id="HOUSE.I18N.NUMBERS.MIXED_DECIMAL_SEPARATORS",
+ )
+ )
+ if guillemet_line is not None and curly_line is not None:
+ diagnostics.append(
+ LintDiagnostic(
+ code="I18N.MIXED_QUOTE_STYLES",
+ message="Avoid mixing quotation styles across locales in the same document",
+ severity="should",
+ path=str(doc.path),
+ line=guillemet_line,
+ column=1,
+ rule_id="HOUSE.I18N.QUOTES.MIXED_STYLES",
+ )
+ )
+
+ return diagnostics
+
+
+def _normalize_sentence_spacing(lines: list[str], fenced: set[int]) -> tuple[list[str], int]:
+ out: list[str] = []
+ count = 0
+ pattern = re.compile(r"([.!?][\]\)\"']?)( {2,})")
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ out.append(line)
+ continue
+ parts: list[str] = []
+ for is_code, seg in _split_inline_code(line):
+ if is_code:
+ parts.append(seg)
+ continue
+ new_seg, n = pattern.subn(r"\1 ", seg)
+ count += n
+ parts.append(new_seg)
+ out.append("".join(parts))
+ return out, count
+
+
+def _normalize_colon_spacing(lines: list[str], fenced: set[int]) -> tuple[list[str], int]:
+ out: list[str] = []
+ count = 0
+ pattern_many = re.compile(r": {2,}")
+ pattern_missing = re.compile(r":(?!\s)(?=[A-Za-z])")
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced or "://" in line:
+ out.append(line)
+ continue
+ parts: list[str] = []
+ for is_code, seg in _split_inline_code(line):
+ if is_code:
+ parts.append(seg)
+ continue
+ seg2, n1 = pattern_many.subn(": ", seg)
+ seg3, n2 = pattern_missing.subn(": ", seg2)
+ count += n1 + n2
+ parts.append(seg3)
+ out.append("".join(parts))
+ return out, count
+
+
+def _normalize_em_dashes(lines: list[str], fenced: set[int]) -> tuple[list[str], int]:
+ out: list[str] = []
+ count = 0
+ pattern = re.compile(r"\s--\s")
+ spaced = re.compile(r"\s—\s")
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ out.append(line)
+ continue
+ parts: list[str] = []
+ for is_code, seg in _split_inline_code(line):
+ if is_code:
+ parts.append(seg)
+ continue
+ seg2, n1 = pattern.subn("—", seg)
+ seg3, n2 = spaced.subn("—", seg2)
+ count += n1 + n2
+ parts.append(seg3)
+ out.append("".join(parts))
+ return out, count
+
+
+def _normalize_leading_zero_decimals(lines: list[str], fenced: set[int]) -> tuple[list[str], int]:
+ out: list[str] = []
+ count = 0
+ pattern = re.compile(r"(? tuple[list[str], int]:
+ out: list[str] = []
+ count = 0
+ pattern = re.compile(r"\b(\d{4})[’']s(?=$|[\s\.,;:!?])")
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ out.append(line)
+ continue
+ parts: list[str] = []
+ for is_code, seg in _split_inline_code(line):
+ if is_code:
+ parts.append(seg)
+ continue
+ seg2, n = pattern.subn(r"\1s", seg)
+ count += n
+ parts.append(seg2)
+ out.append("".join(parts))
+ return out, count
+
+
+def _normalize_markdown_link_trailing_punct(lines: list[str], fenced: set[int]) -> tuple[list[str], int]:
+ out: list[str] = []
+ count = 0
+ pattern = re.compile(r"\]\((https?://[^)\s]+?)([\.,;:])\)")
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ out.append(line)
+ continue
+ new_line, n = pattern.subn(r"](\1)\2", line)
+ count += n
+ out.append(new_line)
+ return out, count
+
+
+def _normalize_smart_quotes(lines: list[str], fenced: set[int]) -> tuple[list[str], int]:
+ out: list[str] = []
+ count = 0
+ for idx, line in enumerate(lines, start=1):
+ if idx in fenced:
+ out.append(line)
+ continue
+ parts: list[str] = []
+ for is_code, seg in _split_inline_code(line):
+ if is_code or seg.count('"') % 2 != 0:
+ parts.append(seg)
+ continue
+ opening = True
+ new_chars: list[str] = []
+ local = 0
+ for ch in seg:
+ if ch != '"':
+ new_chars.append(ch)
+ continue
+ new_chars.append("“" if opening else "”")
+ opening = not opening
+ local += 1
+ count += local
+ parts.append("".join(new_chars))
+ out.append("".join(parts))
+ return out, count
+
+
def _build_report(
*,
diagnostics: list[LintDiagnostic],
diff --git a/src/iftypeset/md_parser.py b/src/iftypeset/md_parser.py
index 03ed6c0..515f3b8 100644
--- a/src/iftypeset/md_parser.py
+++ b/src/iftypeset/md_parser.py
@@ -47,6 +47,7 @@ def normalize_newlines(text: str) -> str:
def detect_degraded(text: str) -> list[str]:
reasons: list[str] = []
lines = [ln for ln in text.splitlines()]
+ non_empty = [ln for ln in lines if ln.strip()]
fenced = code_fence_lines(text)
content_lines: list[str] = []
for idx, ln in enumerate(lines, start=1):
@@ -69,10 +70,27 @@ def detect_degraded(text: str) -> list[str]:
short = [l for l in lengths if l < 35]
ratio = len(short) / max(len(lengths), 1)
median = lengths[len(lengths) // 2]
- if len(lengths) >= 20 and ((ratio > 0.8 and median < 40) or (ratio > 0.6 and median < 30)):
+ continuations = 0
+ possible = 0
+ for prev, nxt in zip(content_lines, content_lines[1:]):
+ if not prev or not nxt:
+ continue
+ possible += 1
+ prev_last = prev[-1]
+ next_first = nxt[0]
+ if prev_last == "-" and next_first.islower():
+ continuations += 1
+ elif prev_last.isalpha() and prev_last.islower() and next_first.islower():
+ continuations += 1
+ continuation_ratio = continuations / max(possible, 1)
+ if (
+ len(lengths) >= 20
+ and continuation_ratio > 0.3
+ and ((ratio > 0.8 and median < 40) or (ratio > 0.6 and median < 30))
+ ):
reasons.append("hard_wrap_density")
- if not any(re.match(r"^#{1,6}\s+", ln) for ln in lines):
+ if len(non_empty) >= 12 and not any(re.match(r"^#{1,6}\s+", ln) for ln in lines):
reasons.append("missing_headings")
return reasons
@@ -124,7 +142,7 @@ def parse_markdown(path: Path, text: str) -> MdDocument:
original = normalize_newlines(text)
reasons = detect_degraded(original)
normalized = original
- if reasons:
+ if "hard_wrap_density" in reasons:
normalized = unwrap_hard_wrapped_paragraphs(original)
blocks = _parse_blocks(normalized)
return MdDocument(
@@ -294,7 +312,7 @@ def _parse_blockquote(lines: list[str], start: int) -> MdBlock:
def _parse_paragraph(lines: list[str], start: int) -> MdBlock:
i = start
- parts: list[str] = []
+ paragraph_lines: list[tuple[str, bool]] = []
while i < len(lines):
line = lines[i]
if not line.strip():
@@ -303,9 +321,23 @@ def _parse_paragraph(lines: list[str], start: int) -> MdBlock:
break
if line.lstrip().startswith(">"):
break
- parts.append(line.strip())
+ hard_break = line.endswith(" ")
+ clean = line.rstrip()
+ if clean.endswith("\\"):
+ hard_break = True
+ clean = clean[:-1].rstrip()
+ text_line = clean.strip()
+ if text_line:
+ paragraph_lines.append((text_line, hard_break))
i += 1
- text = " ".join(parts)
+ text_parts: list[str] = []
+ prev_break = False
+ for idx, (text_line, hard_break) in enumerate(paragraph_lines):
+ if idx > 0:
+ text_parts.append("\n" if prev_break else " ")
+ text_parts.append(text_line)
+ prev_break = hard_break
+ text = "".join(text_parts)
return MdBlock(type="paragraph", start_line=start + 1, end_line=i, text=text)
diff --git a/src/iftypeset/qa.py b/src/iftypeset/qa.py
index f64a168..1e081f2 100644
--- a/src/iftypeset/qa.py
+++ b/src/iftypeset/qa.py
@@ -5,7 +5,9 @@ from datetime import datetime, timezone
from html.parser import HTMLParser
from pathlib import Path
import re
+import subprocess
from typing import Any
+import xml.etree.ElementTree as ET
from iftypeset import __version__
@@ -26,6 +28,15 @@ class LayoutReport:
analysis_mode: str
+@dataclass(frozen=True)
+class PdfAnalysisResult:
+ ok: bool
+ metrics: dict[str, int]
+ incidents: list[LayoutIncident]
+ warnings: list[str]
+ page_count: int | None = None
+
+
@dataclass
class _Block:
type: str
@@ -41,7 +52,7 @@ class HtmlCollector(HTMLParser):
self.headings: list[tuple[int, str]] = []
self.links: list[tuple[str, str]] = []
self.code_blocks: list[str] = []
- self.tables: list[dict[str, int]] = []
+ self.tables: list[dict[str, object]] = []
self.blocks: list[_Block] = []
self._heading_level: int | None = None
self._heading_text: list[str] = []
@@ -56,6 +67,7 @@ class HtmlCollector(HTMLParser):
self._in_table = False
self._table_rows: list[int] = []
self._table_cell_lengths: list[int] = []
+ self._table_max_cell_sample = ""
self._table_word_count = 0
self._current_row_cols = 0
self._cell_text: list[str] | None = None
@@ -84,6 +96,7 @@ class HtmlCollector(HTMLParser):
self._in_table = True
self._table_rows = []
self._table_cell_lengths = []
+ self._table_max_cell_sample = ""
self._table_word_count = 0
self._current_row_cols = 0
if tag == "tr" and self._in_table:
@@ -125,7 +138,10 @@ class HtmlCollector(HTMLParser):
self._list_text = []
if tag in {"td", "th"} and self._in_table and self._cell_text is not None:
text = " ".join(self._cell_text).strip()
+ cell_len = len(text)
self._table_cell_lengths.append(len(text))
+ if cell_len >= max(self._table_cell_lengths):
+ self._table_max_cell_sample = text[:120]
self._table_word_count += _word_count(text)
self._current_row_cols += 1
self._cell_text = None
@@ -136,11 +152,19 @@ class HtmlCollector(HTMLParser):
max_cols = max(self._table_rows) if self._table_rows else 0
max_cell = max(self._table_cell_lengths) if self._table_cell_lengths else 0
row_count = len(self._table_rows)
- self.tables.append({"max_cols": max_cols, "max_cell_len": max_cell, "rows": row_count})
+ self.tables.append(
+ {
+ "max_cols": max_cols,
+ "max_cell_len": max_cell,
+ "rows": row_count,
+ "max_cell_sample": self._table_max_cell_sample,
+ }
+ )
self.blocks.append(_Block(type="table", word_count=self._table_word_count, line_count=row_count))
self._in_table = False
self._table_rows = []
self._table_cell_lengths = []
+ self._table_max_cell_sample = ""
self._table_word_count = 0
def handle_data(self, data: str) -> None:
@@ -167,30 +191,77 @@ def analyze_html(html_text: str, profile: dict[str, Any], *, analysis_mode: str
body_chars = int(body_chars)
link_threshold = max(80, body_chars)
code_threshold = max(90, body_chars + 15)
- table_max_cols = 6
- table_max_cell = 40
+ table_profile = profile.get("tables") or {}
+ shrink_limit = table_profile.get("shrink_limit") or 0.9
+ try:
+ shrink_limit_f = float(shrink_limit)
+ except (TypeError, ValueError):
+ shrink_limit_f = 0.9
+ if not (0.5 <= shrink_limit_f <= 1.0):
+ shrink_limit_f = 0.9
+ effective_chars = int(body_chars * min(1.15, 1.0 / shrink_limit_f))
+ table_max_cols = max(5, min(12, int(round(effective_chars / 11.0))))
+ table_max_cell = max(30, min(100, int(round(effective_chars * 0.6))))
incidents: list[LayoutIncident] = []
link_wrap = 0
+ anchor_tokens: set[str] = set()
for href, text in collector.links:
- token = text or href
- if _long_unbroken(token, link_threshold):
+ for token in _extract_link_like_tokens(text):
+ anchor_tokens.add(token)
+ for token in _extract_link_like_tokens(href):
+ anchor_tokens.add(token)
+
+ for href, text in collector.links:
+ candidates = _extract_link_like_tokens(text) + _extract_link_like_tokens(href)
+ token = max(candidates, key=len) if candidates else (text or href)
+ if token and _long_unbroken(token, link_threshold):
link_wrap += 1
incidents.append(LayoutIncident(kind="link_wrap", detail=href, context=token[:120]))
+ for block in collector.blocks:
+ if block.type not in {"paragraph", "list_item"}:
+ continue
+ tokens = {t for t in _extract_link_like_tokens(block.text) if t not in anchor_tokens}
+ for token in sorted(tokens):
+ if not _long_unbroken(token, link_threshold):
+ continue
+ link_wrap += 1
+ incidents.append(LayoutIncident(kind="link_wrap", detail=token, context=block.text[:140]))
+
code_overflow = 0
for code in collector.code_blocks:
- max_len = max((len(line) for line in code.splitlines()), default=0)
+ max_len = 0
+ max_line_no = 0
+ max_line_sample = ""
+ for idx, line in enumerate(code.splitlines(), start=1):
+ ln = len(line)
+ if ln >= max_len:
+ max_len = ln
+ max_line_no = idx
+ max_line_sample = line[:120]
if max_len > code_threshold:
code_overflow += 1
- incidents.append(LayoutIncident(kind="code_overflow", detail=f"line_len={max_len}"))
+ incidents.append(
+ LayoutIncident(
+ kind="code_overflow",
+ detail=f"line_len={max_len} line_no={max_line_no}",
+ context=max_line_sample or None,
+ )
+ )
table_overflow = 0
for table in collector.tables:
if table.get("max_cols", 0) > table_max_cols or table.get("max_cell_len", 0) > table_max_cell:
table_overflow += 1
- incidents.append(LayoutIncident(kind="table_overflow", detail=str(table)))
+ incidents.append(
+ LayoutIncident(
+ kind="table_overflow",
+ detail=f"cols={table.get('max_cols')} max_cell_len={table.get('max_cell_len')} rows={table.get('rows')} (limits cols={table_max_cols} cell={table_max_cell})",
+ context=str(table.get("max_cell_sample") or "")[:140] or None,
+ )
+ )
heading_errors, heading_incidents = _heading_numbering_errors(collector.headings)
incidents.extend(heading_incidents)
@@ -198,7 +269,8 @@ def analyze_html(html_text: str, profile: dict[str, Any], *, analysis_mode: str
stranded, stranded_incidents = _stranded_headings(collector.blocks, profile)
incidents.extend(stranded_incidents)
- overfull_lines = _overfull_lines(collector.blocks, body_chars)
+ overfull_lines, overfull_incidents = _overfull_lines(collector.blocks, body_chars)
+ incidents.extend(overfull_incidents)
metrics = {
"max_widows_per_10_pages": 0,
"max_orphans_per_10_pages": 0,
@@ -209,6 +281,10 @@ def analyze_html(html_text: str, profile: dict[str, Any], *, analysis_mode: str
"max_link_wrap_incidents": link_wrap,
"max_heading_numbering_errors": heading_errors,
"max_citation_format_errors": 0,
+ "max_caption_separation_incidents": 0,
+ "max_list_break_incidents": 0,
+ "max_heading_proximity_incidents": 0,
+ "max_runt_final_page": 0,
}
return LayoutReport(
@@ -220,6 +296,77 @@ def analyze_html(html_text: str, profile: dict[str, Any], *, analysis_mode: str
)
+def analyze_pdf(pdf_path: Path, profile: dict[str, Any], *, analysis_mode: str = "pdf") -> PdfAnalysisResult:
+ warnings: list[str] = []
+ page_count, info_warnings = _run_pdfinfo(pdf_path)
+ warnings.extend(info_warnings)
+ pages, text_warnings = _run_pdftotext(pdf_path)
+ warnings.extend(text_warnings)
+ xml_pages, xml_warnings = _run_pdftohtml_xml(pdf_path)
+ warnings.extend(xml_warnings)
+
+ if not pages:
+ if not warnings:
+ warnings.append("PDF analysis failed; HTML-only analysis used")
+ return PdfAnalysisResult(ok=False, metrics={}, incidents=[], warnings=warnings, page_count=page_count)
+
+ if page_count and page_count != len(pages):
+ warnings.append(
+ f"pdfinfo pages ({page_count}) differ from pdftotext pages ({len(pages)}); using pdftotext output"
+ )
+
+ measure = profile.get("measure_targets") or {}
+ body_chars = (measure.get("body_chars_per_line") or {}).get("max") or 75
+ body_chars = int(body_chars)
+ keep_lines = int((profile.get("headings") or {}).get("keep_with_next_lines") or 2)
+ heading_max_chars = max(24, min(60, int(body_chars * 0.75)))
+
+ widows_per_page, orphans_per_page, incidents = _detect_widows_orphans(pages)
+ pagination_cfg = profile.get("pagination") or {}
+ runt_ratio = float(pagination_cfg.get("min_last_page_ratio") or 0.33)
+ runt_min_lines = int(pagination_cfg.get("min_last_page_lines") or 4)
+ runt_count, runt_incidents = _detect_runt_final_page(
+ pages,
+ min_ratio=runt_ratio,
+ min_lines=runt_min_lines,
+ )
+ overfull_counts, overfull_incidents = _detect_pdf_overfull_lines(pages, body_chars)
+ caption_counts, caption_incidents = _detect_caption_separation_pdf(pages)
+ list_counts, list_incidents = _detect_list_breaks_pdf(pages)
+ bbox_counts: list[int] = []
+ bbox_incidents: list[LayoutIncident] = []
+ if xml_pages:
+ bbox_counts, bbox_incidents = _detect_pdf_bbox_overflow(xml_pages, tolerance=2.0)
+ incidents.extend(bbox_incidents)
+ stranded_counts, stranded_incidents = _detect_stranded_headings_pdf(pages, keep_lines, heading_max_chars)
+ proximity_counts, proximity_incidents = _detect_heading_proximity_pdf(pages, heading_max_chars)
+ incidents.extend(overfull_incidents)
+ incidents.extend(caption_incidents)
+ incidents.extend(list_incidents)
+ incidents.extend(stranded_incidents)
+ incidents.extend(proximity_incidents)
+ incidents.extend(runt_incidents)
+
+ metrics = {
+ "max_widows_per_10_pages": _max_count_per_window(widows_per_page, window=10),
+ "max_orphans_per_10_pages": _max_count_per_window(orphans_per_page, window=10),
+ "max_overfull_lines": sum(overfull_counts) + sum(bbox_counts),
+ "max_stranded_headings": sum(stranded_counts),
+ "max_caption_separation_incidents": sum(caption_counts),
+ "max_list_break_incidents": sum(list_counts),
+ "max_heading_proximity_incidents": sum(proximity_counts),
+ "max_runt_final_page": runt_count,
+ }
+ warnings.append("PDF QA is heuristic and based on text extraction; verify layout for release-quality outputs.")
+ return PdfAnalysisResult(
+ ok=True,
+ metrics=metrics,
+ incidents=incidents,
+ warnings=warnings,
+ page_count=page_count or len(pages),
+ )
+
+
def evaluate_gates(
metrics: dict[str, int],
gates: dict[str, int],
@@ -321,16 +468,18 @@ def _stranded_headings(blocks: list[_Block], profile: dict[str, Any]) -> tuple[i
return stranded, incidents
-def _overfull_lines(blocks: list[_Block], max_chars: int) -> int:
+def _overfull_lines(blocks: list[_Block], max_chars: int) -> tuple[int, list[LayoutIncident]]:
count = 0
+ incidents: list[LayoutIncident] = []
for block in blocks:
if block.type not in {"paragraph", "list_item"}:
continue
for token in re.findall(r"\S+", block.text):
if len(token) > max_chars:
count += 1
+ incidents.append(LayoutIncident(kind="overfull_token", detail=token[:120], context=block.text[:140]))
break
- return count
+ return count, incidents
def _long_unbroken(text: str, threshold: int) -> bool:
@@ -342,3 +491,569 @@ def _long_unbroken(text: str, threshold: int) -> bool:
def _word_count(text: str) -> int:
return len([t for t in re.split(r"\s+", text.strip()) if t])
+
+
+def _run_pdfinfo(pdf_path: Path) -> tuple[int | None, list[str]]:
+ warnings: list[str] = []
+ try:
+ proc = subprocess.run(
+ ["pdfinfo", str(pdf_path)],
+ check=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+ except FileNotFoundError:
+ return None, ["pdfinfo not available; PDF analysis skipped"]
+ except subprocess.CalledProcessError as exc:
+ msg = exc.stderr.decode("utf-8", errors="replace").strip() or "pdfinfo failed"
+ return None, [msg]
+
+ text = proc.stdout.decode("utf-8", errors="replace")
+ match = re.search(r"^Pages:\s+(\d+)\s*$", text, flags=re.MULTILINE)
+ if not match:
+ warnings.append("pdfinfo did not report page count")
+ return None, warnings
+ return int(match.group(1)), warnings
+
+
+def _run_pdftotext(pdf_path: Path) -> tuple[list[str], list[str]]:
+ warnings: list[str] = []
+ try:
+ proc = subprocess.run(
+ ["pdftotext", "-layout", str(pdf_path), "-"],
+ check=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+ except FileNotFoundError:
+ return [], ["pdftotext not available; PDF analysis skipped"]
+ except subprocess.CalledProcessError as exc:
+ msg = exc.stderr.decode("utf-8", errors="replace").strip() or "pdftotext failed"
+ return [], [msg]
+
+ text = proc.stdout.decode("utf-8", errors="replace")
+ pages = _split_pdf_pages(text)
+ if not pages:
+ warnings.append("pdftotext returned no extractable text")
+ return pages, warnings
+
+
+def _safe_float(value: str | None) -> float:
+ try:
+ return float(value) if value is not None else 0.0
+ except (TypeError, ValueError):
+ return 0.0
+
+
+def _run_pdftohtml_xml(pdf_path: Path) -> tuple[list[dict[str, Any]], list[str]]:
+ warnings: list[str] = []
+ try:
+ proc = subprocess.run(
+ ["pdftohtml", "-xml", "-stdout", str(pdf_path)],
+ check=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+ except FileNotFoundError:
+ return [], ["pdftohtml not available; PDF bbox analysis skipped"]
+ except subprocess.CalledProcessError as exc:
+ msg = exc.stderr.decode("utf-8", errors="replace").strip() or "pdftohtml failed"
+ return [], [msg]
+
+ raw = proc.stdout.decode("utf-8", errors="replace").strip()
+ if not raw:
+ return [], ["pdftohtml returned no XML output"]
+ try:
+ root = ET.fromstring(raw)
+ except ET.ParseError as exc:
+ return [], [f"pdftohtml XML parse error: {exc}"]
+
+ pages: list[dict[str, Any]] = []
+ for page in root.findall(".//page"):
+ width = _safe_float(page.get("width"))
+ height = _safe_float(page.get("height"))
+ number_raw = page.get("number")
+ try:
+ number = int(number_raw) if number_raw is not None else len(pages) + 1
+ except ValueError:
+ number = len(pages) + 1
+
+ texts: list[dict[str, Any]] = []
+ for node in page.findall("text"):
+ text = "".join(node.itertext()).strip()
+ if not text:
+ continue
+ texts.append(
+ {
+ "left": _safe_float(node.get("left")),
+ "top": _safe_float(node.get("top")),
+ "width": _safe_float(node.get("width")),
+ "height": _safe_float(node.get("height")),
+ "text": text,
+ }
+ )
+ pages.append({"number": number, "width": width, "height": height, "texts": texts})
+
+ if not pages:
+ warnings.append("pdftohtml XML contained no pages")
+ return pages, warnings
+
+
+def _split_pdf_pages(text: str) -> list[str]:
+ pages = text.split("\f")
+ if pages and not pages[-1].strip():
+ pages = pages[:-1]
+ return pages
+
+
+def _max_count_per_window(counts: list[int], *, window: int) -> int:
+ if not counts:
+ return 0
+ if len(counts) <= window:
+ return sum(counts)
+ max_sum = 0
+ running = sum(counts[:window])
+ max_sum = max(max_sum, running)
+ for i in range(window, len(counts)):
+ running += counts[i] - counts[i - window]
+ if running > max_sum:
+ max_sum = running
+ return max_sum
+
+
+_PAGE_NUMBER_RE = re.compile(r"^\s*([ivxlcdmIVXLCDM]+|\d{1,4})\s*$")
+_CAPTION_RE = re.compile(r"^(figure|fig\.|table|tbl\.)\s*\d+[A-Za-z0-9.\-]*\b", flags=re.IGNORECASE)
+_LIST_ITEM_RE = re.compile(r"^\s*(?:[-*•]|\d+[.)])\s+\S+")
+_LIST_INTRO_RE = re.compile(r".+:\s*$")
+
+
+def _normalize_pdf_lines(page_text: str) -> list[str]:
+ lines = [ln.rstrip() for ln in page_text.splitlines()]
+ out: list[str] = []
+ for ln in lines:
+ if _PAGE_NUMBER_RE.match(ln):
+ out.append("")
+ else:
+ out.append(ln)
+ return out
+
+
+def _median_int(values: list[int]) -> int:
+ if not values:
+ return 0
+ vals = sorted(values)
+ mid = len(vals) // 2
+ if len(vals) % 2:
+ return vals[mid]
+ return int(round((vals[mid - 1] + vals[mid]) / 2))
+
+
+def _detect_runt_final_page(
+ pages: list[str],
+ *,
+ min_ratio: float,
+ min_lines: int,
+) -> tuple[int, list[LayoutIncident]]:
+ if len(pages) < 2:
+ return 0, []
+ line_counts = []
+ for page in pages:
+ lines = [ln for ln in _normalize_pdf_lines(page) if ln.strip()]
+ line_counts.append(len(lines))
+ last_lines = line_counts[-1] if line_counts else 0
+ sample_counts = [c for c in line_counts[:-1] if c >= max(4, min_lines)]
+ if not sample_counts:
+ return 0, []
+ typical = _median_int(sample_counts)
+ threshold = max(min_lines, int(round(typical * min_ratio)))
+ if last_lines >= threshold:
+ return 0, []
+
+ lines = [ln.strip() for ln in _normalize_pdf_lines(pages[-1]) if ln.strip()]
+ snippet = " | ".join(lines[:3])
+ incident = LayoutIncident(
+ kind="runt_final_page_pdf",
+ detail=f"page={len(pages)} lines={last_lines} threshold={threshold} typical={typical}",
+ context=snippet or None,
+ )
+ return 1, [incident]
+
+
+def _non_empty_line_indices(lines: list[str]) -> list[int]:
+ return [i for i, ln in enumerate(lines) if ln.strip()]
+
+
+def _caption_line_kind(line: str) -> str | None:
+ s = line.strip()
+ if not s:
+ return None
+ match = _CAPTION_RE.match(s)
+ if not match:
+ return None
+ return match.group(1).lower().rstrip(".")
+
+
+def _page_edge_info(page_text: str) -> dict[str, object]:
+ lines = _normalize_pdf_lines(page_text)
+ if not any(ln.strip() for ln in lines):
+ return {
+ "leading_lines": 0,
+ "trailing_lines": 0,
+ "leading_blank": True,
+ "trailing_blank": True,
+ "leading_snippet": "",
+ "trailing_snippet": "",
+ }
+ first_idx = next(i for i, ln in enumerate(lines) if ln.strip())
+ last_idx = len(lines) - 1 - next(i for i, ln in enumerate(reversed(lines)) if ln.strip())
+ leading_blank = first_idx > 0
+ trailing_blank = last_idx < len(lines) - 1
+ trimmed = lines[first_idx : last_idx + 1]
+
+ leading_lines = 0
+ leading_snip: list[str] = []
+ for ln in trimmed:
+ if not ln.strip():
+ break
+ leading_lines += 1
+ if len(leading_snip) < 3:
+ leading_snip.append(ln.strip())
+
+ trailing_lines = 0
+ trailing_snip: list[str] = []
+ for ln in reversed(trimmed):
+ if not ln.strip():
+ break
+ trailing_lines += 1
+ if len(trailing_snip) < 3:
+ trailing_snip.append(ln.strip())
+ trailing_snip = list(reversed(trailing_snip))
+
+ return {
+ "leading_lines": leading_lines,
+ "trailing_lines": trailing_lines,
+ "leading_blank": leading_blank,
+ "trailing_blank": trailing_blank,
+ "leading_snippet": " ".join(leading_snip).strip(),
+ "trailing_snippet": " ".join(trailing_snip).strip(),
+ }
+
+
+def _detect_widows_orphans(pages: list[str]) -> tuple[list[int], list[int], list[LayoutIncident]]:
+ widows = [0 for _ in pages]
+ orphans = [0 for _ in pages]
+ incidents: list[LayoutIncident] = []
+ infos = [_page_edge_info(p) for p in pages]
+
+ for idx in range(len(pages) - 1):
+ cur = infos[idx]
+ nxt = infos[idx + 1]
+ if (
+ cur["trailing_lines"] == 0
+ or nxt["leading_lines"] == 0
+ or cur["trailing_blank"]
+ or nxt["leading_blank"]
+ ):
+ continue
+ if cur["trailing_lines"] == 1:
+ orphans[idx] += 1
+ incidents.append(
+ LayoutIncident(
+ kind="orphan_pdf",
+ detail=f"page={idx + 1}",
+ context=str(cur.get("trailing_snippet") or "")[:140] or None,
+ )
+ )
+ if nxt["leading_lines"] == 1:
+ widows[idx + 1] += 1
+ incidents.append(
+ LayoutIncident(
+ kind="widow_pdf",
+ detail=f"page={idx + 2}",
+ context=str(nxt.get("leading_snippet") or "")[:140] or None,
+ )
+ )
+ return widows, orphans, incidents
+
+
+def _is_heading_candidate(text: str, *, max_chars: int, blank_before: bool, blank_after: bool) -> bool:
+ s = text.strip()
+ if not s or len(s) > max_chars:
+ return False
+ if not re.search(r"[A-Za-z]", s):
+ return False
+ if re.match(r"^[-*+•]\s", s):
+ return False
+ if re.match(r"^\d+[\.)]\s", s):
+ return False
+ if re.search(r"[.!;]$", s):
+ return False
+ words = [w for w in re.split(r"\s+", s) if w]
+ if len(words) > 1:
+ upper_words = sum(1 for w in words if w[:1].isupper())
+ if upper_words / len(words) < 0.6 and not s.isupper():
+ return False
+ if not (blank_before or blank_after or s.isupper()):
+ return False
+ return True
+
+
+def _detect_stranded_headings_pdf(
+ pages: list[str], keep_lines: int, heading_max_chars: int
+) -> tuple[list[int], list[LayoutIncident]]:
+ counts = [0 for _ in pages]
+ incidents: list[LayoutIncident] = []
+ for idx in range(len(pages) - 1):
+ lines = _normalize_pdf_lines(pages[idx])
+ if not any(ln.strip() for ln in lines):
+ continue
+ candidate_idx = None
+ for i in range(len(lines) - 1, -1, -1):
+ s = lines[i].strip()
+ if not s:
+ continue
+ blank_before = i == 0 or not lines[i - 1].strip()
+ blank_after = i == len(lines) - 1 or not lines[i + 1].strip()
+ if _is_heading_candidate(s, max_chars=heading_max_chars, blank_before=blank_before, blank_after=blank_after):
+ candidate_idx = i
+ candidate_text = s
+ break
+ if len(s) > heading_max_chars:
+ continue
+ if candidate_idx is None:
+ continue
+ following = sum(1 for ln in lines[candidate_idx + 1 :] if ln.strip())
+ if following < keep_lines:
+ counts[idx] += 1
+ incidents.append(
+ LayoutIncident(
+ kind="stranded_heading_pdf",
+ detail=f"page={idx + 1}",
+ context=str(candidate_text)[:140] or None,
+ )
+ )
+ return counts, incidents
+
+
+def _detect_caption_separation_pdf(pages: list[str]) -> tuple[list[int], list[LayoutIncident]]:
+ counts = [0 for _ in pages]
+ incidents: list[LayoutIncident] = []
+ for idx, page in enumerate(pages):
+ lines = _normalize_pdf_lines(page)
+ non_empty = _non_empty_line_indices(lines)
+ if not non_empty:
+ continue
+ first_non = non_empty[0]
+ last_non = non_empty[-1]
+ edge_window = {non_empty[0], non_empty[1] if len(non_empty) > 1 else non_empty[0], non_empty[-1]}
+ if len(non_empty) > 1:
+ edge_window.add(non_empty[-2])
+ for line_idx in non_empty:
+ kind = _caption_line_kind(lines[line_idx])
+ if not kind:
+ continue
+ at_top = line_idx in edge_window and line_idx <= first_non + 1
+ at_bottom = line_idx in edge_window and line_idx >= last_non - 1
+ sparse_page = len(non_empty) <= 5
+ if not (at_top or at_bottom or sparse_page):
+ continue
+ pos = "top" if at_top else "bottom" if at_bottom else "sparse"
+ counts[idx] += 1
+ incidents.append(
+ LayoutIncident(
+ kind="caption_separation_pdf",
+ detail=f"page={idx + 1} pos={pos}",
+ context=str(lines[line_idx].strip())[:140] or None,
+ )
+ )
+ return counts, incidents
+
+
+def _detect_list_breaks_pdf(pages: list[str]) -> tuple[list[int], list[LayoutIncident]]:
+ counts = [0 for _ in pages]
+ incidents: list[LayoutIncident] = []
+ for idx, page in enumerate(pages):
+ lines = _normalize_pdf_lines(page)
+ non_empty = _non_empty_line_indices(lines)
+ if not non_empty:
+ continue
+ list_lines = [i for i in non_empty if _LIST_ITEM_RE.match(lines[i])]
+
+ if len(list_lines) == 1:
+ lone_idx = list_lines[0]
+ if lone_idx == non_empty[0] or lone_idx == non_empty[-1]:
+ counts[idx] += 1
+ incidents.append(
+ LayoutIncident(
+ kind="list_lonely_item_pdf",
+ detail=f"page={idx + 1}",
+ context=str(lines[lone_idx].strip())[:140] or None,
+ )
+ )
+
+ last_idx = non_empty[-1]
+ if _LIST_INTRO_RE.search(lines[last_idx].strip()) and idx + 1 < len(pages):
+ next_lines = _normalize_pdf_lines(pages[idx + 1])
+ next_non_empty = _non_empty_line_indices(next_lines)
+ if next_non_empty and _LIST_ITEM_RE.match(next_lines[next_non_empty[0]]):
+ counts[idx] += 1
+ incidents.append(
+ LayoutIncident(
+ kind="list_intro_separated_pdf",
+ detail=f"page={idx + 1} -> {idx + 2}",
+ context=str(lines[last_idx].strip())[:140] or None,
+ )
+ )
+ return counts, incidents
+
+
+def _collect_heading_candidates(lines: list[str], max_chars: int) -> set[int]:
+ candidates: set[int] = set()
+ for i, line in enumerate(lines):
+ s = line.strip()
+ if not s:
+ continue
+ blank_before = i == 0 or not lines[i - 1].strip()
+ blank_after = i == len(lines) - 1 or not lines[i + 1].strip()
+ if _is_heading_candidate(s, max_chars=max_chars, blank_before=blank_before, blank_after=blank_after):
+ candidates.add(i)
+ return candidates
+
+
+def _detect_heading_proximity_pdf(pages: list[str], heading_max_chars: int) -> tuple[list[int], list[LayoutIncident]]:
+ counts = [0 for _ in pages]
+ incidents: list[LayoutIncident] = []
+ for idx, page in enumerate(pages):
+ lines = _normalize_pdf_lines(page)
+ non_empty = _non_empty_line_indices(lines)
+ if not non_empty:
+ continue
+ candidates = _collect_heading_candidates(lines, heading_max_chars)
+ for line_idx in non_empty:
+ if line_idx not in candidates:
+ continue
+ next_idx = next((j for j in non_empty if j > line_idx), None)
+ if next_idx is not None and next_idx in candidates:
+ counts[idx] += 1
+ incidents.append(
+ LayoutIncident(
+ kind="heading_proximity_pdf",
+ detail=f"page={idx + 1}",
+ context=str(lines[line_idx].strip())[:140] or None,
+ )
+ )
+ break
+ last_idx = non_empty[-1]
+ if last_idx in candidates and idx + 1 < len(pages):
+ next_lines = _normalize_pdf_lines(pages[idx + 1])
+ next_non_empty = _non_empty_line_indices(next_lines)
+ if next_non_empty:
+ next_candidates = _collect_heading_candidates(next_lines, heading_max_chars)
+ if next_non_empty[0] in next_candidates:
+ counts[idx] += 1
+ incidents.append(
+ LayoutIncident(
+ kind="heading_proximity_pdf",
+ detail=f"page={idx + 1} -> {idx + 2}",
+ context=str(lines[last_idx].strip())[:140] or None,
+ )
+ )
+ return counts, incidents
+
+
+def _detect_pdf_overfull_lines(pages: list[str], max_chars: int) -> tuple[list[int], list[LayoutIncident]]:
+ counts = [0 for _ in pages]
+ incidents: list[LayoutIncident] = []
+ for idx, page in enumerate(pages):
+ lines = _normalize_pdf_lines(page)
+ for ln in lines:
+ if not ln.strip():
+ continue
+ if len(ln) > max_chars:
+ counts[idx] += 1
+ incidents.append(
+ LayoutIncident(
+ kind="overfull_line_pdf",
+ detail=f"page={idx + 1} line_len={len(ln)}",
+ context=ln.strip()[:140] or None,
+ )
+ )
+ return counts, incidents
+
+
+def _detect_pdf_bbox_overflow(
+ pages: list[dict[str, Any]],
+ *,
+ tolerance: float = 2.0,
+ max_incidents_per_page: int = 5,
+) -> tuple[list[int], list[LayoutIncident]]:
+ counts = [0 for _ in pages]
+ incidents: list[LayoutIncident] = []
+ for idx, page in enumerate(pages):
+ width = float(page.get("width") or 0)
+ height = float(page.get("height") or 0)
+ if width <= 0 or height <= 0:
+ continue
+ page_number = int(page.get("number") or (idx + 1))
+ for text in page.get("texts", []) or []:
+ if counts[idx] >= max_incidents_per_page:
+ break
+ left = float(text.get("left") or 0)
+ top = float(text.get("top") or 0)
+ box_w = float(text.get("width") or 0)
+ box_h = float(text.get("height") or 0)
+ if box_w <= 0 or box_h <= 0:
+ continue
+ right = left + box_w
+ bottom = top + box_h
+ if right <= width + tolerance and bottom <= height + tolerance and left >= -tolerance and top >= -tolerance:
+ continue
+ overflow_x = right - width
+ overflow_y = bottom - height
+ snippet = str(text.get("text") or "").strip()[:120] or None
+ incidents.append(
+ LayoutIncident(
+ kind="overfull_bbox_pdf",
+ detail=f"page={page_number} overflow_x={overflow_x:.1f} overflow_y={overflow_y:.1f}",
+ context=snippet,
+ )
+ )
+ counts[idx] += 1
+ return counts, incidents
+
+
+_URL_RE = re.compile(r"(?i)\bhttps?://[^\s<>\"]+")
+_WWW_RE = re.compile(r"(?i)\bwww\.[^\s<>\"]+")
+_DOI_RE = re.compile(r"\b10\.\d{4,9}/[^\s<>\"']+")
+_EMAIL_RE = re.compile(r"(?i)\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b")
+
+
+def _normalize_link_token(token: str) -> str:
+ token = token.strip()
+ token = token.strip("<>")
+ token = token.strip("()[]{}")
+ token = token.rstrip(".,;:!?)]}\"'")
+ return token
+
+
+def _extract_link_like_tokens(text: str) -> list[str]:
+ if not text:
+ return []
+ tokens: list[str] = []
+ for match in _URL_RE.findall(text):
+ norm = _normalize_link_token(match)
+ if norm:
+ tokens.append(norm)
+ for match in _WWW_RE.findall(text):
+ norm = _normalize_link_token(match)
+ if norm:
+ tokens.append(norm)
+ for match in _DOI_RE.findall(text):
+ norm = _normalize_link_token(match)
+ if norm:
+ tokens.append(norm)
+ for match in _EMAIL_RE.findall(text):
+ norm = _normalize_link_token(match)
+ if norm:
+ tokens.append(norm)
+ return tokens
diff --git a/src/iftypeset/rendering.py b/src/iftypeset/rendering.py
index 37d4274..e498c06 100644
--- a/src/iftypeset/rendering.py
+++ b/src/iftypeset/rendering.py
@@ -3,10 +3,12 @@ from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime, timezone
import base64
+from contextlib import contextmanager
import html
import importlib
import importlib.util
import json
+import math
import mimetypes
import os
from pathlib import Path
@@ -14,12 +16,32 @@ import re
import shutil
import subprocess
import sys
+import tempfile
from typing import Any
+from xml.sax.saxutils import escape as _xml_escape
from iftypeset import __version__
from iftypeset.css_gen import generate_profile_css
from iftypeset.md_parser import MdDocument, parse_markdown, read_markdown
+_NBSP_TOKEN = "{{NBSP}}"
+_DEFAULT_WEAK_WORDS = {
+ "and",
+ "to",
+ "with",
+ "in",
+ "for",
+ "of",
+ "on",
+ "at",
+ "by",
+ "from",
+ "under",
+ "into",
+ "over",
+ "hit",
+}
+
@dataclass(frozen=True)
class HtmlRenderResult:
@@ -28,6 +50,13 @@ class HtmlRenderResult:
warnings: list[str]
degraded: dict[str, list[str]]
typeset_report: dict[str, Any]
+ doc_title: str
+
+
+@dataclass(frozen=True)
+class InlineOptions:
+ small_caps_acronyms: bool
+ small_caps_min_letters: int
@dataclass(frozen=True)
@@ -53,26 +82,77 @@ def render_html(
css_out = generate_profile_css(profile)
warnings: list[str] = []
- html_out = _render_doc(doc, base_path=input_path.parent, self_contained=self_contained, warnings=warnings)
+ doc_title = _doc_title(doc)
+ inline_opts = _inline_options_from_profile(profile)
+ density = _auto_density(doc, profile)
+ body_class = "if-doc"
+ if density:
+ body_class += f" if-density-{density}"
+ html_out = _render_doc(
+ doc,
+ profile=profile,
+ base_path=input_path.parent,
+ self_contained=self_contained,
+ warnings=warnings,
+ doc_title=doc_title,
+ inline_opts=inline_opts,
+ body_class=body_class,
+ )
+ html_out = _balance_lists_with_playwright(html_out, profile, warnings)
+ typeset_report = dict(css_out.report)
+ doc_stats = _doc_stats(doc)
+ if density:
+ typeset_report["auto_density"] = density
+ typeset_report["doc_stats"] = doc_stats
return HtmlRenderResult(
html=html_out,
css=css_out.css,
warnings=warnings,
degraded=degraded,
- typeset_report=css_out.report,
+ typeset_report=typeset_report,
+ doc_title=doc_title,
)
+def _inline_options_from_profile(profile: dict[str, Any]) -> InlineOptions:
+ typography = profile.get("typography") or {}
+ small_caps_cfg = typography.get("small_caps_acronyms")
+ enabled = False
+ min_letters = 2
+ if isinstance(small_caps_cfg, dict):
+ enabled = bool(small_caps_cfg.get("enabled") or False)
+ min_letters = int(small_caps_cfg.get("min_letters") or 2)
+ elif isinstance(small_caps_cfg, bool):
+ enabled = small_caps_cfg
+ return InlineOptions(small_caps_acronyms=enabled, small_caps_min_letters=min_letters)
+
+
+def _running_head_config(profile: dict[str, Any], *, doc_title: str) -> dict[str, str] | None:
+ cfg = profile.get("running_head") or {}
+ if not isinstance(cfg, dict) or not cfg.get("enabled"):
+ return None
+ placement = str(cfg.get("placement") or "footer")
+ template = str(cfg.get("template") or "{page} | {title}")
+ font_size = str(cfg.get("font_size") or "9pt")
+ font_style = str(cfg.get("font_style") or "italic")
+ color = str(cfg.get("color") or "#6b7280")
+ date = str(cfg.get("date") or "")
+ base = template.replace("{title}", doc_title).replace("{date}", date)
+ return {
+ "placement": placement,
+ "template": base,
+ "font_size": font_size,
+ "font_style": font_style,
+ "color": color,
+ }
+
+
def detect_pdf_engines() -> list[dict[str, Any]]:
engines: list[dict[str, Any]] = []
if importlib.util.find_spec("playwright"):
engines.append({"name": "playwright", "detail": "python-module"})
- chromium_path = _find_executable(["chromium", "chromium-browser", "google-chrome", "chrome"])
- if chromium_path:
- engines.append({"name": "chromium", "detail": chromium_path})
-
wk_path = _find_executable(["wkhtmltopdf"])
if wk_path:
engines.append({"name": "wkhtmltopdf", "detail": wk_path})
@@ -93,7 +173,10 @@ def render_pdf(
profile: dict[str, Any],
out_dir: Path,
*,
+ engine_name: str | None = None,
self_contained: bool = False,
+ font_dirs: list[Path] | None = None,
+ strict_fonts: bool = False,
) -> PdfRenderResult:
out_dir.mkdir(parents=True, exist_ok=True)
html_result = render_html(input_path, profile, self_contained=self_contained)
@@ -107,34 +190,86 @@ def render_pdf(
engines = detect_pdf_engines()
log = _base_render_log(engines, html_result.warnings)
+ running_head = _running_head_config(profile, doc_title=html_result.doc_title)
+ if running_head:
+ log["running_head"] = {k: v for k, v in running_head.items() if k != "template"}
+ if engine_name:
+ log["requested_engine"] = engine_name
if not engines:
log["ok"] = False
- log["error"] = "No PDF renderer detected. Install playwright, chromium, wkhtmltopdf, or weasyprint."
+ log["error"] = "No PDF renderer detected. Install playwright (preferred) or wkhtmltopdf/weasyprint."
return PdfRenderResult(ok=False, engine=None, pdf_path=None, log=log)
- engine = engines[0]["name"]
+ requested = str(engine_name or "").strip().lower()
+ if requested in {"", "auto"}:
+ requested = "playwright"
+ if requested == "chromium":
+ log["ok"] = False
+ log["error"] = "Chromium CLI engine is no longer supported; use --engine playwright."
+ return PdfRenderResult(ok=False, engine=None, pdf_path=None, log=log)
+
+ chosen = next((entry for entry in engines if entry.get("name") == requested), None)
+ if not chosen:
+ available = ", ".join(sorted({str(entry.get("name")) for entry in engines if entry.get("name")}))
+ log["ok"] = False
+ log["error"] = f"Requested engine '{engine_name}' not available. Available: {available}"
+ return PdfRenderResult(ok=False, engine=None, pdf_path=None, log=log)
+
+ engine = str(chosen.get("name"))
pdf_path = out_dir / "render.pdf"
log["engine"] = engine
log["engine_versions"] = _engine_versions(engines)
log["html_path"] = str(html_path)
log["pdf_path"] = str(pdf_path)
+ profile_fonts = _profile_font_families(profile)
+ font_policy = _font_policy(profile, strict_fonts=strict_fonts)
+ required_roles = _required_font_roles(profile_fonts, html_result.typeset_report, enforce=font_policy["require_primary"])
+ log["font_policy"] = {**font_policy, "required_roles": required_roles}
+ if font_dirs:
+ log["font_dirs"] = [str(p) for p in font_dirs]
+
try:
- if engine == "playwright":
- _render_pdf_playwright(html_path, pdf_path)
- elif engine == "chromium":
- _render_pdf_chromium(html_path, pdf_path, engines[0]["detail"])
- elif engine == "wkhtmltopdf":
- _render_pdf_wkhtmltopdf(html_path, pdf_path, engines[0]["detail"])
- elif engine == "weasyprint":
- _render_pdf_weasyprint(html_path, pdf_path)
- else:
- raise RuntimeError(f"Unknown engine: {engine}")
+ with _fontconfig_override(font_dirs) as font_env:
+ log["fonts"] = _font_match_report(profile_fonts, extra_env=font_env)
+ if font_policy["require_primary"]:
+ font_contract_error = _font_contract_preflight(required_roles, log["fonts"])
+ if font_contract_error:
+ log["ok"] = False
+ log["error"] = font_contract_error
+ return PdfRenderResult(ok=False, engine=engine, pdf_path=None, log=log)
+
+ if engine == "playwright":
+ _render_pdf_playwright(html_path, pdf_path, running_head=running_head, env=font_env)
+ elif engine == "wkhtmltopdf":
+ detail = chosen.get("detail")
+ if not isinstance(detail, str):
+ raise RuntimeError("wkhtmltopdf engine selected but executable path is missing.")
+ _render_pdf_wkhtmltopdf(html_path, pdf_path, detail, running_head=running_head, env=font_env)
+ elif engine == "weasyprint":
+ if running_head:
+ log["warnings"].append(
+ "Running head requested but weasyprint adapter does not inject headers yet."
+ )
+ with _env_override(font_env):
+ _render_pdf_weasyprint(html_path, pdf_path)
+ else:
+ raise RuntimeError(f"Unknown engine: {engine}")
except Exception as e: # noqa: BLE001
log["ok"] = False
log["error"] = str(e)
return PdfRenderResult(ok=False, engine=engine, pdf_path=None, log=log)
+ embedded_fonts = _pdf_embedded_fonts(pdf_path)
+ if embedded_fonts is not None:
+ log["pdf_fonts"] = embedded_fonts
+ if font_policy["require_primary"]:
+ embedded_error = _font_contract_pdf_check(required_roles, profile_fonts, embedded_fonts)
+ if embedded_error:
+ log["ok"] = False
+ log["error"] = embedded_error
+ return PdfRenderResult(ok=False, engine=engine, pdf_path=None, log=log)
+
log["ok"] = True
return PdfRenderResult(ok=True, engine=engine, pdf_path=str(pdf_path), log=log)
@@ -142,28 +277,59 @@ def render_pdf(
def _render_doc(
doc: MdDocument,
*,
+ profile: dict[str, Any],
base_path: Path,
self_contained: bool,
warnings: list[str],
+ doc_title: str,
+ inline_opts: InlineOptions,
+ body_class: str,
) -> str:
- title = _doc_title(doc)
+ title = doc_title
heading_ids: dict[str, int] = {}
body_lines: list[str] = []
+ section_open = False
+ current_section_slug: str | None = None
body_lines.append("")
for block in doc.blocks:
if block.type == "heading":
level = block.level or 1
slug = _unique_slug(block.text, heading_ids)
- body_lines.append(f"{_render_inline(block.text, base_path, self_contained, warnings)} ")
+ if level == 2:
+ if section_open:
+ body_lines.append(" ")
+ body_lines.append(f"")
+ section_open = True
+ current_section_slug = slug
+ body_lines.append(
+ f"{_render_inline(block.text, base_path, self_contained, warnings, inline_opts)} "
+ )
continue
if block.type == "paragraph":
- body_lines.append(f"{_render_inline(block.text, base_path, self_contained, warnings)}
")
+ img_only = _image_only_paragraph(block.text)
+ if img_only:
+ alt, url = img_only
+ src = _resolve_image_src(url, base_path, self_contained, warnings)
+ body_lines.append("")
+ body_lines.append(f" ")
+ body_lines.append(" ")
+ else:
+ ref_id = _leading_citation_id(block.text)
+ attr = f" id=\"{html.escape(ref_id)}\"" if ref_id else ""
+ body_lines.append(
+ f"{_render_inline(block.text, base_path, self_contained, warnings, inline_opts)}
"
+ )
continue
if block.type == "list":
tag = "ol" if block.ordered else "ul"
body_lines.append(f"<{tag}>")
for item in block.items:
- body_lines.append(f" {_render_inline(item, base_path, self_contained, warnings)} ")
+ groomed = _groom_list_item_text(item, profile, current_section_slug)
+ rendered = _render_inline(groomed, base_path, self_contained, warnings, inline_opts)
+ rendered = rendered.replace(_NBSP_TOKEN, " ")
+ body_lines.append(
+ f" {rendered} "
+ )
body_lines.append(f"{tag}>")
continue
if block.type == "code":
@@ -172,25 +338,36 @@ def _render_doc(
body_lines.append(f"{html.escape(block.text)} ")
continue
if block.type == "blockquote":
- body_lines.append(f"{_render_inline(block.text, base_path, self_contained, warnings)}
")
+ body_lines.append(
+ f"{_render_inline(block.text, base_path, self_contained, warnings, inline_opts)}
"
+ )
continue
if block.type == "table":
+ numeric_cols, bool_cols = _table_column_classes(block.headers, block.rows)
body_lines.append("")
body_lines.append(" ")
body_lines.append(" ")
- for h in block.headers:
- body_lines.append(f" {_render_inline(h, base_path, self_contained, warnings)} ")
+ for idx, h in enumerate(block.headers):
+ class_attr = _table_class_attr(idx, numeric_cols, bool_cols)
+ body_lines.append(
+ f" {_render_inline(h, base_path, self_contained, warnings, inline_opts)} "
+ )
body_lines.append(" ")
body_lines.append(" ")
body_lines.append(" ")
for row in block.rows:
body_lines.append(" ")
- for cell in row:
- body_lines.append(f" {_render_inline(cell, base_path, self_contained, warnings)} ")
- body_lines.append(" ")
+ for idx, cell in enumerate(row):
+ class_attr = _table_class_attr(idx, numeric_cols, bool_cols)
+ body_lines.append(
+ f" {_render_inline(cell, base_path, self_contained, warnings, inline_opts)} "
+ )
+ body_lines.append(" ")
body_lines.append(" ")
body_lines.append("
")
continue
+ if section_open:
+ body_lines.append(" ")
body_lines.append("")
html_lines: list[str] = []
@@ -202,7 +379,7 @@ def _render_doc(
html_lines.append(f" {html.escape(title)} ")
html_lines.append(" ")
html_lines.append("")
- html_lines.append("")
+ html_lines.append(f"")
html_lines.extend([" " + line for line in body_lines])
html_lines.append("")
html_lines.append("")
@@ -216,6 +393,506 @@ def _doc_title(doc: MdDocument) -> str:
return doc.path.stem
+def _doc_stats(doc: MdDocument) -> dict[str, Any]:
+ counts = {"heading": 0, "paragraph": 0, "list": 0, "code": 0, "table": 0, "blockquote": 0}
+ char_count = 0
+ for block in doc.blocks:
+ counts[block.type] = counts.get(block.type, 0) + 1
+ if block.type == "list":
+ for item in block.items:
+ char_count += len(item)
+ else:
+ char_count += len(block.text)
+ return {"blocks": counts, "char_count": char_count}
+
+
+def _groom_list_item_text(text: str, profile: dict[str, Any], section_slug: str | None) -> str:
+ heur = _list_wrap_heuristics(profile)
+ if not heur.get("enabled"):
+ return text
+ if _has_inline_markup(text):
+ return text
+ normalized = " ".join(text.split())
+ words = normalized.split()
+ if len(words) < 8:
+ return text
+ width = _list_item_measure(profile, section_slug, heur)
+ if not width or width < 30:
+ return text
+ min_tail_ratio = float(heur.get("min_tail_ratio") or 0.25)
+ min_tail_chars = int(heur.get("min_tail_chars") or 12)
+ weak_words = {w.lower() for w in (heur.get("weak_words") or _DEFAULT_WEAK_WORDS)}
+ max_shift = int(heur.get("max_shift_words") or 3)
+ min_tail = max(min_tail_chars, int(width * min_tail_ratio))
+ tokens = _build_tokens(words, set())
+ lines = _wrap_tokens(tokens, width)
+ if len(lines) <= 1:
+ return text
+ if _lines_ok(lines, tokens, min_tail, weak_words):
+ return text
+ locks = _group_tail_words(words, width, min_tail, weak_words)
+ if locks:
+ return _join_words_with_locks(words, locks)
+ boundary = _find_shift_boundary(words, width, min_tail, weak_words, max_shift)
+ if boundary is None:
+ return _join_weak_pairs(text, weak_words, max_pairs=1)
+ initial = _join_words_with_locks(words, {boundary})
+ if _has_nbsp_token(initial):
+ return initial
+ return _join_weak_pairs(initial, weak_words, max_pairs=1)
+
+
+def _list_wrap_heuristics(profile: dict[str, Any]) -> dict[str, Any]:
+ lists_cfg = profile.get("lists") or {}
+ heur = lists_cfg.get("wrap_heuristics")
+ if isinstance(heur, dict):
+ enabled = heur.get("enabled")
+ if enabled is None:
+ heur = dict(heur)
+ heur["enabled"] = True
+ return heur
+ if isinstance(heur, bool):
+ return {"enabled": heur}
+ return {"enabled": True}
+
+
+def _has_inline_markup(text: str) -> bool:
+ return bool(re.search(r"[`*_<>\\[]", text))
+
+
+def _list_item_measure(
+ profile: dict[str, Any],
+ section_slug: str | None,
+ heuristics: dict[str, Any] | None = None,
+) -> int | None:
+ measure = profile.get("measure_targets") or {}
+ body_chars = measure.get("body_chars_per_line") or {}
+ ideal = int(body_chars.get("ideal") or 66)
+ layout = profile.get("layout") or {}
+ overrides = layout.get("section_overrides") or {}
+ factor = 1.0
+ indent_chars = 0
+ if isinstance(heuristics, dict):
+ factor = float(heuristics.get("width_factor") or 1.0)
+ indent_chars = int(heuristics.get("indent_chars") or 0)
+ if section_slug:
+ for key, cfg in overrides.items():
+ if not isinstance(cfg, dict):
+ continue
+ if _slugify(str(key)) != section_slug:
+ continue
+ width = _parse_width_to_chars(cfg.get("list_item_width") or cfg.get("list_item_max_width"), ideal)
+ if width:
+ return max(20, int(round(width * factor)) - indent_chars)
+ return max(20, int(round(ideal * factor)) - indent_chars)
+
+
+def _parse_width_to_chars(value: Any, ideal: int) -> int | None:
+ if value is None:
+ return None
+ if isinstance(value, int):
+ return value
+ if isinstance(value, float):
+ return int(round(value))
+ if not isinstance(value, str):
+ return None
+ text = value.strip().lower()
+ if text.endswith("ch"):
+ num = text[:-2].strip()
+ try:
+ return int(round(float(num)))
+ except ValueError:
+ return None
+ if text.endswith("%"):
+ num = text[:-1].strip()
+ try:
+ pct = float(num) / 100.0
+ except ValueError:
+ return None
+ return max(1, int(round(ideal * pct)))
+ return None
+
+
+def _build_tokens(words: list[str], locks: set[int]) -> list[dict[str, Any]]:
+ tokens: list[dict[str, Any]] = []
+ i = 0
+ while i < len(words):
+ start = i
+ token = words[i]
+ while i < len(words) - 1 and i in locks:
+ token = f"{token}{_NBSP_TOKEN}{words[i + 1]}"
+ i += 1
+ end = i
+ tokens.append({"text": token, "start": start, "end": end})
+ i += 1
+ return tokens
+
+
+def _wrap_tokens(tokens: list[dict[str, Any]], width: int) -> list[list[int]]:
+ lines: list[list[int]] = []
+ line: list[int] = []
+ line_len = 0
+ for idx, token in enumerate(tokens):
+ token_len = _token_display_len(token["text"])
+ add = token_len if not line else token_len + 1
+ if line and line_len + add > width:
+ lines.append(line)
+ line = [idx]
+ line_len = token_len
+ else:
+ line.append(idx)
+ line_len += add
+ if line:
+ lines.append(line)
+ return lines
+
+
+def _token_display_len(text: str) -> int:
+ return len(text.replace(_NBSP_TOKEN, " "))
+
+
+def _line_len(line: list[int], tokens: list[dict[str, Any]]) -> int:
+ total = 0
+ for i, idx in enumerate(line):
+ if i:
+ total += 1
+ total += _token_display_len(tokens[idx]["text"])
+ return total
+
+
+def _lines_ok(
+ lines: list[list[int]],
+ tokens: list[dict[str, Any]],
+ min_tail: int,
+ weak_words: set[str],
+) -> bool:
+ if len(lines) < 2:
+ return True
+ last_len = _line_len(lines[-1], tokens)
+ prev_last_word = _last_word(tokens[lines[-2][-1]]["text"])
+ return last_len >= min_tail and prev_last_word not in weak_words
+
+
+def _group_tail_words(
+ words: list[str],
+ width: int,
+ min_tail: int,
+ weak_words: set[str],
+) -> set[int]:
+ tokens = _build_tokens(words, set())
+ lines = _wrap_tokens(tokens, width)
+ if len(lines) < 2:
+ return set()
+ last_len = _line_len(lines[-1], tokens)
+ prev_last = _last_word(tokens[lines[-2][-1]]["text"])
+ if last_len >= min_tail and prev_last not in weak_words:
+ return set()
+ tail_len = 0
+ idx = len(words) - 1
+ while idx >= 0:
+ word = words[idx]
+ tail_len += len(word) + (1 if tail_len else 0)
+ if tail_len >= min_tail:
+ break
+ idx -= 1
+ if idx <= 0 or tail_len > width:
+ return set()
+ start = idx
+ end = len(words) - 1
+ if prev_last in weak_words:
+ boundary = _boundary_between_lines(lines[-2], lines[-1], tokens)
+ if boundary is None:
+ return set()
+ start = max(start, boundary)
+ return set(range(start, end))
+
+
+def _last_word(text: str) -> str:
+ cleaned = text.replace(_NBSP_TOKEN, " ").strip()
+ parts = cleaned.split()
+ return parts[-1].lower() if parts else ""
+
+
+def _boundary_between_lines(
+ prev_line: list[int],
+ next_line: list[int],
+ tokens: list[dict[str, Any]],
+) -> int | None:
+ if not prev_line or not next_line:
+ return None
+ prev_last = tokens[prev_line[-1]]
+ return int(prev_last["end"])
+
+def _find_shift_boundary(
+ words: list[str],
+ width: int,
+ min_tail: int,
+ weak_words: set[str],
+ max_shift: int,
+) -> int | None:
+ base_tokens = _build_tokens(words, set())
+ base_lines = _wrap_tokens(base_tokens, width)
+ if len(base_lines) < 2:
+ return None
+ base_last_len = _line_len(base_lines[-1], base_tokens)
+ base_prev_last = _last_word(base_tokens[base_lines[-2][-1]]["text"])
+ boundary = _boundary_between_lines(base_lines[-2], base_lines[-1], base_tokens)
+ if boundary is None:
+ return None
+ if base_prev_last in weak_words:
+ return boundary
+ tokens = _build_tokens(words, {boundary})
+ lines = _wrap_tokens(tokens, width)
+ if len(lines) >= 2:
+ last_len = _line_len(lines[-1], tokens)
+ prev_last = _last_word(tokens[lines[-2][-1]]["text"])
+ if last_len >= min_tail and prev_last not in weak_words:
+ return boundary
+ best: int | None = None
+ best_last_len = base_last_len
+ best_no_weak = base_prev_last not in weak_words
+ for shift in range(1, max_shift + 1):
+ cand = boundary - shift
+ if cand < 0:
+ break
+ tokens = _build_tokens(words, {cand})
+ lines = _wrap_tokens(tokens, width)
+ if len(lines) < 2:
+ continue
+ last_len = _line_len(lines[-1], tokens)
+ prev_last = _last_word(tokens[lines[-2][-1]]["text"])
+ no_weak = prev_last not in weak_words
+ if last_len >= min_tail and no_weak:
+ return cand
+ if last_len > best_last_len or (last_len == best_last_len and no_weak and not best_no_weak):
+ best = cand
+ best_last_len = last_len
+ best_no_weak = no_weak
+ if best is None:
+ return None
+ if best_last_len > base_last_len:
+ return best
+ if best_no_weak and not (base_prev_last not in weak_words):
+ return best
+ return None
+
+def _join_words_with_locks(words: list[str], locks: set[int]) -> str:
+ out: list[str] = []
+ for idx, word in enumerate(words):
+ out.append(word)
+ if idx < len(words) - 1:
+ sep = _NBSP_TOKEN if idx in locks else " "
+ out.append(sep)
+ return "".join(out)
+
+
+def _join_weak_pairs(text: str, weak_words: set[str], max_pairs: int) -> str:
+ if max_pairs <= 0:
+ return text
+ words = text.split(" ")
+ changed = 0
+ for i in range(len(words) - 1):
+ clean = words[i].replace(_NBSP_TOKEN, "").strip(" ,.;:()[]")
+ if clean.lower() in weak_words:
+ if _NBSP_TOKEN not in words[i]:
+ words[i] = f"{words[i]}{_NBSP_TOKEN}{words[i + 1]}"
+ words.pop(i + 1)
+ changed += 1
+ if changed >= max_pairs:
+ break
+ return " ".join(words)
+
+
+def _has_nbsp_token(text: str) -> bool:
+ return _NBSP_TOKEN in text
+
+
+def _balance_lists_with_playwright(html_doc: str, profile: dict[str, Any], warnings: list[str]) -> str:
+ heur = _list_wrap_heuristics(profile)
+ if not (heur.get("balance_with_playwright") or heur.get("balance_with_chromium")):
+ return html_doc
+ if not importlib.util.find_spec("playwright"):
+ warnings.append("List balancing skipped: playwright not available for layout-aware pass.")
+ return html_doc
+ css = generate_profile_css(profile).css
+ script = _balance_script(heur, css)
+ if not script:
+ return html_doc
+ injected = _inject_script(html_doc, script)
+ with tempfile.TemporaryDirectory(prefix="iftypeset-balance-") as tmpdir:
+ html_path = Path(tmpdir) / "balance.html"
+ html_path.write_text(injected, encoding="utf-8")
+ try:
+ from playwright.sync_api import sync_playwright # type: ignore
+ except Exception as e: # noqa: BLE001
+ warnings.append(f"List balancing skipped: playwright import failed ({e}).")
+ return html_doc
+
+ try:
+ with sync_playwright() as p:
+ browser = p.chromium.launch(**_playwright_launch_kwargs())
+ try:
+ page = browser.new_page()
+ page.goto(html_path.resolve().as_uri(), wait_until="load")
+ try:
+ page.wait_for_function(
+ "() => window.__iftypeset_list_balance_done === true",
+ timeout=2000,
+ )
+ except Exception: # noqa: BLE001
+ pass
+ output = page.content().strip()
+ finally:
+ browser.close()
+ except Exception as e: # noqa: BLE001
+ warnings.append(f"List balancing failed: playwright error ({e}).")
+ return html_doc
+
+ if " str:
+ marker = "
"
+ )
+ lines.append("iftypeset report index ")
+ lines.append(f"Generated (UTC): {generated_at}
")
+
+ lines.append("Summary ")
+ lines.append("")
+ lines.append(f"spec validation: {spec_status} ")
+ lines.append(f"lint: {lint_status} ")
+ lines.append(f"qa: {qa_status} ")
+ lines.append(f"run: {run_status} ")
+ lines.append(f"pdf: {pdf_present} ")
+ lines.append(" ")
+
+ lines.append("Artifacts ")
+ lines.append("")
+ lines.append(link_item("render.html", "render.html"))
+ lines.append(link_item("render.css", "render.css"))
+ lines.append(link_item("render.pdf", "render.pdf", pdf_present))
+ lines.append(link_item("typeset-report.json", "typeset-report.json"))
+ lines.append(link_item("render-log.json", "render-log.json"))
+ lines.append(link_item("lint-report.json", "lint-report.json", lint_status))
+ lines.append(link_item("manual-checklist.md", "manual-checklist.md"))
+ lines.append(link_item("manual-checklist.json", "manual-checklist.json"))
+ lines.append(link_item("layout-report.json", "layout-report.json"))
+ lines.append(link_item("qa-report.json", "qa-report.json", qa_status))
+ lines.append(link_item("coverage-summary.md", "coverage-summary.md"))
+ lines.append(link_item("coverage-report.json", "coverage-report.json"))
+ lines.append(link_item("trust-contract.md", "trust-contract.md"))
+ lines.append(link_item("trust-contract.json", "trust-contract.json"))
+ lines.append(link_item("run-summary.json", "run-summary.json", run_status))
+ lines.append(link_item("spec-validation.json", "spec-validation.json", spec_status))
+ lines.append(" ")
+
+ lines.append(""
+ if marker in html_doc:
+ return html_doc.replace(marker, script + marker)
+ return html_doc + script
+
+
+def _balance_script(heuristics: dict[str, Any], css: str) -> str:
+ min_tail_ratio = float(heuristics.get("min_tail_ratio") or 0.25)
+ min_tail_chars = int(heuristics.get("min_tail_chars") or 12)
+ max_passes = int(heuristics.get("max_passes") or 2)
+ weak_words = heuristics.get("weak_words") or sorted(_DEFAULT_WEAK_WORDS)
+ if not weak_words:
+ weak_words = sorted(_DEFAULT_WEAK_WORDS)
+ config = {
+ "minTailRatio": min_tail_ratio,
+ "minTailChars": min_tail_chars,
+ "maxPasses": max_passes,
+ "weakWords": weak_words,
+ }
+ payload = json.dumps(config)
+ return (
+ f"\n"
+ "\n"
+ )
+
+
+def _auto_density(doc: MdDocument, profile: dict[str, Any]) -> str | None:
+ layout = profile.get("layout") or {}
+ if not layout.get("auto_density"):
+ return None
+ thresholds = layout.get("density_thresholds") or {}
+ tight_over = int(thresholds.get("tight_over") or 46)
+ loose_under = int(thresholds.get("loose_under") or 34)
+ estimated_lines = _estimate_line_count(doc, profile)
+ if estimated_lines >= tight_over:
+ return "tight"
+ if estimated_lines <= loose_under:
+ return "loose"
+ return "normal"
+
+
+def _estimate_line_count(doc: MdDocument, profile: dict[str, Any]) -> int:
+ measure = profile.get("measure_targets") or {}
+ body_chars = measure.get("body_chars_per_line") or {}
+ ideal = int(body_chars.get("ideal") or 66)
+ total = 0
+ for block in doc.blocks:
+ if block.type == "heading":
+ total += max(1, math.ceil(len(block.text) / ideal))
+ elif block.type == "paragraph":
+ parts = block.text.split("\n")
+ for part in parts:
+ total += max(1, math.ceil(len(part) / ideal))
+ elif block.type == "list":
+ for item in block.items:
+ total += max(1, math.ceil(len(item) / ideal))
+ elif block.type == "code":
+ lines = block.text.splitlines() or [""]
+ total += len(lines)
+ elif block.type == "table":
+ total += max(1, len(block.rows) + 1)
+ elif block.type == "blockquote":
+ total += max(1, math.ceil(len(block.text) / ideal))
+ return total
+
+
def _unique_slug(text: str, used: dict[str, int]) -> str:
slug = _slugify(text)
if slug not in used:
@@ -231,22 +908,117 @@ def _slugify(text: str) -> str:
return slug or "section"
-def _render_inline(text: str, base_path: Path, self_contained: bool, warnings: list[str]) -> str:
+def _table_column_classes(headers: list[str], rows: list[list[str]]) -> tuple[set[int], set[int]]:
+ col_count = len(headers)
+ for row in rows:
+ col_count = max(col_count, len(row))
+ numeric_cols: set[int] = set()
+ bool_cols: set[int] = set()
+ for col in range(col_count):
+ values = []
+ for row in rows:
+ if col < len(row):
+ values.append(row[col])
+ if not values:
+ continue
+ if _is_boolean_column(values):
+ bool_cols.add(col)
+ continue
+ if _is_numeric_column(values):
+ numeric_cols.add(col)
+ return numeric_cols, bool_cols
+
+
+def _table_class_attr(col_idx: int, numeric_cols: set[int], bool_cols: set[int]) -> str:
+ if col_idx in bool_cols:
+ return " class=\"if-bool\""
+ if col_idx in numeric_cols:
+ return " class=\"if-num\""
+ return ""
+
+
+def _is_numeric_cell(text: str) -> bool:
+ clean = _strip_inline_markup(text).strip()
+ if not clean:
+ return False
+ if re.search(r"[A-Za-z]", clean):
+ return False
+ if clean.lower() in {"n/a", "na"}:
+ return True
+ return bool(re.fullmatch(r"[\\s\\(\\)\\[\\]\\+\\-−–—$€£¥%.,/0-9]+", clean))
+
+
+def _is_numeric_column(values: list[str]) -> bool:
+ candidates = [v for v in values if _strip_inline_markup(v).strip()]
+ if not candidates:
+ return False
+ numeric_hits = sum(1 for value in candidates if _is_numeric_cell(value))
+ return numeric_hits / max(len(candidates), 1) >= 0.6
+
+
+def _is_boolean_column(values: list[str]) -> bool:
+ tokens = []
+ for value in values:
+ clean = _strip_inline_markup(value).strip().lower()
+ if not clean:
+ continue
+ tokens.append(clean)
+ if not tokens:
+ return False
+ bool_tokens = {"yes", "no", "y", "n", "true", "false", "✓", "✔", "✗", "x"}
+ neutral_tokens = {"n/a", "na", "—", "-", "—-", "–", "—"}
+ significant = [t for t in tokens if t not in neutral_tokens]
+ if not significant:
+ return True
+ if all(t in bool_tokens for t in significant):
+ return True
+ hits = sum(1 for t in significant if t in bool_tokens)
+ return hits / max(len(significant), 1) >= 0.8
+
+
+def _strip_inline_markup(text: str) -> str:
+ without_links = re.sub(r"\[([^\]]+)\]\([^)]+\)", r"\1", text)
+ return re.sub(r"[`*_]", "", without_links)
+
+
+def _render_inline(
+ text: str,
+ base_path: Path,
+ self_contained: bool,
+ warnings: list[str],
+ inline_opts: InlineOptions,
+) -> str:
out: list[str] = []
+ buffer: list[str] = []
+
+ def flush_buffer() -> None:
+ if not buffer:
+ return
+ segment = "".join(buffer)
+ out.append(_render_text_segment(segment, inline_opts))
+ buffer.clear()
+
i = 0
while i < len(text):
if text[i] == "`":
j = text.find("`", i + 1)
if j == -1:
- out.append(html.escape(text[i:]))
+ buffer.append(text[i:])
break
+ flush_buffer()
code_text = text[i + 1 : j]
out.append(f"{html.escape(code_text)}")
i = j + 1
continue
+ if text[i] == "\n":
+ flush_buffer()
+ out.append(" ")
+ i += 1
+ continue
if text[i] == "!" and i + 1 < len(text) and text[i + 1] == "[":
img = _parse_bracket_link(text, i + 1)
if img:
+ flush_buffer()
alt, url, end_idx = img
src = _resolve_image_src(url, base_path, self_contained, warnings)
out.append(f" ")
@@ -255,15 +1027,104 @@ def _render_inline(text: str, base_path: Path, self_contained: bool, warnings: l
if text[i] == "[":
link = _parse_bracket_link(text, i)
if link:
+ flush_buffer()
label, url, end_idx = link
out.append(f"{html.escape(label)} ")
i = end_idx
continue
- out.append(html.escape(text[i]))
+ cite = _parse_citation_token(text, i)
+ if cite:
+ flush_buffer()
+ token, end_idx = cite
+ out.append(
+ f"{html.escape(token)} "
+ )
+ i = end_idx
+ continue
+ buffer.append(text[i])
i += 1
+ flush_buffer()
return "".join(out)
+def _render_text_segment(text: str, inline_opts: InlineOptions) -> str:
+ tokens = _split_emphasis_tokens(text)
+ rendered: list[str] = []
+ for kind, segment in tokens:
+ if not segment:
+ continue
+ if inline_opts.small_caps_acronyms:
+ content = _wrap_small_caps_tokens(segment, min_letters=inline_opts.small_caps_min_letters)
+ else:
+ content = html.escape(segment)
+ if kind == "strong":
+ rendered.append(f"{content} ")
+ elif kind == "em":
+ rendered.append(f"{content} ")
+ else:
+ rendered.append(content)
+ return "".join(rendered)
+
+
+def _split_emphasis_tokens(text: str) -> list[tuple[str, str]]:
+ tokens: list[tuple[str, str]] = []
+ buffer: list[str] = []
+ i = 0
+ while i < len(text):
+ if text.startswith("**", i):
+ end = text.find("**", i + 2)
+ if end != -1:
+ if buffer:
+ tokens.append(("plain", "".join(buffer)))
+ buffer.clear()
+ tokens.append(("strong", text[i + 2 : end]))
+ i = end + 2
+ continue
+ if text[i] == "*":
+ end = text.find("*", i + 1)
+ if end != -1:
+ if buffer:
+ tokens.append(("plain", "".join(buffer)))
+ buffer.clear()
+ tokens.append(("em", text[i + 1 : end]))
+ i = end + 1
+ continue
+ buffer.append(text[i])
+ i += 1
+ if buffer:
+ tokens.append(("plain", "".join(buffer)))
+ return tokens
+
+
+def _wrap_small_caps_tokens(text: str, *, min_letters: int) -> str:
+ pattern = re.compile(r"\b[0-9A-Z][0-9A-Z&/.\-]*\b")
+ out: list[str] = []
+ last = 0
+ for match in pattern.finditer(text):
+ token = match.group(0)
+ letters = [ch for ch in token if ch.isalpha()]
+ if len(letters) < min_letters or any(ch.islower() for ch in letters):
+ continue
+ out.append(html.escape(text[last : match.start()]))
+ out.append(f"{html.escape(token)} ")
+ last = match.end()
+ out.append(html.escape(text[last:]))
+ return "".join(out)
+
+
+def _image_only_paragraph(text: str) -> tuple[str, str] | None:
+ stripped = text.strip()
+ if not (stripped.startswith("![") and len(stripped) > 3):
+ return None
+ img = _parse_bracket_link(stripped, 1)
+ if not img:
+ return None
+ alt, url, end_idx = img
+ if end_idx != len(stripped):
+ return None
+ return alt, url
+
+
def _parse_bracket_link(text: str, idx: int) -> tuple[str, str, int] | None:
if text[idx] != "[":
return None
@@ -278,6 +1139,30 @@ def _parse_bracket_link(text: str, idx: int) -> tuple[str, str, int] | None:
return label, url, end + 1
+def _parse_citation_token(text: str, idx: int) -> tuple[str, int] | None:
+ if text[idx] != "[":
+ return None
+ match = re.match(r"\[S\d{2,4}\]", text[idx:])
+ if not match:
+ return None
+ token = match.group(0)
+ return token, idx + len(token)
+
+
+def _citation_id(token: str) -> str:
+ label = token.strip().strip("[]").lower()
+ return f"cite-{label}"
+
+
+def _leading_citation_id(text: str) -> str | None:
+ stripped = text.lstrip()
+ cite = _parse_citation_token(stripped, 0)
+ if not cite:
+ return None
+ token, _ = cite
+ return _citation_id(token)
+
+
def _resolve_image_src(url: str, base_path: Path, self_contained: bool, warnings: list[str]) -> str:
if not self_contained:
return url
@@ -300,36 +1185,332 @@ def _find_executable(candidates: list[str]) -> str | None:
return None
-def _render_pdf_playwright(html_path: Path, pdf_path: Path) -> None:
+_GENERIC_FONT_FAMILIES = {
+ "serif",
+ "sans-serif",
+ "monospace",
+ "cursive",
+ "fantasy",
+ "system-ui",
+}
+
+
+def _font_token(value: str) -> str:
+ return re.sub(r"[^a-z0-9]+", "", value.lower())
+
+
+def _font_is_generic(family: str) -> bool:
+ return _font_token(family) in {_font_token(f) for f in _GENERIC_FONT_FAMILIES}
+
+
+def _profile_font_families(profile: dict[str, Any]) -> dict[str, list[str]]:
+ fonts = profile.get("fonts") or {}
+ if not isinstance(fonts, dict):
+ return {}
+ out: dict[str, list[str]] = {}
+ for role in ("body", "heading", "mono"):
+ role_info = fonts.get(role) or {}
+ if not isinstance(role_info, dict):
+ continue
+ families = role_info.get("family") or []
+ if isinstance(families, str):
+ families = [families]
+ if not isinstance(families, list):
+ continue
+ cleaned: list[str] = []
+ for item in families:
+ s = str(item).strip()
+ if not s:
+ continue
+ cleaned.append(s.strip("'").strip('"'))
+ if cleaned:
+ out[role] = cleaned
+ return out
+
+
+def _font_policy(profile: dict[str, Any], *, strict_fonts: bool) -> dict[str, Any]:
+ fonts = profile.get("fonts") or {}
+ require_primary = False
+ if isinstance(fonts, dict) and fonts.get("require_primary"):
+ require_primary = True
+ if strict_fonts:
+ require_primary = True
+ return {"require_primary": require_primary}
+
+
+def _required_font_roles(
+ profile_fonts: dict[str, list[str]],
+ typeset_report: dict[str, Any],
+ *,
+ enforce: bool,
+) -> list[str]:
+ if not enforce:
+ return []
+ doc_stats = typeset_report.get("doc_stats") if isinstance(typeset_report.get("doc_stats"), dict) else {}
+ blocks = doc_stats.get("blocks") if isinstance(doc_stats.get("blocks"), dict) else {}
+ required: list[str] = []
+ if "body" in profile_fonts:
+ required.append("body")
+ if blocks.get("heading", 0) and "heading" in profile_fonts:
+ required.append("heading")
+ if blocks.get("code", 0) and "mono" in profile_fonts:
+ required.append("mono")
+ return required
+
+
+def _subprocess_env(extra_env: dict[str, str] | None) -> dict[str, str] | None:
+ if not extra_env:
+ return None
+ merged = os.environ.copy()
+ merged.update(extra_env)
+ return merged
+
+
+def _fc_match(primary_family: str, *, extra_env: dict[str, str] | None = None) -> str | None:
+ fc_match = _find_executable(["fc-match"])
+ if not fc_match:
+ return None
+ try:
+ proc = subprocess.run(
+ [fc_match, "-f", "%{family}\n", primary_family],
+ check=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ text=True,
+ env=_subprocess_env(extra_env),
+ )
+ except (FileNotFoundError, subprocess.CalledProcessError):
+ return None
+ out = proc.stdout.strip()
+ if not out:
+ return None
+ return out.splitlines()[0].strip()
+
+
+def _font_match_report(
+ profile_fonts: dict[str, list[str]],
+ *,
+ extra_env: dict[str, str] | None = None,
+) -> dict[str, Any]:
+ report: dict[str, Any] = {}
+ for role, families in profile_fonts.items():
+ if not families:
+ continue
+ primary = families[0]
+ match = None if _font_is_generic(primary) else _fc_match(primary, extra_env=extra_env)
+ report[role] = {"primary": primary, "fallbacks": families[1:], "match": match}
+ return report
+
+
+def _font_contract_preflight(required_roles: list[str], match_report: dict[str, Any]) -> str | None:
+ fc_match = _find_executable(["fc-match"])
+ if not fc_match:
+ return "Font contract enforcement requires fontconfig (missing `fc-match`)."
+ missing: list[str] = []
+ for role in required_roles:
+ entry = match_report.get(role) if isinstance(match_report.get(role), dict) else None
+ if not entry:
+ continue
+ primary = str(entry.get("primary") or "").strip()
+ if not primary or _font_is_generic(primary):
+ continue
+ match = str(entry.get("match") or "").strip()
+ if not match or _font_token(primary) not in _font_token(match):
+ missing.append(primary)
+ if not missing:
+ return None
+ missing_sorted = ", ".join(sorted(set(missing)))
+ return (
+ "Font contract violated (preflight): required primary font(s) not available: "
+ f"{missing_sorted}. Install the font(s) (e.g., Debian `fonts-noto-core`) or supply a font directory."
+ )
+
+
+@contextmanager
+def _fontconfig_override(font_dirs: list[Path] | None) -> Any:
+ if not font_dirs:
+ yield None
+ return
+ resolved: list[Path] = []
+ for raw in font_dirs:
+ path = Path(raw).expanduser().resolve()
+ if not path.exists() or not path.is_dir():
+ raise RuntimeError(f"Font dir not found: {raw}")
+ resolved.append(path)
+ lines = [
+ '',
+ '',
+ "",
+ ' /etc/fonts/fonts.conf ',
+ ]
+ for path in resolved:
+ lines.append(f" {_xml_escape(str(path))} ")
+ lines.append(" ")
+ payload = "\n".join(lines) + "\n"
+ with tempfile.TemporaryDirectory(prefix="iftypeset-fontconfig-") as tmpdir:
+ config_path = Path(tmpdir) / "fonts.conf"
+ config_path.write_text(payload, encoding="utf-8")
+ yield {"FONTCONFIG_FILE": str(config_path)}
+
+
+@contextmanager
+def _env_override(extra_env: dict[str, str] | None) -> Any:
+ if not extra_env:
+ yield
+ return
+ old_values: dict[str, str | None] = {}
+ for key, value in extra_env.items():
+ old_values[key] = os.environ.get(key)
+ os.environ[key] = value
+ try:
+ yield
+ finally:
+ for key, previous in old_values.items():
+ if previous is None:
+ os.environ.pop(key, None)
+ else:
+ os.environ[key] = previous
+
+
+def _pdf_embedded_fonts(pdf_path: Path) -> list[str] | None:
+ pdffonts = _find_executable(["pdffonts"])
+ if not pdffonts:
+ return None
+ try:
+ proc = subprocess.run(
+ [pdffonts, str(pdf_path)],
+ check=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ text=True,
+ )
+ except (FileNotFoundError, subprocess.CalledProcessError):
+ return None
+ lines = proc.stdout.splitlines()
+ start = 0
+ for idx, line in enumerate(lines):
+ if line.strip().startswith("---"):
+ start = idx + 1
+ break
+ fonts: list[str] = []
+ for line in lines[start:]:
+ if not line.strip():
+ continue
+ fonts.append(line.split()[0])
+ return fonts
+
+
+def _strip_subset_prefix(name: str) -> str:
+ return name.split("+", 1)[1] if "+" in name else name
+
+
+def _font_contract_pdf_check(
+ required_roles: list[str],
+ profile_fonts: dict[str, list[str]],
+ embedded_fonts: list[str],
+) -> str | None:
+ embedded_tokens = [_font_token(_strip_subset_prefix(name)) for name in embedded_fonts]
+ missing: list[str] = []
+ for role in required_roles:
+ families = profile_fonts.get(role) or []
+ if not families:
+ continue
+ primary = families[0]
+ if _font_is_generic(primary):
+ continue
+ expected = _font_token(primary)
+ if not any(expected and expected in tok for tok in embedded_tokens):
+ missing.append(primary)
+ if not missing:
+ return None
+ missing_sorted = ", ".join(sorted(set(missing)))
+ return (
+ "Font contract violated (PDF): expected primary font(s) not embedded: "
+ f"{missing_sorted}. Ensure the fonts are installed or supplied, then re-render."
+ )
+
+
+def _playwright_launch_kwargs() -> dict[str, Any]:
+ kwargs: dict[str, Any] = {}
+ kwargs["headless"] = True
+ if os.geteuid() == 0:
+ kwargs["args"] = ["--no-sandbox"]
+ return kwargs
+
+
+def _render_pdf_playwright(
+ html_path: Path,
+ pdf_path: Path,
+ *,
+ running_head: dict[str, str] | None,
+ env: dict[str, str] | None = None,
+) -> None:
from playwright.sync_api import sync_playwright # type: ignore
with sync_playwright() as p:
- browser = p.chromium.launch()
+ launch_kwargs = _playwright_launch_kwargs()
+ if env:
+ launch_env = os.environ.copy()
+ launch_env.update(env)
+ launch_kwargs["env"] = launch_env
+ browser = p.chromium.launch(**launch_kwargs)
page = browser.new_page()
page.goto(html_path.resolve().as_uri())
- page.pdf(path=str(pdf_path), print_background=True)
+ pdf_kwargs: dict[str, Any] = {
+ "path": str(pdf_path),
+ "print_background": True,
+ "prefer_css_page_size": True,
+ "scale": 1,
+ }
+ if running_head:
+ placement = running_head.get("placement")
+ template = html.escape(running_head.get("template") or "")
+ template = template.replace("{page}", ' ')
+ template = template.replace("{total}", ' ')
+ style = (
+ f"font-size:{running_head.get('font_size')};"
+ f"font-style:{running_head.get('font_style')};"
+ f"color:{running_head.get('color')};"
+ "width:100%;"
+ "text-align:center;"
+ )
+ box = f"
"
+ pdf_kwargs["display_header_footer"] = True
+ if placement == "header":
+ pdf_kwargs["header_template"] = box
+ pdf_kwargs["footer_template"] = "
"
+ else:
+ pdf_kwargs["footer_template"] = box
+ pdf_kwargs["header_template"] = "
"
+ page.pdf(**pdf_kwargs)
browser.close()
-def _render_pdf_chromium(html_path: Path, pdf_path: Path, chromium_path: str) -> None:
- uri = html_path.resolve().as_uri()
- cmd = [
- chromium_path,
- "--headless",
- "--disable-gpu",
- "--print-to-pdf=" + str(pdf_path),
- "--print-to-pdf-no-header",
- "--allow-file-access-from-files",
- uri,
- ]
- if os.geteuid() == 0:
- cmd.insert(1, "--no-sandbox")
- subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-
-
-def _render_pdf_wkhtmltopdf(html_path: Path, pdf_path: Path, wk_path: str) -> None:
- cmd = [wk_path, "--quiet", str(html_path.resolve()), str(pdf_path)]
- subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+def _render_pdf_wkhtmltopdf(
+ html_path: Path,
+ pdf_path: Path,
+ wk_path: str,
+ *,
+ running_head: dict[str, str] | None,
+ env: dict[str, str] | None,
+) -> None:
+ cmd = [wk_path, "--quiet"]
+ if running_head:
+ template = running_head.get("template") or ""
+ template = template.replace("{page}", "[page]").replace("{total}", "[topage]")
+ font_size = running_head.get("font_size") or "9"
+ cmd.extend(["--footer-font-size", str(font_size).replace("pt", "")])
+ cmd.extend(["--footer-font-name", "Times-Roman"])
+ if running_head.get("placement") == "header":
+ cmd.extend(["--header-font-size", str(font_size).replace("pt", "")])
+ cmd.extend(["--header-font-name", "Times-Roman"])
+ cmd.extend(["--header-line"])
+ cmd.extend(["--header-center", template])
+ else:
+ cmd.extend(["--footer-line"])
+ cmd.extend(["--footer-center", template])
+ cmd.extend([str(html_path.resolve()), str(pdf_path)])
+ subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=_subprocess_env(env))
def _render_pdf_weasyprint(html_path: Path, pdf_path: Path) -> None:
@@ -357,9 +1538,7 @@ def _engine_versions(engines: list[dict[str, Any]]) -> dict[str, str]:
for entry in engines:
name = entry.get("name")
detail = entry.get("detail")
- if name == "chromium" and isinstance(detail, str):
- versions[name] = _run_version_cmd([detail, "--version"])
- elif name == "wkhtmltopdf" and isinstance(detail, str):
+ if name == "wkhtmltopdf" and isinstance(detail, str):
versions[name] = _run_version_cmd([detail, "--version"])
elif name == "playwright":
versions[name] = _module_version("playwright")
diff --git a/src/iftypeset/reporting.py b/src/iftypeset/reporting.py
index 08f7087..0af7ab6 100644
--- a/src/iftypeset/reporting.py
+++ b/src/iftypeset/reporting.py
@@ -1,7 +1,15 @@
from __future__ import annotations
+import hashlib
+import json
+import locale
+import os
+import shutil
+import subprocess
+import tarfile
from dataclasses import dataclass, field
from datetime import datetime, timezone
+from pathlib import Path
from typing import Any
from iftypeset.spec_loader import LoadedSpec
@@ -64,6 +72,146 @@ class CoverageReport:
return "\n".join(lines).rstrip() + "\n"
+@dataclass(frozen=True)
+class TrustContract:
+ tool: str
+ tool_version: str
+ generated_at_utc: str
+ spec_root: str
+ manifest_version: str | None
+ profiles: list[str]
+ counts: CoverageCounts
+ enforcement_summary: dict[str, Any]
+ qa_limitations: list[str]
+ determinism_assumptions: list[str]
+ manual_checklist: dict[str, Any]
+ notes: list[str] = field(default_factory=list)
+
+ def to_markdown(self) -> str:
+ lines: list[str] = []
+ lines.append("# iftypeset trust contract\n")
+ lines.append(f"- Generated (UTC): `{self.generated_at_utc}`")
+ lines.append(f"- Spec root: `{self.spec_root}`")
+ if self.manifest_version:
+ lines.append(f"- Manifest version: `{self.manifest_version}`")
+ lines.append(f"- Profiles: {', '.join(f'`{p}`' for p in self.profiles)}\n")
+
+ lines.append("## Enforcement coverage\n")
+ lines.append(f"- Total rules: `{self.counts.total_rules}`")
+ lines.append(
+ f"- Enforced rules (lint/typeset/postrender): `{self.enforcement_summary.get('enforced_total', 0)}` "
+ f"({self.enforcement_summary.get('enforced_percent', 0)}%)"
+ )
+ lines.append(
+ f"- Manual rules: `{self.enforcement_summary.get('manual_total', 0)}` "
+ f"({self.enforcement_summary.get('manual_percent', 0)}%)"
+ )
+ enforced_by = self.enforcement_summary.get("enforced_by_type", {})
+ if enforced_by:
+ lines.append("")
+ for k, v in sorted(enforced_by.items(), key=lambda kv: kv[0]):
+ lines.append(f"- `{k}`: `{v}`")
+ lines.append("")
+
+ lines.append("## Coverage counts\n")
+ lines.append(f"- By category: {', '.join(f'{k}={v}' for k, v in sorted(self.counts.by_category.items()))}")
+ lines.append(f"- By enforcement: {', '.join(f'{k}={v}' for k, v in sorted(self.counts.by_enforcement.items()))}")
+ lines.append(f"- By severity: {', '.join(f'{k}={v}' for k, v in sorted(self.counts.by_severity.items()))}\n")
+
+ lines.append("## Manual checklist\n")
+ lines.append(f"- Tag: `{self.manual_checklist.get('tag')}`")
+ artifacts = self.manual_checklist.get("artifacts") or []
+ if artifacts:
+ lines.append(f"- Artifacts: {', '.join(f'`{a}`' for a in artifacts)}")
+ lines.append("")
+
+ lines.append("## QA limitations (v0)\n")
+ for item in self.qa_limitations:
+ lines.append(f"- {item}")
+ lines.append("")
+
+ lines.append("## Determinism assumptions\n")
+ for item in self.determinism_assumptions:
+ lines.append(f"- {item}")
+ lines.append("")
+
+ if self.notes:
+ lines.append("## Notes\n")
+ for n in self.notes:
+ lines.append(f"- {n}")
+ lines.append("")
+
+ return "\n".join(lines).rstrip() + "\n"
+
+
+@dataclass(frozen=True)
+class DoctorReport:
+ tool: str
+ tool_version: str
+ generated_at_utc: str
+ spec_root: str
+ renderer: dict[str, Any]
+ poppler: dict[str, Any]
+ fonts: dict[str, Any]
+ locale: dict[str, Any]
+ hyphenation: dict[str, Any]
+ determinism_caveats: list[str]
+ notes: list[str] = field(default_factory=list)
+
+ def to_markdown(self) -> str:
+ lines: list[str] = []
+ lines.append("# iftypeset doctor report\n")
+ lines.append(f"- Generated (UTC): `{self.generated_at_utc}`")
+ lines.append(f"- Spec root: `{self.spec_root}`\n")
+
+ lines.append("## Renderer\n")
+ lines.append(f"- PDF engines detected: `{self.renderer.get('pdf_engines_detected')}`")
+ lines.append(f"- PDF engine versions: `{self.renderer.get('pdf_engine_versions')}`\n")
+
+ lines.append("## Poppler tools\n")
+ tools = self.poppler.get("tools") if isinstance(self.poppler.get("tools"), dict) else {}
+ if tools:
+ for name, info in tools.items():
+ path = info.get("path") if isinstance(info, dict) else None
+ version = info.get("version") if isinstance(info, dict) else None
+ lines.append(f"- `{name}`: path={path or 'missing'} version={version or 'unknown'}")
+ else:
+ lines.append("- _No Poppler tools detected._")
+ lines.append("")
+
+ lines.append("## Fonts (primary match per profile)\n")
+ profiles = self.fonts.get("profiles") if isinstance(self.fonts.get("profiles"), dict) else {}
+ if profiles:
+ for profile_id, info in profiles.items():
+ lines.append(f"- `{profile_id}`: {info}")
+ else:
+ lines.append("- _No font data available._")
+ lines.append("")
+
+ lines.append("## Locale\n")
+ for key, value in self.locale.items():
+ lines.append(f"- `{key}`: {value}")
+ lines.append("")
+
+ lines.append("## Hyphenation (profile settings)\n")
+ for profile_id, info in self.hyphenation.items():
+ lines.append(f"- `{profile_id}`: {info}")
+ lines.append("")
+
+ lines.append("## Determinism caveats\n")
+ for item in self.determinism_caveats:
+ lines.append(f"- {item}")
+ lines.append("")
+
+ if self.notes:
+ lines.append("## Notes\n")
+ for note in self.notes:
+ lines.append(f"- {note}")
+ lines.append("")
+
+ return "\n".join(lines).rstrip() + "\n"
+
+
def build_coverage_report(spec: LoadedSpec, *, strict: bool) -> CoverageReport:
by_category: dict[str, int] = {}
by_enforcement: dict[str, int] = {}
@@ -102,3 +250,410 @@ def build_coverage_report(spec: LoadedSpec, *, strict: bool) -> CoverageReport:
counts=counts,
notes=notes,
)
+
+
+def build_trust_contract(spec: LoadedSpec, report: CoverageReport) -> TrustContract:
+ by_enforcement = report.counts.by_enforcement
+ enforced_total = sum(v for k, v in by_enforcement.items() if k != "manual")
+ manual_total = by_enforcement.get("manual", 0)
+ total = report.counts.total_rules or 0
+ enforced_percent = round((enforced_total / total) * 100, 1) if total else 0.0
+ manual_percent = round((manual_total / total) * 100, 1) if total else 0.0
+
+ manifest_contract = spec.manifest.get("coverage_contract", {}) if isinstance(spec.manifest, dict) else {}
+ manual_tag = (
+ (manifest_contract.get("must_rules") or {}).get("manual_checklist_tag")
+ if isinstance(manifest_contract, dict)
+ else None
+ )
+ manual_checklist = {
+ "tag": manual_tag or "manual_checklist=true",
+ "artifacts": ["manual-checklist.md", "manual-checklist.json"],
+ "generated_by": "lint",
+ }
+
+ qa_limitations = [
+ "QA combines HTML heuristics with Poppler-based PDF text extraction; it is not a full layout engine.",
+ "Widows/orphans and true overflow measurement remain heuristic until geometry-aware PDF analysis exists.",
+ "QA does not validate factual correctness or citation accuracy; manual checklist remains required.",
+ "Outbound links are not fetched; availability and trustworthiness are not verified.",
+ ]
+
+ determinism_assumptions = [
+ "Same input content, spec files, and profile settings produce the same outputs.",
+ "Same renderer engine/version and the same font set are available when rendering PDF.",
+ "No external network fetches are required for assets; local files are stable.",
+ "Rendering occurs in a consistent environment (locale, time zone, line endings).",
+ ]
+
+ enforcement_summary = {
+ "enforced_total": enforced_total,
+ "manual_total": manual_total,
+ "enforced_percent": enforced_percent,
+ "manual_percent": manual_percent,
+ "enforced_by_type": {k: v for k, v in by_enforcement.items() if k != "manual"},
+ }
+
+ return TrustContract(
+ tool=report.tool,
+ tool_version=report.tool_version,
+ generated_at_utc=report.generated_at_utc,
+ spec_root=report.spec_root,
+ manifest_version=report.manifest_version,
+ profiles=report.profiles,
+ counts=report.counts,
+ enforcement_summary=enforcement_summary,
+ qa_limitations=qa_limitations,
+ determinism_assumptions=determinism_assumptions,
+ manual_checklist=manual_checklist,
+ notes=report.notes,
+ )
+
+
+def build_doctor_report(spec: LoadedSpec) -> DoctorReport:
+ from iftypeset import __version__
+ from iftypeset.rendering import renderer_info
+
+ now = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
+ renderer = renderer_info()
+ poppler = _detect_poppler_tools()
+ fonts = _font_availability(spec)
+ locale_info = _locale_info()
+ hyphenation = {pid: (spec.profiles[pid].get("hyphenation") or {}) for pid in sorted(spec.profiles.keys())}
+
+ determinism_caveats = [
+ "PDF output depends on renderer engine version and font availability.",
+ "Poppler-based QA relies on text extraction and is not geometry-accurate.",
+ "Locale and line-ending differences can affect hyphenation and wrapping.",
+ "External assets should be local; network fetches are not assumed.",
+ ]
+
+ return DoctorReport(
+ tool="iftypeset",
+ tool_version=__version__,
+ generated_at_utc=now,
+ spec_root=str(spec.spec_root),
+ renderer=renderer,
+ poppler=poppler,
+ fonts=fonts,
+ locale=locale_info,
+ hyphenation=hyphenation,
+ determinism_caveats=determinism_caveats,
+ notes=[],
+ )
+
+
+def _command_version(cmd: str, flags: list[str]) -> str | None:
+ for flag in flags:
+ try:
+ proc = subprocess.run(
+ [cmd, flag],
+ check=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+ except (FileNotFoundError, subprocess.CalledProcessError):
+ continue
+ output = (proc.stdout.decode("utf-8", errors="replace") + proc.stderr.decode("utf-8", errors="replace")).strip()
+ if not output:
+ continue
+ return output.splitlines()[0].strip()
+ return None
+
+
+def _detect_poppler_tools() -> dict[str, Any]:
+ tools = {}
+ for name in ("pdfinfo", "pdftotext", "pdftohtml"):
+ path = shutil.which(name)
+ version = None
+ if path:
+ version = _command_version(name, ["-v", "--version"])
+ tools[name] = {"path": path, "version": version}
+ return {"tools": tools}
+
+
+def _font_availability(spec: LoadedSpec) -> dict[str, Any]:
+ fc_match = shutil.which("fc-match")
+ profiles: dict[str, Any] = {}
+ for profile_id, profile in sorted(spec.profiles.items()):
+ fonts = profile.get("fonts") or {}
+ entry: dict[str, Any] = {}
+ for role in ("body", "heading", "mono"):
+ role_info = fonts.get(role) or {}
+ families = role_info.get("family") or []
+ if not families:
+ continue
+ primary = str(families[0])
+ match = None
+ if fc_match:
+ match = _run_fc_match(primary)
+ entry[role] = {"primary": primary, "fallbacks": families[1:], "match": match}
+ profiles[str(profile_id)] = entry
+ return {"tools": {"fc_match": fc_match}, "profiles": profiles}
+
+
+def _run_fc_match(family: str) -> str | None:
+ try:
+ proc = subprocess.run(
+ ["fc-match", "-f", "%{family}\n", family],
+ check=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+ except (FileNotFoundError, subprocess.CalledProcessError):
+ return None
+ output = proc.stdout.decode("utf-8", errors="replace").strip()
+ if not output:
+ return None
+ return output.splitlines()[0].strip()
+
+
+def _locale_info() -> dict[str, Any]:
+ return {
+ "lang": os.environ.get("LANG"),
+ "lc_all": os.environ.get("LC_ALL"),
+ "lc_ctype": os.environ.get("LC_CTYPE"),
+ "python_locale": locale.getlocale(),
+ "preferred_encoding": locale.getpreferredencoding(False),
+ }
+
+
+def build_report_index(out_dir: Path) -> str:
+ generated_at = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
+
+ def load_ok(path: Path) -> str:
+ if not path.exists():
+ return "missing"
+ try:
+ data = json.loads(path.read_text(encoding="utf-8"))
+ except Exception:
+ return "present"
+ if data.get("ok") is True:
+ return "ok"
+ if data.get("ok") is False:
+ return "fail"
+ return "present"
+
+ def link_item(label: str, filename: str, status: str | None = None) -> str:
+ rel = Path("..") / filename
+ status_html = f'{status} ' if status else ""
+ return f'
'
+
+ lint_status = load_ok(out_dir / "lint-report.json")
+ qa_status = load_ok(out_dir / "qa-report.json")
+ run_status = load_ok(out_dir / "run-summary.json")
+ spec_status = load_ok(out_dir / "spec-validation.json")
+ pdf_present = "present" if (out_dir / "render.pdf").exists() else "missing"
+
+ lines: list[str] = []
+ lines.append("")
+ lines.append("