acorn_lib/powerpoint/
ooxml.rs

1//! ## OOXML data structures
2//!
3//! Data structures for modeling [`OOXML`].
4//!
5//! [`OOXML`]: https://en.wikipedia.org/wiki/Office_Open_XML
6use bon::{builder, Builder};
7use serde::{Deserialize, Serialize};
8use serde_with::skip_serializing_none;
9
10/// OOXML Text Capitalization Type
11///
12/// See <https://datypic.com/sc/ooxml/t-a_ST_TextCapsType.html>
13#[derive(Clone, Debug, Default, Deserialize, Serialize)]
14#[serde(rename_all = "camelCase")]
15pub enum Capitalization {
16    /// No capitalization
17    #[default]
18    #[serde(rename = "none")]
19    NoCap,
20    /// All capitalized
21    All,
22    /// Small caps
23    Small,
24}
25/// OOXML Text Effect
26#[skip_serializing_none]
27#[derive(Clone, Debug, Deserialize, Serialize)]
28#[serde(rename_all = "camelCase")]
29pub enum Effect {
30    /// See <https://datypic.com/sc/ooxml/e-a_blur-1.html>
31    #[serde(rename(serialize = "a:blur", deserialize = "blur"))]
32    Blur {
33        /// Blur radius
34        #[serde(rename = "@rad")]
35        radius: Option<String>,
36        /// Grow bounds
37        #[serde(rename = "@grow")]
38        grow_bounds: Option<String>,
39    },
40    /// See <https://datypic.com/sc/ooxml/e-a_glow-1.html>
41    #[serde(rename(serialize = "a:glow", deserialize = "glow"))]
42    Glow,
43    /// See <https://datypic.com/sc/ooxml/e-a_reflection-1.html>
44    #[serde(rename(serialize = "a:reflection", deserialize = "reflection"))]
45    Reflection,
46}
47/// OOXML Line fill properties
48///
49/// See <https://datypic.com/sc/ooxml/g-a_EG_LineFillProperties.html>
50#[derive(Clone, Debug, Default, Deserialize, Serialize)]
51#[serde(rename_all = "camelCase")]
52pub enum LineFill {
53    /// No fill
54    #[default]
55    #[serde(rename(serialize = "a:noFill", deserialize = "noFill"))]
56    NoFill,
57    /// Solid fill
58    #[serde(rename(serialize = "a:solidFill", deserialize = "solidFill"))]
59    Solid,
60    /// Gradient fill
61    #[serde(rename(serialize = "a:gradFill", deserialize = "gradFill"))]
62    Gradient,
63    /// Pattern fill
64    #[serde(rename(serialize = "a:pattFill", deserialize = "pattFill"))]
65    Pattern,
66}
67/// OOXML Text Strike Type
68///
69/// See <https://datypic.com/sc/ooxml/t-a_ST_TextStrikeType.html>
70#[derive(Clone, Debug, Default, Deserialize, Serialize)]
71#[serde(rename_all = "camelCase")]
72pub enum Strikethrough {
73    /// No strike
74    #[default]
75    #[serde(rename = "noStrike")]
76    NoStrike,
77    /// Single strike
78    #[serde(rename = "sngStrike")]
79    Single,
80    /// Double strike
81    #[serde(rename = "dblStrike")]
82    Double,
83}
84/// OOXML Text Underline Type
85///
86/// See <https://datypic.com/sc/ooxml/g-a_EG_TextUnderlineLine.html>
87#[derive(Clone, Debug, Deserialize, Serialize)]
88#[serde(rename_all = "camelCase")]
89pub enum TextUnderline {
90    /// Underline follows text
91    #[serde(rename(serialize = "a:uLnTx", deserialize = "uLnTx"))]
92    FollowsText,
93    /// Underline stroke
94    #[serde(rename(serialize = "a:uLn", deserialize = "uLn"))]
95    Stroke,
96}
97/// OOXML Bullet Character (`a:buChar`)
98///
99/// See <https://www.datypic.com/sc/ooxml/e-a_buChar-1.html>
100#[derive(Clone, Debug, Deserialize, Serialize)]
101pub struct BulletCharacter {
102    /// Bullet character
103    #[serde(rename = "@char")]
104    pub character: String,
105}
106/// OOXML Bullet Color (`a:buClr`)
107///
108/// See <https://www.datypic.com/sc/ooxml/e-a_buClr-1.html>
109#[derive(Clone, Debug, Deserialize, Serialize)]
110pub struct BulletColor {
111    /// RGB color model - hex variant
112    ///
113    /// See <https://www.datypic.com/sc/ooxml/e-a_srgbClr-1.html>
114    #[serde(rename(serialize = "a:srgbClr", deserialize = "srgbClr"))]
115    pub color: Color,
116}
117/// OOXML Bullet Font (`a:buFont`)
118///
119/// See <https://www.datypic.com/sc/ooxml/e-a_buFont-1.html>
120#[derive(Clone, Debug, Deserialize, Serialize)]
121#[serde(rename_all = "camelCase")]
122pub struct BulletFont {
123    /// Text typeface
124    #[serde(rename = "@typeface")]
125    pub typeface: String,
126    /// Panose setting
127    ///
128    /// See <https://en.wikipedia.org/wiki/PANOSE>
129    #[serde(rename = "@panose")]
130    pub panose: String,
131    /// Similar font family
132    #[serde(rename = "@pitchFamily")]
133    pub similar_font_family: String,
134    /// Similar character set
135    #[serde(rename = "@charset")]
136    pub charset: String,
137}
138/// OOXML RGB Color - Hex variant (`a:srgbClr`)
139///
140/// See <https://www.datypic.com/sc/ooxml/e-a_srgbClr-1.html>
141#[derive(Clone, Debug, Deserialize, Serialize)]
142pub struct Color {
143    /// Hex color
144    #[serde(rename = "@val")]
145    pub value: String,
146}
147/// OOXML Effect Container (`a:effectLst`)
148///
149/// See <https://datypic.com/sc/ooxml/e-a_effectLst-1.html>
150#[skip_serializing_none]
151#[derive(Clone, Debug, Deserialize, Serialize)]
152#[serde(rename_all = "camelCase")]
153pub struct EffectContainer {
154    /// Effects (e.g. blur, glow, etc.)
155    #[serde(rename = "$value")]
156    pub effect: Option<Vec<Effect>>,
157}
158/// OOXML Complex Script Font (`a:cs`)
159///
160/// See <https://www.datypic.com/sc/ooxml/e-a_cs-1.html>
161#[derive(Clone, Debug, Deserialize, Serialize)]
162pub struct FontComplexScript {
163    /// Text typeface
164    #[serde(rename = "@typeface")]
165    pub typeface: String,
166}
167/// OOXML East Asian Font (`a:ea`)
168///
169/// See <https://www.datypic.com/sc/ooxml/e-a_ea-1.html>
170#[derive(Clone, Debug, Deserialize, Serialize)]
171pub struct FontEastAsian {
172    /// Text typeface
173    #[serde(rename = "@typeface")]
174    pub typeface: String,
175}
176/// OOXML Symbol Font (`a:sym`)
177///
178/// See <https://www.datypic.com/sc/ooxml/e-a_sym-1.html>
179#[derive(Clone, Debug, Deserialize, Serialize)]
180pub struct FontSymbol {
181    /// Text typeface
182    #[serde(rename = "@typeface")]
183    pub typeface: String,
184}
185/// OOXML Line (`a:ln`)
186///
187/// See <https://datypic.com/sc/ooxml/e-a_ln-5.html>
188#[skip_serializing_none]
189#[derive(Clone, Debug, Deserialize, Serialize)]
190pub struct Line {
191    #[serde(rename = "$value")]
192    line_fill: LineFill,
193}
194/// Struct for parsing OOXML relationships from .rel files
195#[derive(Clone, Debug, Deserialize, Serialize)]
196#[serde(rename_all = "PascalCase")]
197pub struct Relationships {
198    /// List of relationships
199    pub relationship: Vec<Relationship>,
200}
201/// Relationships describe references from parts to other internal resources in the package or to external resources
202///
203/// See <https://ooxml.info/docs/9/9.2/>
204#[derive(Clone, Debug, Deserialize, Serialize)]
205#[serde(rename_all = "PascalCase")]
206pub struct Relationship {
207    /// Relationship identifier
208    #[serde(rename = "@Id")]
209    pub id: String,
210    /// Relationship type
211    #[serde(rename = "@Type")]
212    pub relationship_type: String,
213    /// Target resource identifier
214    #[serde(rename = "@Target")]
215    pub target: String,
216    /// Target mode
217    #[serde(rename = "@TargetMode")]
218    pub target_mode: Option<String>,
219}
220/// OOXML Text Character Properties (`a:rPr`)
221///
222/// See <https://www.datypic.com/sc/ooxml/e-a_rPr-2.html>
223#[skip_serializing_none]
224#[derive(Builder, Clone, Debug, Deserialize, Serialize)]
225#[builder(start_fn = init)]
226pub struct TextCharacterProperties {
227    /// Baseline
228    #[serde(rename = "@baseline")]
229    pub baseline: Option<String>,
230    /// Bold
231    #[serde(rename = "@b")]
232    pub bold: Option<String>,
233    /// Text capitalization type
234    #[serde(rename = "@cap")]
235    pub capitalization: Option<Capitalization>,
236    /// Dirty
237    #[builder(default = "0".to_string())]
238    #[serde(rename = "@dirty")]
239    pub dirty: String,
240    /// Italic
241    #[serde(rename = "@i")]
242    pub italic: Option<String>,
243    /// Kerning
244    #[builder(default = "0".to_string())]
245    #[serde(rename = "@kern")]
246    pub kerning: String,
247    /// Kumimoji
248    #[serde(rename = "@kumimoji")]
249    pub kumimoji: Option<String>,
250    /// Language identifier
251    #[serde(rename = "@lang")]
252    pub language: Option<String>,
253    /// No proofing
254    #[serde(rename = "@noProof")]
255    pub no_proofing: Option<String>,
256    /// Normalized heights
257    #[serde(rename = "@normalizeH")]
258    pub normalize_heights: Option<String>,
259    /// Spacing
260    #[serde(rename = "@spc")]
261    pub spacing: Option<String>,
262    /// Font size
263    #[serde(rename = "@sz")]
264    pub size: Option<String>,
265    /// Strikethrough
266    #[serde(rename = "@strike")]
267    pub strikethrough: Option<Strikethrough>,
268    /// Underline
269    #[serde(rename = "@u")]
270    pub underline: Option<String>,
271    /// OOXML Line (`a:ln`)
272    ///
273    /// See <https://www.datypic.com/sc/ooxml/e-a_ln-5.html>
274    #[serde(rename(serialize = "a:ln", deserialize = "ln"))]
275    pub line: Option<Line>,
276    /// Effect list
277    #[serde(rename(serialize = "a:effectlst", deserialize = "effectLst"))]
278    pub effect_list: Option<EffectContainer>,
279    /// Underline follows text
280    #[serde(rename(serialize = "a:uLnTx", deserialize = "uLnTx"))]
281    pub underline_follows_text: Option<UnderlineFollowsText>,
282    /// Underline stroke
283    #[serde(rename(serialize = "a:uLn", deserialize = "uLn"))]
284    pub underline_stroke: Option<UnderlineStroke>,
285    /// Underline fill properties follow text
286    #[serde(rename(serialize = "a:uFillTx", deserialize = "uFillTx"))]
287    pub underline_fill_properties_follow_text: Option<UnderlineFillPropertiesFollowText>,
288    /// Underline fill
289    #[serde(rename(serialize = "a:uFill", deserialize = "uFill"))]
290    pub underline_fill: Option<UnderlineFill>,
291    /// Complext script font
292    #[serde(rename(serialize = "a:cs", deserialize = "cs"))]
293    pub font_complex_script: Option<FontComplexScript>,
294    /// East Asian font
295    #[serde(rename(serialize = "a:ea", deserialize = "ea"))]
296    pub font_east_asian: Option<FontEastAsian>,
297    /// Symbol font
298    #[serde(rename(serialize = "a:sym", deserialize = "sym"))]
299    pub font_symbol: Option<FontSymbol>,
300}
301/// OOXML Text Paragraph (`a:p`)
302///
303/// See <https://datypic.com/sc/ooxml/e-a_p-1.html>
304#[skip_serializing_none]
305#[derive(Builder, Clone, Debug, Deserialize, Serialize)]
306#[builder(start_fn = init)]
307#[serde(rename = "a:p")]
308pub struct TextParagraph {
309    /// Text paragraph properties
310    #[builder(default = Vec::new())]
311    #[serde(rename(serialize = "a:pPr", deserialize = "pPr"))]
312    pub text_paragraph_properties: Vec<TextParagraphProperties>,
313    /// Text runs
314    #[builder(default = Vec::new())]
315    #[serde(rename(serialize = "a:r", deserialize = "r"))]
316    pub text_run: Vec<TextRun>,
317    /// OOXML End Paragraph Run Properties (`a:endParaRPr`)
318    ///
319    /// See <https://datypic.com/sc/ooxml/e-a_endParaRPr-1.html>
320    #[serde(rename(serialize = "a:endParaRPr", deserialize = "endParaRPr"))]
321    pub end_paragraph_run_properties: Option<TextCharacterProperties>,
322}
323/// OOXML Text Paragraph Properties (`a:pPr`)
324///
325/// See <https://datypic.com/sc/ooxml/e-a_pPr-1.html>
326#[skip_serializing_none]
327#[derive(Builder, Clone, Debug, Deserialize, Serialize)]
328#[builder(start_fn = init)]
329pub struct TextParagraphProperties {
330    /// Indent
331    #[serde(rename = "@indent")]
332    #[builder(default = "0".to_string())]
333    pub indent: String,
334    /// Left margin
335    #[serde(rename = "@marL")]
336    #[builder(default = "0".to_string())]
337    pub margin_left: String,
338    /// Bullet color
339    #[serde(rename(serialize = "a:buClr", deserialize = "buClr"))]
340    pub bullet_color: Option<BulletColor>,
341    /// Bullet font
342    #[serde(rename(serialize = "a:buFont", deserialize = "buFont"))]
343    pub bullet_font: Option<BulletFont>,
344    /// Bullet character
345    #[serde(rename(serialize = "a:buChar", deserialize = "buChar"))]
346    pub bullet_character: Option<BulletCharacter>,
347    /// Default text run properties
348    #[serde(rename(serialize = "a:defRPr", deserialize = "defRPr"))]
349    pub default_text_run_properties: Option<TextRunPropertiesDefault>,
350}
351/// OOXML Text Run (`a:r`)
352///
353/// See <https://datypic.com/sc/ooxml/e-a_r-1.html>
354#[derive(Builder, Clone, Debug, Deserialize, Serialize)]
355#[builder(start_fn = init)]
356pub struct TextRun {
357    /// Text run properties
358    #[builder(default = Vec::new())]
359    #[serde(rename(serialize = "a:rPr", deserialize = "rPr"))]
360    pub text_run_properties: Vec<TextCharacterProperties>,
361    /// Text
362    #[builder(default = TextString::init().build())]
363    #[serde(rename(serialize = "a:t", deserialize = "t"))]
364    pub text: TextString,
365}
366/// OOXML Default Text Run Properties (`a:defRpr`)
367///
368/// See <https://www.datypic.com/sc/ooxml/e-a_defRPr-1.html>
369#[derive(Clone, Debug, Deserialize, Serialize)]
370pub struct TextRunPropertiesDefault {}
371/// OOXML Text String (`a:t`)
372///
373/// See <https://datypic.com/sc/ooxml/e-a_t-1.html>
374#[derive(Builder, Clone, Debug, Deserialize, Serialize)]
375#[builder(start_fn = init)]
376pub struct TextString {
377    /// Text value
378    #[builder(default = "".to_string())]
379    #[serde(rename = "$text")]
380    pub value: String,
381}
382/// OOXML Underline Fill (`a:uFill`)
383///
384/// See <https://www.datypic.com/sc/ooxml/e-a_uFill-1.html>
385#[derive(Clone, Debug, Deserialize, Serialize)]
386pub struct UnderlineFill {}
387/// OOXML Underline Fill Properties Follow Text (`a:uFillTx`)
388///
389/// See <https://www.datypic.com/sc/ooxml/e-a_uFillTx-1.html>
390#[derive(Clone, Debug, Deserialize, Serialize)]
391pub struct UnderlineFillPropertiesFollowText {}
392/// OOXML Underline Follows Text (`a:uLnTx`)
393///
394/// See <https://datypic.com/sc/ooxml/e-a_uLnTx-1.html>
395#[derive(Clone, Debug, Deserialize, Serialize)]
396pub struct UnderlineFollowsText {}
397/// OOXML Underline Stroke (`a:uLn`)
398///
399/// See <https://www.datypic.com/sc/ooxml/e-a_uLn-1.html>
400#[derive(Clone, Debug, Deserialize, Serialize)]
401pub struct UnderlineStroke {}