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

Homebrew

Panache is available from Homebrew on macOS and Linux:

brew install panache

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.50.0.tar.gz (2.5 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.50.0-py3-none-win_arm64.whl (4.7 MB view details)

Uploaded Python 3Windows ARM64

panache_cli-2.50.0-py3-none-win_amd64.whl (5.0 MB view details)

Uploaded Python 3Windows x86-64

panache_cli-2.50.0-py3-none-musllinux_1_2_x86_64.whl (5.2 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

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

Uploaded Python 3musllinux: musl 1.2+ ARM64

panache_cli-2.50.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (5.1 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

panache_cli-2.50.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.50.0-py3-none-macosx_11_0_arm64.whl (4.7 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

panache_cli-2.50.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.50.0.tar.gz.

File metadata

  • Download URL: panache_cli-2.50.0.tar.gz
  • Upload date:
  • Size: 2.5 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.50.0.tar.gz
Algorithm Hash digest
SHA256 03d6e75480aac6616c330be465a2069225d3dcded9c90ccb6d160ad8e090f98c
MD5 11c5c0e766fe0540541fcd9282ada19f
BLAKE2b-256 cd4109b2a3a3726259a581055b5bc719b5f9b91d6676f96b3f891902b52405c2

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.50.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.50.0-py3-none-win_arm64.whl.

File metadata

  • Download URL: panache_cli-2.50.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.50.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 e15b9d661df48b100a78abe8433c4e556ce746c988b2482b911a8f522bd1d488
MD5 d56c8452bc126c68049284037ad236e8
BLAKE2b-256 9abf40797033f91cdf33131d0d63e4607628c620118089872ffa9c90a6e622ab

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.50.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.50.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: panache_cli-2.50.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 5.0 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.50.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 c37d7d5ee0f7c8a769ffdd8862dd2069deb424a945874028e592812bf6f793b2
MD5 9b84e307a7218fed142679c21fd48bdc
BLAKE2b-256 f8724d496ce45ecc0d8a52a0c4b32e34b03ef5db942013f89c7aea0c9789d342

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.50.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.50.0-py3-none-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for panache_cli-2.50.0-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 63926300436038736033643c4e397e54f3004f2d243b1044ec1804d3ec368e11
MD5 685c8d3c3cd1e75d5fd05f423d2b6fb8
BLAKE2b-256 b6580ac710f4ecced57225a8ab313af6a292762e62dfd0df6c217ed3844609fd

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.50.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.50.0-py3-none-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for panache_cli-2.50.0-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 1b13facc56f3d9d079b48aebabefb8d22cc11ddcb771fd15abfbce7c26064a17
MD5 2b0aa364c2766d1759e8a7f56122d11b
BLAKE2b-256 c349669a2d4f4b6538f8575c909640519a810090342249e77004cdf2fc893066

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.50.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.50.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for panache_cli-2.50.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a5c24d4d6c01143529847c730bdd14c5d35749398352e5f049fae3f07e491be6
MD5 ba20180d1dcb859c9e791114ea6aa940
BLAKE2b-256 b1600e5ece4d0f41d0d37f309cfa59f5ba81227a063e7477146b3b2bcaf03fee

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.50.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.50.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for panache_cli-2.50.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0e6487bf0162a919910087b576a240a99d5c5b4ff8b0580d5fd2c57327160e37
MD5 b687ef299024898cde81b5cc3f234918
BLAKE2b-256 bc824429405930afc16a3a2c195d8f38d6a2e7448326a304534856b7cc3f8a91

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.50.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.50.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for panache_cli-2.50.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 35fe964f6c3b447132b2f9d4e74854de157eb9578b626f680e5226dd918b0780
MD5 f7acacf20dbd626464089ddab3809aaa
BLAKE2b-256 621689d549beb051f82a3a32371925d89cb074fa8e9493db059bbb330547e181

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.50.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.50.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for panache_cli-2.50.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 1547c6021041e0e548e52dfebb9b6ed668dd522644d876c8b2dcd225baefe442
MD5 df99653f4e2099329fca02db273ebce3
BLAKE2b-256 34536eb6550359c2a4003698a901e82c5fdb8fbd69c941061e150916d8eb46af

See more details on using hashes here.

Provenance

The following attestation bundles were made for panache_cli-2.50.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