panache 2.2.0

A formatter for Pandoc, Quarto, and RMarkdown documents
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
# panache TODO

This document tracks implementation status for panache's features.

**Status Legend**

- ✅ **Implemented** - Feature is fully or mostly implemented
- 🚧 **Partial** - Feature is partially implemented or needs work
- ❌ **Not Implemented** - Feature not yet started
- âšī¸ **Won't Implement** - Feature intentionally not implemented

---

## Language Server Protocol (LSP)

### Core LSP Capabilities

- ✅ `textDocument/formatting` - Full document formatting
- ✅ `textDocument/didOpen` - Track document opens
- ✅ `textDocument/didChange` - Track document changes (incremental sync)
- ✅ `textDocument/didClose` - Track document closes
- ✅ Configuration discovery from workspace root (`.panache.toml`)

### Future LSP Features

#### Diagnostics

- ❌ **Syntax error diagnostics** - Report parsing errors as diagnostics
- ❌ **Lint warnings** - Configurable linting rules (e.g., heading levels, list consistency)
- ❌ **Link validation** - Check for broken internal links/references
- ❌ **Citation validation** - Validate citation keys against bibliography
- ❌ **Footnote validation** - Check for undefined footnotes

#### Code Actions

- ❌ **Convert lists** - Convert between bullet/ordered lists
- ❌ **Convert table** - Convert between table styles (simple, pipe, grid)
- ❌ **Convert link styles** - Convert between inline/reference links
- ❌ **Convert footnote styles** - Convert between inline/reference footnotes

#### Navigation & Symbols

- ✅ **Document outline** - `textDocument/documentSymbol` for headings, tables, figures
- ❌ **Folding ranges** - `textDocument/foldingRange` for headings, lists, code blocks
- ❌ **Go to definition** - Jump to reference link/footnote/citation definitions
- ❌ **Find references** - Find all uses of a reference link/footnote/citation

#### Completion

- ❌ **Citation completion** - `textDocument/completion` for `@cite` keys from bibliography
- ❌ **Reference link completion** - Complete `[text][ref]` from defined references
- ❌ **Heading link completion** - Complete internal links to headings
- ❌ **Attribute completion** - Complete class names and attributes in `{.class #id}`

#### Hover Information

- ❌ **Link preview** - `textDocument/hover` to show link target
- ❌ **Reference preview** - Show reference definition on hover
- ❌ **Citation preview** - Show bibliography entry for citation
- ❌ **Footnote preview** - Show footnote content inline

#### Advanced

- ✅ **Range formatting** - `textDocument/rangeFormatting` for selected text only
- ❌ **On-type formatting** - `textDocument/onTypeFormatting` for auto-formatting triggers
- ❌ **Document links** - `textDocument/documentLink` for clickable links
- ❌ **Semantic tokens** - Syntax highlighting via LSP
- ❌ **Rename** - Rename reference links/footnotes/citations across document
- ❌ **Workspace symbols** - Search for headings across all workspace documents
- ❌ **Configuration via LSP** - `workspace/didChangeConfiguration` to reload config

---

## Configuration System

### Current Features

- ✅ Hierarchical config loading (explicit → local → XDG → defaults)
- ✅ Auto-detect flavor from file extension (.qmd → Quarto, .Rmd → RMarkdown)
- ✅ `flavor` config field affects .md files and stdin
- ✅ Global `[extensions]` overrides for all flavors
- ✅ `[formatters]` configuration for external code formatters

### Future Enhancements

#### Per-Flavor Extension Configuration

- ❌ **Per-flavor extension overrides** - `[extensions.gfm]`, `[extensions.quarto]`, `[extensions.rmarkdown]`, etc.
  - Allow fine-grained control of extensions for specific flavors
  - Example: Enable `task_lists` only for GFM, disable `citations` for CommonMark
  - Falls back to global `[extensions]` settings when not specified

#### Per-File Pattern Overrides

- ❌ **Glob pattern flavor overrides** - `[flavor_overrides]` with file patterns
  - Override flavor for specific files or patterns
  - Example: `"README.md" = "gfm"` or `"docs/**/*.md" = "gfm"`
  - Useful for projects with mixed Markdown files (e.g., README.md as GFM, docs as Pandoc)
  - Could potentially extend to per-pattern extension overrides: `[pattern_overrides."docs/**/*.md".extensions]`

---

## Linter

### Current Status

**✅ Implemented** - Basic linter with CLI and one rule.

**Current features:**

