chore: hard-wrap markdown at 80 cols via prettier + pre-commit - #75
Merged
Conversation
Add prettier (proseWrap: always, printWidth: 80) wired through a local pre-commit hook, and tune markdownlint's MD013 to match so the two agree. Tables, fenced code blocks, headings and long URLs are left over-length by design — MD013 disables those three checks and is non-strict for unbreakable lines. embeddedLanguageFormatting is off so prettier never rewrites the contents of a fence. Corpora and fixtures are excluded from both tools: prettier rewrites YAML frontmatter and does not recognise TOML (+++) or bare-brace JSON frontmatter, which would mangle example_kb, assets/demo_kb and the multi-format test fixtures. The generated CHANGELOG.md is excluded to avoid fighting cog. AGENTS.md is reformatted by the new hook; the rest of the tree is left for a separate bulk pass.
`just fmt-md` / `just check-md` mirror the pre-commit hook for manual runs. The CI job re-checks committed content, which the hook cannot do — the hook only ever sees the file it just rewrote, so it can't detect a formatting fixed-point being lost. Prettier is pinned to 3.6.2 in .pre-commit-config.yaml, the Justfile and ci.yml; bump all three together. Config comments trimmed to the non-obvious why.
Mechanical prettier pass over every tracked .md outside .prettierignore. Verified by rendering each file before and after through CommonMark + GFM tables and comparing normalised HTML: 276 files reformatted, zero unintended rendering changes. Five files needed hand-fixing first, from two root causes: - Bare snake_case identifiers in prose pairing as emphasis across a code span. Prettier rewrote `write_index` to `write*index` and ate the spaces around adjacent code spans (TODO-0184), and in TODO-0106 / TODO-0162 the first pass emitted output that a second pass corrupted — a lost fixed point the hook cannot detect. Fixed by code-spanning the identifiers. - Unescaped pipes inside code spans in table cells, which degraded a table to a paragraph of literal pipes (TODO-0149). Fixed with `\|`. TODO-0155 additionally goes from a tight to a loose list: prettier always inserts a blank line before a fence inside a list item, so the blank lines are now explicit rather than appearing in a later diff.
…ting # Conflicts: # docs/spec/todos/TODO-0196.md # docs/spec/todos/index.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Flips the repo's markdown convention from "no hard-wrap" to a hard 80-column wrap, enforced by prettier via a pre-commit hook and a CI check.
MD013 was firing on essentially every markdown file in editors. MD013 has no auto-fix, so the choice was to disable the rule or adopt wrapping; this PR adopts wrapping.
Tooling
.prettierrc.yamlproseWrap: always,printWidth: 80,embeddedLanguageFormatting: off.prettierignoreCHANGELOG.md,target/.markdownlint-cli2.yamlcode_blocks/tables/headingsoff.pre-commit-config.yamlprettier@3.6.2hook,language: nodeJustfilejust fmt-md/just check-mdci.ymlfmt-mdjob runningprettier --checkSetup is
uv tool install pre-commit && pre-commit install.uv tool, notuvx—pre-commit installbakes the interpreter path into.git/hooks/pre-commit, and a uvx cache entry can be pruned out from under it. Node and prettier are provisioned by pre-commit; nothing needs a global npm install.Tables, fenced code blocks, headings and long URLs are deliberately left over-length. MD013 disables those three checks and is non-strict for lines with no space past the limit, so the two tools agree on what "formatted" means.
embeddedLanguageFormatting: offstops prettier rewriting the contents of fences whose language it can parse (json, yaml, js) — otherwise doc examples get silently reformatted.Fixtures and corpora are excluded from both tools because their exact frontmatter bytes are under test: prettier rewrites YAML frontmatter (quote style, indentation, flow-sequence spacing) and doesn't recognise TOML
+++or bare-brace JSON frontmatter at all.Verification
Every file was rendered before and after through CommonMark + GFM tables, with the HTML whitespace-normalised and compared. 276 files reformatted, zero unintended rendering changes. Prettier is idempotent across the repo,
mdbook buildpasses, no fixture or non-markdown file was touched, and MD013 violations went from ~3,400 to 0.Five files hand-fixed first
Two root causes, both of which silently change rendered output:
Bare
snake_caseidentifiers pairing as emphasis across a code span. InTODO-0184, prettier turnedwrite_indexintowrite*indexand ate the spaces around three adjacent code spans:TODO-0106andTODO-0162were worse: the first pass rewrote*every*to_every_, and that new underscore then paired with a bare one earlier in the paragraph on the second pass. Formatted, committed, clean — and corrupting on next touch. The pre-commit hook cannot detect this, because it only ever sees the file it just rewrote. This is what the CI job is for.Unescaped pipes inside code spans in table cells.
| `"value {value} {< | >} {limit}"` |was already splitting cells; after reformatting the whole table degraded to a paragraph of literal pipes. Fixed with\|.TODO-0155also moves from a tight to a loose list — prettier always inserts a blank line before a fence inside a list item, so the blank lines are now explicit rather than surfacing in some later unrelated diff.Commits
e5cf18b— configs, hook, AGENTS.md rule8a15864— just recipes, CI job, trimmed comments46a3cb7— the reformat (273 files)The reformat is mechanical and kept in its own commit; review the first two and skim the third.
Note
Prettier
3.6.2is pinned in three places (.pre-commit-config.yaml,Justfile,ci.yml). Bump all three together — the alternative is CI and local disagreeing about what "formatted" means.