Validation, sanitization and metrics for Markdown manuscripts.
Project description
manuscript-tools
A QA toolkit for German Markdown manuscripts. Validates style, sanitizes encoding, converts quotation marks, and measures readability.
Installation
pip install manuscript-tools
Or as project dependency:
poetry add manuscript-tools
Commands
| Command | Description |
|---|---|
ms-check |
Style checks (6 core rules, --strict adds 3 prose rules) |
ms-sanitize |
Fix encoding, strip invisible chars, normalize Unicode |
ms-quotes |
Convert quotation marks to German typographic style „ " ‚ ' |
ms-dashes |
Rewrite faked dashes (--, spaced hyphen) to a real dash (--to em|en) |
ms-format |
Fix broken bold/italic caused by line-wrapping formatters |
ms-metrics |
Word counts, sentence analysis, Flesch-DE readability score |
ms-validate |
Full QA pipeline (sanitize + quotes + formatting + check + readability) |
Quick start
# Full QA pipeline
ms-validate manuscript/
# Style check only (core rules)
ms-check manuscript/
# Style check with prose analysis (filler words, passive voice, sentence length)
ms-check manuscript/ --strict
# Readability report
ms-metrics manuscript/
# Fix quotation marks (dry-run)
ms-quotes manuscript/ --dry-run
# Fix broken bold/italic formatting (dry-run)
ms-format manuscript/ --dry-run
# Rewrite -- and spaced hyphens to en-dashes (German typography, dry-run)
ms-dashes manuscript/ --to en --dry-run
File selection
Not limited to Markdown. Directories are scanned with the glob **/*.md by default; a single file passed as argument is processed as-is, regardless of extension:
# Single file: no glob filter applied
ms-check brief.txt
# Directory with other extensions: override the glob
ms-sanitize docs/ --include '**/*.txt'
ms-check kapitel/ --include '**/*.tex' --exclude '**/build/**'
Files must be UTF-8 text (txt, tex, rst, html, ...) — binary formats like docx or pdf are not supported. The broken-formatting rule checks Markdown **/* markers; for non-Markdown files it is harmless, or disable it via disable = ["broken-formatting"] in the configuration.
Example
A manuscript with typical artifacts from AI tools, copy-paste, or code formatters — line 1 contains an invisible zero-width space (U+200B) after "Test":
Das ist ein Test mit unsichtbarem Zeichen.
Er sagte: "Hallo Welt" und ging.
Dies ist ein **
wichtiger Satz** im Text.
ms-check reports every problem with file, line, and rule — invisible characters are named by codepoint:
$ ms-check kapitel-01.md
FAIL: kapitel-01.md:1 [no-invisible-chars] Unsichtbare Unicode-Zeichen gefunden: U+200B ZERO WIDTH SPACE
FAIL: kapitel-01.md:3 [non-german-quotes] Nicht-deutsche Anführungszeichen gefunden
FAIL: kapitel-01.md:5 [broken-formatting] Oeffnendes ** am Zeilenende (Formatierung gebrochen)
------------------------------------------------------------
Dateien: 1, Woerter: 21
Status: FEHLER (1 Dateien, 3 Verstoss(e))
Fix step by step — every fixer supports --dry-run (preview) and writes .bak backups:
$ ms-sanitize kapitel-01.md
CLEANED: kapitel-01.md
$ ms-quotes kapitel-01.md
FIXED: kapitel-01.md (1 Ersetzung(en))
$ ms-format kapitel-01.md
FIXED: kapitel-01.md (1 bold, 0 italic)
$ ms-check kapitel-01.md
OK: kapitel-01.md (20 Woerter)
Status: OK
Result:
Das ist ein Test mit unsichtbarem Zeichen.
Er sagte: „Hallo Welt“ und ging.
Dies ist ein **wichtiger Satz** im Text.
Or run the whole pipeline in one go: ms-validate kapitel-01.md --fix.
Rules
Core (always active):
no-dashes, no-invisible-chars, no-repeated-words, no-double-spaces, non-german-quotes, broken-formatting
Prose (with --strict or ms-validate):
max-sentence-length, filler-words-de, passive-voice-de
Opt-in (via rules = ["faked-dashes"] in the configuration):
faked-dashes — flags -- and spaced hyphens standing in for a real dash. By design it contradicts no-dashes (one forbids dashes, the other demands correctly typed ones), so enable one and disable the other. ms-dashes --to em|en rewrites the findings:
Er kam -- wie immer -- viel zu spaet. # before
Er kam – wie immer – viel zu spaet. # after ms-dashes --to en
Seiten 12 - 15 behandeln das Thema. # numeric ranges stay untouched
Custom rules are simple callables with the signature (text: str, path: Path) -> list[StyleViolation]. See the Wiki for a step-by-step tutorial.
Configuration
Configure via [tool.manuscript-tools] in your pyproject.toml:
[tool.manuscript-tools]
rules = ["max-sentence-length"] # merge with defaults
disable = ["passive-voice-de"] # remove from active set
max-sentence-words = 30 # default: 40
flesch-target = [65, 80] # warn if outside range
filler-words-extra = ["definitiv", "absolut"] # extend filler list
No config = all defaults. rules merges with defaults (union). disable removes from the active set and takes precedence over rules. See the Wiki for details.
Readability
ms-metrics computes the Flesch-DE reading ease score (Amstad, 1978) with German-optimized syllable counting. Score interpretation:
| Score | Level | Typical use |
|---|---|---|
| 80-100 | Very easy | Children's books |
| 60-80 | Easy to medium | Fiction, non-fiction |
| 30-60 | Difficult | Journalism, academic |
| 0-30 | Very difficult | Legal, scientific |
Development
git clone https://github.com/astrapi69/manuscript-tools.git
cd manuscript-tools
make install-dev
make ci # lint + format check + 175 tests
Documentation
Full documentation is available in the Wiki:
- Installation and Setup
- Usage
- Writing Custom Rules
- Integration into Projects
- Publishing to PyPI
- Development and CI
- FAQ
- Quick Start for Book Projects
- Configuration
License
BSD 3-Clause. See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file manuscript_tools-0.8.0.tar.gz.
File metadata
- Download URL: manuscript_tools-0.8.0.tar.gz
- Upload date:
- Size: 29.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.4.1 CPython/3.11.13 Linux/7.0.0-28-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa6e4adf331dc6656f9e2ba41f054fa0dbf5e766eedc95faed337b2ce1247810
|
|
| MD5 |
74fc1a5f106519c956a4e9ebeb4413f3
|
|
| BLAKE2b-256 |
5a94ffe8c35bdde1825e56f48c44a9671ee3ff19e72b06cb68f556b143cecabd
|
File details
Details for the file manuscript_tools-0.8.0-py3-none-any.whl.
File metadata
- Download URL: manuscript_tools-0.8.0-py3-none-any.whl
- Upload date:
- Size: 33.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.4.1 CPython/3.11.13 Linux/7.0.0-28-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0296758a87c78c1a846104f90ab8ffc62e0126f727adced0c521ad0895ebccce
|
|
| MD5 |
75e18d544ec9cc9fc644d02014e2628c
|
|
| BLAKE2b-256 |
145989bb2faba7d35814d30b677448efbbb10fa7d6329625dc9dc19dde166022
|