Skip to content

Additional ISO tools: Clause Names -> Clause names; Bold Table Headings. Allow fixing of the found issues.#96

Merged
asluk merged 14 commits into
aousd:mainfrom
OleksiyPuzikov:main
Jun 15, 2026
Merged

Additional ISO tools: Clause Names -> Clause names; Bold Table Headings. Allow fixing of the found issues.#96
asluk merged 14 commits into
aousd:mainfrom
OleksiyPuzikov:main

Conversation

@OleksiyPuzikov

@OleksiyPuzikov OleksiyPuzikov commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

For users

Three linters check Markdown specification sources against ISO/IEC Directives and report violations with file paths and line numbers. Two of them also auto-fix in place when asked.

Linter Rule Auto-fix
iso_heading_case_lint Clause titles in sentence case (§11.4)
iso_bold_table_lint Table column headings in bold
iso_clause_lint No body text before first subclause

Run all at once via iso_lint_all (check) or iso_fix_all (auto-fix what's possible, then run iso_lint_all for the rest). Each tool accepts a directory or a single .md file.

Proper-noun detection combines heuristics (camelCase, ALL_CAPS, mixed alphanumeric tokens) with a YAML allowlist (iso_heading_proper_nouns.yaml). The source-level fixer builds a set of protected character positions (code spans, link URLs) and only lowercases words outside those ranges.

See doc_build/ISO_LINTERS.md for CLI usage, DocBuilder subcommands, and a ready-to-use GitHub Actions snippet.

Note that CI integration in the specification repo is not included here and should be added once this is accepted.

For reviewers

Each linter follows the same pattern: Pandoc parses the file with +sourcepos to produce a JSON AST, then checker walks the AST to detect violations with accurate line numbers, and the fixer (where applicable) edits the source line directly via regex on the specific source lines.

Using the Pandoc AST for editing is considered destructive as additional changes might be introduced besides the requested ISO formatting.

OleksiyPuzikov and others added 3 commits June 8, 2026 14:27
Implement heading-case tooling per ISO/IEC Directives, Part 2, 11.4
(clause titles in sentence case) as both a linter and a build-time
Pandoc filter. Proper nouns are preserved via heuristics (camelCase,
ALL_CAPS, alphanumeric mix) and an extensible YAML allowlist.

Wire the existing bold-table-header filter into the build pipeline
with an opt-in --bold-table-headers flag, and add documentation
comments throughout.

All three ISO features are off by default on the build subcommand:
  --heading-case-lint     (pre-build check, prints violations)
  --heading-case-filter   (rewrites headings in output)
  --bold-table-headers    (bolds table header cells in output)

The heading_case_lint standalone subcommand is also available.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@OleksiyPuzikov
OleksiyPuzikov requested a review from pmolodo June 8, 2026 11:50
OleksiyPuzikov and others added 7 commits June 10, 2026 14:07
Remove filter_heading_case from the build pipeline and add in-place
editing (--fix) to iso_heading_case_lint.py, matching the pattern
already used by bold_table_lint.py. Add heading_case_fix and
bold_table_lint/bold_table_fix DocBuilder subcommands.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These ISO formatting concerns are now handled by source-level lint/fix
tools (iso_heading_case_lint.py, bold_table_lint.py) instead of Pandoc
AST filters applied during PDF/HTML/DOCX production.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Consistent naming with iso_heading_case_lint.py and iso_clause_lint.py.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract _collect_md_files, _get_sourcepos, _unwrap_sourcepos_spans,
  and DEFAULT_WORKERS into iso_lint_utils.py (was duplicated across all
  three linters).
- All linters now accept a single .md file path in addition to
  directories.
- Add iso_lint_all subcommand (runs all three linters).
- Add iso_fix_all subcommand (fixes heading case and bold tables, then
  lints clause structure).
- Rename iso_lint subcommand to iso_clause_lint for consistency with the
  module name and sibling subcommands.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract stringify import and run_parallel_check() into iso_lint_utils
- Add display_path param to Violation.format() instead of cloning objects
- Remove dead _SEPARATOR_RE/_is_separator_line from bold table linter
- Remove duplicate `import re` from heading case linter
- Use set.isdisjoint() for O(1) protected-range checks in heading fixer
- Simplify fix_file() newline handling with rstrip('\n')
- Have main() --fix call fix_spec() instead of reimplementing it
- Refactor iso_lint_all/iso_fix_all into data-driven loops
- Remove clause lint from iso_fix_all (belongs in iso_lint_all only)
- Fix stale iso_clause_lint_all references in docs (actual name: iso_lint_all)
- Add partial-bold edge case comment to _bold_header_row

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…orts

- Move format_report() logic into iso_lint_utils parameterised by label
- Each linter keeps a thin wrapper preserving its public API
- Remove unused imports from iso_bold_table_lint (re, Set, field)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- fix_spec() accepts optional pre-computed violations list, skipping
  the redundant check_spec() call when the caller already has results
- All call sites (main --fix, doc_builder fix methods, iso_fix_all)
  now pass violations through
- Make Violation.format() keyword-only across all three linters
- Remove commented-out code from iso_clause_lint Violation.format()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@OleksiyPuzikov OleksiyPuzikov changed the title DRAFT: Additional ISO tools: Clause Names -> Clause names; Bold Table Headings. Additional ISO tools: Clause Names -> Clause names; Bold Table Headings. Allow fixing of the found issues. Jun 11, 2026

@dgovil dgovil left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me though I think we should replace the getattr calls with direct properties to prevent the risk of typos or issues like that sneaking in.

Comment thread doc_build/doc_builder.py Outdated
OleksiyPuzikov and others added 4 commits June 12, 2026 14:57
The argparse namespaces always have these attributes defined by their
respective parsers, so getattr with a fallback is unnecessary.  Add
--context to the iso_lint_all parser so it's explicitly declared
rather than silently defaulted via getattr.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The build parser defines all five attributes (heading_case_lint,
heading_proper_nouns, iso_xrefs, keep_pdf_latex), so the argparse
namespace always has them — getattr with a fallback was unnecessary.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
build_docs() is called from test scripts that build args via
types.SimpleNamespace without all build-parser attributes.  The
getattr fallbacks are necessary here, unlike the ISO subcommand
methods which are only ever invoked through their own parsers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add the missing build-parser attributes (heading_case_lint,
heading_proper_nouns, iso_xrefs) to the SimpleNamespace in
build_diff.py so build_docs() can use direct attribute access
consistently. Future build flags that are missing from test
callers will fail with a clear AttributeError instead of
silently falling back to a default.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@asluk
asluk merged commit 7a52f1f into aousd:main Jun 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants