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