# panache TODO

This document tracks implementation status for panache's features.

## Language Server

- [ ] Incremental parsing and caching for LSP performance (Implemented, but
      crude and often reparses entire document on change; needs optimization)

### Performance

- [ ] Evaluate `#[salsa::interned]` for common keys (paths/labels) if it reduces
      memory/cost.
- [ ] Evaluate salsa durability policy (`set_with_durability`) with measurements
      (e.g., open buffers LOW, stable dependency files MEDIUM/HIGH), and only
      roll out with a clear update/invalidation policy.
      - [x] Wire conservative defaults: open buffers LOW, config MEDIUM,
            dependency/disk-loaded files HIGH, watcher refreshes MEDIUM.
      - [x] Add ignored durability measurement harness
            (`tests/durability_bench.rs`) for HIGH vs LOW revalidation cost.

### Core LSP Capabilities

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

### Diagnostics

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

### Code Actions

- [ ] Convert between bullet/ordered lists
- [X] Convert loose/compact lists
- [ ] Convert bullet list to task list - Convert `- item` to `- [ ] item`
- [ ] Convert between table styles (simple, pipe, grid)
- [ ] Convert between inline/reference links
- [X] Convert between inline/reference footnotes

### Navigation & Symbols

- [x] Document outline - `textDocument/documentSymbol` for headings, tables,
      figures
- [x] Folding ranges - `textDocument/foldingRange`
      - [x] Code blocks
      - [x] Sections (headings)
- [ ] Go to definition links, images, footnotes). Enabled for some, but not all,
      reference types.
      - [x] Go to definition for reference links - Jump to `[ref]: url`
            definition
      - [x] Go to definition for citations - Jump to bibliography entry for
            `@cite` keys
      - [ ] Go to definition for headings - Jump to heading target for internal
            links
- [x] Find references - Find all uses of a reference link/footnote/citation
      - [x] Find references for citations - Find all `@cite` uses of a
            bibliography entry
      - [ ] Find references for headings - Find all internal links to a heading
      - [ ] Find references for reference links - Find all `[text][ref]` links

### Completion

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

### Inlay Hints (low priority)

Personally I think inlay hints are distractive and I am not sure what we want to
support.

- [ ] Link target hints - Show link targets as inlay hints
- [ ] Reference definition hints - Show reference definitions as inlay hints
- [ ] Citation key hints - Show bibliography entries for `@cite` keys
- [ ] Footnote content hints - Show footnote content as inlay hints

### Hover Information

- [ ] Link preview - `textDocument/hover` to show link target
- [ ] Reference preview - Show reference definition on hover
- [x] Footnote preview - Show footnote content inline
- [x] Citation preview - Show bibliography entry for citation (approximate)

### Advanced

- [x] Range formatting - `textDocument/rangeFormatting` for selected text only
- [ ] On-type formatting - `textDocument/onTypeFormatting` for auto-formatting
      triggers (not sure about this, low priority)
- [ ] Document links - `textDocument/documentLink` for clickable links
- [ ] Semantic tokens - Syntax highlighting via LSP
- [ ] Rename
      - [x] Citations - Rename `@cite` keys and update bibliography
      - [x] Reference links - Rename `[ref]` labels and update definitions
      - [ ] Headings - Rename heading text and update internal links
- [ ] Workspace symbols
      - [ ] General support for pandoc etc
      - [ ] Quarto - project-wide symbol search for figures, tables, sections
      - [ ] Rmarkdown (Bookdown)
- [ ] Configuration via LSP - `workspace/didChangeConfiguration` to reload
      config

## Configuration System

- [x] Enable turning on or off linting rules in `[lint]` section
- [x] Per-flavor extension overrides - `[extensions.gfm]`,
- [x] Glob pattern flavor overrides - `[flavor_overrides]` with file patterns

## Linter

- [x] Add support for comments to disable linting on specific lines or blocks
      (e.g., `<!-- something -->`)
- [x] Auto-fixing for external code linters

### 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

- [x] Inconsistent heading hierarchy (skip levels)
- [x] Duplicate reference labels
- [ ] Multiple top-level headings
- [ ] Empty links/images
- [ ] Unused reference definitions
- [ ] Hard-wrapped text in code blocks
- [ ] Use blanklines around horizontal rules

### 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)

### Open Questions

- How to balance parser error recovery vs. strict linting?
- Performance: incremental linting for LSP mode?
- LSP: incremental parsing cache (tree reuse on didChange)

## Formatter

- [x] Add support for comments to disable formatting on specific lines or blocks
      (e.g., `<!-- something-->`)

### Tables

- [x] Simple tables
- [x] Pipe tables
- [x] Grid tables
- [x] Multiline tables

## Parser

### Performance

- [ ] Avoid temporary green tree when injecting `BLOCKQUOTE_MARKER` tokens into
      inline-parsed paragraphs (current approach parses inlines into a temp
      tree, then replays while inserting markers)

### Long-term YAML parser groundwork

- [ ] Build an in-tree YAML parser module (`src/parser/yaml.rs`) as a long-term
      project with lossless CST goals.
- [ ] Target one shared parser core for plain YAML files and hashpipe-prefixed
      YAML (frontmatter/chunk metadata) with explicit host-range mapping
      support.
- [ ] Roll out via shadow/read-only mode with parity checks against existing
      YAML behavior before any formatter or edit-path replacement.
- [ ] Add first-class YAML formatting support after parser parity, using shared
      CST and idempotency-focused formatting tests for both plain YAML and
      hashpipe-prefixed YAML.
- [x] Add pinned yaml-test-suite fixtures under `tests/fixtures/yaml-test-suite`
      with an update script (`scripts/update-yaml-test-suite-fixtures.sh`).

