A language server, formatter, and linter for Pandoc, Quarto, and R Markdown.
This project is in early development. Expect bugs, missing features, and breaking changes.
If you have Rust installed, the easiest way is likely to install from crates.io:
cargo install panacheAlternatively, 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).
There is also an Arch Linux package available in the AUR: panache-bin.
yay -S panache-bin # or your preferred AUR helperIf 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.
Panache provides a single CLI interface for formatting, linting, and running the LSP server.
To format a file in place, simply run:
panache format document.qmdYou can also format from stdin by piping content into panache format:
cat <file> | panache formatpanache 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.qmdPanache 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 formatterYou 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 = truePanache also features a linter that can report formatting issues and optionally auto-fix them. To run the linter, use:
panache lint document.qmdAs with panache format, you can use glob patterns and recursive formatting:
panache lint **/*.{qmd,md}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 outputPanache implements the language server protocol (LSP) to provide editor features like formatting, diagnostics, code actions, and more.
To start the language server, run:
panache lspMost users will want to configure their editor to start the language server automatically when editing. See the language server documentation for guides on configuring your editor. For VS Code and related editors such as Positron, there is a VS Code Marketplace extension and Open VSX extension that provides an LSP client and additional features.
The server communicates over stdin/stdout and provides document formatting
capabilities. For Quarto projects, the LSP also reads _quarto.yml,
per-directory _metadata.yml, and metadata-files includes to supply
project-level metadata to bibliography-aware features. For Bookdown,
_bookdown.yml, _output.yml, and index.Rmd frontmatter are also considered.
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
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)
# 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 lintingSee .panache.toml.example for a complete configuration reference.
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-commitThen add Panache to your .pre-commit-config.yaml:
repos:
- repo: https://github.com/jolars/panache
rev: v2.16.0 # Use the latest version
hooks:
- id: panache-format # Format files
- id: panache-lint # Lint and auto-fix issuesInstall the hooks:
pre-commit installPanache 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.
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.
- 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
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.
