rust_texas/component/
mod.rs

1use crate::prelude::*;
2
3// Re-exports for compatibility.
4pub use beamer::*;
5pub use builtin::*;
6pub use envs::*;
7pub use hierarchy::*;
8pub use image::*;
9// use markdown::mdast::Node;
10pub use misc::*;
11pub use table::*;
12pub use textchunk::*;
13
14/// One of the main structs, almost everything you put into a document is a `Component`
15#[derive(Debug, Clone)]
16pub enum Component {
17    Part(Part),
18    Chapter(Chapter),
19    Section(Section),
20    Subsection(Subsection),
21    Paragraph(Paragraph),
22    Line(Line),
23
24    Frame(Frame),
25    Block(Block),
26
27    Input(Input),
28
29    Environment(Environment),
30    List(List),
31    Figure(Figure),
32
33    TextChunk(TextChunk),
34    // #[cfg(feature = "markdown")]
35    // Markdown(MarkdownChunk),
36    Command(String),
37
38    /// Outside the figure environment. Sometimes useful.
39    Image(Image),
40
41    Table(Table),
42    Row(Row),
43
44    Builtin(Builtin),
45
46    Label(Label),
47    Reference(Reference),
48    // Dummy(Vec<Component>)
49}
50
51pub mod beamer;
52pub mod builtin;
53pub mod envs;
54pub mod hierarchy;
55pub mod image;
56pub mod misc;
57pub mod table;
58pub mod textchunk;
59
60impl Component {
61    pub fn rank(&self) -> u8 {
62        match &self {
63            Component::Part(_) => 0,
64            Component::Chapter(_) => 1,
65            Component::Section(_) => 2,
66            // #[cfg(feature = "markdown")]
67            // Component::Markdown(_) => 2,
68            Component::Subsection(_) => 3,
69            Component::Paragraph(_) => 5,
70            Component::Line(_) => 10,
71            Component::Frame(_) => 4,
72            Component::Block(_) => 5,
73
74            Component::Input(_) => 9,
75
76            Component::Environment(_) => 8,
77            Component::List(_) => 7,
78            Component::Figure(_) => 8,
79
80            Component::TextChunk(_) => 10,
81
82            Component::Command(_) => 10,
83
84            Component::Image(_) => 10,
85
86            Component::Table(_) => 7,
87
88            Component::Row(_) => 10,
89
90            Component::Builtin(_) => 10,
91            Component::Label(_) => 10,
92            Component::Reference(_) => 10,
93        }
94    }
95}
96impl AsLatex for Component {
97    fn to_string(&self) -> String {
98        match &self {
99            Component::Part(stuff) => stuff.to_string(),
100            Component::Chapter(stuff) => stuff.to_string(),
101            Component::Section(stuff) => stuff.to_string(),
102            Component::Frame(stuff) => stuff.to_string(),
103            Component::Block(stuff) => stuff.to_string(),
104            Component::Paragraph(stuff) => stuff.to_string(),
105            Component::Line(stuff) => stuff.to_string(),
106            Component::Input(stuff) => stuff.to_string(),
107            Component::Environment(stuff) => stuff.to_string(),
108            Component::List(stuff) => stuff.to_string(),
109            Component::TextChunk(stuff) => stuff.to_string(),
110            Component::Command(stuff) => stuff.to_string(),
111            Component::Subsection(stuff) => stuff.to_string(),
112            Component::Image(stuff) => stuff.to_string(),
113            Component::Row(stuff) => stuff.to_string(),
114            Component::Table(stuff) => stuff.to_string(),
115            Component::Builtin(stuff) => stuff.to_string(),
116            Component::Figure(stuff) => stuff.to_string(),
117            Component::Label(stuff) => stuff.to_string(),
118            Component::Reference(stuff) => stuff.to_string(),
119            // #[cfg(feature = "markdown")]
120            // Component::Markdown(stuff) => stuff.to_string(),
121        }
122    }
123}
124impl Populate for Component {
125    fn attach(&mut self, other: Component) -> TexResult<&mut Self> {
126        // assert!(self.rank() >= other.rank());
127        if self.rank() > other.rank() {
128            return Err(TexError::RankMismatch(other.rank(), self.rank()).into());
129        }
130        match self {
131            Component::Part(stuff) => {
132                stuff.attach(other)?;
133            }
134            Component::Chapter(stuff) => {
135                stuff.attach(other)?;
136            }
137            Component::Section(stuff) => {
138                stuff.attach(other)?;
139            }
140            Component::Frame(stuff) => {
141                stuff.attach(other)?;
142            }
143            Component::Block(stuff) => {
144                stuff.attach(other)?;
145            }
146            Component::Subsection(stuff) => {
147                stuff.attach(other)?;
148            }
149            Component::Paragraph(stuff) => {
150                stuff.attach(other)?;
151            }
152            Component::Line(stuff) => {
153                stuff.attach(other)?;
154            }
155            Component::Environment(stuff) => {
156                stuff.attach(other)?;
157            }
158            Component::List(stuff) => {
159                stuff.attach(other)?;
160            }
161            Component::TextChunk(stuff) => {
162                stuff.attach(other)?;
163            }
164            Component::Row(stuff) => {
165                stuff.attach(other)?;
166            }
167            Component::Table(stuff) => {
168                stuff.attach(other)?;
169            }
170            _ => {
171                return Err(TexError::TraitUnimplemented(format!("{:?}", &self)).into());
172            }
173        };
174
175        Ok(self)
176    }
177
178    fn attach_vec(&mut self, other: Vec<Component>) -> TexResult<&mut Self> {
179        let q = other.iter().map(|x| x.rank()).max().unwrap();
180        if self.rank() > q {
181            // dbg!(self.rank());
182            // dbg!(q);
183
184            return Err(TexError::RankMismatch(q, self.rank()).into());
185        }
186        match self {
187            Component::Part(stuff) => {
188                stuff.attach_vec(other)?;
189            }
190            Component::Chapter(stuff) => {
191                stuff.attach_vec(other)?;
192            }
193            Component::Section(stuff) => {
194                stuff.attach_vec(other)?;
195            }
196            Component::Frame(stuff) => {
197                stuff.attach_vec(other)?;
198            }
199            Component::Block(stuff) => {
200                stuff.attach_vec(other)?;
201            }
202            Component::Paragraph(stuff) => {
203                stuff.attach_vec(other)?;
204            }
205            Component::Line(stuff) => {
206                stuff.attach_vec(other)?;
207            }
208            Component::Environment(stuff) => {
209                stuff.attach_vec(other)?;
210            }
211            Component::List(stuff) => {
212                stuff.attach_vec(other)?;
213            }
214            Component::TextChunk(stuff) => {
215                stuff.attach_vec(other)?;
216            }
217            Component::Subsection(stuff) => {
218                stuff.attach_vec(other)?;
219            }
220            Component::Row(stuff) => {
221                stuff.attach_vec(other)?;
222            }
223            Component::Table(stuff) => {
224                stuff.attach_vec(other)?;
225            }
226            _ => {
227                return Err(TexError::TraitUnimplemented(format!("{:?}", &self)).into());
228            }
229        };
230
231        Ok(self)
232    }
233
234    fn attach_iter<I: Iterator<Item = Component>>(&mut self, mut other: I) -> TexResult<&mut Self> {
235        // let q = other.map(|x| x.rank()).max().unwrap();
236        if other.any(|x| x.rank() < self.rank()) {
237            // dbg!(self.rank());
238            // dbg!(q);
239
240            return Err(TexError::RankMismatch(
241                other.max_by_key(|x| x.rank()).unwrap().rank(),
242                self.rank(),
243            )
244            .into());
245        }
246        match self {
247            Component::Part(stuff) => {
248                stuff.attach_iter(other)?;
249            }
250            Component::Chapter(stuff) => {
251                stuff.attach_iter(other)?;
252            }
253            Component::Section(stuff) => {
254                stuff.attach_iter(other)?;
255            }
256            Component::Frame(stuff) => {
257                stuff.attach_iter(other)?;
258            }
259            Component::Block(stuff) => {
260                stuff.attach_iter(other)?;
261            }
262            Component::Paragraph(stuff) => {
263                stuff.attach_iter(other)?;
264            }
265            Component::Line(stuff) => {
266                stuff.attach_iter(other)?;
267            }
268            Component::Environment(stuff) => {
269                stuff.attach_iter(other)?;
270            }
271            Component::List(stuff) => {
272                stuff.attach_iter(other)?;
273            }
274            Component::TextChunk(stuff) => {
275                stuff.attach_iter(other)?;
276            }
277            Component::Subsection(stuff) => {
278                stuff.attach_iter(other)?;
279            }
280            Component::Row(stuff) => {
281                stuff.attach_iter(other)?;
282            }
283            Component::Table(stuff) => {
284                stuff.attach_iter(other)?;
285            }
286            _ => {
287                return Err(TexError::TraitUnimplemented(format!("{:?}", &self)).into());
288            }
289        };
290
291        Ok(self)
292    }
293}