Skip to main content

img

Table of Contents

About

A fast, format-aware semantic line break formatter. Reformats prose so each sentence occupies its own line, producing minimal and meaningful git diffs when collaborating on documents.

Why?

When multiple authors collaborate on a paper using Git, traditional line wrapping at a fixed column width causes problems. A single word change can trigger a diff that spans an entire paragraph. By breaking at sentence boundaries instead, each edit affects only the sentence that changed.

This convention, often called semantic line breaks, enjoys longstanding support from technical writers. Existing tools fall short: latexindent.pl only handles LaTeX, SemBr requires Python and neural networks, and most lack multi-format awareness. snapper solves this as a standalone Rust binary with no runtime dependencies, handling Org-mode, LaTeX, Markdown, and plaintext.

Design

snapper runs a three-stage pipeline:

  • Parse: Classify input into prose regions and structure regions
  • Split: Detect sentence boundaries in prose regions
  • Emit: Output each sentence on its own line

Math environments, tables, front matter, drawers, and non-source comments pass through unchanged. Fenced and delimited source blocks are Region::Code: fence/open/close lines stay structure, non-comment code stays verbatim, and comment lines reflow at sentence boundaries when the language has a [code.<lang>] entry in .snapperrc.toml (snapper init seeds common languages). Pass --format-code to also pipe each block body through an optional per-language formatter argv (missing binary, non-zero exit, and timeouts degrade to the reflowed body). Sentence detection relies on Unicode UAX #29 segmentation with abbreviation-aware post-processing that avoids false breaks at titles (Dr., Prof.), references (Fig., Eq.), and Latin terms (e.g., i.e., et al.). Org emphasis (*bold*, /italic/, _underline_, +strike+) is kept atomic so splits cannot open a pseudo-headline mid-span.

Installation

Pre-built binary (fastest):

cargo binstall snapper-fmt

Shell one-liner (Linux/macOS):

curl -LsSf https://github.com/TurtleTech-ehf/snapper/releases/latest/download/snapper-fmt-installer.sh | sh

Homebrew:

brew install TurtleTech-ehf/tap/snapper-fmt

pip:

pip install snapper-fmt

Compile from source:

cargo install snapper-fmt

Nix:

nix build github:TurtleTech-ehf/snapper

The crate is snapper-fmt on all registries. Each install ships two CLI names for the same program: snapper and snapper-fmt.

Name collision: openSUSE snapper is a different project (Btrfs/LVM snapshots) that also installs a snapper binary. On systems where that tool already owns /usr/bin/snapper, call this formatter as snapper-fmt, or put the TurtleTech install path ahead of the system path.

Usage

Format a file (output to stdout):

snapper paper.org

Format in place:

snapper --in-place paper.org

Pipe through stdin (for editor integration):

cat draft.org | snapper --format org

Check formatting without modifying (for CI):

snapper --check paper.org paper.tex notes.md

Limit line width (wrap long sentences at word boundaries):

snapper --max-width 80 paper.org

Preview changes as a unified diff before committing:

snapper --diff paper.org

Compare two versions at the sentence level (whitespace reflow produces zero diff):

snapper sdiff paper_v1.org paper_v2.org

Watch files and auto-reformat on save:

snapper watch '*.org' 'sections/*.tex'

Initialize a project (generates config, pre-commit, gitattributes):

snapper init

MCP server (AI assistants)

The MCP server is an optional source-build feature; published release binaries do not include it. Install snapper with MCP support, then start the stdio server:

cargo install snapper-fmt --features mcp
snapper mcp

Tools: format_text, detect_format, check_formatting, split_sentences. Configuration guide (org source in-tree): docs/orgmode/howto/mcp-integration.org; HTML docs: https://snapper.turtletech.us/docs/howto/mcp-integration/ .

Supported formats

Format Extensions Structure / code handling
Org-mode .org Drawers, tables, keywords; #+BEGIN_SRC comment reflow
LaTeX .tex, .latex Preamble, math; minted and lstlisting comment reflow
Markdown .md, .markdown Front matter, HTML; fenced blocks comment reflow when configured
RST .rst Directives, literals; .. code-block:: comment reflow
Plaintext everything else (none; all text treated as prose)

Pre-commit hook

- repo: https://github.com/TurtleTech-ehf/snapper
  rev: v0.9.0
  hooks:
    - id: snapper

Emacs (Apheleia)

