Skip to main content

A language server, formatter, and linter for Markdown, Quarto, and R Markdown

Project description

Panache

Build and Test Crates.io Open VSX VS Code PyPI version npm version codecov

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

From crates.io

If you have Rust installed, the easiest way is likely to install from crates.io:

cargo install panache

Pre-built Binaries

Alternatively, you can install pre-built binary packages from the releases page for Linux, macOS, and Windows. For Linux, packages are available for generic distributions (tarballs) as well as Debian/Ubuntu (.deb) and Fedora/RHEL/openSUSE (.rpm).

If you prefer a one-liner installer that picks the right release artifact for your platform, you can use the installer scripts below. These scripts are fetched directly from this repository and then download the latest matching Panache CLI release asset for your platform, installing to a user-local directory by default. If you prefer, download and inspect the script before running it.

For macOS and Linux:

curl --proto '=https' --tlsv1.2 -LsSf \
    https://raw.githubusercontent.com/jolars/panache/refs/heads/main/scripts/panache-installer.sh | sh

For Windows PowerShell:

powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://raw.githubusercontent.com/jolars/panache/refs/heads/main/scripts/panache-installer.ps1 | iex"

Arch Linux

There are also two recipies available for Arch Linux in the AUR: panache and panache-bin. The first builds from source for your system, the second uses precompiled binaries attatched to GH releases. Install either using yay or your favorite AUR helper:

yay -S panache
yay -S panache-bin

NixOS

Panache is available in NixOS via the panache package in nixpkgs. To add it to your system configuration, include it in the environment.systemPackages:

{ pkgs, ... }:

{
  environment.systemPackages = [
    pkgs.panache
  ];
}

From PyPI (via uv or pipx)

Install with uv or pipx:

# One-shot run, no install:
uvx --from panache-cli panache format path/to/file.qmd

# Persistent install:
uv tool install panache-cli
# or
pipx install panache-cli

From NPM (via npmx)

Install with npx or npmx:

# One-shot run, no install:
npx @panache-cli/panache format path/to/file.qmd

# Persistent install:
npm install -g @panache-cli/panache

VS Code Extension

If you are running VS Code or an editor that supports VS Code extensions (like Positron), you can install the Panache extension from the VS Code Marketplace or the Open VSX extension, which will automatically also install the panache CLI and start the language server when editing supported files.

Development Version

To install the latest development version, you can run

cargo install --git https://github.com/jolars/panache.git panache

This presumes you have a working and up-to-date Rust toolchain (stable, 2024 edition) installed. You also need to have cargo in your PATH if you want to use the panache command directly after installation.

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:

  1. .panache.toml or panache.toml in current directory or parent directories
  2. $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 avoids pre-commit autoupdate resolving to unrelated sub-package tags from this monorepo (e.g. panache-code-*). If you currently point at https://github.com/jolars/panache, update the repo: URL and run pre-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.

Project details


Download files

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

Source Distribution

panache_cli-2.48.0.tar.gz (2.4 MB view details)

Uploaded Source

Built Distributions

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

panache_cli-2.48.0-py3-none-win_arm64.whl (4.7 MB view details)

Uploaded Python 3Windows ARM64

panache_cli-2.48.0-py3-none-win_amd64.whl (4.9 MB view details)

Uploaded Python 3Windows x86-64

