spreadsheet_ods/style/
units.rs

1//!
2//! All kinds of units for use in style attributes.
3//!
4
5use crate::style::ParseStyleAttr;
6use crate::OdsError;
7use get_size2::GetSize;
8use std::fmt::{Display, Formatter};
9
10/// An angle, as defined in §4.1 of SVG, is a double value that may be followed immediately by one
11/// of the following angle unit identifiers: deg (degrees), grad (gradiants) or rad (radians). If no unit
12/// identifier is specified, the value is assumed to be in degrees.
13/// Note: OpenDocument v1.1 did not support angle specifications that contain an angle unit
14/// identifier. Angle unit identifiers should be omitted for compatibility with OpenDocument v1.1
15#[derive(Debug, Clone, Copy, PartialEq)]
16pub enum Angle {
17    /// Degrees
18    Deg(f64),
19    /// Grad degrees.
20    Grad(f64),
21    /// Radiant.
22    Rad(f64),
23}
24
25impl Display for Angle {
26    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
27        match self {
28            Angle::Deg(v) => write!(f, "{}deg", v),
29            Angle::Grad(v) => write!(f, "{}grad", v),
30            Angle::Rad(v) => write!(f, "{}rad", v),
31        }
32    }
33}
34
35/// A (positive or negative) length, consisting of magnitude and unit, in conformance with the Units of
36/// Measure defined in §5.9.13 of XSL.
37#[derive(Debug, Clone, Copy, PartialEq, Default, GetSize)]
38pub enum Length {
39    /// Unspecified length, the actual value is some default or whatever.
40    #[default]
41    Default,
42    /// cm
43    Cm(f64),
44    /// mm
45    Mm(f64),
46    /// inch
47    In(f64),
48    /// typographic points
49    Pt(f64),
50    /// pica
51    Pc(f64),
52    /// em
53    Em(f64),
54}
55
56impl Length {
57    /// Is the length positive.
58    pub fn is_positive(&self) -> bool {
59        0f64 <= match self {
60            Length::Default => 0f64,
61            Length::Cm(v) => *v,
62            Length::Mm(v) => *v,
63            Length::In(v) => *v,
64            Length::Pt(v) => *v,
65            Length::Pc(v) => *v,
66            Length::Em(v) => *v,
67        }
68    }
69}
70
71impl Display for Length {
72    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
73        match self {
74            Length::Cm(v) => write!(f, "{}cm", v),
75            Length::Mm(v) => write!(f, "{}mm", v),
76            Length::In(v) => write!(f, "{}in", v),
77            Length::Pt(v) => write!(f, "{}pt", v),
78            Length::Pc(v) => write!(f, "{}pc", v),
79            Length::Em(v) => write!(f, "{}em", v),
80            Length::Default => write!(f, ""),
81        }
82    }
83}
84
85impl ParseStyleAttr<Length> for Length {
86    fn parse_attr(attr: Option<&str>) -> Result<Option<Length>, OdsError> {
87        if let Some(s) = attr {
88            if s.ends_with("cm") {
89                Ok(Some(Length::Cm(s.split_at(s.len() - 2).0.parse()?)))
90            } else if s.ends_with("mm") {
91                Ok(Some(Length::Mm(s.split_at(s.len() - 2).0.parse()?)))
92            } else if s.ends_with("in") {
93                Ok(Some(Length::In(s.split_at(s.len() - 2).0.parse()?)))
94            } else if s.ends_with("pt") {
95                Ok(Some(Length::Pt(s.split_at(s.len() - 2).0.parse()?)))
96            } else if s.ends_with("pc") {
97                Ok(Some(Length::Pc(s.split_at(s.len() - 2).0.parse()?)))
98            } else if s.ends_with("em") {
99                Ok(Some(Length::Em(s.split_at(s.len() - 2).0.parse()?)))
100            } else {
101                Err(OdsError::Parse("invalid length", Some(s.to_string())))
102            }
103        } else {
104            Ok(None)
105        }
106    }
107}
108
109/// (Positive or negative) percentage values in conformance with §5.9.11 of XSL.
110#[derive(Debug, Clone, Copy, PartialEq)]
111pub enum Percent {
112    /// Percentage
113    Percent(f64),
114}
115
116impl Display for Percent {
117    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
118        match self {
119            Percent::Percent(v) => write!(f, "{}%", v),
120        }
121    }
122}
123
124/// Length or percentage.
125#[derive(Debug, Clone, Copy, PartialEq)]
126#[allow(missing_docs)]
127pub enum LengthPercent {
128    Length(Length),
129    Percent(Percent),
130}
131
132impl From<Length> for LengthPercent {
133    fn from(value: Length) -> Self {
134        LengthPercent::Length(value)
135    }
136}
137
138impl From<Percent> for LengthPercent {
139    fn from(value: Percent) -> Self {
140        LengthPercent::Percent(value)
141    }
142}
143
144impl Display for LengthPercent {
145    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
146        match self {
147            LengthPercent::Length(v) => write!(f, "{}", v),
148            LengthPercent::Percent(v) => write!(f, "{}", v),
149        }
150    }
151}
152
153/// 19.348 number:format-source
154///
155/// The number:format-source attribute specifies the source of definitions of the short and
156/// long display formats.
157///
158/// The defined values for the number:format-source attribute are:
159/// * fixed: the values short and long of the number:style attribute are defined by this
160///   standard.
161/// * language: the meaning of the values long and short of the number:style attribute
162///   depend upon the number:language and number:country attributes of the date style. If
163///   neither of those attributes are specified, consumers should use their default locale for short
164///   and long date and time formats.
165///
166/// The default value for this attribute is fixed.
167#[derive(Debug, Clone, Copy, Eq, PartialEq)]
168#[allow(missing_docs)]
169pub enum FormatSource {
170    Fixed,
171    Language,
172}
173
174impl Display for FormatSource {
175    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
176        match self {
177            FormatSource::Fixed => write!(f, "fixed"),
178            FormatSource::Language => write!(f, "language"),
179        }
180    }
181}
182
183impl ParseStyleAttr<FormatSource> for FormatSource {
184    fn parse_attr(attr: Option<&str>) -> Result<Option<FormatSource>, OdsError> {
185        if let Some(attr) = attr {
186            match attr {
187                "fixed" => Ok(Some(FormatSource::Fixed)),
188                "language" => Ok(Some(FormatSource::Language)),
189                _ => Err(OdsError::Parse(
190                    "invalid format source",
191                    Some(attr.to_string()),
192                )),
193            }
194        } else {
195            Ok(None)
196        }
197    }
198}
199
200/// 19.368 number:transliteration-style
201///
202/// The number:transliteration-style attribute specifies the transliteration format of a
203/// number system.
204///
205/// The semantics of the values of the number:transliteration-style attribute are locale- and
206/// implementation-dependent.
207///
208/// The default value for this attribute is short.
209#[derive(Debug, Clone, Copy, Eq, PartialEq)]
210#[allow(missing_docs)]
211pub enum TransliterationStyle {
212    Short,
213    Medium,
214    Long,
215}
216
217impl Display for TransliterationStyle {
218    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
219        match self {
220            TransliterationStyle::Short => write!(f, "short"),
221            TransliterationStyle::Medium => write!(f, "medium"),
222            TransliterationStyle::Long => write!(f, "long"),
223        }
224    }
225}
226
227impl ParseStyleAttr<TransliterationStyle> for TransliterationStyle {
228    fn parse_attr(attr: Option<&str>) -> Result<Option<TransliterationStyle>, OdsError> {
229        if let Some(attr) = attr {
230            match attr {
231                "short" => Ok(Some(TransliterationStyle::Short)),
232                "medium" => Ok(Some(TransliterationStyle::Medium)),
233                "long" => Ok(Some(TransliterationStyle::Long)),
234                _ => Err(OdsError::Parse(
235                    "invalid number:transliteration-style",
236                    Some(attr.to_string()),
237                )),
238            }
239        } else {
240            Ok(None)
241        }
242    }
243}
244
245/// 19.484 style:font-family-generic
246///
247/// The style:font-family-generic attribute specifies a generic font family name.
248///
249/// The defined values for the style:font-family-generic attribute are:
250/// * decorative: the family of decorative fonts.
251/// * modern: the family of modern fonts.
252/// * roman: the family roman fonts (with serifs).
253/// * script: the family of script fonts.
254/// * swiss: the family roman fonts (without serifs).
255/// * system: the family system fonts.
256#[derive(Debug, Clone, Copy, PartialEq, Eq)]
257#[allow(missing_docs)]
258pub enum FontFamilyGeneric {
259    Decorative,
260    Modern,
261    Roman,
262    Script,
263    Swiss,
264    System,
265}
266
267impl Display for FontFamilyGeneric {
268    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
269        match self {
270            FontFamilyGeneric::Decorative => write!(f, "decorative"),
271            FontFamilyGeneric::Modern => write!(f, "modern"),
272            FontFamilyGeneric::Roman => write!(f, "roman"),
273            FontFamilyGeneric::Script => write!(f, "script"),
274            FontFamilyGeneric::Swiss => write!(f, "swiss"),
275            FontFamilyGeneric::System => write!(f, "system"),
276        }
277    }
278}
279
280/// 19.485 style:font-pitch
281/// The style:font-pitch attribute specifies whether a font has a fixed or variable width.
282/// The defined values for the style:font-pitch attribute are:
283/// * fixed: font has a fixed width.
284/// * variable: font has a variable width.
285#[derive(Debug, Clone, Copy, Eq, PartialEq)]
286pub enum FontPitch {
287    /// Variable font with
288    Variable,
289    /// Fixed font width
290    Fixed,
291}
292
293impl Display for FontPitch {
294    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
295        match self {
296            FontPitch::Variable => write!(f, "variable"),
297            FontPitch::Fixed => write!(f, "fixed"),
298        }
299    }
300}
301
302/// 19.509 style:page-usage
303///
304/// The style:page-usage attribute specifies the type of pages that a master page should
305/// generate.
306///
307/// The defined values for the style:page-usage attribute are:
308/// * all: if there are no <style:header-left> or <style:footer-left> elements, the
309///   header and footer content is the same for left and right pages.
310/// * left: <style:header-right> and <style:footer-right> elements are ignored.
311/// * mirrored: if there are no <style:header-left> or <style:footer-left> elements,
312///   the header and footer content is the same for left and right pages.
313/// * right: <style:header-left> and <style:footer-left> elements are ignored.
314///
315/// The default value for this attribute is all.
316#[derive(Debug, Clone, Copy, PartialEq, Eq)]
317#[allow(missing_docs)]
318pub enum MasterPageUsage {
319    All,
320    Left,
321    Mirrored,
322    Right,
323}
324
325impl Display for MasterPageUsage {
326    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
327        match self {
328            MasterPageUsage::All => write!(f, "all"),
329            MasterPageUsage::Left => write!(f, "left"),
330            MasterPageUsage::Mirrored => write!(f, "mirrored"),
331            MasterPageUsage::Right => write!(f, "right"),
332        }
333    }
334}
335
336impl ParseStyleAttr<MasterPageUsage> for MasterPageUsage {
337    fn parse_attr(attr: Option<&str>) -> Result<Option<MasterPageUsage>, OdsError> {
338        if let Some(attr) = attr {
339            match attr {
340                "all" => Ok(Some(MasterPageUsage::All)),
341                "left" => Ok(Some(MasterPageUsage::Left)),
342                "mirrored" => Ok(Some(MasterPageUsage::Mirrored)),
343                "right" => Ok(Some(MasterPageUsage::Right)),
344                _ => Err(OdsError::Parse(
345                    "invalid style:page-usage",
346                    Some(attr.to_string()),
347                )),
348            }
349        } else {
350            Ok(None)
351        }
352    }
353}
354
355/// 19.519 style:type
356///
357/// The style:type attribute specifies the type of a tab stop within paragraph formatting properties.
358///
359/// The defined values for the style:type attribute are:
360/// * center: text is centered on a tab stop.
361/// * char: character appears at a tab stop position.
362/// * left: text is left aligned with a tab stop.
363/// * right: text is right aligned with a tab stop.
364///
365/// For a <style:tab-stop> 17.8 element the default value for this attribute is left.
366#[derive(Clone, Copy, Debug)]
367#[allow(missing_docs)]
368pub enum TabStopType {
369    Center,
370    Left,
371    Right,
372    Char,
373}
374
375impl Display for TabStopType {
376    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
377        match self {
378            TabStopType::Center => write!(f, "center"),
379            TabStopType::Left => write!(f, "left"),
380            TabStopType::Right => write!(f, "right"),
381            TabStopType::Char => write!(f, "char"),
382        }
383    }
384}
385
386impl Default for TabStopType {
387    fn default() -> Self {
388        Self::Left
389    }
390}
391
392/// 19.534 svg:font-stretch
393///
394/// See §20.8.3 of SVG.
395///
396/// The svg:font-stretch attribute is usable with the following element: <style:font-face>
397/// 16.23.
398///
399/// The values of the svg:font-stretch attribute are normal, ultra-condensed, extracondensed,
400/// condensed, semi-condensed, semi-expanded, expanded, extraexpanded or ultra-expanded.
401#[derive(Debug, Clone, Copy, PartialEq, Eq)]
402#[allow(missing_docs)]
403pub enum FontStretch {
404    Normal,
405    UltraCondensed,
406    ExtraCondensed,
407    Condensed,
408    SemiCondensed,
409    SemiExpanded,
410    Expanded,
411    ExtraExpanded,
412    UltraExpanded,
413}
414
415impl Display for FontStretch {
416    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
417        match self {
418            FontStretch::Normal => write!(f, "normal"),
419            FontStretch::UltraCondensed => write!(f, "ultra-condensed"),
420            FontStretch::ExtraCondensed => write!(f, "extra-condensed"),
421            FontStretch::Condensed => write!(f, "condensed"),
422            FontStretch::SemiCondensed => write!(f, "semi-condensed"),
423            FontStretch::SemiExpanded => write!(f, "semi-expanded"),
424            FontStretch::Expanded => write!(f, "expanded"),
425            FontStretch::ExtraExpanded => write!(f, "extra-expanded"),
426            FontStretch::UltraExpanded => write!(f, "ultra-expanded"),
427        }
428    }
429}
430
431/// 20.183 fo-border Properties.
432/// See §7.29.3ff of XSL
433#[allow(missing_docs)]
434#[derive(Debug, Clone, Copy, Eq, PartialEq)]
435pub enum Border {
436    None,
437    Hidden,
438    Dotted,
439    Dashed,
440    Solid,
441    Double,
442    Groove,
443    Ridge,
444    Inset,
445    Outset,
446}
447
448impl Display for Border {
449    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
450        match self {
451            Border::None => write!(f, "none"),
452            Border::Hidden => write!(f, "hidden"),
453            Border::Dotted => write!(f, "dotted"),
454            Border::Dashed => write!(f, "dashed"),
455            Border::Solid => write!(f, "solid"),
456            Border::Double => write!(f, "double"),
457            Border::Groove => write!(f, "groove"),
458            Border::Ridge => write!(f, "ridge"),
459            Border::Inset => write!(f, "inset"),
460            Border::Outset => write!(f, "outset"),
461        }
462    }
463}
464
465/// 20.184 fo:break-after, fo:break-before
466/// See §7.19.1 of XSL. The values odd-page and even-page are not supported.
467///
468/// This attribute shall not be used at the same time as fo:break-before.
469///
470/// In the OpenDocument XSL-compatible namespace, the fo:break-after attribute does not
471/// support even-page, inherit and odd-page values.
472///
473/// The values of the fo:break-after attribute are auto, column or page.
474#[allow(missing_docs)]
475#[derive(Debug, Clone, Copy, Eq, PartialEq)]
476pub enum PageBreak {
477    Auto,
478    Column,
479    Page,
480}
481
482impl Display for PageBreak {
483    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
484        match self {
485            PageBreak::Auto => write!(f, "auto")?,
486            PageBreak::Column => write!(f, "column")?,
487            PageBreak::Page => write!(f, "page")?,
488        }
489        Ok(())
490    }
491}
492
493/// 20.190 fo:font-size
494///
495/// See §7.8.4 of XSL.
496///
497/// The value of this attribute is either an absolute length or a percentage as described in §7.8.4 of
498/// XSL. In contrast to XSL, percentage values can be used within common styles only and are
499/// based on the font height of the parent style rather than to the font height of the attributes
500/// neighborhood. Absolute font heights and relative font heights are not supported.
501///
502/// In the OpenDocument XSL-compatible namespace, the fo:font-size attribute does not
503/// support absolute-size, inherit and relative-size values.
504///
505/// The values of the fo:font-size attribute are a value of type positiveLength 18.3.26 or a
506/// value of type percent 18.3.23.
507#[derive(Debug, Clone, Copy, PartialEq)]
508#[allow(missing_docs)]
509pub enum FontSize {
510    Length(Length),
511    Percent(Percent),
512}
513
514impl FontSize {
515    /// Is the fontsize positive. Percentage is always positive.
516    pub fn is_positive(&self) -> bool {
517        match self {
518            FontSize::Length(v) => v.is_positive(),
519            FontSize::Percent(_) => true,
520        }
521    }
522}
523
524impl From<Length> for FontSize {
525    fn from(value: Length) -> Self {
526        FontSize::Length(value)
527    }
528}
529
530impl From<Percent> for FontSize {
531    fn from(value: Percent) -> Self {
532        FontSize::Percent(value)
533    }
534}
535
536impl Display for FontSize {
537    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
538        match self {
539            FontSize::Percent(v) => write!(f, "{}", v),
540            FontSize::Length(v) => write!(f, "{}", v),
541        }
542    }
543}
544
545/// 20.191 fo:font-style
546/// See §7.8.7 of XSL.
547///
548/// This attribute is evaluated for any UNICODE character whose script type is latin. 20.358
549///
550/// In the OpenDocument XSL-compatible namespace, the fo:font-style attribute does not
551/// support backslant and inherit values.
552///
553/// The values of the fo:font-style attribute are normal, italic or oblique.
554#[derive(Debug, Clone, Copy, Eq, PartialEq)]
555#[allow(missing_docs)]
556pub enum FontStyle {
557    Normal,
558    Italic,
559    Oblique,
560}
561
562impl Display for FontStyle {
563    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
564        match self {
565            FontStyle::Normal => write!(f, "normal"),
566            FontStyle::Italic => write!(f, "italic"),
567            FontStyle::Oblique => write!(f, "oblique"),
568        }
569    }
570}
571
572/// 20.192 fo:font-variant
573///
574/// See §7.8.8 of XSL.
575///
576/// In the OpenDocument XSL-compatible namespace, the fo:font-variant attribute does not
577/// support the inherit value.
578///
579/// The values of the fo:font-variant attribute are normal or small-caps.
580#[derive(Debug, Clone, Copy, Eq, PartialEq)]
581#[allow(missing_docs)]
582pub enum FontVariant {
583    Normal,
584    SmallCaps,
585}
586
587impl Display for FontVariant {
588    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
589        match self {
590            FontVariant::Normal => write!(f, "normal"),
591            FontVariant::SmallCaps => write!(f, "small-caps"),
592        }
593    }
594}
595
596/// 20.193 fo:font-weight
597///
598/// See §7.8.9 of XSL.
599///
600/// This attribute is evaluated for any UNICODE character whose script type is latin. 20.358
601/// In the OpenDocument XSL-compatible namespace, the fo:font-weight attribute does not
602/// support bolder, inherit and lighter values.
603///
604/// The values of the fo:font-weight attribute are normal, bold, 100, 200, 300, 400, 500,
605/// 600, 700, 800 or 900.
606#[derive(Debug, Clone, Copy, Eq, PartialEq)]
607#[allow(missing_docs)]
608pub enum FontWeight {
609    Normal,
610    Bold,
611    W100,
612    W200,
613    W300,
614    W400,
615    W500,
616    W600,
617    W700,
618    W800,
619    W900,
620}
621
622impl Display for FontWeight {
623    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
624        match self {
625            FontWeight::Normal => write!(f, "normal"),
626            FontWeight::Bold => write!(f, "bold"),
627            FontWeight::W100 => write!(f, "100"),
628            FontWeight::W200 => write!(f, "200"),
629            FontWeight::W300 => write!(f, "300"),
630            FontWeight::W400 => write!(f, "400"),
631            FontWeight::W500 => write!(f, "500"),
632            FontWeight::W600 => write!(f, "600"),
633            FontWeight::W700 => write!(f, "700"),
634            FontWeight::W800 => write!(f, "800"),
635            FontWeight::W900 => write!(f, "900"),
636        }
637    }
638}
639
640/// 20.196 fo:hyphenation-keep
641///
642/// See §7.15.1 of XSL.
643///  
644/// The values of the fo:hyphenation-keep attribute are auto or page
645#[derive(Debug, Clone, Copy, PartialEq, Eq)]
646#[allow(missing_docs)]
647pub enum Hyphenation {
648    Auto,
649    Page,
650}
651
652impl Display for Hyphenation {
653    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
654        match self {
655            Hyphenation::Auto => write!(f, "auto"),
656            Hyphenation::Page => write!(f, "page"),
657        }
658    }
659}
660
661/// 20.197 fo:hyphenation-ladder-count
662///
663/// See §7.15.2 of XSL.
664///
665/// The defined values for the fo:hyphenation-ladder-count attribute are:
666/// * no-limit:
667/// * a value of type positiveInteger
668#[derive(Debug, Clone, Copy, PartialEq, Eq)]
669#[allow(missing_docs)]
670pub enum HyphenationLadderCount {
671    NoLimit,
672    Count(u32),
673}
674
675impl Display for HyphenationLadderCount {
676    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
677        match self {
678            HyphenationLadderCount::NoLimit => write!(f, "no_limit"),
679            HyphenationLadderCount::Count(c) => c.fmt(f),
680        }
681    }
682}
683
684/// 20.200 fo:keep-together and fo:keep-with-next
685/// See §7.19.3 of XSL.
686/// In the OpenDocument XSL-compatible namespace, the fo:keep-together attribute does not
687/// support the integer value.
688/// The values of the fo:keep-together attribute are auto or always.
689#[derive(Debug, Clone, Copy, Eq, PartialEq)]
690#[allow(missing_docs)]
691pub enum TextKeep {
692    Auto,
693    Always,
694}
695
696impl Display for TextKeep {
697    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
698        match self {
699            TextKeep::Auto => write!(f, "auto")?,
700            TextKeep::Always => write!(f, "always")?,
701        }
702        Ok(())
703    }
704}
705
706/// 20.203 fo:letter-spacing
707///
708/// See §7.16.2 of XSL.
709///
710/// In the OpenDocument XSL-compatible namespace, the fo:letter-spacing attribute does not
711/// support the inherit and space values.
712///
713/// The defined value for the fo:letter-spacing attribute is a value of type length 18.3.18.
714///
715/// The values of the fo:letter-spacing attribute are a value of type length 18.3.18 or
716/// normal.
717#[derive(Debug, Clone, PartialEq)]
718#[allow(missing_docs)]
719pub enum LetterSpacing {
720    Normal,
721    Length(Length),
722}
723
724impl From<Length> for LetterSpacing {
725    fn from(value: Length) -> Self {
726        LetterSpacing::Length(value)
727    }
728}
729
730impl Display for LetterSpacing {
731    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
732        match self {
733            LetterSpacing::Normal => write!(f, "normal"),
734            LetterSpacing::Length(v) => write!(f, "{}", v),
735        }
736    }
737}
738
739/// 20.204 fo:line-height
740///
741/// See §7.15.4 of XSL.
742///
743/// The value normal activates the default line height calculation. The value of this attribute
744/// can be a length, a percentage, normal.
745///
746/// In the OpenDocument XSL-compatible namespace, the fo:line-height attribute does not
747/// support the inherit, number, and space values.
748///
749/// The defined values for the fo:line-height attribute are:
750/// * a value of type nonNegativeLength 18.3.20
751/// * normal: disables the effects of style:line-height-at-least 20.317 and
752///   style:line-spacing 20.318.
753/// * a value of type percent 18.3.23
754#[derive(Debug, Clone, Copy, PartialEq)]
755#[allow(missing_docs)]
756pub enum LineHeight {
757    Normal,
758    Length(Length),
759    Percent(Percent),
760}
761
762impl LineHeight {
763    /// Is the fontsize positive. Percentage is always positive.
764    pub fn is_positive(&self) -> bool {
765        match self {
766            LineHeight::Normal => true,
767            LineHeight::Length(v) => v.is_positive(),
768            LineHeight::Percent(_) => true,
769        }
770    }
771}
772
773impl From<Length> for LineHeight {
774    fn from(value: Length) -> Self {
775        LineHeight::Length(value)
776    }
777}
778
779impl From<Percent> for LineHeight {
780    fn from(value: Percent) -> Self {
781        LineHeight::Percent(value)
782    }
783}
784
785impl Display for LineHeight {
786    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
787        match self {
788            LineHeight::Normal => write!(f, "normal"),
789            LineHeight::Length(v) => v.fmt(f),
790            LineHeight::Percent(v) => v.fmt(f),
791        }
792    }
793}
794
795/// 20.205 fo:margin
796///
797/// See §7.29.14 of XSL.
798///
799/// In the OpenDocument XSL-compatible namespace, the fo:margin attribute does not support
800/// auto and inherit values.
801///
802/// The values of the fo:margin attribute are a value of type nonNegativeLength 18.3.20 or a
803/// value of type percent 18.3.23.
804#[derive(Debug, Clone, Copy, PartialEq)]
805#[allow(missing_docs)]
806pub enum Margin {
807    Length(Length),
808    Percent(Percent),
809}
810
811impl Margin {
812    /// Is the fontsize positive. Percentage is always positive.
813    pub fn is_positive(&self) -> bool {
814        match self {
815            Margin::Length(v) => v.is_positive(),
816            Margin::Percent(_) => true,
817        }
818    }
819}
820
821impl From<Length> for Margin {
822    fn from(value: Length) -> Self {
823        Margin::Length(value)
824    }
825}
826
827impl From<Percent> for Margin {
828    fn from(value: Percent) -> Self {
829        Margin::Percent(value)
830    }
831}
832
833impl Display for Margin {
834    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
835        match self {
836            Margin::Length(v) => v.fmt(f),
837            Margin::Percent(v) => v.fmt(f),
838        }
839    }
840}
841
842/// 20.223 fo:text-align
843///
844/// See §7.15.9 of XSL.
845///
846/// If there are no values specified for the fo:text-align and style:justify-single-word
847/// 20.301 attributes within the same formatting properties element, the values of those attributes is
848/// set to start and false respectively.
849/// In the OpenDocument XSL-compatible namespace, the fo:text-align attribute does not
850/// support the inherit, inside, outside, or string values.
851///
852/// The values of the fo:text-align attribute are start, end, left, right, center or
853/// justify.
854#[derive(Debug, Clone, Copy, Eq, PartialEq)]
855#[allow(missing_docs)]
856pub enum TextAlign {
857    Start,
858    Center,
859    End,
860    Justify,
861    Inside,
862    Outside,
863    Left,
864    Right,
865}
866
867impl Display for TextAlign {
868    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
869        match self {
870            TextAlign::Start => write!(f, "start"),
871            TextAlign::Center => write!(f, "center"),
872            TextAlign::End => write!(f, "end"),
873            TextAlign::Justify => write!(f, "justify"),
874            TextAlign::Inside => write!(f, "inside"),
875            TextAlign::Outside => write!(f, "outside"),
876            TextAlign::Left => write!(f, "left"),
877            TextAlign::Right => write!(f, "right"),
878        }
879    }
880}
881
882/// 20.224 fo:text-align-last
883///
884/// See §7.15.10 of XSL.
885///
886/// This attribute is ignored if it not accompanied by an fo:text-align 20.223 attribute.
887/// If no value is specified for this attribute, the value is set to start.
888///
889/// The values of the fo:text-align-last attribute are start, center or justify.
890#[derive(Debug, Clone, Copy, Eq, PartialEq)]
891#[allow(missing_docs)]
892pub enum TextAlignLast {
893    Start,
894    Center,
895    Justify,
896}
897
898impl Display for TextAlignLast {
899    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
900        match self {
901            TextAlignLast::Start => write!(f, "start"),
902            TextAlignLast::Center => write!(f, "center"),
903            TextAlignLast::Justify => write!(f, "justify"),
904        }
905    }
906}
907
908/// 20.225 fo:text-indent
909///
910/// The fo:text-indent attribute specifies a positive or negative indent for the first line of a
911/// paragraph.
912///
913/// See §7.15.11 of XSL.
914///
915/// The attribute value is a length. If the attribute is contained in a
916/// common style, the attribute value may be also a percentage that refers to the corresponding text
917/// indent of a parent style.
918#[derive(Debug, Clone, Copy, PartialEq)]
919#[allow(missing_docs)]
920pub enum Indent {
921    Length(Length),
922    Percent(Percent),
923}
924
925impl From<Length> for Indent {
926    fn from(value: Length) -> Self {
927        Indent::Length(value)
928    }
929}
930
931impl From<Percent> for Indent {
932    fn from(value: Percent) -> Self {
933        Indent::Percent(value)
934    }
935}
936
937impl Display for Indent {
938    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
939        match self {
940            Indent::Length(v) => v.fmt(f),
941            Indent::Percent(v) => v.fmt(f),
942        }
943    }
944}
945
946/// 20.227 fo:text-transform
947///
948/// See §7.16.6 of XSL.
949///  
950/// If fo:text-transform and fo:font-variant 20.192 attributes are used simultaneously and
951/// have different values than normal and none, the result is undefined.
952///
953/// Note: In consumers, the fo:text-transform and fo:font-variant
954/// attributes are mutually exclusive.
955///
956/// The values of the fo:text-transform attribute are none, lowercase, uppercase or
957/// capitalize.
958#[derive(Debug, Clone, Copy, Eq, PartialEq)]
959#[allow(missing_docs)]
960pub enum TextTransform {
961    None,
962    Lowercase,
963    Uppercase,
964    Capitalize,
965}
966
967impl Display for TextTransform {
968    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
969        match self {
970            TextTransform::None => write!(f, "none"),
971            TextTransform::Lowercase => write!(f, "lowercase"),
972            TextTransform::Uppercase => write!(f, "uppercase"),
973            TextTransform::Capitalize => write!(f, "capitalize"),
974        }
975    }
976}
977
978/// 20.230 fo:wrap-option
979/// See §7.15.13 of XSL.
980///
981/// If wrapping is disabled, it is implementation-defined whether the overflow text is visible or hidden.
982/// If the text is hidden consumers may support a scrolling to access the text.
983///
984/// The values of the fo:wrap-option attribute are no-wrap or wrap.
985#[allow(missing_docs)]
986#[derive(Debug, Clone, Copy, Eq, PartialEq)]
987pub enum WrapOption {
988    NoWrap,
989    Wrap,
990}
991
992impl Display for WrapOption {
993    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
994        match self {
995            WrapOption::NoWrap => write!(f, "no-wrap"),
996            WrapOption::Wrap => write!(f, "wrap"),
997        }
998    }
999}
1000
1001/// 20.253 style:cell-protect
1002///
1003/// The style:cell-protect attribute specifies how a cell is protected.
1004/// This attribute is only evaluated if the current table is protected.
1005///
1006/// The defined values for the style:cell-protect attribute are:
1007/// * formula-hidden: if cell content is a formula, it is not displayed. It can be replaced by
1008///   changing the cell content.
1009///   Note: Replacement of cell content includes replacement with another formula or
1010///   other cell content.
1011/// * hidden-and-protected: cell content is not displayed and cannot be edited. If content is a
1012///   formula, the formula result is not displayed.
1013/// * none: formula responsible for cell content is neither hidden nor protected.
1014/// * protected: cell content cannot be edited.
1015/// * protected formula-hidden: cell content cannot be edited. If content is a formula, it is not
1016///   displayed. A formula result is displayed.
1017#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1018#[allow(missing_docs)]
1019pub enum CellProtect {
1020    /// If cell content is a formula, it is not displayed. It can be replaced by
1021    /// changing the cell content.
1022    /// Note: Replacement of cell content includes replacement with another formula or
1023    /// other cell content.
1024    FormulaHidden,
1025    /// cell content is not displayed and cannot be edited. If content is a
1026    /// formula, the formula result is not displayed.
1027    HiddenAndProtected,
1028    /// Formula responsible for cell content is neither hidden nor protected.
1029    None,
1030    /// Cell content cannot be edited.
1031    Protected,
1032    /// cell content cannot be edited. If content is a formula, it is not
1033    /// displayed.
1034    ProtectedFormulaHidden,
1035}
1036
1037impl Display for CellProtect {
1038    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1039        match self {
1040            CellProtect::FormulaHidden => write!(f, "formula-hidden"),
1041            CellProtect::HiddenAndProtected => write!(f, "hidden-and-protected"),
1042            CellProtect::None => write!(f, "none"),
1043            CellProtect::Protected => write!(f, "protected"),
1044            CellProtect::ProtectedFormulaHidden => write!(f, "protected formula-hidden"),
1045        }
1046    }
1047}
1048
1049/// 20.263 style:direction
1050///
1051/// The style:direction attribute specifies the direction of characters.
1052///
1053/// The style:direction attribute modifies the direction of text rendering as specified by a
1054/// style:writing-mode attribute. 20.404
1055///
1056/// The defined values for the style:direction attribute are:
1057/// * ltr – left to right, text is rendered in the direction specified by the style:writing-mode
1058///   attribute
1059/// * ttb – top to bottom, characters are vertically stacked but not rotated
1060#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1061#[allow(missing_docs)]
1062pub enum WritingDirection {
1063    Ltr,
1064    Ttb,
1065}
1066
1067impl Display for WritingDirection {
1068    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1069        match self {
1070            WritingDirection::Ltr => write!(f, "ltr"),
1071            WritingDirection::Ttb => write!(f, "ttb"),
1072        }
1073    }
1074}
1075
1076/// 20.283 style:font-relief
1077///
1078/// The style:font-relief attribute specifies whether a font should be embossed, engraved, or
1079/// neither.
1080///
1081/// The defined values for the style:font-relief attribute are:
1082/// * embossed: characters are embossed.
1083/// * engraved: characters are engraved.
1084/// * none: characters are neither embossed or engraved.
1085#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1086#[allow(missing_docs)]
1087pub enum TextRelief {
1088    None,
1089    Embossed,
1090    Engraved,
1091}
1092
1093impl Display for TextRelief {
1094    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1095        match self {
1096            TextRelief::None => write!(f, "none"),
1097            TextRelief::Embossed => write!(f, "embossed"),
1098            TextRelief::Engraved => write!(f, "engraved"),
1099        }
1100    }
1101}
1102
1103/// 20.297 style:glyph-orientation-vertical
1104///
1105/// The style:glyph-orientation-vertical attribute specifies a vertical glyph orientation.
1106/// See §10.7.3 of SVG. The attribute specifies an angle or automatic mode. The only defined angle
1107/// is 0 degrees, which disables this feature.
1108///
1109/// Note: OpenDocument v1.1 did not support angle specifications that contain an
1110/// angle unit identifier. Angle unit identifiers should be omitted for compatibility with
1111/// OpenDocument v1.1.
1112///
1113/// The values of the style:glyph-orientation-vertical attribute are auto, 0, 0deg, 0rad
1114/// or 0grad.
1115#[derive(Debug, Clone, Copy, PartialEq)]
1116#[allow(missing_docs)]
1117pub enum GlyphOrientation {
1118    Auto,
1119    Zero,
1120    Angle(Angle),
1121}
1122
1123impl Display for GlyphOrientation {
1124    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1125        match self {
1126            GlyphOrientation::Auto => write!(f, "auto"),
1127            GlyphOrientation::Zero => write!(f, "0"),
1128            GlyphOrientation::Angle(a) => a.fmt(f),
1129        }
1130    }
1131}
1132
1133/// 20.315 style:line-break
1134/// The style:line-break attribute specifies line breaking rules.
1135/// The defined values for the style:line-break attribute are:
1136/// * normal: line breaks may occur between any characters.
1137/// * strict: line breaks shall not occur before or after implementation-defined characters.
1138#[allow(missing_docs)]
1139#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1140pub enum LineBreak {
1141    Normal,
1142    Strict,
1143}
1144
1145impl Display for LineBreak {
1146    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1147        match self {
1148            LineBreak::Normal => write!(f, "normal")?,
1149            LineBreak::Strict => write!(f, "strict")?,
1150        }
1151        Ok(())
1152    }
1153}
1154
1155/// 20.322 style:num-format
1156///
1157/// The style:num-format attribute specifies a numbering sequence.
1158/// If no value is given, no number sequence is displayed.
1159///
1160/// The defined values for the style:num-format attribute are:
1161/// * 1: number sequence starts with “1”.
1162/// * a: number sequence starts with “a”.
1163/// * A: number sequence starts with “A”.
1164/// * empty string: no number sequence displayed.
1165/// * i: number sequence starts with “i”.
1166/// * I: number sequence start with “I”.
1167/// * a value of type string 18.2
1168#[derive(Debug, Clone, PartialEq, Eq)]
1169#[allow(missing_docs)]
1170pub enum StyleNumFormat {
1171    None,
1172    Number,
1173    LowerAlpha,
1174    Alpha,
1175    LowerRoman,
1176    Roman,
1177    Text(String),
1178}
1179
1180impl Display for StyleNumFormat {
1181    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1182        match self {
1183            StyleNumFormat::None => write!(f, ""),
1184            StyleNumFormat::Number => write!(f, "1"),
1185            StyleNumFormat::LowerAlpha => write!(f, "a"),
1186            StyleNumFormat::Alpha => write!(f, "A"),
1187            StyleNumFormat::LowerRoman => write!(f, "i"),
1188            StyleNumFormat::Roman => write!(f, "I"),
1189            StyleNumFormat::Text(v) => write!(f, "{}", v),
1190        }
1191    }
1192}
1193
1194/// 20.328 style:page-number
1195///
1196/// The style:page-number attribute specifies the page number that should be used for a new
1197/// page when either a paragraph or table style specifies a master page that should be applied
1198/// beginning from the start of a paragraph or table.
1199///
1200/// The defined values for the style:page-number attribute are:
1201/// * auto: a page has the page number of the previous page, incremented by one.
1202/// * a value of type nonNegativeInteger 18.2: specifies a page number.
1203#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1204#[allow(missing_docs)]
1205pub enum PageNumber {
1206    Auto,
1207    Number(u32),
1208}
1209
1210impl Display for PageNumber {
1211    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1212        match self {
1213            PageNumber::Auto => write!(f, "auto"),
1214            PageNumber::Number(v) => v.fmt(f),
1215        }
1216    }
1217}
1218
1219/// 20.330 style:print
1220///
1221/// The style:print attribute specifies the components in a spreadsheet document to print.
1222///
1223/// The value of the style:print attribute is a white space separated list of one or more of these
1224/// values:
1225/// * annotations: annotations should be printed.
1226/// * charts: charts should be printed.
1227/// * drawings: drawings should be printed.
1228/// * formulas: formulas should be printed.
1229/// * grid: grid lines should be printed.
1230/// * headers: headers should be printed.
1231/// * objects: (including graphics): objects should be printed.
1232/// * zero-values: zero-values should be printed.
1233#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1234#[allow(missing_docs)]
1235pub enum PrintContent {
1236    Headers,
1237    Grid,
1238    Annotations,
1239    Objects,
1240    Charts,
1241    Drawings,
1242    Formulas,
1243    ZeroValues,
1244}
1245
1246impl Display for PrintContent {
1247    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1248        match self {
1249            PrintContent::Headers => write!(f, "headers"),
1250            PrintContent::Grid => write!(f, "grid"),
1251            PrintContent::Annotations => write!(f, "annotations"),
1252            PrintContent::Objects => write!(f, "objects"),
1253            PrintContent::Charts => write!(f, "charts"),
1254            PrintContent::Drawings => write!(f, "drawings"),
1255            PrintContent::Formulas => write!(f, "formulas"),
1256            PrintContent::ZeroValues => write!(f, "zero-values"),
1257        }
1258    }
1259}
1260
1261/// 20.332 style:print-page-order
1262///
1263/// The style:print-page-order attribute specifies the order in which data in a spreadsheet is
1264/// numbered and printed when the data does not fit on one printed page.
1265///
1266/// The defined values for the style:print-page-order attribute are:
1267/// * ltr: create pages from the first column to the last column before continuing with the next set
1268///   of rows.
1269/// * ttb: create pages from the top row to the bottom row before continuing with the next set of
1270///   columns.
1271#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1272#[allow(missing_docs)]
1273pub enum PrintOrder {
1274    Ltr,
1275    Ttb,
1276}
1277
1278impl Display for PrintOrder {
1279    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1280        match self {
1281            PrintOrder::Ltr => write!(f, "ltr"),
1282            PrintOrder::Ttb => write!(f, "ttb"),
1283        }
1284    }
1285}
1286
1287/// 20.333 style:print-orientation
1288///
1289/// The style:print-orientation attribute specifies the orientation of the printed page. The
1290/// value of this attribute can be portrait or landscape.
1291///
1292/// The defined values for the style:print-orientation attribute are:
1293/// * landscape: a page is printed in landscape orientation.
1294/// * portrait: a page is printed in portrait orientation
1295#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1296#[allow(missing_docs)]
1297pub enum PrintOrientation {
1298    Landscape,
1299    Portrait,
1300}
1301
1302impl Display for PrintOrientation {
1303    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1304        match self {
1305            PrintOrientation::Landscape => write!(f, "landscape"),
1306            PrintOrientation::Portrait => write!(f, "portrait"),
1307        }
1308    }
1309}
1310
1311/// 20.335 style:punctuation-wrap
1312///
1313/// The style:punctuation-wrap attribute specifies whether a punctuation mark, if one is
1314/// present, can be hanging, that is, whether it can placed in the margin area at the end of a full line of
1315/// text.
1316///
1317/// The defined values for the style:punctuation-wrap attribute are:
1318/// * hanging: a punctuation mark can be placed in the margin area at the end of a full line of text.
1319/// * simple: a punctuation mark cannot be placed in the margin area at the end of a full line of
1320///   text.
1321#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1322#[allow(missing_docs)]
1323pub enum PunctuationWrap {
1324    Hanging,
1325    Simple,
1326}
1327
1328impl Display for PunctuationWrap {
1329    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1330        match self {
1331            PunctuationWrap::Hanging => write!(f, "hanging"),
1332            PunctuationWrap::Simple => write!(f, "simple"),
1333        }
1334    }
1335}
1336
1337/// 20.340 style:rel-width
1338///
1339/// The style:rel-width attribute specifies the width of a table relative to the width of the area
1340/// that the table is in.
1341///
1342/// The style:rel-width attribute has the data type percent 18.3.23.
1343#[derive(Debug, Clone, PartialEq)]
1344#[allow(missing_docs)]
1345pub enum RelativeScale {
1346    Scale,
1347    ScaleMin,
1348    Percent(Percent),
1349}
1350
1351impl Display for RelativeScale {
1352    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1353        match self {
1354            RelativeScale::Scale => write!(f, "scale"),
1355            RelativeScale::ScaleMin => write!(f, "scale-min"),
1356            RelativeScale::Percent(v) => write!(f, "{}", v),
1357        }
1358    }
1359}
1360
1361/// 20.346 style:rotation-align
1362/// The style:rotation-align attribute specifies how the edge of the text in a cell is aligned
1363/// after a rotation.
1364///
1365/// The values of the style:rotation-align attribute are none, bottom, top or center.
1366#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1367#[allow(missing_docs)]
1368pub enum RotationAlign {
1369    None,
1370    Bottom,
1371    Top,
1372    Center,
1373}
1374
1375impl Display for RotationAlign {
1376    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1377        match self {
1378            RotationAlign::None => write!(f, "none"),
1379            RotationAlign::Bottom => write!(f, "bottom"),
1380            RotationAlign::Top => write!(f, "top"),
1381            RotationAlign::Center => write!(f, "center"),
1382        }
1383    }
1384}
1385
1386/// 20.363 style:table-centering
1387///
1388/// The style:table-centering attribute specifies whether tables are centered horizontally and/
1389/// or vertically on the page. This attribute only applies to spreadsheet documents.
1390///
1391/// The default is to align the table to the top-left or top-right corner of the page, depending of its
1392/// writing direction.
1393///
1394/// The defined values for the style:table-centering attribute are:
1395/// * both: tables should be centered both horizontally and vertically on the pages where they
1396///   appear.
1397/// * horizontal: tables should be centered horizontally on the pages where they appear.
1398/// * none: tables should not be centered both horizontally or vertically on the pages where they
1399///   appear.
1400/// * vertical: tables should be centered vertically on the pages where they appear.
1401#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1402#[allow(missing_docs)]
1403pub enum PrintCentering {
1404    None,
1405    Horizontal,
1406    Vertical,
1407    Both,
1408}
1409
1410impl Display for PrintCentering {
1411    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1412        match self {
1413            PrintCentering::None => write!(f, "none"),
1414            PrintCentering::Horizontal => write!(f, "horizontal"),
1415            PrintCentering::Vertical => write!(f, "vertical"),
1416            PrintCentering::Both => write!(f, "both"),
1417        }
1418    }
1419}
1420
1421/// 20.364 style:text-align-source
1422///
1423/// The style:text-align-source attribute specifies the source of a text-align attribute.
1424///
1425/// The defined values for the style:text-align-source attribute are:
1426/// * fix: content alignment uses the value of the fo:text-align 20.223 attribute.
1427/// * value-type: content alignment uses the value-type of the cell.
1428///
1429/// The default alignment for a cell value-type string is left, for other value-types it is right.
1430///
1431/// The values of the style:text-align-source attribute are fix or value-type.
1432#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1433#[allow(missing_docs)]
1434pub enum TextAlignSource {
1435    Fix,
1436    ValueType,
1437}
1438
1439impl Display for TextAlignSource {
1440    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1441        match self {
1442            TextAlignSource::Fix => write!(f, "fix"),
1443            TextAlignSource::ValueType => write!(f, "value-type"),
1444        }
1445    }
1446}
1447
1448/// 20.365 style:text-autospace
1449///
1450/// The style:text-autospace attribute specifies whether to add space between portions of
1451/// Asian, Western, and complex texts.
1452///
1453/// The defined values for the style:text-autospace attribute are:
1454/// * ideograph-alpha: space should be added between portions of Asian, Western and
1455///   Complex texts.
1456/// * none: space should not be added between portions of Asian, Western and complex texts.
1457#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1458#[allow(missing_docs)]
1459pub enum TextAutoSpace {
1460    IdeographAlpha,
1461    None,
1462}
1463
1464impl Display for TextAutoSpace {
1465    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1466        match self {
1467            TextAutoSpace::IdeographAlpha => write!(f, "ideograph-alpha"),
1468            TextAutoSpace::None => write!(f, "none"),
1469        }
1470    }
1471}
1472
1473/// 20.367 style:text-combine
1474///
1475/// The style:text-combine attribute specifies whether to combine characters so that they are
1476/// displayed within two lines.
1477///
1478/// The defined values for the style:text-combine attribute are:
1479/// * letters: Display text in Kumimoji. Up to five (5) characters are combined within two lines
1480///   and are displayed with a reduced size in a single wide-cell character. Additional characters
1481///   are displayed as normal text.
1482/// * lines: Displays text in Warichu. All characters with the style:text-combine attribute that
1483///   immediately follow each other are displayed within two lines of approximately the same length.
1484///   A line break may occur between any two characters to meet this constraint.
1485/// * none: characters should not be combined.
1486#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1487#[allow(missing_docs)]
1488pub enum TextCombine {
1489    None,
1490    Letters,
1491    Lines,
1492}
1493
1494impl Display for TextCombine {
1495    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1496        match self {
1497            TextCombine::None => write!(f, "none"),
1498            TextCombine::Letters => write!(f, "letters"),
1499            TextCombine::Lines => write!(f, "lines"),
1500        }
1501    }
1502}
1503
1504/// 20.370 style:text-emphasize
1505///
1506/// The style:text-emphasize attribute specifies emphasis in a text composed of UNICODE
1507/// characters whose script type is asian. 20.358
1508///
1509/// The value of this attribute consists of two white space-separated values.
1510/// The first value represents the style to use for emphasis.
1511/// The second value represents the position of the emphasis and it can be above or below. If the
1512/// first value is none, the second value can be omitted.
1513///
1514/// The defined values for the style:text-emphasize attribute are:
1515/// * accent: calligraphic accent strokes.
1516/// * circle: hollow circles.
1517/// * disc: filled circles.
1518/// * dot: calligraphic dot.
1519/// * none: no emphasis marks.
1520#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1521#[allow(missing_docs)]
1522pub enum TextEmphasize {
1523    None,
1524    Accent,
1525    Circle,
1526    Disc,
1527    Dot,
1528}
1529
1530impl Display for TextEmphasize {
1531    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1532        match self {
1533            TextEmphasize::None => write!(f, "none"),
1534            TextEmphasize::Accent => write!(f, "accent"),
1535            TextEmphasize::Circle => write!(f, "circle"),
1536            TextEmphasize::Disc => write!(f, "disc"),
1537            TextEmphasize::Dot => write!(f, "dot"),
1538        }
1539    }
1540}
1541
1542/// 20.370 style:text-emphasize
1543///
1544/// The style:text-emphasize attribute specifies emphasis in a text composed of UNICODE
1545/// characters whose script type is asian. 20.358
1546///
1547/// The value of this attribute consists of two white space-separated values.
1548/// The first value represents the style to use for emphasis.
1549/// The second value represents the position of the emphasis and it can be above or below. If the
1550/// first value is none, the second value can be omitted.
1551///
1552/// The defined values for the style:text-emphasize attribute are:
1553/// * accent: calligraphic accent strokes.
1554/// * circle: hollow circles.
1555/// * disc: filled circles.
1556/// * dot: calligraphic dot.
1557/// * none: no emphasis marks.
1558#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1559#[allow(missing_docs)]
1560pub enum TextEmphasizePosition {
1561    Above,
1562    Below,
1563}
1564
1565impl Display for TextEmphasizePosition {
1566    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1567        match self {
1568            TextEmphasizePosition::Above => write!(f, "above"),
1569            TextEmphasizePosition::Below => write!(f, "below"),
1570        }
1571    }
1572}
1573
1574/// Line modes for underline, overline, line-through.
1575///
1576/// 20.372 style:text-line-through-mode
1577/// 20.380 style:text-overline-mode
1578/// 20.389 style:text-underline-mode
1579///
1580/// The style:text-line-through-mode attribute specifies whether lining through is applied to
1581/// words only or to portions of text.
1582///
1583/// The defined values for the style:text-line-through-mode attribute are:
1584/// * continuous: lining is applied to words and separating spaces.
1585/// * skip-white-space: lining is not applied to spaces between words.
1586///
1587/// The values of the style:text-line-through-mode attribute are continuous or skip-white-space.
1588#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1589#[allow(missing_docs)]
1590pub enum LineMode {
1591    Continuous,
1592    SkipWhiteSpace,
1593}
1594
1595impl Display for LineMode {
1596    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1597        match self {
1598            LineMode::Continuous => write!(f, "continuous"),
1599            LineMode::SkipWhiteSpace => write!(f, "skip-white-space"),
1600        }
1601    }
1602}
1603
1604/// Line style for underline, overline, line-through.
1605///
1606/// 20.373 style:text-line-through-style
1607/// 20.390 style:text-underline-style
1608/// 20.381 style:text-overline-style
1609///
1610/// The style:text-underline-style attribute specifies a style for underlining text.
1611/// The defined values for the style:text-underline-style attribute are:
1612/// * none: text has no underlining.
1613/// * dash: text has a dashed line underlining it.
1614/// * dot-dash: text has a line whose repeating pattern is a dot followed by a dash underlining it.
1615/// * dot-dot-dash: text has a line whose repeating pattern is two dots followed by a dash
1616///   underlining it.
1617/// * dotted: text has a dotted line underlining it.
1618/// * long-dash: text has a dashed line whose dashes are longer than the ones from the dashed
1619///   line for value dash underlining it.
1620/// * solid: text has a solid line underlining it.
1621/// * wave: text has a wavy line underlining it.
1622///
1623/// Note: The definitions of the values of the style:text-underline-style
1624/// attribute are based on the text decoration style 'text-underline-style' from
1625/// CSS3Text, §9.2.
1626///
1627/// The values of the style:text-underline-style attribute are none, solid, dotted, dash,
1628/// long-dash, dot-dash, dot-dot-dash or wave.
1629#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1630#[allow(missing_docs)]
1631pub enum LineStyle {
1632    Dash,
1633    DotDash,
1634    DotDotDash,
1635    Dotted,
1636    LongDash,
1637    None,
1638    Solid,
1639    Wave,
1640}
1641
1642impl Display for LineStyle {
1643    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1644        match self {
1645            LineStyle::Dash => write!(f, "dash"),
1646            LineStyle::DotDash => write!(f, "dot-dash"),
1647            LineStyle::DotDotDash => write!(f, "dot-dot-dash"),
1648            LineStyle::Dotted => write!(f, "dotted"),
1649            LineStyle::LongDash => write!(f, "long-dash"),
1650            LineStyle::None => write!(f, "none"),
1651            LineStyle::Solid => write!(f, "solid"),
1652            LineStyle::Wave => write!(f, "wave"),
1653        }
1654    }
1655}
1656
1657/// 20.376 style:text-line-through-type
1658/// 20.382 style:text-overline-type
1659/// 20.391 style:text-underline-type
1660///
1661/// The style:text-line-through-type attribute specifies whether text is lined through, and if
1662/// so, whether a single or double line will be used.
1663///
1664/// The defined values for the style:text-line-through-type attribute are:
1665/// * double: a double line should be used for a line-through text.
1666/// * none: deprecated.
1667/// * single: a single line should be used for a line-through text.
1668///
1669/// Every occurrence of the style:text-line-through-type attribute should be accompanied
1670/// by an occurrence of the style:text-line-through-style 20.373 attribute on the same
1671/// element. There should not be an occurrence of the style:text-line-through-type attribute
1672/// if the value of the style:text-line-through-style attribute is none.
1673///
1674/// The values of the style:text-line-through-type attribute are none, single or double.
1675#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1676#[allow(missing_docs)]
1677pub enum LineType {
1678    None,
1679    Single,
1680    Double,
1681}
1682
1683impl Display for LineType {
1684    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1685        match self {
1686            LineType::None => write!(f, "none"),
1687            LineType::Single => write!(f, "single"),
1688            LineType::Double => write!(f, "double"),
1689        }
1690    }
1691}
1692
1693/// Line width for underline, overline, line-through.
1694///
1695/// 20.377 style:text-line-through-width
1696/// 20.383 style:text-overline-width
1697/// 20.392 style:text-underline-width
1698///
1699/// The style:text-line-through-width attribute specifies the width of a line-through line. The
1700/// value bold specifies a line width that is calculated from the font sizes like an auto width, but is
1701/// wider than an auto width.
1702///
1703/// The defined values for the style:text-line-through-width attribute are:
1704/// * auto: the width of a line-through should be calculated from the font size of the text where the
1705///   line-through will appear.
1706/// * bold: the width of a line-through should be calculated from the font size of the text where the
1707///   line-through will appear but is wider than for the value of auto.
1708/// * a value of type percent 18.3.23
1709/// * a value of type positiveInteger 18.2
1710/// * a value of type positiveLength 18.3.26
1711///
1712/// The line-through text styles referenced by the values dash, medium, thick and thin, are
1713/// implementation-defined. Thin shall be smaller width than medium and medium shall be a smaller
1714/// width than thick.
1715///
1716/// The values of the style:text-line-through-width attribute are auto, normal, bold,
1717/// thin, medium, thick, a value of type positiveInteger 18.2, a value of type percent
1718/// 18.3.23 or a value of type positiveLength 18.3.26.
1719#[derive(Debug, Clone, Copy, PartialEq)]
1720#[allow(missing_docs)]
1721pub enum LineWidth {
1722    Auto,
1723    Bold,
1724    Percent(Percent),
1725    Int(u32),
1726    Length(Length),
1727    Normal,
1728    Dash,
1729    Thin,
1730    Medium,
1731    Thick,
1732}
1733
1734impl From<Length> for LineWidth {
1735    fn from(value: Length) -> Self {
1736        LineWidth::Length(value)
1737    }
1738}
1739
1740impl From<Percent> for LineWidth {
1741    fn from(value: Percent) -> Self {
1742        LineWidth::Percent(value)
1743    }
1744}
1745
1746impl Display for LineWidth {
1747    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1748        match self {
1749            LineWidth::Auto => write!(f, "auto"),
1750            LineWidth::Bold => write!(f, "bold"),
1751            LineWidth::Percent(v) => write!(f, "{}", v),
1752            LineWidth::Int(v) => write!(f, "{}", v),
1753            LineWidth::Length(v) => write!(f, "{}", v),
1754            LineWidth::Normal => write!(f, "normal"),
1755            LineWidth::Dash => write!(f, "dash"),
1756            LineWidth::Thin => write!(f, "thin"),
1757            LineWidth::Medium => write!(f, "medium"),
1758            LineWidth::Thick => write!(f, "thick"),
1759        }
1760    }
1761}
1762
1763/// 20.384 style:text-position
1764///
1765/// The style:text-position attribute specifies whether text is positioned above or below the
1766/// baseline:
1767///
1768/// The value specifies the vertical text position as a percentage of the
1769/// current font height or it takes one of the values sub or super. Negative percentages or the sub
1770/// value place the text below the baseline. Positive percentages or the super value place the text
1771/// above the baseline. If sub or super is specified, the consumer chooses an appropriate text
1772/// position.
1773///
1774/// The style:text-position attribute has one or two white space separated values. The first
1775/// values is of type percent 18.3.23, or is one of: super or sub.
1776#[derive(Debug, Clone, Copy, PartialEq)]
1777#[allow(missing_docs)]
1778pub enum TextPosition {
1779    Sub,
1780    Super,
1781    Percent(Percent),
1782}
1783
1784impl From<Percent> for TextPosition {
1785    fn from(value: Percent) -> Self {
1786        TextPosition::Percent(value)
1787    }
1788}
1789
1790impl Display for TextPosition {
1791    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1792        match self {
1793            TextPosition::Sub => write!(f, "sub"),
1794            TextPosition::Super => write!(f, "super"),
1795            TextPosition::Percent(v) => write!(f, "{}", v),
1796        }
1797    }
1798}
1799
1800/// 20.386 style:text-rotation-scale
1801/// The style:text-rotation-scale attribute specifies whether for rotated text the width of the
1802/// text should be scaled to fit into the current line height or the width of the text should remain fixed,
1803/// therefore changing the current line height.
1804///
1805/// The defined values for the style:text-rotation-scale attribute are:
1806/// * fixed: width of text should remain fixed.
1807/// * line-height: width of text should be scaled to fit the current line height.
1808///
1809/// The values of the style:text-rotation-scale attribute are fixed or line-height
1810#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1811#[allow(missing_docs)]
1812pub enum RotationScale {
1813    Fixed,
1814    LineHeight,
1815}
1816
1817impl Display for RotationScale {
1818    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1819        match self {
1820            RotationScale::Fixed => write!(f, "fixed"),
1821            RotationScale::LineHeight => write!(f, "line-height"),
1822        }
1823    }
1824}
1825
1826/// 20.396 style:vertical-align
1827///
1828/// The style:vertical-align attribute specifies the vertical position of a character. By default
1829/// characters are aligned according to their baseline.
1830///
1831/// The defined values for the style:vertical-align attribute are:
1832/// * auto: automatically, which sets the vertical alignment to suit the text rotation. Text that is
1833///   rotated 0 or 90 degrees is aligned to the baseline, while text that is rotated 270 degrees is
1834///   aligned to the center of the line.
1835/// * baseline: to the baseline of the character.
1836/// * bottom: to the bottom of the line.
1837/// * middle: to the center of the line.
1838/// * top: to the top of the line.
1839///
1840/// The values of the style:vertical-align attribute are top, middle, bottom, auto or
1841/// baseline.
1842#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1843#[allow(missing_docs)]
1844pub enum ParaAlignVertical {
1845    Top,
1846    Middle,
1847    Bottom,
1848    Auto,
1849    Baseline,
1850}
1851
1852impl Display for ParaAlignVertical {
1853    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1854        match self {
1855            ParaAlignVertical::Top => write!(f, "top"),
1856            ParaAlignVertical::Middle => write!(f, "middle"),
1857            ParaAlignVertical::Bottom => write!(f, "bottom"),
1858            ParaAlignVertical::Auto => write!(f, "auto"),
1859            ParaAlignVertical::Baseline => write!(f, "baseline"),
1860        }
1861    }
1862}
1863
1864/// 20.396 style:vertical-align
1865///
1866/// The style:vertical-align attribute specifies the vertical alignment of text in a table cell. The
1867/// options for the vertical alignment attribute are as follows:
1868///
1869/// The defined values for the style:vertical-align attribute are:
1870/// * automatic: consumer determines how to align the text.
1871/// * bottom: aligns text vertically with the bottom of the cell.
1872/// * middle: aligns text vertically with the middle of the cell.
1873/// * top: aligns text vertically with the top of the cell.
1874///
1875/// The values of the style:vertical-align attribute are top, middle, bottom or
1876/// automatic.
1877#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1878#[allow(missing_docs)]
1879pub enum CellAlignVertical {
1880    Top,
1881    Middle,
1882    Bottom,
1883    Automatic,
1884}
1885
1886impl Display for CellAlignVertical {
1887    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1888        match self {
1889            CellAlignVertical::Top => write!(f, "top"),
1890            CellAlignVertical::Middle => write!(f, "middle"),
1891            CellAlignVertical::Bottom => write!(f, "bottom"),
1892            CellAlignVertical::Automatic => write!(f, "automatic"),
1893        }
1894    }
1895}
1896
1897/// 20.404 style:writing-mode
1898///
1899/// See §7.27.7 of XSL with the additional value of page.
1900/// The defined value for the style:writing-mode attribute is page: writing mode is inherited from
1901/// the page that contains the element where this attribute appears.
1902///
1903/// The values of the style:writing-mode attribute are lr-tb, rl-tb, tb-rl, tb-lr, lr, rl,
1904/// tb or page.
1905#[derive(Debug, Clone, Copy, Eq, PartialEq)]
1906#[allow(missing_docs)]
1907pub enum WritingMode {
1908    LrTb,
1909    RlTb,
1910    TbRl,
1911    TbLr,
1912    Lr,
1913    Rl,
1914    Tb,
1915    Page,
1916}
1917
1918impl Display for WritingMode {
1919    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
1920        match self {
1921            WritingMode::LrTb => write!(f, "lr-tb"),
1922            WritingMode::RlTb => write!(f, "rl-tb"),
1923            WritingMode::TbRl => write!(f, "tb-rl"),
1924            WritingMode::TbLr => write!(f, "tb-lr"),
1925            WritingMode::Lr => write!(f, "lr"),
1926            WritingMode::Rl => write!(f, "rl"),
1927            WritingMode::Tb => write!(f, "tb"),
1928            WritingMode::Page => write!(f, "page"),
1929        }
1930    }
1931}
1932
1933/// 20.414 table:align
1934///
1935/// The table:align attribute specifies the horizontal alignment of a table.
1936///
1937/// The defined values for the table:align attribute are:
1938/// * center: table aligns to the center between left and right margins.
1939/// * left: table aligns to the left margin.
1940/// * margins: table fills all the space between the left and right margins.
1941/// * right: table aligns to the right margin.
1942///
1943/// Consumers that do not support the margins value, may treat this value as left.
1944#[derive(Debug, Clone, PartialEq, Eq)]
1945#[allow(missing_docs)]
1946pub enum TableAlign {
1947    Center,
1948    Left,
1949    Right,
1950    Margins,
1951}
1952
1953impl Display for TableAlign {
1954    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1955        match self {
1956            TableAlign::Center => write!(f, "center"),
1957            TableAlign::Left => write!(f, "left"),
1958            TableAlign::Right => write!(f, "right"),
1959            TableAlign::Margins => write!(f, "margins"),
1960        }
1961    }
1962}
1963
1964/// 20.415 table:border-model
1965///
1966/// The table:border-model attribute specifies what border model to use when creating a table
1967/// with a border.
1968///
1969/// The defined values for the table:border-model attribute are:
1970/// * collapsing: when two adjacent cells have different borders, the wider border appears as
1971///   the border between the cells. Each cell receives half of the width of the border.
1972/// * separating: borders appear within the cell that specifies the border.
1973///
1974/// In OpenDocument, a row height or column width includes any space required to display borders
1975/// or padding. This means that, while the width and height of the content area is less than the
1976/// column width and row height, the sum of the widths of all columns is equal to the total width of the
1977/// table.
1978#[derive(Debug, Clone, PartialEq, Eq)]
1979#[allow(missing_docs)]
1980pub enum TableBorderModel {
1981    Collapsing,
1982    Separating,
1983}
1984
1985impl Display for TableBorderModel {
1986    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1987        match self {
1988            TableBorderModel::Collapsing => write!(f, "collapsing"),
1989            TableBorderModel::Separating => write!(f, "separating"),
1990        }
1991    }
1992}
1993
1994/// 20.426 text:condition
1995///
1996/// The text:condition attribute specifies the display of text.
1997/// The defined value of the text:condition attribute is none, which means text is hidden.
1998#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1999#[allow(missing_docs)]
2000pub enum TextCondition {
2001    None,
2002}
2003
2004impl Display for TextCondition {
2005    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2006        match self {
2007            TextCondition::None => write!(f, "none"),
2008        }
2009    }
2010}
2011
2012/// 20.427 text:display
2013///
2014/// The text:display attribute specifies whether text is hidden.
2015///
2016/// The defined values for the text:display attribute are:
2017/// * condition: text is hidden under the condition specified in the text:condition 20.426
2018///   attribute.
2019/// * none: text is hidden unconditionally.
2020/// * true: text is displayed. This is the default setting
2021#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2022#[allow(missing_docs)]
2023pub enum TextDisplay {
2024    None,
2025    Condition,
2026    True,
2027}
2028
2029impl Display for TextDisplay {
2030    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2031        match self {
2032            TextDisplay::None => write!(f, "none"),
2033            TextDisplay::Condition => write!(f, "condition"),
2034            TextDisplay::True => write!(f, "true"),
2035        }
2036    }
2037}