1use serde_derive::Serialize;
2use std::path::PathBuf;
3
4use crate::attribute_types::{CanBeEmpty, ID, NameToken};
5#[allow(clippy::wildcard_imports)]
6use crate::element_categories::*;
7use crate::extra_attributes::{self, ExtraAttributes};
8
9pub trait Element {
14 fn ids(&self) -> &Vec<ID>;
16 fn ids_mut(&mut self) -> &mut Vec<ID>;
17 fn names(&self) -> &Vec<NameToken>;
22 fn names_mut(&mut self) -> &mut Vec<NameToken>;
23 fn source(&self) -> &Option<PathBuf>;
24 fn source_mut(&mut self) -> &mut Option<PathBuf>;
25 fn classes(&self) -> &Vec<String>;
26 fn classes_mut(&mut self) -> &mut Vec<String>;
27}
28
29#[derive(Debug, Default, PartialEq, Serialize, Clone)]
30pub struct CommonAttributes {
31 #[serde(skip_serializing_if = "CanBeEmpty::is_empty")]
32 ids: Vec<ID>,
33 #[serde(skip_serializing_if = "CanBeEmpty::is_empty")]
34 names: Vec<NameToken>,
35 #[serde(skip_serializing_if = "CanBeEmpty::is_empty")]
36 source: Option<PathBuf>,
37 #[serde(skip_serializing_if = "CanBeEmpty::is_empty")]
38 classes: Vec<String>,
39 }
41
42macro_rules! impl_element {
47 ($name:ident) => {
48 impl Element for $name {
49 fn ids(&self) -> &Vec<ID> {
50 &self.common.ids
51 }
52 fn ids_mut(&mut self) -> &mut Vec<ID> {
53 &mut self.common.ids
54 }
55 fn names(&self) -> &Vec<NameToken> {
56 &self.common.names
57 }
58 fn names_mut(&mut self) -> &mut Vec<NameToken> {
59 &mut self.common.names
60 }
61 fn source(&self) -> &Option<PathBuf> {
62 &self.common.source
63 }
64 fn source_mut(&mut self) -> &mut Option<PathBuf> {
65 &mut self.common.source
66 }
67 fn classes(&self) -> &Vec<String> {
68 &self.common.classes
69 }
70 fn classes_mut(&mut self) -> &mut Vec<String> {
71 &mut self.common.classes
72 }
73 }
74 };
75}
76
77macro_rules! impl_children {
78 ($name:ident, $childtype:ident) => {
79 impl HasChildren<$childtype> for $name {
80 #[allow(clippy::needless_update)]
81 fn with_children(children: Vec<$childtype>) -> $name {
82 $name {
83 children,
84 ..Default::default()
85 }
86 }
87 fn children(&self) -> &Vec<$childtype> {
88 &self.children
89 }
90 fn children_mut(&mut self) -> &mut Vec<$childtype> {
91 &mut self.children
92 }
93 }
94 };
95}
96
97macro_rules! impl_extra { ($name:ident $($more:tt)*) => (
98 impl ExtraAttributes<extra_attributes::$name> for $name {
99 #[allow(clippy::needless_update)]
100 fn with_extra(extra: extra_attributes::$name) -> $name { $name { common: Default::default(), extra $($more)* } }
101 fn extra (& self) -> & extra_attributes::$name { & self.extra }
102 fn extra_mut(&mut self) -> &mut extra_attributes::$name { &mut self.extra }
103 }
104)}
105
106#[allow(dead_code)]
107trait HasExtraAndChildren<C, A> {
108 fn with_extra_and_children(extra: A, children: Vec<C>) -> Self;
109}
110
111impl<T, C, A> HasExtraAndChildren<C, A> for T
112where
113 T: HasChildren<C> + ExtraAttributes<A>,
114{
115 #[allow(clippy::needless_update)]
116 fn with_extra_and_children(extra: A, mut children: Vec<C>) -> Self {
117 let mut r = Self::with_extra(extra);
118 r.children_mut().append(&mut children);
119 r
120 }
121}
122
123macro_rules! impl_new {(
124 $(#[$attr:meta])*
125 pub struct $name:ident { $(
126 $(#[$fattr:meta])*
127 $field:ident : $typ:path
128 ),* $(,)* }
129) => (
130 $(#[$attr])*
131 #[derive(Debug,PartialEq,Serialize,Clone)]
132 pub struct $name { $(
133 $(#[$fattr])* $field: $typ,
134 )* }
135 impl $name {
136 #[must_use]
137 pub fn new( $( $field: $typ, )* ) -> $name { $name { $( $field, )* } }
138 }
139)}
140
141macro_rules! impl_elem {
142 ($name:ident) => {
143 impl_new!(
144 #[derive(Default)]
145 pub struct $name {
146 #[serde(flatten)]
147 common: CommonAttributes,
148 }
149 );
150 impl_element!($name);
151 };
152 ($name:ident; +) => {
153 impl_new!(
154 #[derive(Default)]
155 pub struct $name {
156 #[serde(flatten)]
157 common: CommonAttributes,
158 #[serde(flatten)]
159 extra: extra_attributes::$name,
160 }
161 );
162 impl_element!($name);
163 impl_extra!($name, ..Default::default());
164 };
165 ($name:ident; *) => {
166 impl_new!(
168 pub struct $name {
169 #[serde(flatten)]
170 common: CommonAttributes,
171 #[serde(flatten)]
172 extra: extra_attributes::$name,
173 }
174 );
175 impl_element!($name);
176 impl_extra!($name);
177 };
178 ($name:ident, $childtype:ident) => {
179 impl_new!(
180 #[derive(Default)]
181 pub struct $name {
182 #[serde(flatten)]
183 common: CommonAttributes,
184 children: Vec<$childtype>,
185 }
186 );
187 impl_element!($name);
188 impl_children!($name, $childtype);
189 };
190 ($name:ident, $childtype:ident; +) => {
191 impl_new!(
192 #[derive(Default)]
193 pub struct $name {
194 #[serde(flatten)]
195 common: CommonAttributes,
196 #[serde(flatten)]
197 extra: extra_attributes::$name,
198 children: Vec<$childtype>,
199 }
200 );
201 impl_element!($name);
202 impl_extra!($name, ..Default::default());
203 impl_children!($name, $childtype);
204 };
205}
206
207macro_rules! impl_elems { ( $( ($($args:tt)*) )* ) => (
208 $( impl_elem!($($args)*); )*
209)}
210
211#[derive(Default, Debug, Serialize)]
212pub struct Document {
213 children: Vec<StructuralSubElement>,
214}
215impl_children!(Document, StructuralSubElement);
216
217impl_elems!(
218 (Section, StructuralSubElement)
220 (Topic, SubTopic)
221 (Sidebar, SubSidebar)
222
223 (Title, TextOrInlineElement)
225 (Subtitle, TextOrInlineElement)
226 (Decoration, DecorationElement)
227 (Docinfo, BibliographicElement)
228 (Transition)
229
230 (Author, TextOrInlineElement)
232 (Authors, AuthorInfo)
233 (Organization, TextOrInlineElement)
234 (Address, TextOrInlineElement; +)
235 (Contact, TextOrInlineElement)
236 (Version, TextOrInlineElement)
237 (Revision, TextOrInlineElement)
238 (Status, TextOrInlineElement)
239 (Date, TextOrInlineElement)
240 (Copyright, TextOrInlineElement)
241 (Field, SubField)
242
243 (Header, BodyElement)
245 (Footer, BodyElement)
246
247 (Paragraph, TextOrInlineElement)
249 (LiteralBlock, TextOrInlineElement; +)
250 (DoctestBlock, TextOrInlineElement; +)
251 (MathBlock, String)
252 (Rubric, TextOrInlineElement)
253 (SubstitutionDefinition, TextOrInlineElement; +)
254 (Comment, TextOrInlineElement; +)
255 (Pending)
256 (Target; +)
257 (Raw, String; +)
258 (Image; *)
259
260 (Compound, BodyElement)
262 (Container, BodyElement)
263
264 (BulletList, ListItem; +)
265 (EnumeratedList, ListItem; +)
266 (DefinitionList, DefinitionListItem)
267 (FieldList, Field)
268 (OptionList, OptionListItem)
269
270 (LineBlock, SubLineBlock)
271 (BlockQuote, SubBlockQuote)
272 (Admonition, SubTopic)
273 (Attention, BodyElement)
274 (Hint, BodyElement)
275 (Note, BodyElement)
276 (Caution, BodyElement)
277 (Danger, BodyElement)
278 (Error, BodyElement)
279 (Important, BodyElement)
280 (Tip, BodyElement)
281 (Warning, BodyElement)
282 (Footnote, SubFootnote; +)
283 (Citation, SubFootnote; +)
284 (SystemMessage, BodyElement; +)
285 (Figure, SubFigure; +)
286 (Table, SubTable; +)
287
288 (TableGroup, SubTableGroup; +)
290 (TableHead, TableRow; +)
291 (TableBody, TableRow; +)
292 (TableRow, TableEntry; +)
293 (TableEntry, BodyElement; +)
294 (TableColspec; +)
295
296 (ListItem, BodyElement)
298
299 (DefinitionListItem, SubDLItem)
300 (Term, TextOrInlineElement)
301 (Classifier, TextOrInlineElement)
302 (Definition, BodyElement)
303
304 (FieldName, TextOrInlineElement)
305 (FieldBody, BodyElement)
306
307 (OptionListItem, SubOptionListItem)
308 (OptionGroup, Option_)
309 (Description, BodyElement)
310 (Option_, SubOption)
311 (OptionString, String)
312 (OptionArgument, String; +)
313
314 (Line, TextOrInlineElement)
315 (Attribution, TextOrInlineElement)
316 (Label, TextOrInlineElement)
317
318 (Caption, TextOrInlineElement)
319 (Legend, BodyElement)
320
321 (Emphasis, TextOrInlineElement)
323 (Literal, String)
324 (Reference, TextOrInlineElement; +)
325 (Strong, TextOrInlineElement)
326 (FootnoteReference, TextOrInlineElement; +)
327 (CitationReference, TextOrInlineElement; +)
328 (SubstitutionReference, TextOrInlineElement; +)
329 (TitleReference, TextOrInlineElement)
330 (Abbreviation, TextOrInlineElement)
331 (Acronym, TextOrInlineElement)
332 (Superscript, TextOrInlineElement)
333 (Subscript, TextOrInlineElement)
334 (Inline, TextOrInlineElement)
335 (Problematic, TextOrInlineElement; +)
336 (Generated, TextOrInlineElement)
337 (Math, String)
338
339 (TargetInline, String; +)
341 (RawInline, String; +)
342 (ImageInline; *)
343
344 );
346
347impl<'a> From<&'a str> for TextOrInlineElement {
348 fn from(s: &'a str) -> Self {
349 s.to_owned().into()
350 }
351}
352
353impl Footnote {
354 pub fn get_label(&self) -> Result<&str, anyhow::Error> {
359 use anyhow::{Context, bail};
360
361 let SubFootnote::Label(e) = self
362 .children()
363 .first()
364 .context("Footnote has no children")?
365 else {
366 bail!("Non-auto footnote has no label");
367 };
368 match e
369 .children()
370 .first()
371 .context("Footnote label has no child")?
372 {
373 TextOrInlineElement::String(s) => Ok(s.as_ref()),
374 _ => bail!("Footnote label is not a string"),
375 }
376 }
377}