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.59.0.tar.gz (1.2 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.59.0-py3-none-win_arm64.whl (6.7 MB view details)

Uploaded Python 3Windows ARM64

panache_cli-2.59.0-py3-none-win_amd64.whl (7.1 MB view details)

Uploaded Python 3Windows x86-64

panache_cli-2.59.0-py3-none-musllinux_1_2_x86_64.whl (7.5 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

panache_cli-2.59.0-py3-none-musllinux_1_2_aarch64.whl (6.8 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

panache_cli-2.59.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.5 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

panache_cli-2.59.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (6.9 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

panache_cli-2.59.0-py3-none-macosx_11_0_arm64.whl (6.7 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

panache_cli-2.59.0-py3-none-macosx_10_12_x86_64.whl (7.1 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

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

File metadata

  • Download URL: panache_cli-2.59.0.tar.gz
  • Upload date:
  • Size: 1.2 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.59.0.tar.gz
Algorithm Hash digest
SHA256 9c258e62ddda3bd0fa5debd4dee08e8be33e411185aa325d88ffcb13bf225781
MD5 445710c9a78629f885239cea0eadd351
BLAKE2b-256 ba765697c2b614da2daae0d3420bc4387d19ead9c46c9072cd953ad630bc6a10

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: panache_cli-2.59.0-py3-none-win_arm64.whl
  • Upload date:
  • Size: 6.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.59.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 e79384dfe16b7572ceeb3db5f5f0c2aa0c89e81576a292a952464ef50e6e7791
MD5 de61ab40bfb3b42e3703745b09ba2515
BLAKE2b-256 1e906f7efaf1e850a58d23e4e6645437968bd9346bdc40b88098dc7564313f99

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: panache_cli-2.59.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 7.1 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.59.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 f5a0b0541f9fd5d0f570c49880cf5ebfda32a305090022fb735fc6998cc19187
MD5 0fcfe6823880144cf1b5f583cc57e954
BLAKE2b-256 d8a6782ba7ac61556fb980f2c7d75155202db9fba6b050d0a6dae9496a0d143e

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for panache_cli-2.59.0-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 e22a4a7cbd38f93ea625cd4b9949ee0797688b4f3918818e44fb888a69429ca9
MD5 c4956b02688f25aa585ec00e1cc9d1e5
BLAKE2b-256 4b08d035bd06d71c5c39524d884c06ad931575ab72177ca4df257a628300751a

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for panache_cli-2.59.0-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 883174552e73341b3afc724f1cd75df7c8db0fb6b6e700c93000caf32eb1d5f7
MD5 4de88f00e04dde9b96ebc09f7dd83ac6
BLAKE2b-256 47809ccbd6ce8fff55721f24ff4e183ac86da9e2a478b60921f600a93d6a340a

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for panache_cli-2.59.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9996a16ef6e523b34e0158b85ae219646ed6dffb4d7b3a8b8d002a9882394b59
MD5 b04d0f95b20773395e76cc027a807341
BLAKE2b-256 dc5a5ea776f9b18ea277beba4f1fea458f758660893be832c66b8d080d27a25f

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for panache_cli-2.59.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 1680a002c22471e4342c2335bdd8318911a6504916420a0f6ee9b4ce6b39b409
MD5 b7fcfb5c3b6d227fb5a0b07e1657a578
BLAKE2b-256 e3a395ec23c3a44b4d5c1ec47df55b97b94b36f41408caefe997d2ef3f5fbc09

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for panache_cli-2.59.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 5744d14cf7773a01ef205f1612f615cde9225740bf980ce31164f31f73b95231
MD5 652df445a530dcc1153de41c6dc22f8b
BLAKE2b-256 2803a962f3dc3622d30047e17eb6917958bbbf77a3b8d2d8b6f1a8cd529b4618

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for panache_cli-2.59.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 6e5aa502dd6f5472ea92022359e65e1a1dfc3af72b417b8dfdcd534cbcd3d295
MD5 b2c32e8218eb9268882f28ed58d6407e
BLAKE2b-256 8be1c01ca7c0ec9af7cf60ef8ca6a72595220f761ce051026338524d9e6e0b74

See more details on using hashes here.

Provenance

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