orgdoc-lint - report lightweight-markup hazards in Org-mode documents before they leak into the LaTeX or HTML build
orgdoc-lint [options] FILE.org [FILE.org...]
orgdoc-lint scans Org-mode source files for the lightweight-markup hazards described in DevelopmentStandard.org and reports each as file:line:col: CODE message, with the offending source line and a caret under the column. These are hazards that are invisible in the Org source and surface only on reading the generated .tex or the rendered PDF/HTML: a bare underscore that LaTeX turns into a subscript, a verbatim span that does not close on its line, and so on.
The checker reports; it does not edit. Several hazards — above all the tilde used as an "approximately" sign versus as code markup — need human judgement to resolve correctly, so the tool flags and the author decides. The corresponding corrections are made by hand, guided by the file:line:col locations.
Content that Org does not process is exempt from the content checks: #+begin_example, #+begin_src and #+begin_export blocks, lines beginning with “:” (fixed-width), the target of a link ([[url]] or [[path][desc]]) and bare URLs. A link description is processed and so is still checked.
It is invoked by the make lint family of targets (see EXAMPLES ) and depends only on python3(1).
--select=CODES
Check only the comma-separated CODES (for example --select=OD001,OD002).
--ignore=CODES
Skip the comma-separated CODES.
--errors-only
Narrow whatever is already selected (the default set, or --select’s choice) down to its error-severity codes. Against the default selection this means OD005 and OD006 — the ones that silently corrupt output or break the build. OD001 is also error-severity but is not in the default selection (see OD001 below); add it explicitly to see it under --errors-only too (--select=OD001 --errors-only).
--fail-on=LEVEL
Set the severity at which a non-zero status is returned: error, warning (the default) or never. With --fail-on=never the tool always exits 0 (report-only).
|
--fix |
Apply the auto-fixable findings in place. Only the unambiguous codes are fixed: OD001 (wrap the identifier in “˜”...“˜”) and OD006 (replace a prime glyph with a math span). The span codes (OD002, OD003, OD004) are never auto-edited; an OD001 whose identifier abuts a span-blocking character is also left for review (wrapping it would only produce an OD004). |
--diff
Show a unified diff of what --fix would change, without writing. Combined with --fix it writes the files and prints the diff.
--format=FMT
Output format: text (the default) or json. The JSON form lists each finding with its severity, whether it is fixable, and — when fixable — the column span and replacement text, for consumption by other tools.
--max-line=N
Also flag source lines longer than N characters (enables OD007, otherwise off).
--quiet
Print only the summary line.
--no-color
Disable ANSI colour (also the default when output is not a terminal).
--explain=CODE
Print the long description of one CODE and exit.
--list
List the codes with their severities and exit.
--version
Print the version and exit.
Each finding carries a code and a severity. Error codes mark silent corruption or a build failure and must be fixed; warning codes mark fragile constructs that often render acceptably but are not guaranteed to, and want review.
|
OD001 |
(error, opt-in) underscore in processed text. An identifier such as body_shape in prose, a table, a heading, or a non-verbatim block exports as body with a shape subscript, unless the file’s preamble sets #+OPTIONS: ˆ:{} , which this project’s files all do; not run by default for that reason. Wrap the identifier in code markup, or add #+OPTIONS: ˆ:{} , or add --select=OD001 to check for it explicitly. | ||
|
OD002 |
(warning) verbatim span crosses a line break. A ˜...˜ or =...= span must open and close on one source line. | ||
|
OD003 |
(warning) verbatim span contains its own delimiter. A =...= span cannot contain a literal “=”, nor a ˜...˜ span a literal “˜”; use the other delimiter. | ||
|
OD004 |
(warning) closing marker abuts a blocking character. A closing “˜” or “=” immediately followed by /, +, ( (and similar) does not close the span; extend the span or add a space. | ||
|
OD005 |
(error) bare backslash-command in prose. A command such as \footnotesize in running prose is passed to LaTeX as live code; wrap it in markup. | ||
|
OD006 |
(error) literal prime / double-prime. The U+2032 / U+2033 glyphs lack a font and warn at build; write $3’$ or $6’’$ in a math span instead. | ||
|
OD007 |
(warning) line longer than --max-line. Opt-in stylistic check; not a build hazard on its own. |
|
0 |
No findings at or above the --fail-on level. |
|||
|
1 |
Findings at or above the --fail-on level were reported. |
|||
|
2 |
Usage error (unknown option, or no input files). |
None. The linter is a single python3(1) script with no third-party dependencies. configure(1) checks for python3(1) and warns if it is absent (it is needed only by the make lint targets).
Lint every document, failing on any finding:
orgdoc-lint *.org
Gate only on the silent-corruption codes (a good pre-commit hook):
orgdoc-lint --errors-only *.org
Through the build, over the whole project in one pass:
make lint
make lint-errors
make check-org
Read the long description of a code:
orgdoc-lint --explain=OD001
checkxref(1), applyxref(1), render-views(1), man2htmldoc(1).
DevelopmentStandard.org LaTeX-export hazards, which specifies every rule the linter enforces, and the portable orgdoc-kit from which the linter originates.
Written in iteration 0.87.x as part of the portable orgdoc-kit documentation kit, then integrated into BSPPFit in iteration 0.88.0: shipped in bin/, wired to the make lint, make lint-errors and make check-org targets, and run across all project documents (clearing every error-severity finding). Link-target and bare-URL exemption was added in linter version 1.1.0 after an underscore inside a Wikimedia File: URL was flagged spuriously. The --fix, --diff and --format=json options were added in linter version 1.2.0 (BSPPFit iteration 0.89.0): the two unambiguous codes (OD001, OD006) became auto-correctable, while the span codes remain report-only. Linter version 1.4.0 (BSPPFit iteration 0.135.0) removed OD001 from the default selection: every project file’s preamble now sets #+OPTIONS: ˆ:{} , which removes the underlying hazard project-wide (see --explain=OD001 ). OD001 remains fully available via --select=OD001.
Peter Felecan, assisted by Claude Sonnet 5 (Anthropic).