- ✅ `panache lint` CLI subcommand
- ✅ `--check` mode for CI (exit 1 if violations found)
- ✅ `--fix` mode for auto-fixing violations
- ✅ Diagnostic output with file locations
- ✅ Pluggable rule system with `RuleRegistry`
- ✅ **Implemented rule:** `heading-hierarchy` - Warns when heading levels are skipped (e.g., h1 → h3)

### Architecture

Follows the ruff/clippy pattern: separate concerns, shared infrastructure

```
src/linter/           # Core linting logic
  ├── rules/          # Individual lint rules
  │   └── heading_hierarchy.rs  # Heading level checking
  ├── diagnostics.rs  # Diagnostic types (Diagnostic, Severity, Fix, Edit)
  ├── rules.rs        # Rule trait and registry
  └── runner.rs       # Rule execution
src/main.rs           # CLI: `panache lint` subcommand
src/lsp.rs            # LSP: TODO - integrate diagnostics
```

Both linter and formatter:

- ✅ Share the same parser and AST
- ✅ Use the same config system
- ✅ Benefit from rowan's CST

### CLI Commands

```bash
panache lint document.qmd           # Report violations
panache lint --fix document.qmd     # Auto-fix what's possible
panache lint --check document.qmd   # CI mode: exit non-zero if violations
panache lint --config cfg.toml      # Custom config
```

### Future Lint Rules

**Syntax correctness:**

- ❌ Malformed fenced divs (unclosed, invalid attributes)
- ❌ Broken table structures
- ❌ Invalid citation syntax (`@citekey` malformations)
- ❌ Unclosed inline math/code spans
- ❌ Invalid shortcode syntax (Quarto-specific)

**Style/Best practices:**

- ✅ Inconsistent heading hierarchy (skip levels)
- ❌ Multiple top-level headings
- ❌ Empty links/images
- ❌ Duplicate reference labels
- ❌ Unused reference definitions
- ❌ Hard-wrapped text in code blocks

**Configuration:**

- ❌ Per-rule enable/disable in `.panache.toml` `[lint]` section
- ❌ Severity levels (error, warning, info)
- ❌ Auto-fix capability per rule (infrastructure exists, rules need implementation)

### Next Steps

- [ ] Add more lint rules (empty links, duplicate refs, etc.)
- [ ] Make rules configurable via `[lint]` section in config
- [ ] LSP integration with `textDocument/publishDiagnostics`
- [ ] Add auto-fix implementations for fixable rules

### Open Questions

- Should linter rules be pluggable (external crates)?
- How to balance parser error recovery vs. strict linting?
- Performance: incremental linting for LSP mode?

## Formatter

### Lists

- ✅ **Bullet lists** - Standardize bullet list markers to `-` (all `*`, `+`, `-` converted to `-`)

### Tables

- ❌ **Simple tables** - Support for formatting tables
- ✅ **Pipe tables** - Support for formatting GitHub-style tables
- ❌ **Grid tables** - Support for formatting grid-style tables
- ❌ **Multiline tables** - Support for formatting tables with multiline cells

Parser - Comprehensive Pandoc Feature Coverage

This section tracks implementation status of Pandoc Markdown features based on the spec files in `docs/pandoc-spec/`.

**Focus**: Initial development prioritizes **default Pandoc extensions**. Non-default extensions are tracked separately for future consideration.

### Block-Level Elements

### Paragraphs ✅

- ✅ Basic paragraphs
- ✅ Paragraph wrapping/reflow
- ✅ Extension: `escaped_line_breaks` (backslash at line end)

### Headings ✅

- ✅ ATX-style headings (`# Heading`)
- ✅ Setext-style headings (underlined with `===` or `---`)
- ✅ Heading identifier attributes (`# Heading {#id}`)
- ✅ Extension: `blank_before_header` - Require blank line before headings (default behavior)
- ✅ Extension: `header_attributes` - Full attribute syntax `{#id .class key=value}`
- âšī¸ Extension: `implicit_header_references` - Auto-generate reference links (conversion feature, not formatting concern)

### Block Quotations ✅

- ✅ Basic block quotes (`> text`)
- ✅ Nested block quotes (`> > nested`)
- ✅ Block quotes with paragraphs
- ✅ Extension: `blank_before_blockquote` - Require blank before quote (default behavior)
- ✅ Block quotes containing lists
- ✅ Block quotes containing code blocks

### Lists 🚧

