Panache 
A language server, formatter, and linter for Markdown, Quarto, and R Markdown, built in Rust with a lossless CST parser and support for external formatters and linters on code blocks.
Installation
Panache is available from several sources:
- crates.io:
cargo install panache - Homebrew:
brew install panache - npm:
npm install -g @panache-cli/panache(ornpx @panache-cli/panache) - PyPI:
uv tool install panache-cli/pipx install panache-cli - Aqua:
aqua install jolars/panache - NixOS: the
panachepackage on Nixpkgs - Arch Linux: from the AUR:
panache-bin(prebuilt),panache(built from source) - Prebuilt binaries: tarballs,
.deb, and.rpmfrom the releases page - VS Code/Open VSX: the Panache extension, from the VS Code Marketplace or Open VSX (also works in Positron), which installs the CLI and starts the language server automatically
Install Script
The installer scripts pick the right release artifact for your platform and install to a user-local directory by default. They are fetched from the latest release and then download the matching Panache CLI release asset. If you prefer, download and inspect the script before running it.
For macOS and Linux:
curl --proto '=https' --tlsv1.2 -LsSf \
https://github.com/jolars/panache/releases/latest/download/panache-installer.sh | sh
For Windows PowerShell:
powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://github.com/jolars/panache/releases/latest/download/panache-installer.ps1 | iex"
Set PANACHE_INSTALL_DIR to change the destination and PANACHE_TAG to pin a
version.
See getting started for per-platform detail and the development version.
Usage
Panache provides a single CLI interface for formatting, linting, and running the LSP server.
Formatting
To format a file in place, simply run:
panache format document.qmd
You can also format from stdin by piping content into panache format:
cat <file> | panache format
panache format supports glob patterns and recursive directory formatting:
panache format **/*.{qmd,md}
You can use Panache as a linter via the --check flag to check if files are
already formatted without making changes:
panache format --check document.qmd
External Code Formatters
Panache supports external formatters for code blocks. For example, you can
configure it to run air on R code blocks and ruff on Python code blocks:
[formatters]
r = "air"
python = "ruff"
javascript = "prettier"
typescript = "prettier" # Reuse same formatter
You can setup custom formatters or modify built-in presets with additional arguments:
[formatters]
python = ["isort", "black"]
javascript = "foobar"
[formatters.isort]
args = ["--profile=black"]
[formatters.myformatters]
cmd = "foobar"
args = ["--print-width=100"]
stdin = true
Linting
Panache also features a linter that can report formatting issues and optionally auto-fix them. To run the linter, use:
panache lint document.qmd
As with panache format, you can use glob patterns and recursive formatting:
panache lint **/*.{qmd,md}
External Linters
As with formatting, Panache supports external linters for code blocks. These are
configured in the [linters] section of the configuration, but due to the
complexity of linting, including dealing with auto-fixing, external linters
cannot be customized and only support presets and at the moment only support R
via the jarl linter:
# Enable R linting
[linters]
r = "jarl" # R linter with JSON output
Language Server
Panache implements the language server protocol (LSP) to provide editor features like formatting, diagnostics, code actions, and more. See the language server documentation for guides on how to connect Panache to your editor and configure LSP features.
The list of LSP features supported by Panache includes, among others:
- Document formatting (full document, incremental and range)
- Diagnostics with quick fixes
- Code actions for refactoring
- Convert between loose/compact lists
- Convert between inline/reference footnotes
- Document symbols/outline
- Folding ranges
- Go to definition for references and footnotes
- Quaro and Bookdown project awareness
Configuration
Panache looks for a configuration in:
.panache.tomlorpanache.tomlin current directory or parent directories$XDG_CONFIG_HOME/panache/config.toml(usually~/.config/panache/config.toml)
Example
# Markdown flavor and line width
flavor = "quarto"
line-width = 80
line-ending = "auto"
# Formatting style
[format]
wrap = "reflow"
# External code formatters (opt-in)
[formatters]
python = ["isort", "black"] # Sequential formatting
r = "air" # Built-in preset
javascript = "prettier" # Reusable definitions
typescript = "prettier"
yaml = "yamlfmt" # Formats both code blocks AND frontmatter
# Customize formatters
[formatters.prettier]
prepend-args = ["--print-width=100"]
# External code linters
[linters]
r = "jarl" # Enable R linting
python = "ruff"
See examples/panache.toml for a complete configuration reference.
Integrations
GitHub Actions
For CI, use the dedicated GitHub Action:
- uses: jolars/panache-action@v1
See the Integrations documentation for configuration options.
Pre-commit Hooks
Panache integrates with pre-commit to automatically format and lint your files before committing.
Installation:
First, install pre-commit if you haven't already:
pip install pre-commit
# or
brew install pre-commit
Then add Panache to your .pre-commit-config.yaml:
repos:
- repo: https://github.com/jolars/panache-pre-commit
rev: v2.43.1 # Use the latest version
hooks:
- id: panache-format # Format files
- id: panache-lint # Lint and auto-fix issues
Note: The hooks live in
jolars/panache-pre-commit, a thin shim repo. This avoidspre-commit autoupdateresolving to unrelated sub-package tags from this monorepo (e.g.panache-code-*). If you currently point athttps://github.com/jolars/panache, update therepo:URL and runpre-commit autoupdate.
Install the hooks:
pre-commit install
Panache will now automatically run on your staged .qmd, .md, and .Rmd
files before each commit.
See examples/pre-commit-config.yaml for more configuration options.
Motivation
I wanted a formatter that understands Quarto and Pandoc syntax. I have tried to use Prettier as well as mdformat, but both fail to handle some of the particular syntax used in Quarto documents, such as fenced divs and some of the table syntax.
For a side-by-side overview of how Panache compares to Prettier, Pandoc, rumdl, mdformat, mado, markdownlint, markdownlint-cli2, and marksman, see the comparison page. For benchmarks against the same set of tools, see the performance page.
Design Goals and Scope
- Full LSP implementation with formatting, diagnostics, code actions, and more
- Standalone CLI for both formatting and linting
- Support for Quarto, Pandoc, and R Markdown syntax
- Lossless CST-based parsing
- Idempotent formatting
- Semi-opinionated defaults with configurable style options for common formatting decisions
- Support for running external formatters and linters on code blocks, with built-in presets for popular languages and tools
Acknowledgements
The development of Panache has simplified considerably thanks to the extensive documentation, well-structured code, and testing infrastructure provided by Pandoc. We also owe significant debt to the rust-analyzer project, on which Panche is heavily inspired.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
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 panache_cli-3.2.0.tar.gz.
File metadata
- Download URL: panache_cli-3.2.0.tar.gz
- Upload date:
- Size: 1.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f7da6fe945d4cb03ee103e8fe0271122c6867d5bf5c41f01dbc7195ec85e60e
|
|
| MD5 |
ef996891eaa365f5bd77c88013eef397
|
|
| BLAKE2b-256 |
2018d8807dc90ed3e94cd184bd4808257427c6c60b56e9e4a93aad0ba242cfd7
|
Provenance
The following attestation bundles were made for panache_cli-3.2.0.tar.gz:
Publisher:
publish-pypi.yml on jolars/panache
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
panache_cli-3.2.0.tar.gz -
Subject digest:
5f7da6fe945d4cb03ee103e8fe0271122c6867d5bf5c41f01dbc7195ec85e60e - Sigstore transparency entry: 2345830829
- Sigstore integration time:
-
Permalink:
jolars/panache@855506a430331fdce918291f7475e2e3941f39b2 -
Branch / Tag:
refs/tags/v3.2.0 - Owner: https://github.com/jolars
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@855506a430331fdce918291f7475e2e3941f39b2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file panache_cli-3.2.0-py3-none-win_arm64.whl.
File metadata
- Download URL: panache_cli-3.2.0-py3-none-win_arm64.whl
- Upload date:
- Size: 7.1 MB
- Tags: Python 3, Windows ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ed8ec9d4f8e4504b35184b39e8ca40313805c85dbed7a19d5dc5ad85ab4e409
|
|
| MD5 |
4ba0e2ef980614805c1a9bc57e99b066
|
|
| BLAKE2b-256 |
d534a93de1d54039713c3bbdd190cfca1d3856a9d2760d40efdce86664728243
|
Provenance
The following attestation bundles were made for panache_cli-3.2.0-py3-none-win_arm64.whl:
Publisher:
publish-pypi.yml on jolars/panache
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
panache_cli-3.2.0-py3-none-win_arm64.whl -
Subject digest:
7ed8ec9d4f8e4504b35184b39e8ca40313805c85dbed7a19d5dc5ad85ab4e409 - Sigstore transparency entry: 2345831296
- Sigstore integration time:
-
Permalink:
jolars/panache@855506a430331fdce918291f7475e2e3941f39b2 -
Branch / Tag:
refs/tags/v3.2.0 - Owner: https://github.com/jolars
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@855506a430331fdce918291f7475e2e3941f39b2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file panache_cli-3.2.0-py3-none-win_amd64.whl.
File metadata
- Download URL: panache_cli-3.2.0-py3-none-win_amd64.whl
- Upload date:
- Size: 7.5 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1085ab14046e43d84001fbb3c6368dd18bd894e052ca3944d060399138d2daa
|
|
| MD5 |
971aacfc9b0712f3bed9776d641e7295
|
|
| BLAKE2b-256 |
e1b89c6bdb373bf5825863e9eea4f0d1c0260e74b5cf9cdb76a83f0db7c55507
|
Provenance
The following attestation bundles were made for panache_cli-3.2.0-py3-none-win_amd64.whl:
Publisher:
publish-pypi.yml on jolars/panache
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
panache_cli-3.2.0-py3-none-win_amd64.whl -
Subject digest:
e1085ab14046e43d84001fbb3c6368dd18bd894e052ca3944d060399138d2daa - Sigstore transparency entry: 2345831042
- Sigstore integration time:
-
Permalink:
jolars/panache@855506a430331fdce918291f7475e2e3941f39b2 -
Branch / Tag:
refs/tags/v3.2.0 - Owner: https://github.com/jolars
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@855506a430331fdce918291f7475e2e3941f39b2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file panache_cli-3.2.0-py3-none-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: panache_cli-3.2.0-py3-none-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 7.9 MB
- Tags: Python 3, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c150835bafbd10f019f1442137053c79d0776e53406953a3b940e3ea9b3df74
|
|
| MD5 |
727bd6c2b12efea8444f81f014fb672a
|
|
| BLAKE2b-256 |
aa4b525d5db648364d6b411e2b44c18ef168dcd9236b3a8dc24010b9ce1e7066
|
Provenance
The following attestation bundles were made for panache_cli-3.2.0-py3-none-musllinux_1_2_x86_64.whl:
Publisher:
publish-pypi.yml on jolars/panache
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
panache_cli-3.2.0-py3-none-musllinux_1_2_x86_64.whl -
Subject digest:
9c150835bafbd10f019f1442137053c79d0776e53406953a3b940e3ea9b3df74 - Sigstore transparency entry: 2345831567
- Sigstore integration time:
-
Permalink:
jolars/panache@855506a430331fdce918291f7475e2e3941f39b2 -
Branch / Tag:
refs/tags/v3.2.0 - Owner: https://github.com/jolars
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@855506a430331fdce918291f7475e2e3941f39b2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file panache_cli-3.2.0-py3-none-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: panache_cli-3.2.0-py3-none-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 7.2 MB
- Tags: Python 3, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9b38676aad68bfd749bb1ae433760dc45707809149c76a431832ffebaa89545
|
|
| MD5 |
493a8d3165de5b3b062cb11cc0699438
|
|
| BLAKE2b-256 |
e5a349e26069f6a49119e1432114de87f0edd07dbe97d9daad4750d133ac4c2d
|
Provenance
The following attestation bundles were made for panache_cli-3.2.0-py3-none-musllinux_1_2_aarch64.whl:
Publisher:
publish-pypi.yml on jolars/panache
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
panache_cli-3.2.0-py3-none-musllinux_1_2_aarch64.whl -
Subject digest:
b9b38676aad68bfd749bb1ae433760dc45707809149c76a431832ffebaa89545 - Sigstore transparency entry: 2345832026
- Sigstore integration time:
-
Permalink:
jolars/panache@855506a430331fdce918291f7475e2e3941f39b2 -
Branch / Tag:
refs/tags/v3.2.0 - Owner: https://github.com/jolars
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@855506a430331fdce918291f7475e2e3941f39b2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file panache_cli-3.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: panache_cli-3.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 7.9 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
949e9ff8bfb433eeaabb063c5ae4a0b529c2d0e9f77d2d79ca07c20bdb8b77c5
|
|
| MD5 |
fdfd989349a41356bb8ce17f1668f4fb
|
|
| BLAKE2b-256 |
5b662520ace0550ec4981ca7dcd1969c11e42540130381b691b7b40ae17844a7
|
Provenance
The following attestation bundles were made for panache_cli-3.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
publish-pypi.yml on jolars/panache
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
panache_cli-3.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
949e9ff8bfb433eeaabb063c5ae4a0b529c2d0e9f77d2d79ca07c20bdb8b77c5 - Sigstore transparency entry: 2345833737
- Sigstore integration time:
-
Permalink:
jolars/panache@855506a430331fdce918291f7475e2e3941f39b2 -
Branch / Tag:
refs/tags/v3.2.0 - Owner: https://github.com/jolars
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@855506a430331fdce918291f7475e2e3941f39b2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file panache_cli-3.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: panache_cli-3.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 7.3 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c64ce2b578a848c84c30b82ad826328a6e9c2af7a603aa76b97c79f6c8d6fb9
|
|
| MD5 |
bd1a3024da9e3912a0ad434448471e1e
|
|
| BLAKE2b-256 |
cd1541692ae6ea37726b68d54958d6db6c2a650a4961abe58225e65dd2f89843
|
Provenance
The following attestation bundles were made for panache_cli-3.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
publish-pypi.yml on jolars/panache
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
panache_cli-3.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
3c64ce2b578a848c84c30b82ad826328a6e9c2af7a603aa76b97c79f6c8d6fb9 - Sigstore transparency entry: 2345833125
- Sigstore integration time:
-
Permalink:
jolars/panache@855506a430331fdce918291f7475e2e3941f39b2 -
Branch / Tag:
refs/tags/v3.2.0 - Owner: https://github.com/jolars
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@855506a430331fdce918291f7475e2e3941f39b2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file panache_cli-3.2.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: panache_cli-3.2.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 7.1 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
115edaa98c9f6bc0317d12c7409fa89c249bd76b5b8ad8b480015919402cf99b
|
|
| MD5 |
4c7f4385b61532a594c989620d284db5
|
|
| BLAKE2b-256 |
75013922c87ce62efdc38e3da257c4f2120d5d7bb3f7bf16f584e7540d472c41
|
Provenance
The following attestation bundles were made for panache_cli-3.2.0-py3-none-macosx_11_0_arm64.whl:
Publisher:
publish-pypi.yml on jolars/panache
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
panache_cli-3.2.0-py3-none-macosx_11_0_arm64.whl -
Subject digest:
115edaa98c9f6bc0317d12c7409fa89c249bd76b5b8ad8b480015919402cf99b - Sigstore transparency entry: 2345832730
- Sigstore integration time:
-
Permalink:
jolars/panache@855506a430331fdce918291f7475e2e3941f39b2 -
Branch / Tag:
refs/tags/v3.2.0 - Owner: https://github.com/jolars
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@855506a430331fdce918291f7475e2e3941f39b2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file panache_cli-3.2.0-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: panache_cli-3.2.0-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 7.5 MB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
766fb0f302ffad98fb534bed22c0e9f1217e371661ab84e5fae462263bd4ea2c
|
|
| MD5 |
a4ec0fd318aa36506937c8f25085cdcd
|
|
| BLAKE2b-256 |
7906e050a867bd75346e020fa550193708212e1c4241d31be04bb2d2f808494b
|
Provenance
The following attestation bundles were made for panache_cli-3.2.0-py3-none-macosx_10_12_x86_64.whl:
Publisher:
publish-pypi.yml on jolars/panache
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
panache_cli-3.2.0-py3-none-macosx_10_12_x86_64.whl -
Subject digest:
766fb0f302ffad98fb534bed22c0e9f1217e371661ab84e5fae462263bd4ea2c - Sigstore transparency entry: 2345832405
- Sigstore integration time:
-
Permalink:
jolars/panache@855506a430331fdce918291f7475e2e3941f39b2 -
Branch / Tag:
refs/tags/v3.2.0 - Owner: https://github.com/jolars
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@855506a430331fdce918291f7475e2e3941f39b2 -
Trigger Event:
push
-
Statement type: