docx_rust/document/
footnotes.rs1use hard_xml::{XmlRead, XmlResult, XmlWrite, XmlWriter};
7use std::borrow::Cow;
8use std::io::Write;
9
10use crate::schema::{SCHEMA_MAIN, SCHEMA_WORDML_14};
11use crate::{__string_enum, __xml_test_suites};
12
13use crate::document::BodyContent;
14
15#[derive(Debug, Default, XmlRead, Clone)]
16#[cfg_attr(test, derive(PartialEq))]
17#[xml(tag = "w:footnotes")]
18pub struct FootNotes<'a> {
19 #[xml(child = "w:footnote")]
20 pub content: Vec<FootNote<'a>>,
21}
22
23#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
24#[cfg_attr(test, derive(PartialEq))]
25#[xml(tag = "w:footnote")]
26pub struct FootNote<'a> {
27 #[xml(attr = "w:type")]
28 pub ty: Option<NoteSeparator>,
29 #[xml(attr = "w:id")]
30 pub id: Option<isize>,
31 #[xml(child = "w:sdt", child = "w:p", child = "w:tbl", child = "w:sectPr")]
32 pub content: Vec<BodyContent<'a>>,
33}
34
35#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
36#[cfg_attr(test, derive(PartialEq))]
37#[xml(tag = "w:footnoteRef")]
38pub struct FootnoteRef;
39
40#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
41#[cfg_attr(test, derive(PartialEq))]
42#[xml(tag = "w:footnoteReference")]
43pub struct FootnoteReference<'a> {
44 #[xml(attr = "w:customMarkFollows")]
46 pub supress_reference_mark: Option<bool>,
47 #[xml(attr = "w:id")]
48 pub id: Option<Cow<'a, str>>,
49}
50
51impl<'a> FootNote<'a> {
52 pub fn push<T: Into<BodyContent<'a>>>(&mut self, content: T) -> &mut Self {
53 self.content.push(content.into());
54 self
55 }
56}
57
58impl<'a> XmlWrite for FootNotes<'a> {
59 fn to_writer<W: Write>(&self, writer: &mut XmlWriter<W>) -> XmlResult<()> {
60 let FootNotes { content } = self;
61
62 log::debug!("[FootNotes] Started writing.");
63 let _ = write!(writer.inner, "{}", crate::schema::SCHEMA_XML);
64
65 writer.write_element_start("w:footnotes")?;
66
67 writer.write_attribute("xmlns:w", SCHEMA_MAIN)?;
68
69 writer.write_attribute("xmlns:w14", SCHEMA_WORDML_14)?;
70
71 writer.write_element_end_open()?;
72
73 for c in content {
74 c.to_writer(writer)?;
75 }
76
77 writer.write_element_end_close("w:footnotes")?;
78
79 log::debug!("[Document] Finished writing.");
80
81 Ok(())
82 }
83}
84
85#[derive(Debug, Clone)]
86#[cfg_attr(test, derive(PartialEq))]
87pub enum NoteSeparator {
88 Separator,
89 ContinuationSeparator,
90 ContinuationNotice,
91}
92
93__string_enum! {
94 NoteSeparator {
95 Separator = "separator",
96 ContinuationSeparator = "continuationSeparator",
97 ContinuationNotice = "continuationNotice",
98 }
99}
100
101__xml_test_suites!(
102 FootNotes,
103 FootNotes::default(),
104 format!(
105 r#"{}<w:footnotes xmlns:w="{}" xmlns:w14="{}"></w:footnotes>"#,
106 crate::schema::SCHEMA_XML,
107 SCHEMA_MAIN,
108 SCHEMA_WORDML_14
109 )
110 .as_str(),
111);