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-3.0.1.tar.gz (1.3 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-3.0.1-py3-none-win_arm64.whl (6.8 MB view details)

Uploaded Python 3Windows ARM64

panache_cli-3.0.1-py3-none-win_amd64.whl (7.3 MB view details)

Uploaded Python 3Windows x86-64

panache_cli-3.0.1-py3-none-musllinux_1_2_x86_64.whl (7.7 MB view details)

Uploaded Python 3musllinux: musl 1.2+ x86-64

panache_cli-3.0.1-py3-none-musllinux_1_2_aarch64.whl (6.9 MB view details)

Uploaded Python 3musllinux: musl 1.2+ ARM64

panache_cli-3.0.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (7.7 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

panache_cli-3.0.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (7.0 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

panache_cli-3.0.1-py3-none-macosx_11_0_arm64.whl (6.9 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

panache_cli-3.0.1-py3-none-macosx_10_12_x86_64.whl (7.2 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

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

File metadata

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

File hashes

Hashes for panache_cli-3.0.1.tar.gz
Algorithm Hash digest
SHA256 c9c3a22f6d0ada578b2b1225e3a12253b2a453da5216c2b83354dab7b4a11f86
MD5 b6e4df531114efc4ed95dde4a4018e2d
BLAKE2b-256 b7ef38bf01bdc3145e3f0edabac93d9b7f4514726d8f7ad094dadf2229d09a7b

See more details on using hashes here.

Provenance

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

File metadata

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

File hashes

Hashes for panache_cli-3.0.1-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 089fd2fa504076fbdd4417199062a4fa2fba05cae851cb17f410c4ea049cd88a
MD5 21560c410d0ef3f21add48bf80b5c1d9
BLAKE2b-256 32eae683d4e66708d7a059a6049b732ce4fd9364dcb9b88f0d63f7941a72dfeb

See more details on using hashes here.

Provenance

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

File metadata

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

File hashes

Hashes for panache_cli-3.0.1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 d6e39b81796771ecc459e28b2d37b871b5ed557ee8e964b3593d5f0dbc8a6d41
MD5 b3c68b412afa82c1b6e3f06794548be3
BLAKE2b-256 d24473c9ea6c242929bcc012ac4dd6d97e20d9476814d7c0f90ea08c04392cb3

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for panache_cli-3.0.1-py3-none-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 b0db91699121d1ce19171abf71a48fdf8d7fd72f786c0e6b90637461a50646b4
MD5 1a8f04fc39bba25f8c61086008d973c1
BLAKE2b-256 431f87383ae681764458252f582d690f9986284324bc253818f9e0952352285b

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for panache_cli-3.0.1-py3-none-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 76101b95ea36e0704310b4b552d2d0754d9d4e8ae86766d7977f45c6937f93f4
MD5 5847d872a84e11265711488249cda5e9
BLAKE2b-256 850834a49f6b9775c0005ac23966810ef93759bc308c08d6e8ea4f96ac9f7ab6

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for panache_cli-3.0.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 70ee9cf4924e9acafeb59b8751e083125bf386758981bda98d5d8fc5b41227b0
MD5 3e93ac899c89512eca9dbb6cb2dc9528
BLAKE2b-256 a8245a7617c7031d5dffc1d39b6e3a00afebcc4532bd3b5ccd5868b6b0711ad1

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for panache_cli-3.0.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0e09d9f7be22892b87d4d0bd21290fce5850827ad127ab645eef3e0a05fb605d
MD5 23b4c0b415b80ded9812bc14f114107f
BLAKE2b-256 29baa3c0275a6b54c4c675f8e3be785b43a18695bf6168dcc71507d8ead6004f

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for panache_cli-3.0.1-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 41be512007b0d8aafec40aab85c713adbe85df81674ca2e2201eb4af16bb8071
MD5 7c2318fa823f901485556157e4e6cb82
BLAKE2b-256 5ad8cb10a4b9b046625369425e84068e728591ed0a0cff1ad18deac4cbf804c7

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for panache_cli-3.0.1-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 5139a70b3d266e70bdf13477c083747865dd10fee712b08991282f00b1e6beb6
MD5 f6b5acaf775dd66a9d68358fd550d888
BLAKE2b-256 2a33366c273bfaf552b3160f583432739689e3738ec4178897783df30f4f6211

See more details on using hashes here.

Provenance

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