## Parser - Coverage

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

**Focus**: Prioritize **default Pandoc extensions**. Non-default extensions are
lower priority and may be deferred until after core formatting features are
implemented.

### 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

### Block Quotations ✅

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

### Lists 🚧

- [x] Bullet lists (`-`, `+`, `*`)
- [x] Ordered lists (`1.`, `2.`, etc.)
- [x] Nested lists
- [x] List item continuation
- [x] Complex nested mixed lists
- [x] Extension: `fancy_lists` - Roman numerals, letters `(a)`, `A)`, etc.
- [ ] Extension: `startnum` - Start ordered lists at arbitrary number (low
      priority, if we even should support this)
- [x] Extension: `example_lists` - Example lists with `(@)` markers
- [x] Extension: `task_lists` - GitHub-style `- [ ]` and `- [x]`
- [x] Extension: `definition_lists` - Term/definition syntax

### Code Blocks

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

### Horizontal Rules

- [x] Basic horizontal rules (`---`, `***`, `___`)

### Fenced Divs

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

### Tables

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

### Line Blocks

- [x] Extension: `line_blocks` - Poetry/verse with `|` prefix

### Inline Elements

#### Emphasis & Formatting

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

#### Code & Verbatim

- [x] Inline code (`code`)
- [x] Multi-backtick code spans (\`\`\`\`\`)
- [x] Code spans containing backticks
- [x] Proper whitespace preservation in code spans
- [x] Fenced code blocks (\`\`\` and \~\~\~)
- [x] Indented code blocks

#### Links

- [x] Inline links `[text](url)`
- [x] Automatic links `<http://example.com>`
- [x] Nested inline elements in link text (code, emphasis, math)
- [x] Reference links `[text][ref]`
- [x] Extension: `shortcut_reference_links` - `[ref]` without second `[]`
- [x] Extension: `link_attributes` - `[text](url){.class}`
- [x] Extension: `implicit_header_references` - `[Heading Name]` links to header

#### Images

- [x] Inline images `![alt](url)`
- [x] Nested inline elements in alt text (code, emphasis, math)
- [x] Reference images `![alt][ref]`
- [x] Image attributes `![alt](url){#id .class key=value}`
- [x] Extension: `implicit_figures`

#### Math

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

#### Footnotes

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

#### Citations

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

#### Spans

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

### Metadata & Front Matter

#### Metadata Blocks

- [x] Extension: `yaml_metadata_block` - YAML frontmatter
- [x] Extension: `pandoc_title_block` - Title/author/date at top

### Raw Content & Special Syntax

#### Raw HTML

- [x] Extension: `raw_html` - Inline and block HTML
- [ ] Extension: `markdown_in_html_blocks` - Markdown inside HTML blocks

#### Raw LaTeX

- [x] Extension: `raw_tex` - Inline LaTeX commands (`\cite{ref}`,
      `\textbf{text}`, etc.)
- [x] Extension: `raw_tex` - Block LaTeX environments
      (`\begin{tabular}...\end{tabular}`)
- [x] Extension: `latex_macros` - Expand LaTeX macros (conversion feature, not
      formatting concern)

#### Other Raw

- [x] Extension: `raw_attribute` - Generic raw blocks `{=format}`

### Escapes & Special Characters

#### Backslash Escapes

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

#### Line Breaks

- [x] 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

- [x] Extension: `tex_math_single_backslash` - `\( \)` and `\[ \]` (non-default,
      enabled for RMarkdown)
- [x] Extension: `tex_math_double_backslash` - `\\( \\)` and `\\[ \\]`
      (non-default)
- [x] 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

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

#### Non-Default: Quarto-Specific

- [x] Quarto executable code cells with output
- [x] Quarto cross-references `@fig-id`, `@tbl-id`

#### Non-Default: RMarkdown-Specific

- [x] RMarkdown code chunks with output
- [x] 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)

### Quarto Shortcodes

- [x] Parser support for `{{< name args >}}` syntax
- [x] Parser support for `{{{< name args >}}}` escape syntax
- [x] Formatter with normalized spacing
- [x] Extension flag `quarto_shortcodes` (enabled for Quarto flavor)
- [x] Golden test coverage
- [ ] LSP diagnostics for malformed shortcodes
- [ ] Completion for built-in shortcode names

### Known Differences from Pandoc

#### Reference Link Parsing

**Status**: 🤔 **Deferred architectural decision**

**Issue**: Our CST structure differs from Pandoc's AST for undefined reference
links.

**Current behavior**:

- `[undefined]` (no definition exists) → Parsed as LINK node in CST
- Pandoc behavior: `[undefined]` → Parsed as literal text `Str "[undefined]"`
- **Formatting output is correct** (both produce `[undefined]`)

**Impact**:

- ✅ No impact on formatting (our primary use case)
- ✅ No impact on LSP features (uses CST traversal)
- ✅ No impact on linting (uses CST traversal)
- ⚠️ CST structure differs from Pandoc's AST (only matters for library users
  inspecting CST)

**Possible solutions** (if needed):

1. CST traversal during inline parsing to check if definition exists (O(n) cost
   per reference)
2. Minimal registry with `HashSet<String>` of definition labels (O(1) lookup)
3. Two-pass parsing (parse blocks first, then inline with definition knowledge)

**Decision**: Accept current behavior until a real-world use case requires
matching Pandoc's AST structure exactly.

#### Smart Abbreviation Non-Breaking Spaces

- [ ] Follow Pandoc `Ext_smart` abbreviation behavior: convert the space after
      recognized abbreviations (for example `M.A. 2007`) to a non-breaking space
      so wrapping does not split them.

## Architecture

- [ ] Separate out some functionality into separate crates (long-term)