- ✅ Bullet lists (`-`, `+`, `*`)
- ✅ Ordered lists (`1.`, `2.`, etc.)
- ✅ Nested lists
- ✅ List item continuation
- 🚧 Complex nested mixed lists (fragile, needs parser structure improvement)
- ✅ Extension: `fancy_lists` - Roman numerals, letters `(a)`, `A)`, etc.
- ❌ Extension: `startnum` - Start ordered lists at arbitrary number (low priority)
- ✅ Extension: `example_lists` - Example lists with `(@)` markers
- ✅ Extension: `task_lists` - GitHub-style `- [ ]` and `- [x]`
- ✅ Extension: `definition_lists` - Term/definition syntax

### Code Blocks ✅

- ✅ Fenced code blocks (backticks and tildes)
- ✅ Code block attributes (language, etc.)
- ✅ Indented code blocks (4-space indent)
- ✅ Extension: `fenced_code_attributes` - `{.language #id}`
- ✅ Extension: `backtick_code_blocks` - Backtick-only fences
- ✅ Extension: `inline_code_attributes` - Attributes on inline code

### Horizontal Rules ✅

- ✅ Basic horizontal rules (`---`, `***`, `___`)

### Fenced Divs ✅

- ✅ Basic fenced divs (`::: {.class}`)
- ✅ Nested fenced divs
- ✅ Colon count normalization based on nesting
- ✅ Proper formatting with attribute preservation

### Tables ✅

- ✅ Extension: `simple_tables` - Simple table syntax (parsing complete, formatting deferred)
- ✅ Extension: `table_captions` - Table captions (both before and after tables)
- ✅ Extension: `pipe_tables` - GitHub/PHP Markdown tables (all alignments, orgtbl variant)
- ✅ Extension: `multiline_tables` - Multiline cell content (parsing complete, formatting deferred)
- ✅ Extension: `grid_tables` - Grid-style tables (parsing complete, formatting deferred)

### Line Blocks ✅

- ✅ Extension: `line_blocks` - Poetry/verse with `|` prefix

---

## Inline Elements

### Emphasis & Formatting ✅

- ✅ `*italic*` and `_italic_`
- ✅ `**bold**` and `__bold__`
- ✅ Nested emphasis (e.g., `***bold italic***`)
- ✅ Overlapping and adjacent emphasis handling
- ✅ Extension: `intraword_underscores` - `snake_case` handling
- ✅ Extension: `strikeout` - `~~strikethrough~~`
- ✅ Extension: `superscript` - `^super^`
- ✅ Extension: `subscript` - `~sub~`
- ✅ Extension: `bracketed_spans` - Small caps `[text]{.smallcaps}`, underline `[text]{.underline}`, etc.

### Code & Verbatim ✅

- ✅ Inline code (`` `code` ``)
- ✅ Multi-backtick code spans (``` `` ` `` ```)
- ✅ Code spans containing backticks
- ✅ Proper whitespace preservation in code spans
- ✅ Fenced code blocks (``` and ~~~)
- ✅ Indented code blocks\*\* (4 spaces or 1 tab)

### Links ✅

- ✅ Inline links `[text](url)`
- ✅ Automatic links `<http://example.com>`
- ✅ Nested inline elements in link text (code, emphasis, math)
- ✅ Reference links `[text][ref]`
- ✅ Extension: `shortcut_reference_links` - `[ref]` without second `[]`
- ✅ Extension: `link_attributes` - `[text](url){.class}`
- âšī¸ Extension: `implicit_header_references` - `[Heading Name]` links to header (conversion feature, not formatting concern)

### Images ✅

- ✅ Inline images `![alt](url)`
- ✅ Nested inline elements in alt text (code, emphasis, math)
- ✅ Reference images `![alt][ref]`
- ✅ Image attributes `![alt](url){#id .class key=value}`
- âšī¸ Extension: `implicit_figures` - Conversion feature, not formatting concern

### Math ✅

- ✅ Inline math `$x = y$`
- ✅ Display math `$$equation$$`
- ✅ Multi-dollar math spans (e.g., `$$$ $$ $$$`)
- ✅ Math containing special characters
- ✅ Extension: `tex_math_dollars` - Dollar-delimited math

### Footnotes ✅

- ✅ Inline footnotes `^[note text]`
- ✅ Reference footnotes `[^1]` with definition block
- ✅ Extension: `inline_notes` - Inline note syntax
- ✅ Extension: `footnotes` - Reference-style footnotes

### Citations ✅

- ✅ Extension: `citations` - `[@cite]` and `@cite` syntax with complex key support

### Spans ✅

- ✅ Extension: `bracketed_spans` - `[text]{.class}` inline
- ✅ Extension: `native_spans` - HTML `<span>` elements with markdown content

---

## Metadata & Front Matter

### Metadata Blocks ✅