panache_cli-2.48.0-py3-none-musllinux_1_2_x86_64.whl (5.1 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

panache_cli-2.48.0-py3-none-musllinux_1_2_aarch64.whl (4.7 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

panache_cli-2.48.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.0 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

panache_cli-2.48.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.7 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

panache_cli-2.48.0-py3-none-macosx_11_0_arm64.whl (4.6 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

panache_cli-2.48.0-py3-none-macosx_10_12_x86_64.whl (4.9 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file panache_cli-2.48.0.tar.gz.

File metadata

  • Download URL: panache_cli-2.48.0.tar.gz
  • Upload date:
  • Size: 2.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for panache_cli-2.48.0.tar.gz
Algorithm Hash digest
SHA256 e9c4be66c0b66ffbd191f7202e439e407df150fdd7f47827560cf6f488d371f6
MD5 a85f6e3e87e06e937a119e87b505d554
BLAKE2b-256 9f7d2a9fe6b2926134b7fd0cb8d597985281cea05a66883a9c2608c03c760b82

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.48.0.tar.gz:

Publisher: publish-pypi.yml on jolars/panache

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

File details

Details for the file panache_cli-2.48.0-py3-none-win_arm64.whl.

File metadata

  • Download URL: panache_cli-2.48.0-py3-none-win_arm64.whl
  • Upload date:
  • Size: 4.7 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for panache_cli-2.48.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 a8166ea81fcca38d4fdb7564c1dad0807ba3e650b4f1039932071c170d803e2e
MD5 892ba1d6fc948232d3b1a9d104d9b86f
BLAKE2b-256 8797d48515001d5c3c2ef15e6e6238fa8a94458be3d0a4757cf18b6ec4f6dc7c

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.48.0-py3-none-win_arm64.whl:

Publisher: publish-pypi.yml on jolars/panache

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

File details

Details for the file panache_cli-2.48.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: panache_cli-2.48.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 4.9 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for panache_cli-2.48.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 cf616c2ca9ca52348907cc90739727452e3c9ac589fd157e53aec07ac7ac7ea3
MD5 2e6b87279478afd681872c36e0845831
BLAKE2b-256 99628ed91986df625c25c4cff49ece6c59073be602be1dc6045eb383b7b040a4

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.48.0-py3-none-win_amd64.whl:

Publisher: publish-pypi.yml on jolars/panache

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

File details

Details for the file panache_cli-2.48.0-py3-none-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for panache_cli-2.48.0-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 044908249ddb873d19d71828a86b9d3ff5e7efe907809d06373a1fb9a8df80b6
MD5 8a17e364b1bda1aac72a1575fe028e83
BLAKE2b-256 dc26b5fc66fad50db5fd1d44cfa7b35d7f92084ca647f10ba7f859de0b22e25c

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.48.0-py3-none-musllinux_1_2_x86_64.whl:

Publisher: publish-pypi.yml on jolars/panache

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

File details

Details for the file panache_cli-2.48.0-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for panache_cli-2.48.0-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 2c91a9645be292307b85e62fd7897b4f488a32ecc6efa7479a099b5c2b32d12f
MD5 f60fc58b182309b5c512d39c356602d3
BLAKE2b-256 84ee65887daa41b457b87dfb0342716932af067023eda941c8acef85aef83e2d

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.48.0-py3-none-musllinux_1_2_aarch64.whl:

Publisher: publish-pypi.yml on jolars/panache

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

File details

Details for the file panache_cli-2.48.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for panache_cli-2.48.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2951561a976e01206d3bf40e1391daa2152d9cb400c2e046ff9cfd2d970ec407
MD5 878ce4be701063fdacc8e8462465e53a
BLAKE2b-256 deafee4edd0d6c877fc85531705a35cdff6dff39a45067696619f4e748fd3bfe

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.48.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish-pypi.yml on jolars/panache

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

File details

Details for the file panache_cli-2.48.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for panache_cli-2.48.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d3a1c7a62c40966fae953c32fb74632b5910e193d9d4fe88732d01dc8a84c037
MD5 f4df3d9c49f3d79f8151aa25bb135c5e
BLAKE2b-256 43095e3a911b6f2220ac2fad0c31e70dd45c3c91904d45e52234080f52bb198f

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.48.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish-pypi.yml on jolars/panache

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

File details

Details for the file panache_cli-2.48.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for panache_cli-2.48.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 97b9969a16fde29e2f89d3d41a60f02c684d1383915faad936f758df55a704bd
MD5 2c83c6a59d88633df783cc0c4a8e1fa7
BLAKE2b-256 85c4d16a190b69ef5561b2c08d89243e29898ade02abc24857c70779160190a0

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.48.0-py3-none-macosx_11_0_arm64.whl:

Publisher: publish-pypi.yml on jolars/panache

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

File details

Details for the file panache_cli-2.48.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for panache_cli-2.48.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f91d51efefd7019ea418941f4cf41f74cdb4e20b517b137ac440e5107c6188fd
MD5 d6d250ac1f70f18f2245acdf88f2f306
BLAKE2b-256 d32f90f4d194a684cf1f2da283f962dc340e5f80d6d5c077dea341d3acda3bdb

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.48.0-py3-none-macosx_10_12_x86_64.whl:

Publisher: publish-pypi.yml on jolars/panache

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 Pingdom Monitoring Sentry Error logging StatusPage Status page