Repository navigation
Implement the md-lines hook: one sentence per line in Markdown - #1
Conversation
A general pre-commit hook grown out of the sentence-per-line script in NeurodataWithoutBorders/nwb-benchmarks-paper. - Block structure comes from markdown-it-py (CommonMark plus tables and strikethrough): only paragraph lines are reflowed, including paragraphs inside list items and block quotes; headings, code, tables, HTML, link reference definitions, thematic breaks and YAML/TOML front matter are never touched. A wrapped line that starts with a link or emphasis is therefore joined correctly, which the line-prefix heuristics of the original script got wrong. - Within a paragraph, wrapped sentences are joined and lines holding several sentences are split. List items are joined but not split unless --split-lists is given; new lines reproduce block quote markers and list indentation. Hard line breaks are kept. - Sentence ends are ignored inside inline code, link destinations, autolinks, inline HTML, bare URLs and $math$, after abbreviations (built-in list, --abbreviations, --abbreviations-file, --no-default-abbreviations), initials, dotted abbreviations and line enumerators, after a bold lead-in such as **Note.**, and inside unbalanced bold markers, brackets or parentheses. - --check and --diff modes, --keep-breaks-after for authors who break after colons or semicolons, exit codes 0/1/2. CRLF, BOM and a missing final newline are preserved; the output is a fixed point. - Packaged with a console script (md-lines) and a .pre-commit-hooks.yaml manifest so consumers use `repo:` + `rev:`; 48 tests; CI runs the tests on Python 3.9, 3.11 and 3.13, this repository's own pre-commit hooks (ruff, hygiene, md-lines on README.md) and a consumer-style `pre-commit try-repo`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ToiYPiSdU8NM9h1UmLgsq8
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ToiYPiSdU8NM9h1UmLgsq8
Review feedback on #1: the version string was duplicated in pyproject.toml and __init__.py. pyproject.toml is now the only place it is written; __init__.py reads it through importlib.metadata, which is what carries the pyproject version once the package is installed (also for `pip install -e .`), and falls back to "0+unknown" in a bare checkout. A test asserts the two agree. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ToiYPiSdU8NM9h1UmLgsq8
Review feedback on #1: - requires-python >= 3.13, ruff targets py313, the `from __future__ import annotations` shims are gone, and CI tests on the latest stable Python ("3.x") instead of a 3.9/3.11/3.13 matrix. The README notes that an older Python running pre-commit needs `language_version` on the hook entry. - src/md_lines/__main__.py is removed: pre-commit runs the `md-lines` console script named in .pre-commit-hooks.yaml, so `python -m md_lines` was an extra entry point nothing here needs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ToiYPiSdU8NM9h1UmLgsq8
Signed-off-by: Cody Baker <51133164+CodyCBakerPhD@users.noreply.github.com>
- src/md_lines/schema/md_lines.yaml defines Options, Problem, Result and Paragraph; src/md_lines/models.py is generated from it with `gen-python --no-metadata`, and a test fails when the two drift apart - src/md_lines/globals.py holds the abbreviation list, the parser, the regular expressions and DEFAULT_OPTIONS; reflow.py keeps only functions - Options.abbreviations is a list (multivalued slot) and Problem has no __str__, so the CLI formats line and message itself - pre-commit after CodyCBakerPhD/historia: black, ruff (with its isort rules), codespell (with the en-GB_to_en-US dictionary, so the text stays in American English), check-github-workflows - tests: the console entry point only, since `python -m md_lines` went away with __main__.py; CI installs the dev extra so the schema test runs - README: Python 3.13 or newer, `language_version` for older pre-commit interpreters, and how the model is generated Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ToiYPiSdU8NM9h1UmLgsq8
Review feedback on #1. - AGENTS.md ported from CodyCBakerPhD/historia, with sections for this repository's data model (LinkML schema, generated models.py, globals) and the American English and sentence-per-line rules; CHANGELOG.md started with an Upcoming entry for this PR - Internal imports are relative; external modules are imported whole (markdown_it, collections.abc, importlib.metadata); multi-input functions take keyword-only arguments, single-input ones positional-only - __init__.py holds imports and __all__ only; the version lookup moves to _version.py - Tests carry the ai_generated marker, registered in pyproject.toml - .github/workflows/ci.yml renamed to continuous_integration.yml with name "Continuous Integration" - pre-commit.ci skips the md-lines hook, which is `language: system` and therefore cannot run there; the GitHub Actions workflow runs it Co-Authored-By: Claude Code 2.1.293 / Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ToiYPiSdU8NM9h1UmLgsq8
The tests job runs pytest with coverage and uploads coverage.xml with codecov/codecov-action, failing when the upload fails, as in CodyCBakerPhD/historia. pytest-cov joins the dev extra and the generated models.py is omitted from coverage. actions/checkout and actions/setup-python move to v7. docs/development.md names the CODECOV_TOKEN secret the upload needs. Co-Authored-By: Claude Code 2.1.293 / Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ToiYPiSdU8NM9h1UmLgsq8
|
The Nothing in the branch can fix this. The repository needs a Generated by Claude Code |
Review feedback on #1. pre-commit.ci runs the hooks on every pull request, so the Actions job no longer repeats them. It keeps the two things pre-commit.ci does not do: this repository's own md-lines hook (language: system, skipped there) and the try-repo installation test. Co-Authored-By: Claude Code 2.1.293 / Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ToiYPiSdU8NM9h1UmLgsq8
Welcome to Codecov 🎉Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests. Thanks for integrating Codecov - We've got you covered ☂️ |
Signed-off-by: Cody Baker <51133164+CodyCBakerPhD@users.noreply.github.com>
What this is
A general pre-commit hook grown out of
scripts/check_sentence_per_line.pyin nwb-benchmarks-paper. Consumers add it withrepo:+rev:; it also installs as themd-linescommand. Python 3.13 or newer; consumers whose pre-commit runs under an older interpreter addlanguage_version: python3.13to the hook entry.How it differs from the original script
;/:were left as fragments.>marker, inside list items the item's indentation (also for nested lists and loose items). Lazy block quote continuations are normalized.$math$; respects abbreviations (built-in list,--abbreviations,--abbreviations-file,--no-default-abbreviations), initials, dotted abbreviations, enumerators, bold lead-ins (**Note.**) and unbalanced bold markers, brackets or parentheses.--check,--diff,--split-lists,--keep-breaks-after(default.!?; add:;to keep the original script's behavior of breaking after colons and semicolons),-q.Layout
src/md_lines/schema/md_lines.yaml: the data model (Options,Problem,Result,Paragraph) as a LinkML schema.src/md_lines/models.py: generated from the schema withgen-python --no-metadata; a test fails when the two drift apart. Excluded from the formatters and from coverage.src/md_lines/globals.py: the abbreviation list, the parser, the regular expressions andDEFAULT_OPTIONS.src/md_lines/reflow.py: functions only.src/md_lines/cli.py: the command.src/md_lines/_version.py: reads the version from the installed metadata, sopyproject.tomlis the only place it is written.AGENTS.mdported from historia and applied: relative internal imports, whole-module external imports, keyword-only arguments on multi-input functions,ai_generatedtest marker,CHANGELOG.md.Repository checks
pre-commit after historia: pre-commit-hooks, check-github-workflows, black, ruff (lint plus isort rules,
--fix), codespell with theen-GB_to_en-USdictionary so the text stays in American English, and this repository's ownmd-lineshook on its Markdown. pre-commit.ci runs the hooks on every pull request, except themd-lineshook, which islanguage: systemand skipped there. TheContinuous Integrationworkflow runs the tests on the newest Python with coverage uploaded to Codecov (using theCODECOV_TOKENrepository secret), runs that one hook, and installs the hook the way a consumer does withpre-commit try-repo.Validation
pytest), covering joins, splits, lists (kept, split, nested, loose, lazy), block quotes, every protected block type, front matter, hard breaks, inline masking, abbreviations, bold labels, CRLF/BOM, CLI modes and exit codes, the console entry point, and the schema/model agreement. 97% line coverage.pre-commit run --all-filesandpre-commit try-repo . md-lines --files README.mdpass locally on Python 3.13.After merging
Create the
v0.1.0tag so consumers can pinrev: v0.1.0. No LICENSE file is included; that choice is yours.🤖 Generated with Claude Code
https://claude.ai/code/session_01ToiYPiSdU8NM9h1UmLgsq8