coradoc-docx 0.1.3 → 0.1.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/lib/coradoc/docx/transform/from_core_model.rb +21 -5
- data/lib/coradoc/docx/transform/frontmatter_core_properties.rb +1 -1
- data/lib/coradoc/docx/transform/numbering_access.rb +62 -0
- data/lib/coradoc/docx/transform/rules/list_item_rule.rb +2 -1
- data/lib/coradoc/docx/transform/rules/math_rule.rb +7 -49
- data/lib/coradoc/docx/transform/rules/run_rule.rb +5 -3
- data/lib/coradoc/docx/transform/rules/simple_field_rule.rb +1 -1
- data/lib/coradoc/docx/transform/rules/table_rule.rb +14 -1
- data/lib/coradoc/docx/transform/style_resolver.rb +16 -18
- data/lib/coradoc/docx/transform/to_core_model.rb +7 -5
- data/lib/coradoc/docx/transform.rb +1 -0
- data/lib/coradoc/docx/version.rb +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 18f25e708f14692cd5a7b48a8636e34df3eee0b5ac3fa8a7f0904a5f56acbeaa
|
|
4
|
+
data.tar.gz: b15177104fe5b8b50635fb6856fa059856c0fb4abfea48efaf15a7bb0cad0a20
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9889857c0c723281bc2c45903c31898b8881d49ff431a7aef699882a74dd1243009f9d1cbd548bc9970f09131b34316743a90d00ee99e6ce9f7509dec7f3276a
|
|
7
|
+
data.tar.gz: b1a47163cdb94d6ecc07d0d0fb4ca1a36eb9539867620f5b7ad861aa7d789fedaaa6018d5731855938ba164b47ae35874d6fb29d028f67e6567221619a2cfdbd
|
|
@@ -234,6 +234,14 @@ module Coradoc
|
|
|
234
234
|
builder.table do |t|
|
|
235
235
|
table.rows.each do |row|
|
|
236
236
|
t.row do |r|
|
|
237
|
+
# TableRowBuilder#header_row is broken upstream (calls a
|
|
238
|
+
# nonexistent table_header= setter), so set the persisted
|
|
239
|
+
# w:tblHeader property on the row model directly
|
|
240
|
+
if row.header
|
|
241
|
+
r.model.properties = Uniword::Wordprocessingml::TableRowProperties.new(
|
|
242
|
+
tbl_header: Uniword::Wordprocessingml::ValInt.new(value: 1)
|
|
243
|
+
)
|
|
244
|
+
end
|
|
237
245
|
row.cells.each do |cell|
|
|
238
246
|
r.cell(text: cell.flat_text)
|
|
239
247
|
end
|
|
@@ -295,7 +303,9 @@ module Coradoc
|
|
|
295
303
|
|
|
296
304
|
props = Uniword::Wordprocessingml::RunProperties.new
|
|
297
305
|
|
|
298
|
-
|
|
306
|
+
# resolve_format_type covers typed subclasses (BoldElement etc.)
|
|
307
|
+
# that carry no explicit format_type attribute
|
|
308
|
+
case inline.resolve_format_type
|
|
299
309
|
when 'bold'
|
|
300
310
|
props.bold = Uniword::Properties::Bold.new
|
|
301
311
|
when 'italic'
|
|
@@ -355,6 +365,11 @@ module Coradoc
|
|
|
355
365
|
|
|
356
366
|
table.rows.each do |row|
|
|
357
367
|
tr = Uniword::Wordprocessingml::TableRow.new
|
|
368
|
+
if row.header
|
|
369
|
+
tr.properties = Uniword::Wordprocessingml::TableRowProperties.new(
|
|
370
|
+
tbl_header: Uniword::Wordprocessingml::ValInt.new(value: 1)
|
|
371
|
+
)
|
|
372
|
+
end
|
|
358
373
|
row.cells.each do |cell|
|
|
359
374
|
tc = Uniword::Wordprocessingml::TableCell.new
|
|
360
375
|
|
|
@@ -395,8 +410,7 @@ module Coradoc
|
|
|
395
410
|
def build_page_break
|
|
396
411
|
para = Uniword::Wordprocessingml::Paragraph.new
|
|
397
412
|
run = Uniword::Wordprocessingml::Run.new
|
|
398
|
-
run.break = Uniword::Wordprocessingml::Break.new
|
|
399
|
-
run.break.type = 'page'
|
|
413
|
+
run.break = Uniword::Wordprocessingml::Break.new(type: 'page')
|
|
400
414
|
para.runs << run
|
|
401
415
|
para
|
|
402
416
|
end
|
|
@@ -404,7 +418,9 @@ module Coradoc
|
|
|
404
418
|
def build_inline_text(inline)
|
|
405
419
|
text = inline.content.to_s
|
|
406
420
|
|
|
407
|
-
|
|
421
|
+
# resolve_format_type covers typed subclasses (BoldElement etc.)
|
|
422
|
+
# that carry no explicit format_type attribute
|
|
423
|
+
case inline.resolve_format_type
|
|
408
424
|
when 'bold' then Uniword::Builder.text(text, bold: true)
|
|
409
425
|
when 'italic' then Uniword::Builder.text(text, italic: true)
|
|
410
426
|
when 'underline' then Uniword::Builder.text(text, underline: true)
|
|
@@ -415,7 +431,7 @@ module Coradoc
|
|
|
415
431
|
run = Uniword::Wordprocessingml::Run.new(text: text)
|
|
416
432
|
props = Uniword::Wordprocessingml::RunProperties.new
|
|
417
433
|
va = Uniword::Properties::VerticalAlign.new
|
|
418
|
-
va.value = inline.
|
|
434
|
+
va.value = inline.resolve_format_type
|
|
419
435
|
props.vertical_align = va
|
|
420
436
|
run.properties = props
|
|
421
437
|
run
|
|
@@ -39,7 +39,7 @@ module Coradoc
|
|
|
39
39
|
def apply(builder, block)
|
|
40
40
|
return unless block.is_a?(Coradoc::CoreModel::FrontmatterBlock)
|
|
41
41
|
|
|
42
|
-
data = block
|
|
42
|
+
data = Coradoc::CoreModel::FrontmatterBlock::Codec.to_hash(block)
|
|
43
43
|
|
|
44
44
|
if (v = find_first_scalar(data, KEYWORDS_KEYS))
|
|
45
45
|
builder.keywords(v)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Coradoc
|
|
4
|
+
module Docx
|
|
5
|
+
module Transform
|
|
6
|
+
# Shared access to a paragraph's numbering (list) attributes.
|
|
7
|
+
#
|
|
8
|
+
# uniword persists w:numPr as NESTED properties:
|
|
9
|
+
# paragraph.properties.numbering_properties.num_id.value
|
|
10
|
+
# paragraph.properties.numbering_properties.ilvl.value
|
|
11
|
+
# while the flat integers (properties.num_id / properties.ilvl) are
|
|
12
|
+
# only populated programmatically (builder/YAML API). Readers must
|
|
13
|
+
# consult the nested shape first and fall back to the flat one —
|
|
14
|
+
# documents deserialized from DOCX only ever carry the nested shape.
|
|
15
|
+
#
|
|
16
|
+
# lutaml-model also returns an UninitializedClass sentinel for
|
|
17
|
+
# attributes that were not deserialized from source, so every read
|
|
18
|
+
# is guarded by an Integer type check instead of truthiness.
|
|
19
|
+
module NumberingAccess
|
|
20
|
+
# Numbering definition ID (w:numId) for a paragraph.
|
|
21
|
+
#
|
|
22
|
+
# @param paragraph [Uniword::Wordprocessingml::Paragraph]
|
|
23
|
+
# @return [Integer, nil]
|
|
24
|
+
def paragraph_num_id(paragraph)
|
|
25
|
+
nested_numbering_value(paragraph, :num_id)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Numbering level (w:ilvl) for a paragraph.
|
|
29
|
+
#
|
|
30
|
+
# @param paragraph [Uniword::Wordprocessingml::Paragraph]
|
|
31
|
+
# @return [Integer, nil]
|
|
32
|
+
def paragraph_ilvl(paragraph)
|
|
33
|
+
nested_numbering_value(paragraph, :ilvl)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def nested_numbering_value(paragraph, attribute)
|
|
39
|
+
numbering = paragraph_properties(paragraph)&.numbering_properties
|
|
40
|
+
nested = numbering&.public_send(attribute)
|
|
41
|
+
value = wrapper_value(nested)
|
|
42
|
+
return value if value.is_a?(Integer)
|
|
43
|
+
|
|
44
|
+
# Fall back to the flat builder/YAML attribute
|
|
45
|
+
flat = paragraph_properties(paragraph)&.public_send(attribute)
|
|
46
|
+
flat.is_a?(Integer) ? flat : nil
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def paragraph_properties(paragraph)
|
|
50
|
+
paragraph.properties if paragraph.respond_to?(:properties)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Unwrap w:numId / w:ilvl element models to their value; sentinel
|
|
54
|
+
# objects (UninitializedClass) and nils fail the Integer check.
|
|
55
|
+
def wrapper_value(node)
|
|
56
|
+
value = node.respond_to?(:value) ? node.value : node
|
|
57
|
+
value.is_a?(Integer) ? value : nil
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -17,13 +17,14 @@ module Coradoc
|
|
|
17
17
|
# dispatches directly after checking style_resolver.list_item?.
|
|
18
18
|
class ListItemRule < Rule
|
|
19
19
|
include OrderedContent
|
|
20
|
+
include NumberingAccess
|
|
20
21
|
|
|
21
22
|
def matches?(_element)
|
|
22
23
|
false # Never auto-matched; orchestrator dispatches directly
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
def apply(paragraph, context)
|
|
26
|
-
ilvl = paragraph.
|
|
27
|
+
ilvl = paragraph_ilvl(paragraph).to_i
|
|
27
28
|
|
|
28
29
|
children = transform_paragraph_content(paragraph, context)
|
|
29
30
|
|
|
@@ -6,23 +6,20 @@ module Coradoc
|
|
|
6
6
|
module Rules
|
|
7
7
|
# Transforms OMML math elements to CoreModel.
|
|
8
8
|
#
|
|
9
|
-
# Display math (
|
|
10
|
-
# Inline math (
|
|
9
|
+
# Display math (MathEquation#block?) → CoreModel::Block (stem)
|
|
10
|
+
# Inline math (MathEquation#inline?) → CoreModel::InlineElement (stem)
|
|
11
11
|
#
|
|
12
|
-
#
|
|
13
|
-
# Falls back to raw XML string when Plurimath is not loaded.
|
|
12
|
+
# LaTeX conversion is provided natively by Uniword::MathEquation.
|
|
14
13
|
class MathRule < Rule
|
|
15
14
|
def matches?(element)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
element.is_a?(Uniword::Math::OMathPara) ||
|
|
19
|
-
element.is_a?(Uniword::Math::OMath)
|
|
15
|
+
defined?(Uniword::MathEquation) &&
|
|
16
|
+
element.is_a?(Uniword::MathEquation)
|
|
20
17
|
end
|
|
21
18
|
|
|
22
19
|
def apply(element, _context)
|
|
23
|
-
latex =
|
|
20
|
+
latex = element.to_latex.to_s
|
|
24
21
|
|
|
25
|
-
if
|
|
22
|
+
if element.block?
|
|
26
23
|
CoreModel::PassBlock.new(
|
|
27
24
|
delimiter_type: '++++',
|
|
28
25
|
language: 'latexmath',
|
|
@@ -35,45 +32,6 @@ module Coradoc
|
|
|
35
32
|
)
|
|
36
33
|
end
|
|
37
34
|
end
|
|
38
|
-
|
|
39
|
-
private
|
|
40
|
-
|
|
41
|
-
def display_math?(element)
|
|
42
|
-
defined?(Uniword::Math::OMathPara) &&
|
|
43
|
-
element.is_a?(Uniword::Math::OMathPara)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def omml_to_latex(element)
|
|
47
|
-
if defined?(Plurimath)
|
|
48
|
-
plurimath_to_latex(element)
|
|
49
|
-
else
|
|
50
|
-
# Fallback: serialize to XML string
|
|
51
|
-
element_respond_to_xml(element) || ''
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def plurimath_to_latex(element)
|
|
56
|
-
xml = element_to_xml(element)
|
|
57
|
-
return '' if xml.nil? || xml.empty?
|
|
58
|
-
|
|
59
|
-
begin
|
|
60
|
-
formula = Plurimath::OMML.parse(xml)
|
|
61
|
-
formula.to_latex
|
|
62
|
-
rescue StandardError
|
|
63
|
-
''
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def element_to_xml(element)
|
|
68
|
-
return '' unless element.is_a?(Uniword::Wordprocessingml::AlternateContent) ||
|
|
69
|
-
element.is_a?(Uniword::Wordprocessingml::OMath)
|
|
70
|
-
|
|
71
|
-
element.to_xml
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def element_respond_to_xml(element)
|
|
75
|
-
element_to_xml(element)
|
|
76
|
-
end
|
|
77
35
|
end
|
|
78
36
|
end
|
|
79
37
|
end
|
|
@@ -25,9 +25,11 @@ module Coradoc
|
|
|
25
25
|
def apply(run, context)
|
|
26
26
|
# Delegate non-text children (breaks, drawings, footnotes, etc.)
|
|
27
27
|
non_text = extract_non_text_children(run, context)
|
|
28
|
-
return non_text.first if non_text.any? && run.text.
|
|
28
|
+
return non_text.first if non_text.any? && Array(run.text).empty?
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
# w:r may carry several w:t children (uniword models text as
|
|
31
|
+
# a collection) — join them in document order
|
|
32
|
+
text = Array(run.text).map { |node| node&.content.to_s }.join
|
|
31
33
|
return '' if text.empty? && non_text.empty?
|
|
32
34
|
|
|
33
35
|
props = effective_props(run)
|
|
@@ -54,7 +56,7 @@ module Coradoc
|
|
|
54
56
|
def extract_non_text_children(run, context)
|
|
55
57
|
result = []
|
|
56
58
|
|
|
57
|
-
result
|
|
59
|
+
result.concat(Array(run.break).map { |brk| context.transform(brk) })
|
|
58
60
|
|
|
59
61
|
result << context.transform(run.footnote_reference) if run.footnote_reference
|
|
60
62
|
|
|
@@ -32,10 +32,23 @@ 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?(row)
|
|
36
36
|
)
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
# The persisted header flag lives in w:trPr/w:tblHeader
|
|
40
|
+
# (row.properties.tbl_header); TableRow#header? is a runtime-only
|
|
41
|
+
# accessor that deserialized documents never populate.
|
|
42
|
+
def row_header?(row)
|
|
43
|
+
tbl_header = row.properties&.tbl_header
|
|
44
|
+
return row.header? unless tbl_header.is_a?(Uniword::Wordprocessingml::ValInt)
|
|
45
|
+
|
|
46
|
+
# <w:tblHeader/> without w:val means "on" (ST_OnOff semantics)
|
|
47
|
+
return true if tbl_header.value.nil?
|
|
48
|
+
|
|
49
|
+
tbl_header.value.to_i.positive?
|
|
50
|
+
end
|
|
51
|
+
|
|
39
52
|
def transform_cell(cell, context)
|
|
40
53
|
inline_children = cell_paragraphs(cell).flat_map do |para|
|
|
41
54
|
extract_inline_from_paragraph(para, context)
|
|
@@ -15,6 +15,8 @@ module Coradoc
|
|
|
15
15
|
# The style map is built from the Uniword StylesConfiguration by walking
|
|
16
16
|
# all style definitions and their basedOn chains.
|
|
17
17
|
class StyleResolver
|
|
18
|
+
include NumberingAccess
|
|
19
|
+
|
|
18
20
|
HEADING_PATTERN = /^(heading|heading|h)\s*(\d+)$/i
|
|
19
21
|
QUOTE_PATTERN = /\bquote\b/i
|
|
20
22
|
CODE_PATTERN = /\b(code|source|listing)\b/i
|
|
@@ -53,14 +55,14 @@ module Coradoc
|
|
|
53
55
|
|
|
54
56
|
ol = paragraph.properties.outline_level
|
|
55
57
|
if ol
|
|
56
|
-
ol_level = ol.is_a?(Uniword::
|
|
58
|
+
ol_level = ol.is_a?(Uniword::Properties::OutlineLevel) ? ol.value.to_i : ol.to_i
|
|
57
59
|
return true if ol_level.positive?
|
|
58
60
|
end
|
|
59
61
|
|
|
60
62
|
style = find_style_for_paragraph(paragraph)
|
|
61
63
|
if style&.outline_level
|
|
62
64
|
ol_val = style.outline_level
|
|
63
|
-
ol_val = ol_val.is_a?(Uniword::
|
|
65
|
+
ol_val = ol_val.is_a?(Uniword::Properties::OutlineLevel) ? ol_val.value.to_i : ol_val.to_i
|
|
64
66
|
return true if ol_val.positive?
|
|
65
67
|
end
|
|
66
68
|
|
|
@@ -80,7 +82,7 @@ module Coradoc
|
|
|
80
82
|
# Check outline_level on paragraph properties
|
|
81
83
|
ol = paragraph.properties&.outline_level
|
|
82
84
|
if ol
|
|
83
|
-
level = ol.is_a?(Uniword::
|
|
85
|
+
level = ol.is_a?(Uniword::Properties::OutlineLevel) ? ol.value.to_i : ol.to_i
|
|
84
86
|
return level if level.positive?
|
|
85
87
|
end
|
|
86
88
|
|
|
@@ -93,13 +95,10 @@ module Coradoc
|
|
|
93
95
|
def list_item?(paragraph)
|
|
94
96
|
return false unless paragraph.properties
|
|
95
97
|
|
|
96
|
-
|
|
97
|
-
#
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return false unless num_id.is_a?(Integer)
|
|
101
|
-
|
|
102
|
-
num_id.positive?
|
|
98
|
+
# w:numPr is persisted as nested numbering_properties; the flat
|
|
99
|
+
# num_id is only set by the builder/YAML API (see NumberingAccess)
|
|
100
|
+
num_id = paragraph_num_id(paragraph)
|
|
101
|
+
!num_id.nil? && num_id.positive?
|
|
103
102
|
end
|
|
104
103
|
|
|
105
104
|
# Check if paragraph has a specific role based on style name
|
|
@@ -138,10 +137,7 @@ module Coradoc
|
|
|
138
137
|
private
|
|
139
138
|
|
|
140
139
|
def resolve_style_name(paragraph)
|
|
141
|
-
|
|
142
|
-
return nil unless style_ref
|
|
143
|
-
|
|
144
|
-
value = style_ref.is_a?(Uniword::Wordprocessingml::PStyle) ? style_ref.val : style_ref.to_s
|
|
140
|
+
value = paragraph_style_value(paragraph)
|
|
145
141
|
return nil unless value
|
|
146
142
|
|
|
147
143
|
mapped = @style_map[value]
|
|
@@ -154,7 +150,7 @@ module Coradoc
|
|
|
154
150
|
style_ref = run.properties.style
|
|
155
151
|
return nil unless style_ref
|
|
156
152
|
|
|
157
|
-
value = style_ref.
|
|
153
|
+
value = style_ref.value.to_s
|
|
158
154
|
return nil unless value
|
|
159
155
|
|
|
160
156
|
mapped = @style_map[value]
|
|
@@ -173,10 +169,12 @@ module Coradoc
|
|
|
173
169
|
end
|
|
174
170
|
|
|
175
171
|
def style_id_from_paragraph(paragraph)
|
|
176
|
-
|
|
177
|
-
|
|
172
|
+
paragraph_style_value(paragraph)
|
|
173
|
+
end
|
|
178
174
|
|
|
179
|
-
|
|
175
|
+
# uniword models w:pStyle as a collection of StyleReference
|
|
176
|
+
def paragraph_style_value(paragraph)
|
|
177
|
+
Array(paragraph.properties&.style).filter_map(&:value).first.to_s
|
|
180
178
|
end
|
|
181
179
|
|
|
182
180
|
def build_style_map(config)
|
|
@@ -24,6 +24,8 @@ module Coradoc
|
|
|
24
24
|
# core = ToCoreModel.transform(doc)
|
|
25
25
|
# # => Coradoc::CoreModel::StructuralElement
|
|
26
26
|
class ToCoreModel
|
|
27
|
+
include NumberingAccess
|
|
28
|
+
|
|
27
29
|
class << self
|
|
28
30
|
def transform(document)
|
|
29
31
|
new.transform(document)
|
|
@@ -139,7 +141,7 @@ module Coradoc
|
|
|
139
141
|
|
|
140
142
|
def section_break_element(paragraph, context)
|
|
141
143
|
# First, transform the paragraph content if it has text
|
|
142
|
-
content = paragraph.runs&.map { |r| r.text
|
|
144
|
+
content = paragraph.runs&.map { |r| Array(r.text).map(&:to_s).join }&.join
|
|
143
145
|
if content && !content.strip.empty?
|
|
144
146
|
# Has content — transform normally (content comes before the break)
|
|
145
147
|
context.transform(paragraph)
|
|
@@ -154,7 +156,7 @@ module Coradoc
|
|
|
154
156
|
# Collect consecutive list items with the same numId into a ListBlock
|
|
155
157
|
def group_list(elements, start_index, context)
|
|
156
158
|
first = elements[start_index]
|
|
157
|
-
num_id = first.
|
|
159
|
+
num_id = paragraph_num_id(first).to_i
|
|
158
160
|
items = []
|
|
159
161
|
consumed = 0
|
|
160
162
|
|
|
@@ -163,7 +165,7 @@ module Coradoc
|
|
|
163
165
|
para = elements[idx]
|
|
164
166
|
break unless paragraph?(para)
|
|
165
167
|
break unless context.style_resolver.list_item?(para)
|
|
166
|
-
break unless para.
|
|
168
|
+
break unless paragraph_num_id(para).to_i == num_id
|
|
167
169
|
|
|
168
170
|
items << @list_item_rule.apply(para, context)
|
|
169
171
|
consumed += 1
|
|
@@ -242,7 +244,7 @@ module Coradoc
|
|
|
242
244
|
next unless context.style_resolver.heading_level(para) == 1
|
|
243
245
|
|
|
244
246
|
runs = para.runs || []
|
|
245
|
-
return runs.map { |r| r.text
|
|
247
|
+
return runs.map { |r| Array(r.text).map(&:to_s).join }.join
|
|
246
248
|
end
|
|
247
249
|
|
|
248
250
|
nil
|
|
@@ -312,7 +314,7 @@ module Coradoc
|
|
|
312
314
|
runs = para.runs || []
|
|
313
315
|
return nil unless runs
|
|
314
316
|
|
|
315
|
-
runs.map { |r| r.text
|
|
317
|
+
runs.map { |r| Array(r.text).map(&:to_s).join }.join
|
|
316
318
|
end
|
|
317
319
|
|
|
318
320
|
# Check if header/footer text is purely layout content
|
|
@@ -10,6 +10,7 @@ module Coradoc
|
|
|
10
10
|
autoload :FromCoreModel, 'coradoc/docx/transform/from_core_model'
|
|
11
11
|
autoload :StyleResolver, 'coradoc/docx/transform/style_resolver'
|
|
12
12
|
autoload :NumberingResolver, 'coradoc/docx/transform/numbering_resolver'
|
|
13
|
+
autoload :NumberingAccess, 'coradoc/docx/transform/numbering_access'
|
|
13
14
|
autoload :OrderedContent, 'coradoc/docx/transform/ordered_content'
|
|
14
15
|
autoload :FrontmatterCoreProperties, 'coradoc/docx/transform/frontmatter_core_properties'
|
|
15
16
|
|
data/lib/coradoc/docx/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: coradoc-docx
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -41,16 +41,16 @@ dependencies:
|
|
|
41
41
|
name: uniword
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
43
43
|
requirements:
|
|
44
|
-
- - "
|
|
44
|
+
- - "~>"
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '
|
|
46
|
+
version: '1.6'
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
|
-
- - "
|
|
51
|
+
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '
|
|
53
|
+
version: '1.6'
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
55
|
name: rake
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -109,6 +109,7 @@ files:
|
|
|
109
109
|
- lib/coradoc/docx/transform/context.rb
|
|
110
110
|
- lib/coradoc/docx/transform/from_core_model.rb
|
|
111
111
|
- lib/coradoc/docx/transform/frontmatter_core_properties.rb
|
|
112
|
+
- lib/coradoc/docx/transform/numbering_access.rb
|
|
112
113
|
- lib/coradoc/docx/transform/numbering_resolver.rb
|
|
113
114
|
- lib/coradoc/docx/transform/ordered_content.rb
|
|
114
115
|
- lib/coradoc/docx/transform/rule.rb
|