Skip to main content

panache_parser/syntax/
kind.rs

1//! Syntax kinds and language definition for the Quarto/Pandoc CST.
2
3use rowan::Language;
4
5#[allow(non_camel_case_types)]
6#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
7#[repr(u16)]
8pub enum SyntaxKind {
9    // Tokens
10    WHITESPACE = 0,
11    NEWLINE,
12    TEXT,
13    BACKSLASH,         // \ (for escaping)
14    ESCAPED_CHAR,      // Any escaped character
15    NONBREAKING_SPACE, // \<space>
16    HARD_LINE_BREAK,   // \<newline>
17    DIV_MARKER,        // :::
18
19    // YAML tokens (metadata and in-tree YAML CST parser)
20    YAML_METADATA_DELIM, // --- or ... (for YAML blocks)
21    YAML_KEY,            // YAML mapping key token
22    YAML_COLON,          // YAML mapping key-value separator
23    YAML_TAG,            // YAML explicit tag token (e.g. !!str)
24    YAML_ANCHOR,         // YAML anchor token (e.g. &name)
25    YAML_ALIAS,          // YAML alias token (e.g. *name)
26    YAML_SCALAR_TEXT,    // YAML scalar content fragment (one physical line of a scalar)
27    YAML_FLOW_INDICATOR, // YAML flow structural punctuation ([ ] { } ,)
28    YAML_DIRECTIVE,      // YAML directive line (%YAML, %TAG)
29    YAML_COMMENT,        // YAML inline comment token
30    YAML_LINE_PREFIX,    // Embedded-YAML per-line prefix trivia (hashpipe `#|`)
31    YAML_DOCUMENT_START, // YAML document start marker (---)
32    YAML_DOCUMENT_END,   // YAML document end marker (...)
33
34    BLOCK_QUOTE_MARKER, // >
35    ALERT_MARKER,       // [!NOTE], [!TIP], etc.
36    IMAGE_LINK_START,   // ![
37    LIST_MARKER,        // - + *
38    TASK_CHECKBOX,      // [ ] or [x] or [X]
39    COMMENT_START,      // <!--
40    COMMENT_END,        // -->
41    ATTRIBUTE,          // {#label} for headings, math, etc.
42    // Structured children of a Pandoc `{...}` ATTRIBUTE. Each wraps the
43    // existing source bytes (markers/quotes included); the projector strips
44    // them. Absent on opaque ATTRIBUTE forms (MMD `[#id]`, raw-inline
45    // `{=format}`, fallback), which keep a single inner ATTRIBUTE token.
46    ATTR_ID,         // #id (token text includes the leading '#')
47    ATTR_CLASS,      // .class (token text includes the leading '.')
48    ATTR_KEY_VALUE,  // key=value (node grouping the pieces below)
49    ATTR_KEY,        // key (token, no '=')
50    ATTR_VALUE,      // value or "value"/'value' (token text includes quotes)
51    HORIZONTAL_RULE, // --- or *** or ___
52    BLANK_LINE,
53
54    // Links and images
55    LINK_START,           // [
56    LINK,                 // [text](url)
57    LINK_TEXT,            // text part of link
58    LINK_TEXT_END,        // ] closing link text
59    LINK_DEST_START,      // ( opening link destination
60    LINK_DEST,            // (url) or (url "title")
61    LINK_DEST_END,        // ) closing link destination
62    LINK_REF,             // [ref] in reference links
63    IMAGE_LINK,           // ![alt](url)
64    IMAGE_ALT,            // alt text in image
65    IMAGE_ALT_END,        // ] closing image alt
66    IMAGE_DEST_START,     // ( opening image destination
67    IMAGE_DEST_END,       // ) closing image destination
68    AUTO_LINK,            // <http://example.com>
69    AUTO_LINK_MARKER,     // < and >
70    REFERENCE_DEFINITION, // [label]: url "title"
71    FOOTNOTE_DEFINITION,  // [^id]: content
72    FOOTNOTE_REFERENCE,   // [^id]
73    FOOTNOTE_LABEL_START, // [^
74    FOOTNOTE_LABEL_ID,    // id in [^id] or [^id]:
75    FOOTNOTE_LABEL_END,   // ]
76    FOOTNOTE_LABEL_COLON, // :
77    REFERENCE_LABEL,      // [label] part
78    REFERENCE_URL,        // url part
79    REFERENCE_TITLE,      // "title" part
80
81    // Wikilinks (Pandoc `wikilinks_title_{after,before}_pipe` extensions)
82    WIKI_LINK,       // [[url]] or [[url|title]]
83    IMAGE_WIKI_LINK, // ![[url]] or ![[url|title]]
84    WIKI_LINK_OPEN,  // [[ or ![[
85    WIKI_LINK_URL,   // URL slot (raw TEXT child, no inline parsing)
86    WIKI_LINK_PIPE,  // | separator
87    WIKI_LINK_TITLE, // title slot (raw TEXT child, no inline parsing)
88    WIKI_LINK_CLOSE, // ]]
89
90    // Math
91    INLINE_MATH_MARKER,  // $
92    DISPLAY_MATH_MARKER, // $$
93    INLINE_MATH,
94    DISPLAY_MATH,
95    MATH_CONTENT, // wrapper node for parsed TeX math content (subtree root)
96
97    // Math content (structural TeX CST under MATH_CONTENT)
98    MATH_GROUP,       // { ... } brace group (node)
99    MATH_ENVIRONMENT, // \begin{env} ... \end{env} (node)
100    MATH_DELIMITED,   // \left<d> ... \right<d> paired delimiters (node)
101    MATH_GROUP_OPEN,  // {
102    MATH_GROUP_CLOSE, // }
103    MATH_COMMAND,     // \foo control word or \% control symbol
104    MATH_LINE_BREAK,  // \\
105    MATH_ALIGN,       // & alignment tab
106    MATH_SCRIPT,      // ^ or _
107    MATH_COMMENT,     // % to end of line (TeX comment)
108    // `+ - * = < >` operator atom; one token per char. Class/precedence are
109    // contextual (unary minus, `\mathbin`) and deferred to the formatter.
110    MATH_OPERATOR,
111    // Delimiters and punctuation whose TeX mathcode class is fixed at the
112    // character level (unlike operator class, which is contextual): `( [` open,
113    // `) ]` close, `, ;` punctuation. One token per char. The ambiguous `| . /`
114    // stay in MATH_TEXT โ€” their class needs macro context.
115    MATH_OPEN,    // ( or [
116    MATH_CLOSE,   // ) or ]
117    MATH_PUNCT,   // , or ;
118    MATH_TEXT,    // run of ordinary atoms
119    MATH_SPACE,   // run of spaces/tabs
120    MATH_NEWLINE, // newline within math content
121    // Bookdown equation label `(\#eq:label)`, recognized only when the
122    // `bookdown_equation_references` extension is enabled. A single token over
123    // the whole `(\#eq:...)` span so the indexer/LSP can target it precisely.
124    MATH_EQUATION_LABEL,
125
126    // Footnotes
127    INLINE_FOOTNOTE_START, // ^[
128    INLINE_FOOTNOTE_END,   // ]
129    INLINE_FOOTNOTE,       // ^[text]
130
131    // Citations
132    CITATION,                // [@key] or @key
133    CITATION_MARKER,         // @ or -@
134    CITATION_KEY,            // The citation key identifier
135    CITATION_BRACE_OPEN,     // { for complex keys
136    CITATION_BRACE_CLOSE,    // } for complex keys
137    CITATION_CONTENT,        // Text content in bracketed citations
138    CITATION_SEPARATOR,      // ; between multiple citations
139    CROSSREF,                // Quarto cross-reference: @fig-*, @eq-*, etc.
140    CROSSREF_MARKER,         // @ or -@ for cross-references
141    CROSSREF_KEY,            // Cross-reference key identifier
142    CROSSREF_BRACE_OPEN,     // { for braced cross-reference keys
143    CROSSREF_BRACE_CLOSE,    // } for braced cross-reference keys
144    CROSSREF_BOOKDOWN_OPEN,  // \@ref(
145    CROSSREF_BOOKDOWN_CLOSE, // )
146
147    // Spans
148    BRACKETED_SPAN,     // [text]{.class}
149    SPAN_CONTENT,       // text inside span
150    SPAN_ATTRIBUTES,    // {.class key="val"}
151    SPAN_BRACKET_OPEN,  // [
152    SPAN_BRACKET_CLOSE, // ]
153
154    // Shortcodes (Quarto)
155    SHORTCODE,              // {{< name args >}} or {{{< name args >}}}
156    SHORTCODE_MARKER_OPEN,  // {{< or {{{<
157    SHORTCODE_MARKER_CLOSE, // >}} or >}}}
158    SHORTCODE_CONTENT,      // content between markers
159
160    // Svelte template syntax (mdsvex). Opaque, lossless spans: the content
161    // between the braces is preserved verbatim. The parent kind records the
162    // category (block logic / tag / expression) by leading sigil.
163    SVELTE_BLOCK_LOGIC,  // {#if}, {:else}, {/each}, ...
164    SVELTE_TAG,          // {@html ...}, {@const ...}, {@debug ...}
165    SVELTE_EXPRESSION,   // {expr}
166    SVELTE_MARKER_OPEN,  // {
167    SVELTE_MARKER_CLOSE, // }
168    SVELTE_CONTENT,      // verbatim content between the braces
169    SVELTE_BLOCK,        // a standalone Svelte span occupying a whole line
170
171    // Code
172    INLINE_CODE,
173    INLINE_CODE_MARKER,  // ` or `` or ```
174    INLINE_CODE_CONTENT, // Literal inline code content
175    INLINE_EXEC,         // Inline executable code span variants
176    INLINE_EXEC_MARKER,  // Backtick markers delimiting inline executable code
177    INLINE_EXEC_LANG,    // Runtime marker (`r` or `{r}`)
178    INLINE_EXEC_CONTENT, // Executable inline code expression
179    CODE_FENCE_MARKER,   // ``` or ~~~
180    CODE_BLOCK,
181
182    // Raw inline spans
183    RAW_INLINE,         // `content`{=format}
184    RAW_INLINE_MARKER,  // ` markers
185    RAW_INLINE_FORMAT,  // format name (html, latex, etc.)
186    RAW_INLINE_CONTENT, // raw content
187
188    // Inline emphasis and formatting
189    EMPHASIS,           // *text* or _text_
190    STRONG,             // **text** or __text__
191    STRIKEOUT,          // ~~text~~
192    MARK,               // ==text==
193    SUPERSCRIPT,        // ^text^
194    SUBSCRIPT,          // ~text~
195    EMPHASIS_MARKER,    // * or _ (for emphasis)
196    STRONG_MARKER,      // ** or __ (for strong)
197    STRIKEOUT_MARKER,   // ~~ (for strikeout)
198    MARK_MARKER,        // == (for mark/highlight)
199    SUPERSCRIPT_MARKER, // ^ (for superscript)
200    SUBSCRIPT_MARKER,   // ~ (for subscript)
201
202    // Composite nodes
203    DOCUMENT,
204
205    // YAML nodes
206    YAML_METADATA,
207    YAML_METADATA_CONTENT,    // Content lines inside YAML metadata block
208    YAML_STREAM, // YAML 1.2 stream wrapper (zero or more YAML_DOCUMENT children + trivia)
209    YAML_DOCUMENT, // a single YAML document (markers + body)
210    YAML_SCALAR, // YAML scalar value node (wraps YAML_SCALAR_TEXT content + NEWLINE/prefix leaves)
211    YAML_BLOCK_MAP, // YAML block mapping container
212    YAML_BLOCK_MAP_ENTRY, // YAML block mapping entry (key: value)
213    YAML_BLOCK_MAP_KEY, // YAML block mapping key wrapper
214    YAML_BLOCK_MAP_VALUE, // YAML block mapping value wrapper
215    YAML_FLOW_MAP, // YAML flow mapping container ({key: value, ...})
216    YAML_FLOW_MAP_ENTRY, // YAML flow mapping entry
217    YAML_FLOW_MAP_KEY, // YAML flow mapping key wrapper
218    YAML_FLOW_MAP_VALUE, // YAML flow mapping value wrapper
219    YAML_FLOW_SEQUENCE, // YAML flow sequence container ([a, b, ...])
220    YAML_FLOW_SEQUENCE_ITEM, // YAML flow sequence item wrapper
221    YAML_BLOCK_SEQUENCE, // YAML block sequence container (- item ...)
222    YAML_BLOCK_SEQUENCE_ITEM, // YAML block sequence item wrapper
223    YAML_BLOCK_SEQ_ENTRY, // YAML block sequence entry marker (-)
224
225    PANDOC_TITLE_BLOCK,
226    MMD_TITLE_BLOCK,
227    FENCED_DIV,
228    // python-markdown admonition (`!!! note`) and pymdownx details
229    // (`???`/`???+`) container block. Content is 4-space indented and
230    // parsed recursively; closes on dedent (like a footnote definition).
231    ADMONITION,
232    // MyST directive container (```` ```{name} ```` or, with `colon_fence`,
233    // `:::{name}`). Fence-delimited like a fenced div, but its body is parsed
234    // recursively as markdown and the closer must match the opener's fence
235    // character and count.
236    MYST_DIRECTIVE,
237    PARAGRAPH,
238    PLAIN, // Inline content without paragraph break (tight lists, definition lists, table cells)
239    BLOCK_QUOTE,
240    ALERT,
241    LIST,
242    LIST_ITEM,
243    DEFINITION_LIST,
244    DEFINITION_ITEM,
245    TERM,
246    DEFINITION,
247    DEFINITION_MARKER, // : or ~
248    LINE_BLOCK,
249    LINE_BLOCK_LINE,
250    LINE_BLOCK_MARKER, // |
251    COMMENT,
252    FIGURE, // Standalone image (Pandoc figure)
253
254    // HTML blocks
255    HTML_BLOCK,         // Generic HTML block
256    HTML_BLOCK_TAG,     // Opening/closing tags
257    HTML_BLOCK_CONTENT, // Content between tags
258    // Pandoc-dialect lift: a matched <div ...>...</div> block.
259    HTML_BLOCK_DIV,
260    // Pandoc-dialect lift: a single-construct opaque HTML block that
261    // projects to exactly one `RawBlock "html"` โ€” an HTML comment
262    // (`<!-- -->`), a processing instruction (`<? ?>`), or a verbatim
263    // raw-text element (`<pre>`/`<script>`/`<style>`/`<textarea>`). The
264    // wrapper kind lets the pandoc-native projector route by CST kind
265    // instead of re-sniffing the leading bytes. CommonMark dialect keeps
266    // the opaque HTML_BLOCK shape.
267    HTML_BLOCK_RAW,
268    // Structural region inside an HTML opening tag holding the
269    // attribute-list bytes โ€” i.e. everything between the tag name and
270    // the closing `>`, exclusive. Recognized by `AttributeNode::cast`,
271    // so the salsa anchor index sees `id`/`class`/key=val attrs from
272    // `<div id="x">` blocks via the same walk that handles fenced-div
273    // and heading attributes.
274    HTML_ATTRS,
275
276    // Inline raw HTML (CommonMark ยง6.6 / Pandoc raw_html). One node per HTML
277    // tag/comment/declaration/PI/CDATA span; child token holds the verbatim
278    // bytes of the span.
279    INLINE_HTML,
280    INLINE_HTML_CONTENT,
281    // Pandoc-dialect inline lift: a matched <span ...>...</span> tag pair,
282    // mirroring HTML_BLOCK_DIV at the inline level. The open tag's
283    // attribute region is exposed structurally as HTML_ATTRS so the
284    // existing AttributeNode walk picks up `<span id>` ids automatically.
285    INLINE_HTML_SPAN,
286
287    // TeX blocks
288    TEX_BLOCK, // Raw tex block (e.g., LaTeX commands)
289
290    // Headings
291    HEADING,
292    HEADING_CONTENT,
293    ATX_HEADING_MARKER,       // leading #####
294    SETEXT_HEADING_UNDERLINE, // ===== or -----
295
296    // LaTeX inline commands
297    LATEX_COMMAND, // \command{...}
298
299    // Tables
300    SIMPLE_TABLE,
301    MULTILINE_TABLE,
302    PIPE_TABLE,
303    GRID_TABLE,
304    TABLE_HEADER,
305    TABLE_FOOTER,
306    TABLE_SEPARATOR,
307    TABLE_ROW,
308    TABLE_CELL,
309    TABLE_CAPTION,
310    TABLE_CAPTION_PREFIX, // "Table: ", "table: ", or ": "
311    // Separator-row markers (split out of the coalesced separator TEXT so
312    // alignment/width derivations read structure instead of re-scanning a
313    // string). One `TABLE_SEP_DELIM` covers both `|` and `+`.
314    TABLE_SEP_DELIM,      // single column delimiter: `|` (pipe) or `+` (grid)
315    TABLE_SEP_DASHES,     // a run of `-`
316    TABLE_SEP_EQUALS,     // a run of `=` (grid `+===+` header divider)
317    TABLE_SEP_COLON,      // single `:` alignment marker
318    TABLE_SEP_WHITESPACE, // interior spaces/tabs between dash runs
319
320    // Code block parts
321    CODE_FENCE_OPEN,
322    CODE_FENCE_CLOSE,
323    CODE_INFO,     // Raw info string (preserved for lossless formatting)
324    CODE_LANGUAGE, // Parsed language identifier (r, python, etc.)
325
326    // Chunk options (for executable chunks like {r, echo=TRUE})
327    CHUNK_OPTIONS,          // Container for all chunk options
328    CHUNK_OPTION,           // Single option (key=value pair)
329    CHUNK_OPTION_KEY,       // Option name (e.g., echo, fig.cap)
330    CHUNK_OPTION_VALUE,     // Option value (e.g., TRUE, "text")
331    CHUNK_OPTION_QUOTE,     // Quote character (" or ') if present
332    CHUNK_LABEL,            // Special case: unlabeled first option in {r mylabel}
333    HASHPIPE_YAML_PREAMBLE, // Hashpipe YAML option preamble region inside CODE_CONTENT
334    HASHPIPE_YAML_CONTENT,  // Content lines belonging to hashpipe YAML preamble
335    HASHPIPE_PREFIX,        // Hashpipe option marker prefix (e.g., #|, //|, --|)
336
337    CODE_CONTENT,
338
339    // Div parts
340    DIV_FENCE_OPEN,
341    DIV_FENCE_CLOSE,
342    DIV_INFO,
343    DIV_CONTENT,
344
345    // Admonition parts (`!!! type "title"` / `???`/`???+`)
346    ADMONITION_MARKER, // `!!!`, `???`, or `???+`
347    ADMONITION_TYPE,   // type/class words (e.g. `note`, `danger highlight`)
348    ADMONITION_TITLE,  // optional quoted title (e.g. `"Heads up"`)
349
350    // MyST directive parts
351    MYST_DIRECTIVE_OPEN,   // opener line node (fence + name + optional argument)
352    MYST_DIRECTIVE_CLOSE,  // closer line node (matching fence)
353    MYST_DIRECTIVE_FENCE,  // the fence run itself (```` ``` ````, `~~~`, or `:::`)
354    MYST_DIRECTIVE_NAME,   // the `{name}` token, braces included (lossless)
355    MYST_DIRECTIVE_ARG,    // argument text after `{name}` on the opener line
356    MYST_DIRECTIVE_OPTION, // one `:key: value` option line node
357    MYST_DIRECTIVE_OPTION_MARKER, // a `:` delimiter (leading and closing colon)
358    MYST_DIRECTIVE_OPTION_NAME, // the option key (e.g. `alt`)
359    MYST_DIRECTIVE_OPTION_VALUE, // the option value (e.g. `An image`)
360    MYST_DIRECTIVE_BODY,   // verbatim body of a code/math directive (raw, not reflowed)
361
362    // MyST inline role parts (`` {name}`content` ``)
363    MYST_ROLE,         // the whole role
364    MYST_ROLE_NAME,    // the `{name}` token, braces included
365    MYST_ROLE_MARKER,  // the backtick run delimiting the content
366    MYST_ROLE_CONTENT, // the literal content between the backticks
367
368    // MyST target / comment / substitution parts
369    MYST_TARGET,             // a `(label)=` target line
370    MYST_TARGET_LABEL,       // the label between `(` and `)=`
371    MYST_COMMENT,            // a `% ...` line comment
372    MYST_BLOCK_BREAK,        // a `+++` block break line
373    MYST_BLOCK_BREAK_MARKER, // the `+++` marker run
374    MYST_BLOCK_BREAK_META,   // optional trailing cell metadata after `+++`
375    MYST_SUBSTITUTION,       // an inline `{{ name }}` substitution
376    MYST_SUBSTITUTION_NAME,  // the substitution key between `{{` and `}}`
377
378    EMOJI, // :alias:
379
380    // Bracket-shape pattern that did not resolve as a link/image.
381    // Distinct from LINK/IMAGE_LINK so downstream tools (linter, LSP) can
382    // walk a typed wrapper without the parser having to lie about
383    // resolution. `is_image()` on the typed wrapper distinguishes
384    // `[foo]` from `![foo]` shapes.
385    UNRESOLVED_REFERENCE,
386}
387
388impl From<SyntaxKind> for rowan::SyntaxKind {
389    fn from(kind: SyntaxKind) -> Self {
390        Self(kind as u16)
391    }
392}
393
394#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
395pub enum PanacheLanguage {}
396
397impl Language for PanacheLanguage {
398    type Kind = SyntaxKind;
399
400    fn kind_from_raw(raw: rowan::SyntaxKind) -> Self::Kind {
401        unsafe { std::mem::transmute::<u16, SyntaxKind>(raw.0) }
402    }
403
404    fn kind_to_raw(kind: Self::Kind) -> rowan::SyntaxKind {
405        kind.into()
406    }
407}