Skip to main content

djot-fmt

Automatic formatter for djot markup files.

Overview

djot-fmt is a command-line tool that automatically formats djot files, focusing primarily on fixing common list formatting issues:

  • Missing newlines between list items
  • Incorrect indentation for nested lists
  • Blank line spacing before nested content

Installation

go install github.com/KyleKing/djot-fmt@latest

Or from PyPI, which ships the same formatter as a shared library bound with ctypes:

uv tool install djot-fmt   # or: pipx install djot-fmt
uvx djot-fmt file.dj       # run without installing

The Python wheels carry a compiled library rather than a reimplementation, so output is byte-identical to the Go binary. Formatting runs in-process, which costs about 9 microseconds for a small document against roughly 3 milliseconds to spawn the CLI.

Python API

import djot_fmt

djot_fmt.format('-  a\n-  b\n')  # '- a\n- b\n'
djot_fmt.format(source, wrap_sentences=False)

format raises djot_fmt.DjotFormatError on input the formatter rejects. Calls are serialized internally because the underlying djot parser is not goroutine-safe.

The shared library is opened on the first call rather than at import, so a process that imports djot_fmt and then forks stays safe. Calling into it before forking does not, because the Go runtime does not survive fork() without exec(). Use the spawn or forkserver start method with multiprocessing.

Usage

Basic Usage

# Format stdin to stdout
cat file.dj | djot-fmt

# Format file and write back
djot-fmt -w file.dj

# Format multiple files and write back
djot-fmt -w file1.dj file2.dj file3.dj

# Check if file is formatted (exit 1 if not)
djot-fmt -c file.dj

# Check multiple files
djot-fmt -c file1.dj file2.dj file3.dj

# Format to different file
djot-fmt -o output.dj input.dj

Batch Processing

# Format all .dj files in current directory
fd -e dj -x djot-fmt -w

# Format all .dj files in specific directory
fd -e dj . content/ -x djot-fmt -w

# Check formatting for all .dj files
fd -e dj -x djot-fmt -c

# Using find (alternative to fd)
find . -name "*.dj" -exec djot-fmt -w {} \;

Options

  • -w, --write - Write result to source file(s) instead of stdout
  • -c, --check - Check if file(s) are formatted (exit 1 if not)
  • -o, --output FILE - Write output to FILE instead of stdout (single input file only)
  • -h, --help - Show help message
  • -v, --version - Show version information

Validation Options

After formatting, djot-fmt renders both the input and the output to HTML and compares them. A difference means formatting changed what the document says, which is a bug in djot-fmt, so the run fails rather than writing the file.

  • --no-validate - Skip the check
  • --from-md - Allow the list changes that formatting markdown as djot causes, and report each one that was waived. djot requires a blank line before a nested list where markdown does not, so inserting that line legitimately changes the parse. Nothing else is waived: losing a word, a block kind, or an <ol> start number still fails

SLW (Semantic Line Wrap) Options

  • --no-wrap-sentences - Disable semantic line wrapping
  • --slw-markers TEXT - Characters that mark sentence endings (default: ".!?")
  • --slw-wrap INTEGER - Maximum line width for wrapping (default: 88, set to 0 to disable)
  • --slw-min-line INTEGER - Minimum line length before wrapping (default: 40, set to 0 for aggressive mode)

Development

This project uses mise for tool management and hk for git hooks.

Setup

# Install mise (if not already installed)
# See: https://mise.jdx.dev/getting-started.html

# Install project tools
mise install

# Install git hooks
hk install --mise

Common Commands

# Run all checks (linting, tests)
mise run ci

# Format code
mise run fmt

# Run tests
mise run test

# Build binary
mise run build

# Install locally
mise run install

Python bindings

# Build the wheel (compiles bindings/cshared with -buildmode=c-shared)
uv build --wheel

