acdc_parser/model/inlines/
macros.rs

1use std::collections::HashSet;
2
3use serde::{Deserialize, Serialize};
4
5use crate::{ElementAttributes, InlineNode, Location, Source, StemNotation, Substitution};
6
7pub const ICON_SIZES: &[&str] = &["1x", "2x", "3x", "4x", "5x", "lg", "fw"];
8
9/// A `Pass` represents a passthrough macro in a document.
10#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
11#[non_exhaustive]
12pub struct Pass {
13    #[serde(default, skip_serializing_if = "Option::is_none")]
14    pub text: Option<String>,
15    #[serde(default, skip_serializing_if = "HashSet::is_empty")]
16    pub substitutions: HashSet<Substitution>,
17    pub location: Location,
18    #[serde(skip)]
19    pub kind: PassthroughKind,
20}
21
22#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Default)]
23pub enum PassthroughKind {
24    #[default]
25    Single,
26    Double,
27    Triple,
28    Macro,
29}
30
31/// A `Footnote` represents an inline footnote in a document.
32#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
33#[non_exhaustive]
34pub struct Footnote {
35    #[serde(default, skip_serializing_if = "Option::is_none")]
36    pub id: Option<String>,
37    #[serde(default, skip_serializing_if = "Vec::is_empty")]
38    pub content: Vec<InlineNode>,
39    #[serde(skip)]
40    pub number: u32,
41    pub location: Location,
42}
43
44/// An `Icon` represents an inline icon in a document.
45#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
46#[non_exhaustive]
47pub struct Icon {
48    pub target: Source,
49    pub attributes: ElementAttributes,
50    pub location: Location,
51}
52
53/// A `Link` represents an inline link in a document.
54#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
55#[non_exhaustive]
56pub struct Link {
57    // We don't serialize the text here because it's already serialized in the attributes
58    // (that's how it's represented in the ASG)
59    #[serde(skip_serializing)]
60    pub text: Option<String>,
61    pub target: Source,
62    pub attributes: ElementAttributes,
63    pub location: Location,
64}
65
66impl Link {
67    /// Creates a new `Link` with the given target.
68    #[must_use]
69    pub fn new(target: Source, location: Location) -> Self {
70        Self {
71            text: None,
72            target,
73            attributes: ElementAttributes::default(),
74            location,
75        }
76    }
77
78    /// Sets the link text.
79    #[must_use]
80    pub fn with_text(mut self, text: Option<String>) -> Self {
81        self.text = text;
82        self
83    }
84
85    /// Sets the link attributes.
86    #[must_use]
87    pub fn with_attributes(mut self, attributes: ElementAttributes) -> Self {
88        self.attributes = attributes;
89        self
90    }
91}
92
93/// An `Url` represents an inline URL in a document.
94#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
95#[non_exhaustive]
96pub struct Url {
97    // We don't serialize the text here because it's already serialized in the attributes
98    // (that's how it's represented in the ASG)
99    #[serde(skip_serializing)]
100    pub text: Vec<InlineNode>,
101    pub target: Source,
102    pub attributes: ElementAttributes,
103    pub location: Location,
104}
105
106/// An `Mailto` represents an inline `mailto:` in a document.
107#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
108#[non_exhaustive]
109pub struct Mailto {
110    // We don't serialize the text here because it's already serialized in the attributes
111    // (that's how it's represented in the ASG)
112    #[serde(skip_serializing)]
113    pub text: Vec<InlineNode>,
114    pub target: Source,
115    pub attributes: ElementAttributes,
116    pub location: Location,
117}
118
119/// A `Button` represents an inline button in a document.
120#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
121#[non_exhaustive]
122pub struct Button {
123    pub label: String,
124    pub location: Location,
125}
126
127/// A `Menu` represents an inline menu in a document.
128#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
129#[non_exhaustive]
130pub struct Menu {
131    pub target: String,
132    #[serde(default, skip_serializing_if = "Vec::is_empty")]
133    pub items: Vec<String>,
134    pub location: Location,
135}
136
137/// A `Keyboard` represents an inline keyboard shortcut in a document.
138#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
139#[non_exhaustive]
140pub struct Keyboard {
141    pub keys: Vec<Key>,
142    pub location: Location,
143}
144
145impl Keyboard {
146    /// Creates a new `Keyboard` with the given keys.
147    #[must_use]
148    pub fn new(keys: Vec<Key>, location: Location) -> Self {
149        Self { keys, location }
150    }
151}
152
153// TODO(nlopes): this could perhaps be an enum instead with the allowed keys
154pub type Key = String;
155
156/// A `CrossReference` represents an inline cross-reference (xref) in a document.
157#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
158#[non_exhaustive]
159pub struct CrossReference {
160    pub target: String,
161    #[serde(default, skip_serializing_if = "Option::is_none")]
162    pub text: Option<String>,
163    pub location: Location,
164}
165
166impl CrossReference {
167    /// Creates a new `CrossReference` with the given target.
168    #[must_use]
169    pub fn new(target: impl Into<String>, location: Location) -> Self {
170        Self {
171            target: target.into(),
172            text: None,
173            location,
174        }
175    }
176
177    /// Sets the cross-reference display text.
178    #[must_use]
179    pub fn with_text(mut self, text: Option<String>) -> Self {
180        self.text = text;
181        self
182    }
183}
184
185/// An `Autolink` represents an inline autolink in a document.
186#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
187#[non_exhaustive]
188pub struct Autolink {
189    pub url: Source,
190    /// Whether the autolink was written with angle brackets (e.g., `<user@example.com>`).
191    /// When true, the renderer should preserve the brackets in the output.
192    #[serde(default, skip_serializing_if = "std::ops::Not::not")]
193    pub bracketed: bool,
194    pub location: Location,
195}
196
197/// A `Stem` represents an inline mathematical expression.
198#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
199#[non_exhaustive]
200pub struct Stem {
201    pub content: String,
202    pub notation: StemNotation,
203    pub location: Location,
204}