Skip to main content

libmandoc_rs/
ast.rs

1//! Owned, renderer-neutral syntax data copied from a completed libmandoc parse.
2//!
3//! These types contain no C pointers and remain valid after the parser session
4//! has been released.  They deliberately describe source semantics rather than
5//! imposing a presentation model on downstream renderers.
6
7/// High-level macro package detected by libmandoc.
8#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
9#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10pub enum MacroSet {
11    None,
12    Mdoc,
13    Man,
14}
15
16/// Renderer-neutral node role copied from the libmandoc syntax tree.
17#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
18#[derive(Clone, Copy, Debug, Eq, PartialEq)]
19pub enum NodeKind {
20    Root,
21    Block,
22    Head,
23    Body,
24    Tail,
25    Element,
26    Text,
27    Comment,
28    Table,
29    Equation,
30}
31
32/// Normalized mdoc list behavior copied independently of upstream enum values.
33#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
34#[derive(Clone, Copy, Debug, Eq, PartialEq)]
35pub enum NormalizedListKind {
36    Bullet,
37    Ordered,
38    Definition,
39    Column,
40    Plain,
41}
42
43/// Whether an mdoc display preserves source line layout.
44#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
45#[derive(Clone, Copy, Debug, Eq, PartialEq)]
46pub enum DisplayKind {
47    Literal,
48    Filled,
49}
50
51/// Horizontal alignment retained for one parsed tbl(7) cell.
52#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
53#[derive(Clone, Copy, Debug, Eq, PartialEq)]
54pub enum TableAlignment {
55    Left,
56    Center,
57    Right,
58}
59
60/// Owned payload of one cell in a libmandoc table row.
61#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
62#[derive(Clone, Debug, Eq, PartialEq)]
63pub struct TableCell {
64    pub text: Option<String>,
65    pub column_span: u16,
66    pub row_span: u16,
67    pub alignment: TableAlignment,
68}
69
70/// Source and renderer flags needed by a lowering or rendering pass.
71#[allow(clippy::struct_excessive_bools)]
72#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
73#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
74pub struct NodeFlags {
75    pub generated: bool,
76    pub sentence_end: bool,
77    pub no_print: bool,
78    pub no_fill: bool,
79    /// libmandoc selected this node as a same-document destination.
80    pub deep_link_target: bool,
81    /// libmandoc renders a self-link for this destination.
82    pub permalink: bool,
83    /// This node begins a roff input line (`NODE_LINE`).
84    ///
85    /// Some man macros keep same-line layout arguments and next-line visible
86    /// content in one syntax head, so source-line role is semantic data.
87    pub line_start: bool,
88    /// This text node is opening punctuation and suppresses spacing after it.
89    pub delimiter_open: bool,
90    /// This text node is closing punctuation and suppresses spacing before it.
91    pub delimiter_close: bool,
92}
93
94/// An owned syntax node with no pointers into the C parser.
95#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
96#[derive(Clone, Debug, Eq, PartialEq)]
97pub struct Node {
98    pub kind: NodeKind,
99    pub macro_name: Option<String>,
100    pub text: Option<String>,
101    /// Canonical same-document tag assigned during libmandoc validation.
102    pub tag: Option<String>,
103    pub line: u32,
104    pub column: u32,
105    pub flags: NodeFlags,
106    pub list_kind: Option<NormalizedListKind>,
107    pub display_kind: Option<DisplayKind>,
108    pub compact: bool,
109    pub offset: Option<String>,
110    /// Normalized mdoc(7) list width, including its roff scale suffix.
111    pub width: Option<String>,
112    pub table_cells: Vec<TableCell>,
113    pub equation: Option<String>,
114    pub children: Vec<Self>,
115}
116
117/// Metadata copied from a completed libmandoc parse.
118#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
119#[derive(Clone, Debug, Default, Eq, PartialEq)]
120pub struct Metadata {
121    pub title: Option<String>,
122    pub section: Option<String>,
123    pub volume: Option<String>,
124    pub os: Option<String>,
125    pub arch: Option<String>,
126    pub name: Option<String>,
127    pub date: Option<String>,
128    pub alias_target: Option<String>,
129    pub has_body: bool,
130}
131
132/// Complete owned output of the low-level parser, excluding diagnostics.
133#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
134#[derive(Clone, Debug, Eq, PartialEq)]
135pub struct Document {
136    pub macro_set: MacroSet,
137    pub metadata: Metadata,
138    pub root: Node,
139}