1use std::cell::RefCell;
2use std::collections::HashMap;
3
4use crate::model::{
5 ParagraphSpacing, ParagraphStyle, ParagraphStyleDefinition, TableAlignment, TableBorderSet,
6 TableBoxSpacing, TableFloating, TableLayout, TablePreferredWidth, TextStyle,
7};
8use crate::package::OoxmlPart;
9
10#[derive(Clone, Debug, Default, PartialEq, Eq)]
12pub struct ContentTypeLookup {
13 pub default_by_extension: HashMap<String, String>,
14 pub override_by_part_name: HashMap<String, String>,
15}
16
17#[derive(Clone, Debug, Default, PartialEq, Eq)]
19pub struct ThemeFontMap {
20 pub major_latin: Option<String>,
21 pub minor_latin: Option<String>,
22 pub major_east_asia: Option<String>,
23 pub minor_east_asia: Option<String>,
24 pub major_complex_script: Option<String>,
25 pub minor_complex_script: Option<String>,
26}
27
28pub type ThemeColorMap = HashMap<String, String>;
30
31#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
33pub enum TableConditionalStyleType {
34 WholeTable,
35 FirstRow,
36 LastRow,
37 FirstCol,
38 LastCol,
39 Band1Horz,
40 Band2Horz,
41 Band1Vert,
42 Band2Vert,
43 NwCell,
44 NeCell,
45 SwCell,
46 SeCell,
47}
48
49impl TableConditionalStyleType {
50 pub const ALL: [TableConditionalStyleType; 13] = [
51 TableConditionalStyleType::WholeTable,
52 TableConditionalStyleType::FirstRow,
53 TableConditionalStyleType::LastRow,
54 TableConditionalStyleType::FirstCol,
55 TableConditionalStyleType::LastCol,
56 TableConditionalStyleType::Band1Horz,
57 TableConditionalStyleType::Band2Horz,
58 TableConditionalStyleType::Band1Vert,
59 TableConditionalStyleType::Band2Vert,
60 TableConditionalStyleType::NwCell,
61 TableConditionalStyleType::NeCell,
62 TableConditionalStyleType::SwCell,
63 TableConditionalStyleType::SeCell,
64 ];
65}
66
67#[derive(Clone, Debug, PartialEq)]
69pub struct ParsedTableLook {
70 pub first_row: bool,
71 pub last_row: bool,
72 pub first_col: bool,
73 pub last_col: bool,
74 pub no_h_band: bool,
75 pub no_v_band: bool,
76 pub row_band_size: i64,
77 pub col_band_size: i64,
78}
79
80#[derive(Clone, Debug, Default, PartialEq)]
82pub struct ParsedTableProperties {
83 pub width_twips: Option<i64>,
84 pub preferred_width: Option<TablePreferredWidth>,
85 pub alignment: Option<TableAlignment>,
86 pub bidi_visual: Option<bool>,
87 pub indent_twips: Option<i64>,
88 pub layout: Option<TableLayout>,
89 pub cell_spacing_twips: Option<i64>,
90 pub cell_margin_twips: Option<TableBoxSpacing>,
91 pub floating: Option<TableFloating>,
92}
93
94#[derive(Clone, Debug, Default, PartialEq)]
96pub struct ParsedTableStyleCondition {
97 pub row_background_color: Option<String>,
98 pub cell_background_color: Option<String>,
99 pub cell_preferred_width: Option<TablePreferredWidth>,
100 pub paragraph_align: Option<crate::model::ParagraphAlignment>,
101 pub paragraph_snap_to_grid: Option<bool>,
102 pub paragraph_text_alignment: Option<crate::model::ParagraphTextAlignment>,
103 pub run_style: Option<TextStyle>,
104 pub table_borders: Option<TableBorderSet>,
105 pub cell_borders: Option<TableBorderSet>,
106 pub table_properties: Option<ParsedTableProperties>,
107 pub table_look: Option<ParsedTableLook>,
108}
109
110#[derive(Clone, Debug, PartialEq)]
112pub struct ParsedTableStyleDefinition {
113 pub id: String,
114 pub based_on_id: Option<String>,
115 pub name: String,
116 pub conditions: HashMap<TableConditionalStyleType, ParsedTableStyleCondition>,
117 pub floating: Option<TableFloating>,
118 pub properties: Option<ParsedTableProperties>,
119 pub has_row_cell_spacing: bool,
120}
121
122#[derive(Clone, Debug, PartialEq)]
124pub struct ParsedStyleSheet {
125 pub paragraph_styles: Vec<ParagraphStyleDefinition>,
126 pub paragraph_style_by_id: HashMap<String, ParagraphStyleDefinition>,
127 pub run_style_by_id: HashMap<String, TextStyle>,
128 pub table_style_by_id: HashMap<String, ParsedTableStyleDefinition>,
129 pub default_table_style_id: Option<String>,
130 pub table_paragraph_spacing_by_style_id: HashMap<String, ParagraphSpacing>,
134 pub doc_default_paragraph_spacing: Option<ParagraphSpacing>,
135 pub default_paragraph_style: Option<ParagraphStyle>,
136 pub default_paragraph_text_alignment: Option<crate::model::ParagraphTextAlignment>,
137 pub default_paragraph_style_id: Option<String>,
138 pub default_run_style: Option<TextStyle>,
139 pub theme_fonts: ThemeFontMap,
140 pub theme_colors: ThemeColorMap,
141}
142
143impl ParsedStyleSheet {
144 pub fn empty() -> Self {
145 empty_style_sheet()
146 }
147}
148
149pub fn empty_style_sheet() -> ParsedStyleSheet {
151 ParsedStyleSheet {
152 paragraph_styles: Vec::new(),
153 paragraph_style_by_id: HashMap::new(),
154 run_style_by_id: HashMap::new(),
155 table_style_by_id: HashMap::new(),
156 default_table_style_id: None,
157 table_paragraph_spacing_by_style_id: HashMap::new(),
158 doc_default_paragraph_spacing: None,
159 default_paragraph_style: None,
160 default_paragraph_text_alignment: None,
161 default_paragraph_style_id: None,
162 default_run_style: None,
163 theme_fonts: ThemeFontMap::default(),
164 theme_colors: ThemeColorMap::new(),
165 }
166}
167
168pub fn default_table_look() -> ParsedTableLook {
169 ParsedTableLook {
170 first_row: false,
171 last_row: false,
172 first_col: false,
173 last_col: false,
174 no_h_band: true,
175 no_v_band: true,
176 row_band_size: 1,
177 col_band_size: 1,
178 }
179}
180
181pub struct ParseContext<'a, S = ParsedStyleSheet> {
183 pub relationships: HashMap<String, String>,
184 pub content_types: ContentTypeLookup,
185 pub parts: &'a HashMap<String, OoxmlPart>,
186 pub binary_assets: &'a HashMap<String, Vec<u8>>,
187 pub style_sheet: S,
188 pub warnings: RefCell<Vec<String>>,
189}
190
191impl<'a, S: std::borrow::Borrow<ParsedStyleSheet>> ParseContext<'a, S> {
192 pub fn styles(&self) -> &ParsedStyleSheet {
193 self.style_sheet.borrow()
194 }
195
196 pub fn push_warning(&self, message: impl Into<String>) {
197 self.warnings.borrow_mut().push(message.into());
198 }
199}