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.4

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.4
File Size Uploaded
djot_fmt-0.2.4.tar.gz 31.2 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for djot-fmt 0.2.4
File
djot_fmt-0.2.4-py3-none-win_arm64.whl Python 3 none Windows ARM64 Details
djot_fmt-0.2.4-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
djot_fmt-0.2.4-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.4-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.4-py3-none-macosx_15_0_x86_64.whl Python 3 none macOS 15.0+ x86-64 Details
djot_fmt-0.2.4-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.4.tar.gz

Download URL djot_fmt-0.2.4.tar.gz
Size 31.2 kB
Tags Source
SHA-256 checksum
How to use checksums
f73282e20ad2e81fdc39f8d6e1e528bc94c0fb5397f2126510ab7f6aa1ece6b8
BLAKE2b-256 checksum
How to use checksums
79b70246073e0e41f703a4246400b19c9e81ccfe8cb174a0a8c1caae50323cb0
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.4-py3-none-win_arm64.whl

Download URL djot_fmt-0.2.4-py3-none-win_arm64.whl
Size 873.9 kB
Tags Python 3 Windows ARM64
SHA-256 checksum
How to use checksums
4a0d828894356ae003375618d387b7c04240115e35c31d9bd9857c3cde3b5feb
BLAKE2b-256 checksum
How to use checksums
45b28bf223faae3f3d4c13d301ac2703f57d91bf6019672b55f97c7fe0cbe32f
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.4-py3-none-win_amd64.whl

Download URL djot_fmt-0.2.4-py3-none-win_amd64.whl
Size 961.4 kB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
af910719661dc005908ec5182b9bab76bd501e20ce4bf5d863bb63b405cb750b
BLAKE2b-256 checksum
How to use checksums
482fc16112161001c3bef5638ff0a35b5c68a6f3c20fdd07706a87caa6131d70
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.4-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl

Download URL djot_fmt-0.2.4-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Size 893.7 kB
Tags Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 Python 3
SHA-256 checksum
How to use checksums
27978729e9ef84161b015abe98f8ab577f065fcc2831a5f94022dc926f04c64f
BLAKE2b-256 checksum
How to use checksums
1715fad56a5092af6a176fce4f7418a1343c2e199172d87a1b6766de05948990
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.4-py3-none-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl

Download URL djot_fmt-0.2.4-py3-none-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Size 969.1 kB
Tags Linux glibc 2.28+ x86-64 Linux glibc 2.5+ x86-64 Python 3
SHA-256 checksum
How to use checksums
4fa3b469f83845393165abbb83ba9d7fa863aea21fd0ac464ecac9be7fc659a5
BLAKE2b-256 checksum
How to use checksums
5d183d33c2997762c80db638e619a8f51c7890a6c0d2e37d3344de2c1d264e16
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.4-py3-none-macosx_15_0_x86_64.whl

Download URL djot_fmt-0.2.4-py3-none-macosx_15_0_x86_64.whl
Size 961.4 kB
Tags Python 3 macOS 15.0+ x86-64
SHA-256 checksum
How to use checksums
62701ef7d4f8c5360d6b5d7f98a14a05231d0c2d019a2f152bb52fd172bdde31
BLAKE2b-256 checksum
How to use checksums
facb8caf5f8ea6e72d7f5940b1f6646a3fdf5d8f228a56307a9e782eecb821d3
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.4-py3-none-macosx_15_0_arm64.whl

Download URL djot_fmt-0.2.4-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
1e617f589daae13de0df84a8bcb2f84f554c4f93354c91b354d11caa1527f612
BLAKE2b-256 checksum
How to use checksums
b2937f1149e432e576622634f72e6e367c0d3dfa75e5bcfb27f9e3785bc540e7
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

This release

0.2.4 This release

7 release files

0.2.3

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