(with-eval-after-load 'apheleia
  (push '(snapper . ("snapper" "--format" "org")) apheleia-formatters)
  (push '(org-mode . snapper) apheleia-mode-alist))

VS Code

Install TurtleTech.snapper from the VS Code Marketplace. The extension uses the built-in LSP server for format-on-save, range formatting, diagnostics, and code actions.

Neovim

With lazy.nvim (rocks support):

{
  "TurtleTech-ehf/snapper",
  ft = { "org", "tex", "markdown", "rst" },
  config = function()
    vim.opt.runtimepath:append(
      vim.fn.stdpath("data") .. "/lazy/snapper/editors/nvim"
    )
    require("snapper").setup()
  end,
}

Or with rocks.nvim:

:Rocks install snapper.nvim

Vim

Plug 'TurtleTech-ehf/snapper', { 'rtp': 'editors/vim' }

This provides formatprg support for automatic formatting with the gq operator.

Obsidian

Development preview; not listed in Community Plugins. The WebAssembly plugin source lives in editors/obsidian and is available for development builds only.

Microsoft Word

Development preview; not published in AppSource. The WebAssembly add-in source and sideloading instructions live in editors/word.

Git smudge/clean filter

Auto-format on commit, transparent to collaborators:

git config filter.snapper.clean "snapper --format org"
git config filter.snapper.smudge cat

Then add to .gitattributes:

*.org filter=snapper

Vale integration

snapper ships a vale style package for editor hints. Add to your .vale.ini:

StylesPath = /path/to/snapper/vale
[*.org]
BasedOnStyles = snapper

For precise CI checks, use snapper --check directly.

Project config

Drop a .snapperrc.toml in your project root:

extra_abbreviations = ["GROMACS", "LAMMPS", "DFT"]
ignore = ["*.bib", "*.cls"]
format = "org"
max_width = 0

snapper walks up from the current directory to find it.

Documentation

Build the docs site with:

pixi run docbld

Development

Key dependencies

  • Clap 4 (derive): CLI argument parsing
  • unicode-segmentation: UAX #29 sentence boundaries
  • regex: Abbreviation and format pattern matching
  • textwrap: Optional line width limiting
  • thiserror: Typed error handling

Conventions

We use cocogitto via cog to handle commit conventions.

Readme

Construct the readme via:

./scripts/org_to_md.sh readme_src.org README.md

License

MIT.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

snapper_fmt-0.9.0.tar.gz (1.9 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

snapper_fmt-0.9.0-py3-none-win_amd64.whl (14.4 MB view details)

Uploaded Python 3Windows x86-64

snapper_fmt-0.9.0-py3-none-manylinux_2_28_aarch64.whl (12.4 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARM64

snapper_fmt-0.9.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (13.7 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

snapper_fmt-0.9.0-py3-none-macosx_11_0_arm64.whl (12.2 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

snapper_fmt-0.9.0-py3-none-macosx_10_12_x86_64.whl (13.1 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file snapper_fmt-0.9.0.tar.gz.

File metadata

  • Download URL: snapper_fmt-0.9.0.tar.gz
  • Upload date:
  • Size: 1.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for snapper_fmt-0.9.0.tar.gz
Algorithm Hash digest
SHA256 84ee9aa6aa88d3251c723f111d2f879e495374442539a23b5426199fb42b7cf5
MD5 08510f6d6c09821759703ce6bfda2cb2
BLAKE2b-256 16149c5ca6a19832f76f385875ccbb24e8fbb7e83f648fe94eb62ec0e75ce37b

See more details on using hashes here.

Provenance

The following attestation bundles were made for snapper_fmt-0.9.0.tar.gz:

Publisher: pypi.yml on TurtleTech-ehf/snapper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file snapper_fmt-0.9.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: snapper_fmt-0.9.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 14.4 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for snapper_fmt-0.9.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 0c9c2c1653c7db220ad9ea1b6c4ccccf3ea135032382e80a792f95102a5f0389
MD5 bf81eb4c8d3b17d618c66b99d442aad3
BLAKE2b-256 fdb7f9909f8d91a0398ddf0ec064f733e12720127b268504adbb3247b70e8c8c

See more details on using hashes here.

Provenance

The following attestation bundles were made for snapper_fmt-0.9.0-py3-none-win_amd64.whl:

Publisher: pypi.yml on TurtleTech-ehf/snapper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file snapper_fmt-0.9.0-py3-none-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for snapper_fmt-0.9.0-py3-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 4cee062a16cd1aa5929f77ac82cc0c5e2463c6d2c39362faa2aa2da973df8c46
MD5 e37e15a06f7be5498d9215b6b53a9d90
BLAKE2b-256 db062c621c5b3080421fbca7d70d40b24e3cd14d460e5986874e309d838ac121

See more details on using hashes here.

Provenance

The following attestation bundles were made for snapper_fmt-0.9.0-py3-none-manylinux_2_28_aarch64.whl:

Publisher: pypi.yml on TurtleTech-ehf/snapper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file snapper_fmt-0.9.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for snapper_fmt-0.9.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e08d85243cda384b69251800db350109a4577979d7ca88cd0b4a2112aa8a9b79
MD5 e3ea239e30ece34bcb480823ec43c62d
BLAKE2b-256 65121005a2a5df1a2deb7f065619b0bc9cd5ba3e9e0b7942ecca4d8aac295f27

See more details on using hashes here.

Provenance

The following attestation bundles were made for snapper_fmt-0.9.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: pypi.yml on TurtleTech-ehf/snapper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file snapper_fmt-0.9.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for snapper_fmt-0.9.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3a5e93d8e16597dd7e2caf2e1e72872accb2d4c6fce930c957f7c745256ccb59
MD5 be47266a5b0b00f963de2d1684e1c7b4
BLAKE2b-256 1d000eef251356c117e5bcf2665a6c1ba41ef55a257334efeb37f0d03adaf29c

See more details on using hashes here.

Provenance

The following attestation bundles were made for snapper_fmt-0.9.0-py3-none-macosx_11_0_arm64.whl:

Publisher: pypi.yml on TurtleTech-ehf/snapper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file snapper_fmt-0.9.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for snapper_fmt-0.9.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 0fd18fdfd888c076120146435cdac5e16c142cfc7c51bfb1cf36a86c2592d38d
MD5 475a2a99ea5b7a86dc8a25eebcb142f8
BLAKE2b-256 50d5527a651b9ca98aeb3be9128b9c2cb8b84c6804ab2e44c7da75081161045f

See more details on using hashes here.

Provenance

The following attestation bundles were made for snapper_fmt-0.9.0-py3-none-macosx_10_12_x86_64.whl:

Publisher: pypi.yml on TurtleTech-ehf/snapper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page