- ✅ Extension: `yaml_metadata_block` - YAML frontmatter
- ✅ Extension: `pandoc_title_block` - Title/author/date at top

---

## Raw Content & Special Syntax

### Raw HTML ✅

- ✅ Extension: `raw_html` - Inline and block HTML
- ❌ Extension: `markdown_in_html_blocks` - Markdown inside HTML blocks

### Raw LaTeX ✅

- ✅ Extension: `raw_tex` - Inline LaTeX commands (`\cite{ref}`, `\textbf{text}`, etc.)
- ✅ Extension: `raw_tex` - Block LaTeX environments (`\begin{tabular}...\end{tabular}`)
- âšī¸ Extension: `latex_macros` - Expand LaTeX macros (conversion feature, not formatting concern)

### Other Raw

- ✅ Extension: `raw_attribute` - Generic raw blocks `{=format}` (blocks ✅, inline spans ✅)

---

## Escapes & Special Characters

### Backslash Escapes ✅

- ✅ Extension: `all_symbols_escapable` - Backslash escapes any symbol
- ✅ Extension: `angle_brackets_escapable` - Escape `<` and `>`
- ✅ Escape sequences in inline elements (emphasis, code, math)

### Line Breaks ✅

- ✅ Extension: `escaped_line_breaks` - Backslash at line end = `<br>`

---

## Non-Default Extensions (Future Consideration)

These extensions are **not enabled by default** in Pandoc and are lower priority for initial implementation.

### Non-Default: Emphasis & Formatting

- ❌ Extension: `mark` - `==highlighted==` text (non-default)

### Non-Default: Links

- ❌ Extension: `autolink_bare_uris` - Bare URLs as links (non-default)
- ❌ Extension: `mmd_link_attributes` - MultiMarkdown link attributes (non-default)

### Non-Default: Math

- ✅ Extension: `tex_math_single_backslash` - `\( \)` and `\[ \]` (non-default, enabled for RMarkdown)
- ✅ Extension: `tex_math_double_backslash` - `\\( \\)` and `\\[ \\]` (non-default)
- ❌ Extension: `tex_math_gfm` - GitHub Flavored Markdown math (non-default)

### Non-Default: Metadata

- ❌ Extension: `mmd_title_block` - MultiMarkdown metadata (non-default)

### Non-Default: Headings

- ❌ Extension: `mmd_header_identifiers` - MultiMarkdown style IDs (non-default)

### Non-Default: Lists

- ❌ Extension: `lists_without_preceding_blankline` (non-default)
- ❌ Extension: `four_space_rule` - Four space vs two space list indent (non-default)

### Non-Default: Line Breaks

- ❌ Extension: `hard_line_breaks` - Newline = `<br>` (non-default)
- ❌ Extension: `ignore_line_breaks` - Ignore single newlines (non-default)
- ❌ Extension: `east_asian_line_breaks` - Smart line breaks for CJK (non-default)

### Non-Default: GitHub-specific

- ❌ Extension: `alerts` - GitHub/Quarto alert/callout boxes (non-default)
- ❌ Extension: `emoji` - `:emoji:` syntax (non-default)
- ❌ Extension: `wikilinks_title_after_pipe` - `[[link|title]]` (non-default)

### Non-Default: Quarto-Specific

- ✅ Quarto executable code cells with output
- ❌ Quarto cross-references `@fig-id`, `@tbl-id`
- ❌ Quarto callout blocks (`.callout-note`, etc.)

### Non-Default: RMarkdown-Specific

- ❌ RMarkdown code chunks with output
- ❌ Bookdown-style references (`\@ref(fig-id)`, etc.`)

### Non-Default: Other

- ❌ Extension: `abbreviations` - Abbreviation definitions (non-default)
- ❌ Extension: `attributes` - Universal attribute syntax (non-default, commonmark only)
- ❌ Extension: `gutenberg` - Project Gutenberg conventions (non-default)
- ❌ Extension: `markdown_attribute` - `markdown="1"` in HTML (non-default)
- ❌ Extension: `old_dashes` - Old-style em/en dash parsing (non-default)
- ❌ Extension: `rebase_relative_paths` - Rebase relative paths (non-default)
- ❌ Extension: `short_subsuperscripts` - MultiMarkdown `x^2` style (non-default)
- ❌ Extension: `sourcepos` - Include source position info (non-default)
- ❌ Extension: `space_in_atx_header` - Allow no space after `#` (non-default)
- ❌ Extension: `spaced_reference_links` - Allow space in `[ref] [def]` (non-default)

---

## Won't Implement

- Format-specific output conventions (e.g., `gutenberg` for plain text output)