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, // 
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}