Skip to content

Command line

simplemark [--check] [--compat] [--strict]
           [--width N] [--style none|ansi|auto] [FILE]
python -m simplemark [...]

Reads standard input when no file is given. The two forms are identical.

Render

printf 'Compute `n` factorial.\n\nExample:\n\n    >>> fact(5)\n    120\n' > doc.txt
simplemark --width 44 --style none doc.txt
Compute 'n' factorial.

Example:

    >>> fact(5)
    120
option effect
--width N Wrap to N columns. Default: the terminal's width, or 80.
--style none No styling; code spans are quoted.
--style ansi Bold and underline via ANSI escapes.
--style auto (default) ansi on a TTY, none when piped. Honours NO_COLOR and TERM=dumb.

Because auto detects a pipe, this is safe:

simplemark --width 40 doc.txt | head -1
Compute 'n' factorial.

No escape sequences leaked into the pipe.

Check

--check reports diagnostics to standard error and prints nothing to standard output.

printf 'A command `foo is dispatched.\n' > legacy.txt
simplemark --check legacy.txt 2>&1 || echo "exit=$?"
legacy.txt:1:11: E001 unclosed code span
exit=1

The format is file:line:col: CODE message: the one every editor and CI system already parses.

Exit status is 1 only if an error was found. CommonMark notes do not fail the build:

printf 'Uses 10**e and x**y internally.\n' > note.txt
simplemark --check note.txt 2>&1; echo "exit=$?"
note.txt:1:1: CM001 CommonMark reads some of these delimiters as emphasis
exit=0

That split is deliberate. An error means the text is ambiguous or the author made a mistake. A note means another renderer would read it differently: useful to know, not a reason to stop.

Compat and strict

--compat adds the legacy notes: reStructuredText constructs and older docstring conventions. They are off by default, because a project that never used reStructuredText should never hear about them.

printf 'Example::\n\n    code()\n' > legacy2.txt
simplemark --check legacy2.txt 2>&1; echo "default exit=$?"
simplemark --check --compat legacy2.txt 2>&1; echo "compat exit=$?"
default exit=0
legacy2.txt:1:8: L001 trailing '::' is reStructuredText; write ':'
compat exit=0

--strict makes every reported diagnostic a failure. It changes only the exit status:

simplemark --check --compat --strict legacy2.txt 2>&1; echo "strict exit=$?"
legacy2.txt:1:8: L001 trailing '::' is reStructuredText; write ':'
strict exit=1

The intended workflow when adopting simplemark on an existing codebase: run --check --compat once, fix what it finds, then drop --compat and put --check in CI.

In CI

- name: Check docstrings
  run: simplemark --check docs/*.txt

To fail on notes as well, add --strict.

Note: it reads text, not Python

simplemark --check module.py checks the file as simplemark text; it does not extract docstrings from it. To check the docstrings in a module, use the API:

python - <<'EOF'
import ast
import simplemark

source = open("legacy.txt").read()  # any text
for diagnostic in simplemark.check(source):
    print(diagnostic)
EOF
1:11: E001 unclosed code span

Walking a module's docstrings is a dozen lines with ast, and a linter plugin is the right home for it rather than this CLI.