coradoc 2.0.2 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +65 -8
- data/coradoc-adoc/lib/coradoc/asciidoc/model/attached.rb +3 -0
- data/coradoc-adoc/lib/coradoc/asciidoc/model/base.rb +10 -0
- data/coradoc-adoc/lib/coradoc/asciidoc/model/comment_block.rb +4 -0
- data/coradoc-adoc/lib/coradoc/asciidoc/model/image/block_image.rb +4 -0
- data/coradoc-adoc/lib/coradoc/asciidoc/model/image/inline_image.rb +4 -0
- data/coradoc-adoc/lib/coradoc/asciidoc/model/inline/base.rb +3 -0
- data/coradoc-adoc/lib/coradoc/asciidoc/model/inline/hard_line_break.rb +3 -0
- data/coradoc-adoc/lib/coradoc/asciidoc/model/list/core.rb +4 -0
- data/coradoc-adoc/lib/coradoc/asciidoc/model/list/item.rb +0 -17
- data/coradoc-adoc/lib/coradoc/asciidoc/model/section.rb +4 -0
- data/coradoc-adoc/lib/coradoc/asciidoc/model/table.rb +4 -0
- data/coradoc-adoc/lib/coradoc/asciidoc/model/text_element.rb +4 -0
- data/coradoc-adoc/lib/coradoc/asciidoc/serializer/serializers/base.rb +0 -11
- data/coradoc-adoc/lib/coradoc/asciidoc/serializer/serializers/list/item.rb +4 -10
- data/coradoc-adoc/lib/coradoc/asciidoc/serializer/spacing_strategy.rb +4 -18
- data/coradoc-adoc/spec/coradoc/asciidoc/model/base_spec.rb +16 -2
- data/coradoc-adoc/spec/coradoc/asciidoc/model/element_classification_spec.rb +146 -0
- data/coradoc-docx/lib/coradoc/docx/transform/context.rb +1 -1
- data/coradoc-docx/lib/coradoc/docx/transform/from_core_model.rb +13 -6
- data/coradoc-docx/lib/coradoc/docx/transform/numbering_resolver.rb +9 -7
- data/coradoc-docx/lib/coradoc/docx/transform/ordered_content.rb +2 -2
- data/coradoc-docx/lib/coradoc/docx/transform/rules/image_rule.rb +4 -1
- data/coradoc-docx/lib/coradoc/docx/transform/rules/math_rule.rb +2 -1
- data/coradoc-docx/lib/coradoc/docx/transform/rules/run_rule.rb +17 -30
- data/coradoc-docx/lib/coradoc/docx/transform/rules/simple_field_rule.rb +3 -5
- data/coradoc-docx/lib/coradoc/docx/transform/rules/table_rule.rb +3 -4
- data/coradoc-docx/lib/coradoc/docx/transform/style_resolver.rb +19 -24
- data/coradoc-docx/lib/coradoc/docx/transform/to_core_model.rb +18 -11
- data/coradoc-html/lib/coradoc/html/base.rb +3 -7
- data/coradoc-html/lib/coradoc/html/converter_base.rb +5 -15
- data/coradoc-html/lib/coradoc/html/converters/base.rb +18 -27
- data/coradoc-html/lib/coradoc/html/converters/comment_line.rb +2 -2
- data/coradoc-html/lib/coradoc/html/converters/link.rb +1 -1
- data/coradoc-html/lib/coradoc/html/converters/list_item.rb +3 -3
- data/coradoc-html/lib/coradoc/html/converters/ordered.rb +1 -1
- data/coradoc-html/lib/coradoc/html/converters/span.rb +2 -2
- data/coradoc-html/lib/coradoc/html/converters/table.rb +3 -3
- data/coradoc-html/lib/coradoc/html/converters/table_cell.rb +14 -28
- data/coradoc-html/lib/coradoc/html/converters/table_row.rb +2 -2
- data/coradoc-html/lib/coradoc/html/converters/text_element.rb +1 -5
- data/coradoc-html/lib/coradoc/html/input/converters/a.rb +2 -2
- data/coradoc-html/lib/coradoc/html/input/converters/dl.rb +1 -1
- data/coradoc-html/lib/coradoc/html/input/converters/figure.rb +2 -2
- data/coradoc-html/lib/coradoc/html/input/converters/markup.rb +3 -3
- data/coradoc-html/lib/coradoc/html/input/converters/p.rb +1 -1
- data/coradoc-html/lib/coradoc/html/input/converters/td.rb +1 -1
- data/coradoc-html/lib/coradoc/html/input/converters.rb +1 -2
- data/coradoc-html/lib/coradoc/html/input/html_converter.rb +3 -3
- data/coradoc-html/lib/coradoc/html/input/plugin.rb +2 -2
- data/coradoc-html/lib/coradoc/html/renderer.rb +4 -6
- data/coradoc-html/lib/coradoc/html/theme/base.rb +2 -3
- data/coradoc-html/lib/coradoc/html/theme/classic_renderer.rb +9 -12
- data/coradoc-html/lib/coradoc/html/theme/modern/serializers/document_serializer.rb +3 -3
- data/coradoc-markdown/lib/coradoc/markdown/model/base.rb +6 -5
- data/coradoc-markdown/lib/coradoc/markdown/serializer.rb +2 -2
- data/coradoc-markdown/lib/coradoc/markdown/toc_generator.rb +4 -5
- data/coradoc-markdown/lib/coradoc/markdown/transformer.rb +5 -3
- data/lib/coradoc/version.rb +1 -1
- metadata +2 -1
|
@@ -18,7 +18,7 @@ module Coradoc
|
|
|
18
18
|
# @param context [Context] transform context with registry
|
|
19
19
|
# @return [Array] transformed content (Strings, InlineElements, etc.)
|
|
20
20
|
def transform_paragraph_content(paragraph, context)
|
|
21
|
-
order = paragraph.
|
|
21
|
+
order = paragraph.is_a?(Uniword::Wordprocessingml::Paragraph) ? paragraph.element_order : nil
|
|
22
22
|
|
|
23
23
|
if order && !order.empty?
|
|
24
24
|
transform_ordered(paragraph, order, context)
|
|
@@ -49,7 +49,7 @@ module Coradoc
|
|
|
49
49
|
|
|
50
50
|
result = []
|
|
51
51
|
order.each do |entry|
|
|
52
|
-
name = entry.
|
|
52
|
+
name = entry.is_a?(String) ? entry : entry.name
|
|
53
53
|
idx = counters[name]
|
|
54
54
|
counters[name] = idx + 1
|
|
55
55
|
|
|
@@ -109,7 +109,10 @@ module Coradoc
|
|
|
109
109
|
def extent_to_px(extent, dimension)
|
|
110
110
|
return nil unless extent
|
|
111
111
|
|
|
112
|
-
value =
|
|
112
|
+
value = case dimension
|
|
113
|
+
when :cx then extent.cx
|
|
114
|
+
when :cy then extent.cy
|
|
115
|
+
end
|
|
113
116
|
return nil unless value
|
|
114
117
|
|
|
115
118
|
px = value.to_i / EMU_PER_PX
|
|
@@ -66,7 +66,8 @@ module Coradoc
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
def element_to_xml(element)
|
|
69
|
-
return '' unless element.
|
|
69
|
+
return '' unless element.is_a?(Uniword::Wordprocessingml::AlternateContent) ||
|
|
70
|
+
element.is_a?(Uniword::Wordprocessingml::OMath)
|
|
70
71
|
|
|
71
72
|
element.to_xml
|
|
72
73
|
end
|
|
@@ -45,10 +45,8 @@ module Coradoc
|
|
|
45
45
|
private
|
|
46
46
|
|
|
47
47
|
def effective_props(run)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return ep if ep
|
|
51
|
-
end
|
|
48
|
+
ep = run.effective_run_properties
|
|
49
|
+
return ep if ep
|
|
52
50
|
|
|
53
51
|
run.properties
|
|
54
52
|
end
|
|
@@ -66,15 +64,12 @@ module Coradoc
|
|
|
66
64
|
result << context.transform(drawing)
|
|
67
65
|
end
|
|
68
66
|
|
|
69
|
-
|
|
70
|
-
result << "\t" if run.respond_to?(:tab) && run.tab
|
|
67
|
+
result << "\t" if run.tab
|
|
71
68
|
|
|
72
|
-
|
|
73
|
-
result << context.transform(run.o_math) if run.respond_to?(:o_math) && run.o_math
|
|
69
|
+
result << context.transform(run.o_math) if run.class.attributes.key?(:o_math) && run.o_math
|
|
74
70
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
text = run.del_text.respond_to?(:content) ? run.del_text.content.to_s : run.del_text.to_s
|
|
71
|
+
if run.del_text
|
|
72
|
+
text = run.del_text.is_a?(Uniword::Wordprocessingml::DeletedText) ? run.del_text.content.to_s : run.del_text.to_s
|
|
78
73
|
unless text.empty?
|
|
79
74
|
result << CoreModel::InlineElement.new(
|
|
80
75
|
format_type: 'strikethrough',
|
|
@@ -83,24 +78,18 @@ module Coradoc
|
|
|
83
78
|
end
|
|
84
79
|
end
|
|
85
80
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
sym = run.sym
|
|
89
|
-
char = sym.respond_to?(:char) ? sym.char : nil
|
|
81
|
+
if run.sym
|
|
82
|
+
char = run.sym.char
|
|
90
83
|
result << char.to_s if char && !char.empty?
|
|
91
84
|
end
|
|
92
85
|
|
|
93
|
-
|
|
94
|
-
result << "\u2011" if run.respond_to?(:no_break_hyphen) && run.no_break_hyphen
|
|
86
|
+
result << "\u2011" if run.no_break_hyphen
|
|
95
87
|
|
|
96
|
-
|
|
97
|
-
result << "\u00AD" if run.respond_to?(:soft_hyphen) && run.soft_hyphen
|
|
88
|
+
result << "\u00AD" if run.class.attributes.key?(:soft_hyphen) && run.soft_hyphen
|
|
98
89
|
|
|
99
|
-
|
|
100
|
-
result << CoreModel::InlineElement.new(format_type: 'hard_line_break') if run.respond_to?(:carriage_return) && run.carriage_return
|
|
90
|
+
result << CoreModel::InlineElement.new(format_type: 'hard_line_break') if run.class.attributes.key?(:carriage_return) && run.carriage_return
|
|
101
91
|
|
|
102
|
-
|
|
103
|
-
if run.respond_to?(:alternate_content) && run.alternate_content
|
|
92
|
+
if run.alternate_content
|
|
104
93
|
result << extract_alternate_content(run.alternate_content,
|
|
105
94
|
context)
|
|
106
95
|
end
|
|
@@ -109,19 +98,17 @@ module Coradoc
|
|
|
109
98
|
end
|
|
110
99
|
|
|
111
100
|
def extract_alternate_content(ac, context)
|
|
112
|
-
|
|
113
|
-
content = if ac.respond_to?(:fallback) && ac.fallback
|
|
101
|
+
content = if ac.fallback
|
|
114
102
|
ac.fallback
|
|
115
|
-
elsif ac.
|
|
103
|
+
elsif ac.choice
|
|
116
104
|
ac.choice
|
|
117
105
|
end
|
|
118
106
|
|
|
119
107
|
return nil unless content
|
|
120
108
|
|
|
121
|
-
|
|
122
|
-
if content.respond_to?(:runs)
|
|
109
|
+
if content.is_a?(Uniword::Wordprocessingml::Run)
|
|
123
110
|
content.runs&.each { |r| context.transform(r) }
|
|
124
|
-
elsif content.
|
|
111
|
+
elsif content.is_a?(Uniword::Wordprocessingml::Paragraph)
|
|
125
112
|
content.paragraphs&.flat_map { |p| context.transform(p) }
|
|
126
113
|
end
|
|
127
114
|
end
|
|
@@ -147,7 +134,7 @@ module Coradoc
|
|
|
147
134
|
return nil unless props
|
|
148
135
|
|
|
149
136
|
# Check rStyle for semantic role
|
|
150
|
-
if context.style_resolver.
|
|
137
|
+
if context.style_resolver.is_a?(Coradoc::Docx::Transform::StyleResolver)
|
|
151
138
|
role = context.style_resolver.run_semantic_role(run)
|
|
152
139
|
case role
|
|
153
140
|
when :monospace then return 'monospace'
|
|
@@ -62,19 +62,17 @@ module Coradoc
|
|
|
62
62
|
private
|
|
63
63
|
|
|
64
64
|
def field_text(field)
|
|
65
|
-
|
|
66
|
-
if field.respond_to?(:runs) && field.runs && !field.runs.empty?
|
|
65
|
+
if field.runs && !field.runs.empty?
|
|
67
66
|
return field.runs.map do |r|
|
|
68
67
|
r.text&.content.to_s
|
|
69
68
|
end.join
|
|
70
69
|
end
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
field.respond_to?(:text) ? field.text.to_s : nil
|
|
71
|
+
nil
|
|
74
72
|
end
|
|
75
73
|
|
|
76
74
|
def field_instruction(field)
|
|
77
|
-
instr = field.
|
|
75
|
+
instr = field.instr
|
|
78
76
|
instr.to_s
|
|
79
77
|
end
|
|
80
78
|
|
|
@@ -32,7 +32,7 @@ module Coradoc
|
|
|
32
32
|
def transform_row(row, context)
|
|
33
33
|
CoreModel::TableRow.new(
|
|
34
34
|
cells: row.cells.map { |c| transform_cell(c, context) },
|
|
35
|
-
header: row.
|
|
35
|
+
header: row.header?
|
|
36
36
|
)
|
|
37
37
|
end
|
|
38
38
|
|
|
@@ -69,15 +69,14 @@ module Coradoc
|
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def cell_paragraphs(cell)
|
|
72
|
-
cell.
|
|
72
|
+
cell.paragraphs || []
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
def header_cell?(cell)
|
|
76
76
|
return false unless cell.properties
|
|
77
|
-
return false unless cell.properties.respond_to?(:v_merge)
|
|
78
77
|
|
|
79
78
|
vm = cell.properties.v_merge
|
|
80
|
-
vm
|
|
79
|
+
vm&.value.to_s == 'restart'
|
|
81
80
|
end
|
|
82
81
|
end
|
|
83
82
|
end
|
|
@@ -51,18 +51,16 @@ module Coradoc
|
|
|
51
51
|
style_name = resolve_style_name(paragraph)
|
|
52
52
|
return true if style_name && HEADING_PATTERN.match?(style_name)
|
|
53
53
|
|
|
54
|
-
# Check outline_level on paragraph properties
|
|
55
54
|
ol = paragraph.properties.outline_level
|
|
56
55
|
if ol
|
|
57
|
-
ol_level = ol.
|
|
56
|
+
ol_level = ol.is_a?(Uniword::Wordprocessingml::OutlineLevel) ? ol.value.to_i : ol.to_i
|
|
58
57
|
return true if ol_level.positive?
|
|
59
58
|
end
|
|
60
59
|
|
|
61
|
-
# Check outline_level from style definition
|
|
62
60
|
style = find_style_for_paragraph(paragraph)
|
|
63
|
-
if style
|
|
61
|
+
if style&.outline_level
|
|
64
62
|
ol_val = style.outline_level
|
|
65
|
-
ol_val = ol_val.
|
|
63
|
+
ol_val = ol_val.is_a?(Uniword::Wordprocessingml::OutlineLevel) ? ol_val.value.to_i : ol_val.to_i
|
|
66
64
|
return true if ol_val.positive?
|
|
67
65
|
end
|
|
68
66
|
|
|
@@ -82,7 +80,7 @@ module Coradoc
|
|
|
82
80
|
# Check outline_level on paragraph properties
|
|
83
81
|
ol = paragraph.properties&.outline_level
|
|
84
82
|
if ol
|
|
85
|
-
level = ol.
|
|
83
|
+
level = ol.is_a?(Uniword::Wordprocessingml::OutlineLevel) ? ol.value.to_i : ol.to_i
|
|
86
84
|
return level if level.positive?
|
|
87
85
|
end
|
|
88
86
|
|
|
@@ -138,10 +136,9 @@ module Coradoc
|
|
|
138
136
|
style_ref = paragraph.properties&.style
|
|
139
137
|
return nil unless style_ref
|
|
140
138
|
|
|
141
|
-
value = style_ref.
|
|
139
|
+
value = style_ref.is_a?(Uniword::Wordprocessingml::PStyle) ? style_ref.val : style_ref.to_s
|
|
142
140
|
return nil unless value
|
|
143
141
|
|
|
144
|
-
# Check local style map first (for custom style aliases)
|
|
145
142
|
mapped = @style_map[value]
|
|
146
143
|
return mapped if mapped
|
|
147
144
|
|
|
@@ -152,7 +149,7 @@ module Coradoc
|
|
|
152
149
|
style_ref = run.properties.style
|
|
153
150
|
return nil unless style_ref
|
|
154
151
|
|
|
155
|
-
value = style_ref.
|
|
152
|
+
value = style_ref.is_a?(Uniword::Wordprocessingml::PStyle) ? style_ref.val : style_ref.to_s
|
|
156
153
|
return nil unless value
|
|
157
154
|
|
|
158
155
|
mapped = @style_map[value]
|
|
@@ -165,23 +162,21 @@ module Coradoc
|
|
|
165
162
|
style_id = style_id_from_paragraph(paragraph)
|
|
166
163
|
return nil unless style_id
|
|
167
164
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
@config.styles.find { |s| s.styleId == style_id }
|
|
172
|
-
end
|
|
165
|
+
return unless @config.is_a?(Uniword::Wordprocessingml::StylesConfiguration)
|
|
166
|
+
|
|
167
|
+
@config.style_by_id(style_id)
|
|
173
168
|
end
|
|
174
169
|
|
|
175
170
|
def style_id_from_paragraph(paragraph)
|
|
176
171
|
style_ref = paragraph.properties&.style
|
|
177
172
|
return nil unless style_ref
|
|
178
173
|
|
|
179
|
-
style_ref.
|
|
174
|
+
style_ref.is_a?(Uniword::Wordprocessingml::PStyle) ? style_ref.val : style_ref.to_s
|
|
180
175
|
end
|
|
181
176
|
|
|
182
177
|
def build_style_map(config)
|
|
183
178
|
return {} unless config
|
|
184
|
-
return {} unless config.
|
|
179
|
+
return {} unless config.is_a?(Uniword::Wordprocessingml::StylesConfiguration)
|
|
185
180
|
|
|
186
181
|
map = {}
|
|
187
182
|
config.styles.each do |style|
|
|
@@ -191,7 +186,6 @@ module Coradoc
|
|
|
191
186
|
|
|
192
187
|
map[id] = name
|
|
193
188
|
|
|
194
|
-
# Detect custom heading styles by basedOn chain
|
|
195
189
|
if heading_by_based_on?(config, style)
|
|
196
190
|
level = heading_level_from_chain(config, style)
|
|
197
191
|
map[id] = "Heading#{level}"
|
|
@@ -202,26 +196,27 @@ module Coradoc
|
|
|
202
196
|
end
|
|
203
197
|
|
|
204
198
|
def extract_style_name(style)
|
|
205
|
-
|
|
199
|
+
sn = style.style_name
|
|
200
|
+
return sn if sn
|
|
206
201
|
|
|
207
202
|
name = style.name
|
|
208
203
|
return nil unless name
|
|
209
204
|
|
|
210
|
-
name.
|
|
205
|
+
name.is_a?(Uniword::Wordprocessingml::StyleName) ? name.val.to_s : name.to_s
|
|
211
206
|
end
|
|
212
207
|
|
|
213
208
|
def heading_by_based_on?(config, style)
|
|
214
|
-
based_on = style.
|
|
209
|
+
based_on = style.based_on
|
|
215
210
|
return false unless based_on
|
|
216
211
|
|
|
217
212
|
visited = Set.new
|
|
218
213
|
current = style
|
|
219
214
|
while current && !visited.include?(current.styleId)
|
|
220
215
|
visited << current.styleId
|
|
221
|
-
parent_id = current.
|
|
216
|
+
parent_id = current.based_on
|
|
222
217
|
return true if parent_id && HEADING_PATTERN.match?(parent_id)
|
|
223
218
|
|
|
224
|
-
break unless parent_id
|
|
219
|
+
break unless parent_id
|
|
225
220
|
|
|
226
221
|
current = config.styles.find { |s| s.styleId == parent_id }
|
|
227
222
|
end
|
|
@@ -240,8 +235,8 @@ module Coradoc
|
|
|
240
235
|
return match[2].to_i if match
|
|
241
236
|
end
|
|
242
237
|
|
|
243
|
-
parent_id = current.
|
|
244
|
-
break unless parent_id
|
|
238
|
+
parent_id = current.based_on
|
|
239
|
+
break unless parent_id
|
|
245
240
|
|
|
246
241
|
current = config.styles.find { |s| s.styleId == parent_id }
|
|
247
242
|
end
|
|
@@ -129,14 +129,13 @@ module Coradoc
|
|
|
129
129
|
end
|
|
130
130
|
|
|
131
131
|
def section_break?(paragraph)
|
|
132
|
-
return false unless paragraph.
|
|
132
|
+
return false unless paragraph.is_a?(Uniword::Wordprocessingml::Paragraph)
|
|
133
133
|
return false unless paragraph.properties
|
|
134
134
|
|
|
135
135
|
sect_pr = paragraph.properties.section_properties
|
|
136
136
|
return false unless sect_pr
|
|
137
137
|
|
|
138
|
-
|
|
139
|
-
sect_pr.respond_to?(:type) && sect_pr.type
|
|
138
|
+
sect_pr.type ? true : false
|
|
140
139
|
end
|
|
141
140
|
|
|
142
141
|
def section_break_element(paragraph, context)
|
|
@@ -182,12 +181,12 @@ module Coradoc
|
|
|
182
181
|
end
|
|
183
182
|
|
|
184
183
|
def body_ordered_elements(body)
|
|
185
|
-
order = body.
|
|
184
|
+
order = body.is_a?(Uniword::Wordprocessingml::Body) ? body.element_order : nil
|
|
186
185
|
return body.elements if order.nil? || order.empty?
|
|
187
186
|
|
|
188
187
|
p_idx = tbl_idx = sdt_idx = 0
|
|
189
188
|
order.filter_map do |entry|
|
|
190
|
-
name = entry.
|
|
189
|
+
name = entry.is_a?(String) ? entry : entry.name
|
|
191
190
|
case name
|
|
192
191
|
when 'p'
|
|
193
192
|
para = body.paragraphs[p_idx]
|
|
@@ -216,7 +215,7 @@ module Coradoc
|
|
|
216
215
|
doc_footnotes = document.footnotes
|
|
217
216
|
if doc_footnotes.is_a?(Hash)
|
|
218
217
|
doc_footnotes.each do |id, fn|
|
|
219
|
-
paragraphs = fn.
|
|
218
|
+
paragraphs = fn.is_a?(Uniword::Wordprocessingml::Footnote) ? fn.paragraphs : fn[:content]
|
|
220
219
|
footnotes[id.to_s] = Array(paragraphs)
|
|
221
220
|
end
|
|
222
221
|
end
|
|
@@ -280,7 +279,10 @@ module Coradoc
|
|
|
280
279
|
end
|
|
281
280
|
|
|
282
281
|
def extract_from_parts(document, method, prefix, core_doc)
|
|
283
|
-
parts =
|
|
282
|
+
parts = case method
|
|
283
|
+
when :headers then document.headers
|
|
284
|
+
when :footers then document.footers
|
|
285
|
+
end
|
|
284
286
|
return unless parts
|
|
285
287
|
|
|
286
288
|
Array(parts).each_with_index do |part, idx|
|
|
@@ -288,13 +290,18 @@ module Coradoc
|
|
|
288
290
|
next if text.nil? || text.strip.empty?
|
|
289
291
|
next if layout_only_text?(text)
|
|
290
292
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
+
part_type = if part.is_a?(Uniword::Wordprocessingml::Header) ||
|
|
294
|
+
part.is_a?(Uniword::Wordprocessingml::Footer)
|
|
295
|
+
part.type
|
|
296
|
+
else
|
|
297
|
+
idx
|
|
298
|
+
end
|
|
299
|
+
core_doc.set_metadata("docx.#{prefix}.#{part_type}", text.strip)
|
|
293
300
|
end
|
|
294
301
|
end
|
|
295
302
|
|
|
296
303
|
def extract_part_text(part)
|
|
297
|
-
paragraphs = part.
|
|
304
|
+
paragraphs = part.paragraphs || []
|
|
298
305
|
return nil unless paragraphs
|
|
299
306
|
|
|
300
307
|
paragraphs.map do |para|
|
|
@@ -303,7 +310,7 @@ module Coradoc
|
|
|
303
310
|
end
|
|
304
311
|
|
|
305
312
|
def extract_paragraph_text_content(para)
|
|
306
|
-
runs = para.
|
|
313
|
+
runs = para.runs || []
|
|
307
314
|
return nil unless runs
|
|
308
315
|
|
|
309
316
|
runs.map { |r| r.text&.content.to_s }.join
|
|
@@ -125,14 +125,10 @@ module Coradoc
|
|
|
125
125
|
def extract_attributes(model)
|
|
126
126
|
attrs = {}
|
|
127
127
|
|
|
128
|
-
|
|
129
|
-
attrs[:
|
|
128
|
+
attrs[:id] = model.id if model.id
|
|
129
|
+
attrs[:title] = model.title if model.title
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
attrs[:title] = model.title if model.respond_to?(:title) && model.title
|
|
133
|
-
|
|
134
|
-
# Extract class/role if available
|
|
135
|
-
if model.respond_to?(:metadata) && model.metadata
|
|
131
|
+
if model.is_a?(Coradoc::CoreModel::StructuralElement) && model.metadata
|
|
136
132
|
attrs[:class] = model.metadata[:class] || model.metadata[:role]
|
|
137
133
|
attrs.merge!(model.metadata.except(:class, :role))
|
|
138
134
|
end
|
|
@@ -118,25 +118,19 @@ module Coradoc
|
|
|
118
118
|
# @param config [Hash, Object] Configuration options or object
|
|
119
119
|
# @return [Object] Built configuration object
|
|
120
120
|
def build_config(config)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
config.validate! if config.respond_to?(:validate!)
|
|
121
|
+
if config.public_methods.include?(:validate!)
|
|
122
|
+
config.validate!
|
|
124
123
|
return config
|
|
125
124
|
end
|
|
126
125
|
|
|
127
|
-
# Otherwise, build from hash (subclasses should override this)
|
|
128
126
|
config
|
|
129
127
|
end
|
|
130
128
|
|
|
131
|
-
# Extract document title
|
|
132
|
-
#
|
|
133
|
-
# @return [String] Document title
|
|
134
129
|
def extract_document_title
|
|
135
|
-
|
|
136
|
-
if @document.respond_to?(:title) && @document.title
|
|
130
|
+
if @document.is_a?(Coradoc::CoreModel::StructuralElement) && @document.title
|
|
137
131
|
title = @document.title
|
|
138
132
|
return title if title.is_a?(String)
|
|
139
|
-
return title.text if title.
|
|
133
|
+
return title.text if title.is_a?(Coradoc::CoreModel::Base) && title.text
|
|
140
134
|
|
|
141
135
|
return title.to_s
|
|
142
136
|
end
|
|
@@ -144,10 +138,6 @@ module Coradoc
|
|
|
144
138
|
'Untitled Document'
|
|
145
139
|
end
|
|
146
140
|
|
|
147
|
-
# Extract text from content (array of inline elements)
|
|
148
|
-
#
|
|
149
|
-
# @param content [Array] Content elements
|
|
150
|
-
# @return [String] Extracted text
|
|
151
141
|
def extract_text_from_content(content)
|
|
152
142
|
case content
|
|
153
143
|
when Array
|
|
@@ -157,7 +147,7 @@ module Coradoc
|
|
|
157
147
|
when Coradoc::CoreModel::InlineElement
|
|
158
148
|
content.content.to_s
|
|
159
149
|
when Coradoc::CoreModel::Base
|
|
160
|
-
if content.
|
|
150
|
+
if content.content
|
|
161
151
|
extract_text_from_content(content.content)
|
|
162
152
|
else
|
|
163
153
|
content.to_s
|
|
@@ -434,37 +434,28 @@ module Coradoc
|
|
|
434
434
|
|
|
435
435
|
# Extract text from unknown model types as a fallback
|
|
436
436
|
def extract_text_fallback(content)
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
return text_val.to_s if text_val.respond_to?(:to_s)
|
|
442
|
-
end
|
|
437
|
+
if content.is_a?(Coradoc::CoreModel::Base)
|
|
438
|
+
if content.class.attributes.key?(:text) && content.text
|
|
439
|
+
text_val = content.text
|
|
440
|
+
return text_val if text_val.is_a?(String)
|
|
443
441
|
|
|
444
|
-
|
|
445
|
-
if content.respond_to?(:content) && content.content
|
|
446
|
-
content_val = content.content
|
|
447
|
-
if content_val.is_a?(String)
|
|
448
|
-
return content_val
|
|
449
|
-
elsif content_val.is_a?(Array)
|
|
450
|
-
return content_val.map { |item| convert_content_to_html(item, {}) }.join
|
|
442
|
+
return text_val.to_s
|
|
451
443
|
end
|
|
452
|
-
end
|
|
453
|
-
|
|
454
|
-
# Try href attribute (for cross-references)
|
|
455
|
-
return content.href.to_s if content.respond_to?(:href) && content.href
|
|
456
444
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
445
|
+
if content.class.attributes.key?(:content) && content.content
|
|
446
|
+
content_val = content.content
|
|
447
|
+
if content_val.is_a?(String)
|
|
448
|
+
return content_val
|
|
449
|
+
elsif content_val.is_a?(Array)
|
|
450
|
+
return content_val.map { |item| convert_content_to_html(item, {}) }.join
|
|
451
|
+
end
|
|
452
|
+
end
|
|
465
453
|
|
|
466
|
-
|
|
467
|
-
|
|
454
|
+
return content.href.to_s if content.class.attributes.key?(:href) && content.href
|
|
455
|
+
return content.term.to_s if content.class.attributes.key?(:term) && content.term
|
|
456
|
+
return content.id.to_s if content.class.attributes.key?(:id) && content.id
|
|
457
|
+
return content.name.to_s if content.class.attributes.key?(:name) && content.name
|
|
458
|
+
end
|
|
468
459
|
|
|
469
460
|
''
|
|
470
461
|
end
|
|
@@ -12,9 +12,9 @@ module Coradoc
|
|
|
12
12
|
return '' unless options[:preserve_comments]
|
|
13
13
|
|
|
14
14
|
# Get comment text - check for content or text attribute
|
|
15
|
-
text = if comment.
|
|
15
|
+
text = if comment.content
|
|
16
16
|
comment.content
|
|
17
|
-
elsif comment.
|
|
17
|
+
elsif comment.text
|
|
18
18
|
comment.text
|
|
19
19
|
else
|
|
20
20
|
''
|
|
@@ -11,7 +11,7 @@ module Coradoc
|
|
|
11
11
|
attrs[:id] = model.id if model.id
|
|
12
12
|
|
|
13
13
|
# Get title from metadata
|
|
14
|
-
if model.
|
|
14
|
+
if model.metadata && model.metadata[:title]
|
|
15
15
|
attrs[:title] =
|
|
16
16
|
model.metadata[:title]
|
|
17
17
|
end
|
|
@@ -50,18 +50,18 @@ module Coradoc
|
|
|
50
50
|
parts = []
|
|
51
51
|
|
|
52
52
|
# Convert main content - check children first (mixed content), then content
|
|
53
|
-
content_to_render = model.
|
|
53
|
+
content_to_render = model.children&.any? ? model.children : model.content
|
|
54
54
|
parts << convert_content_to_html(content_to_render, state) if content_to_render
|
|
55
55
|
|
|
56
56
|
# Convert attached content
|
|
57
|
-
if model.
|
|
57
|
+
if model.attached && !model.attached.empty?
|
|
58
58
|
model.attached.each do |attached_item|
|
|
59
59
|
parts << convert_content_to_html(attached_item, state)
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
# Convert nested list
|
|
64
|
-
parts << convert_content_to_html(model.nested, state) if model.
|
|
64
|
+
parts << convert_content_to_html(model.nested, state) if model.nested
|
|
65
65
|
|
|
66
66
|
attrs = {}
|
|
67
67
|
attrs[:id] = model.id if model.id
|
|
@@ -42,7 +42,7 @@ module Coradoc
|
|
|
42
42
|
attrs[:id] = model.id if model.id
|
|
43
43
|
|
|
44
44
|
# Add start attribute if not starting from 1
|
|
45
|
-
attrs[:start] = model.start if model.
|
|
45
|
+
attrs[:start] = model.start if model.start && model.start != 1
|
|
46
46
|
|
|
47
47
|
build_element('ol', "\n#{items_html}\n", attrs)
|
|
48
48
|
end
|
|
@@ -39,7 +39,7 @@ module Coradoc
|
|
|
39
39
|
# @return [String] HTML string
|
|
40
40
|
def to_html(model, state = {})
|
|
41
41
|
# Prefer children for mixed content, fall back to content
|
|
42
|
-
content = if model.
|
|
42
|
+
content = if model.children&.any?
|
|
43
43
|
model.children.map { |c| convert_content_to_html(c, state) }.join
|
|
44
44
|
else
|
|
45
45
|
escape_html(model.content || '')
|
|
@@ -47,7 +47,7 @@ module Coradoc
|
|
|
47
47
|
|
|
48
48
|
# Build attributes from metadata
|
|
49
49
|
attrs = {}
|
|
50
|
-
if model.
|
|
50
|
+
if model.metadata && model.metadata[:class]
|
|
51
51
|
attrs[:class] =
|
|
52
52
|
model.metadata[:class]
|
|
53
53
|
end
|
|
@@ -48,16 +48,16 @@ module Coradoc
|
|
|
48
48
|
attrs = []
|
|
49
49
|
|
|
50
50
|
# Add ID if present
|
|
51
|
-
attrs << %( id="#{escape_attribute(table.id)}") if table.
|
|
51
|
+
attrs << %( id="#{escape_attribute(table.id)}") if table.id
|
|
52
52
|
|
|
53
53
|
# CoreModel::Table with frame attribute
|
|
54
|
-
attrs << %( class="frame-#{escape_attribute(table.frame)}") if table.
|
|
54
|
+
attrs << %( class="frame-#{escape_attribute(table.frame)}") if table.frame
|
|
55
55
|
|
|
56
56
|
attrs.join
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def self.build_caption(table)
|
|
60
|
-
return nil unless table.
|
|
60
|
+
return nil unless table.title
|
|
61
61
|
|
|
62
62
|
caption_text = table.title.to_s
|
|
63
63
|
return nil if caption_text.empty?
|