# Run the Python tests against the built wheel
uv run --isolated --with dist/*.whl --with pytest pytest bindings/python/tests

bindings/cshared/lib.go is the cgo boundary. Every exported function there recovers from panics, because a panic crossing into C terminates the host process, which for a Python caller means killing the interpreter. Strings allocated on the Go side are freed through DjotFree.

Roadmap

Future enhancements under consideration:

  • Support for all djot node types (ordered lists, tables, code blocks, etc.)
  • Configurable formatting options (indentation width, line wrapping)
  • Semantic line wrapping (similar to mdformat-slw)
  • Code block formatting integration

License

MIT

Credits

Built using godjot for djot parsing and AST manipulation.

Metadata

Release files for djot-fmt 0.2.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for djot-fmt 0.2.3
File Size Uploaded
djot_fmt-0.2.3.tar.gz 31.1 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for djot-fmt 0.2.3
File
djot_fmt-0.2.3-py3-none-win_arm64.whl Python 3 none Windows ARM64 Details
djot_fmt-0.2.3-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
djot_fmt-0.2.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64, Linux glibc 2.28+ ARM64 Details
djot_fmt-0.2.3-py3-none-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl Python 3 none Linux glibc 2.5+ x86-64, Linux glibc 2.28+ x86-64 Details
djot_fmt-0.2.3-py3-none-macosx_15_0_x86_64.whl Python 3 none macOS 15.0+ x86-64 Details
djot_fmt-0.2.3-py3-none-macosx_15_0_arm64.whl Python 3 none macOS 15.0+ ARM64 Details

Total release size: 5.6 MB

Release files / djot_fmt-0.2.3.tar.gz

Download URL djot_fmt-0.2.3.tar.gz
Size 31.1 kB
Tags Source
SHA-256 checksum
How to use checksums
6faafeae3d4946ef5f402ad2ce06098de2cab2c967ea9dcff1601c18f364cf16
BLAKE2b-256 checksum
How to use checksums
8f8d1fd55b5a3fc70aa86e02d979fbff9e4112e1d50e54e1ae592cde520692f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / djot_fmt-0.2.3-py3-none-win_arm64.whl

Download URL djot_fmt-0.2.3-py3-none-win_arm64.whl
Size 873.8 kB
Tags Python 3 Windows ARM64
SHA-256 checksum
How to use checksums
175ecfc0f9d9b39996c5a3d09169a63edcbf6a7e11b139f477f14d5ad11177a8
BLAKE2b-256 checksum
How to use checksums
78e32f44eea3a8f0a52cd8d8ffdc02769cf948c1a2fecffde392a0d69856417c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / djot_fmt-0.2.3-py3-none-win_amd64.whl

Download URL djot_fmt-0.2.3-py3-none-win_amd64.whl
Size 961.3 kB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
3e2d94e53e0fb92807bd08f0c3e1dd6723e07bc6317d5124506fb005f39296eb
BLAKE2b-256 checksum
How to use checksums
ea03cc16d45242c38dff8d0d9d99863bb21aeefae33119d0a82ba907dadb1811
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / djot_fmt-0.2.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl

Download URL djot_fmt-0.2.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Size 893.6 kB
Tags Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 Python 3
SHA-256 checksum
How to use checksums
7bfb1d2915564bf4d6492477c955e4ded2efc0fd7ffdae10cd0b3cacdf7204c4
BLAKE2b-256 checksum
How to use checksums
7f191aaba9cf78cd15edb892167733c955396db0c712e3e40a0dbc85729d5991
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / djot_fmt-0.2.3-py3-none-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl

Download URL djot_fmt-0.2.3-py3-none-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Size 969.0 kB
Tags Linux glibc 2.28+ x86-64 Linux glibc 2.5+ x86-64 Python 3
SHA-256 checksum
How to use checksums
6f63b5d9703e394cd51d883f750f81dad05dd8325e57efdfce40e9c11aa47192
BLAKE2b-256 checksum
How to use checksums
e9d4b44a5499da64783d2b94a2909bcc0c3644e60a6343db2b7a69686471b8ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / djot_fmt-0.2.3-py3-none-macosx_15_0_x86_64.whl

Download URL djot_fmt-0.2.3-py3-none-macosx_15_0_x86_64.whl
Size 961.3 kB
Tags Python 3 macOS 15.0+ x86-64
SHA-256 checksum
How to use checksums
0a2aa556b41b8de4a3f3c6eb4d8a33680e6ecc18b81369683ab5ee1d3d6823c7
BLAKE2b-256 checksum
How to use checksums
1f4bbd3e3f0e1a6ce2bda47886d03a4982f047a48b0edeae85456163b5513f45
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / djot_fmt-0.2.3-py3-none-macosx_15_0_arm64.whl

Download URL djot_fmt-0.2.3-py3-none-macosx_15_0_arm64.whl
Size 902.9 kB
Tags Python 3 macOS 15.0+ ARM64
SHA-256 checksum
How to use checksums
0e4b143e99c14462a38b3faf2e03462b3dfcd89821bc09e0d65675ed2ea9603a
BLAKE2b-256 checksum
How to use checksums
23cef6d02e8dc80dbcf1e244dd9dddef82193fd658bb16d3191d40ed2caf10bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.4

7 release files

This release

0.2.3 This release

7 release files

0.2.2

7 release files

0.2.1

7 release files

0.2.0

7 release files

0.1.2

7 release files

0.1.1

7 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page