uniword 1.0.4 → 1.0.5
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/uniword/accessibility/rules/descriptive_headings_rule.rb +7 -9
- data/lib/uniword/accessibility/rules/document_title_rule.rb +2 -2
- data/lib/uniword/accessibility/rules/heading_structure_rule.rb +4 -3
- data/lib/uniword/accessibility/rules/language_specification_rule.rb +2 -2
- data/lib/uniword/accessibility/rules/table_headers_rule.rb +1 -1
- data/lib/uniword/assembly/cross_reference_resolver.rb +6 -59
- data/lib/uniword/assembly/toc.rb +2 -2
- data/lib/uniword/assembly/variable_substitutor.rb +0 -24
- data/lib/uniword/batch/stages/compress_images_stage.rb +2 -2
- data/lib/uniword/batch/stages/normalize_styles_stage.rb +12 -12
- data/lib/uniword/batch/stages/update_metadata_stage.rb +26 -11
- data/lib/uniword/batch/stages/validate_links_stage.rb +1 -1
- data/lib/uniword/builder/bibliography_builder.rb +1 -1
- data/lib/uniword/builder/chart_builder.rb +2 -2
- data/lib/uniword/builder/has_borders.rb +1 -1
- data/lib/uniword/builder/image_builder.rb +1 -1
- data/lib/uniword/cli/main.rb +4 -4
- data/lib/uniword/diff/document_differ.rb +11 -7
- data/lib/uniword/document_factory.rb +3 -3
- data/lib/uniword/docx/document_statistics.rb +3 -3
- data/lib/uniword/docx/package_defaults.rb +2 -2
- data/lib/uniword/docx/reconciler.rb +3 -3
- data/lib/uniword/element_registry.rb +1 -1
- data/lib/uniword/endnote.rb +3 -1
- data/lib/uniword/footnote.rb +3 -1
- data/lib/uniword/format_converter.rb +7 -7
- data/lib/uniword/format_detector.rb +1 -1
- data/lib/uniword/generation/document_generator.rb +2 -2
- data/lib/uniword/infrastructure/zip_extractor.rb +1 -1
- data/lib/uniword/math_equation.rb +3 -1
- data/lib/uniword/mhtml/math_converter.rb +1 -1
- data/lib/uniword/mhtml/word_css.rb +14 -14
- data/lib/uniword/ooxml/schema/element_serializer.rb +14 -14
- data/lib/uniword/quality/document_checker.rb +2 -2
- data/lib/uniword/quality/rules/link_validation_rule.rb +4 -4
- data/lib/uniword/quality/rules/style_consistency_rule.rb +1 -1
- data/lib/uniword/quality/rules/table_header_rule.rb +1 -1
- data/lib/uniword/resource/color_transformer.rb +1 -1
- data/lib/uniword/resource/resource_resolver.rb +1 -1
- data/lib/uniword/resource/theme_processor.rb +1 -1
- data/lib/uniword/resource/theme_transition.rb +1 -1
- data/lib/uniword/review/interactive_review.rb +1 -1
- data/lib/uniword/spellcheck/spell_checker.rb +6 -6
- data/lib/uniword/styleset.rb +1 -1
- data/lib/uniword/template/helpers/conditional_helper.rb +3 -4
- data/lib/uniword/template/helpers/filter_helper.rb +1 -1
- data/lib/uniword/template/helpers/loop_helper.rb +1 -1
- data/lib/uniword/template/helpers/variable_helper.rb +1 -1
- data/lib/uniword/template/template_parser.rb +9 -7
- data/lib/uniword/template/template_renderer.rb +3 -3
- data/lib/uniword/template/variable_resolver.rb +5 -6
- data/lib/uniword/themes/theme_transformation.rb +1 -1
- data/lib/uniword/toc/toc_generator.rb +1 -1
- data/lib/uniword/transformation/mhtml_element_renderer.rb +5 -7
- data/lib/uniword/transformation/mhtml_metadata_builder.rb +17 -18
- data/lib/uniword/transformation/ooxml_to_html_converter.rb +1 -1
- data/lib/uniword/transformation/transformer.rb +6 -6
- data/lib/uniword/validation/checkers/external_link_checker.rb +1 -1
- data/lib/uniword/validation/checkers/file_reference_checker.rb +5 -5
- data/lib/uniword/validation/checkers/footnote_reference_checker.rb +12 -12
- data/lib/uniword/validation/checkers/internal_link_checker.rb +7 -9
- data/lib/uniword/validation/link_validator.rb +17 -23
- data/lib/uniword/validation/validation_report.rb +5 -3
- data/lib/uniword/validation/validation_result.rb +4 -4
- data/lib/uniword/validators/element_validator.rb +1 -7
- data/lib/uniword/version.rb +1 -1
- data/lib/uniword/visitor/text_extractor.rb +3 -3
- data/lib/uniword/warnings/warning_collector.rb +1 -1
- data/lib/uniword/watermark/manager.rb +1 -1
- data/lib/uniword/wordprocessingml/numbering_configuration.rb +1 -1
- data/lib/uniword/wordprocessingml/run.rb +4 -4
- data/lib/uniword/wordprocessingml/styles/style_definition.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6bf213950306833f5f1b647478fcbdf3d3567510a34ed6329e0d0d1ed6eedf6a
|
|
4
|
+
data.tar.gz: d9b9e0ef1afffe36923b9dcd55831ce4a35441f5bbd4277d821a491b0b0f008d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ead9275e412cabb6d6f6ac359fec7d2ac4b2fcd298886ac8fa5e5623532d9bb8b8fb56fe957552fef12d296cd066c440ba225bff7816a690dc63c1323d4db5ce
|
|
7
|
+
data.tar.gz: ac185de3d3411ff440d9d2651f3d5d88c101c35d19a05cbe9e886e7afdb7f42cd8780f907bdfedcc17ab439a54a4ac926fb8a99286b844b59f0ad87c2d447143
|
|
@@ -69,16 +69,14 @@ module Uniword
|
|
|
69
69
|
def heading_paragraph?(paragraph)
|
|
70
70
|
return false unless paragraph.style
|
|
71
71
|
|
|
72
|
-
paragraph.style.
|
|
73
|
-
|
|
72
|
+
style_str = paragraph.style.to_s
|
|
73
|
+
style_str.match?(/^Heading\s*\d+$/i) ||
|
|
74
|
+
style_str.match?(/^h\d+$/i)
|
|
74
75
|
end
|
|
75
76
|
|
|
76
|
-
# Extract heading level from paragraph
|
|
77
|
-
#
|
|
78
|
-
# @param paragraph [Paragraph] Paragraph to extract from
|
|
79
|
-
# @return [Integer] Heading level
|
|
80
77
|
def extract_heading_level(paragraph)
|
|
81
|
-
|
|
78
|
+
style_str = paragraph.style.to_s
|
|
79
|
+
match = style_str.match(/(\d+)/)
|
|
82
80
|
match ? match[1].to_i : 1
|
|
83
81
|
end
|
|
84
82
|
|
|
@@ -87,9 +85,9 @@ module Uniword
|
|
|
87
85
|
# @param paragraph [Paragraph] Paragraph to extract from
|
|
88
86
|
# @return [String, nil] Heading text
|
|
89
87
|
def extract_heading_text(paragraph)
|
|
90
|
-
if paragraph.
|
|
88
|
+
if paragraph.is_a?(Lutaml::Model::Serializable) && paragraph.class.attributes.key?(:text)
|
|
91
89
|
paragraph.text
|
|
92
|
-
elsif paragraph.
|
|
90
|
+
elsif paragraph.is_a?(Lutaml::Model::Serializable) && paragraph.class.attributes.key?(:runs)
|
|
93
91
|
paragraph.runs.map(&:text).join
|
|
94
92
|
end
|
|
95
93
|
end
|
|
@@ -52,9 +52,9 @@ module Uniword
|
|
|
52
52
|
# @return [String, nil] Document title
|
|
53
53
|
def extract_title(document)
|
|
54
54
|
# Try to get title from document metadata/properties
|
|
55
|
-
if document.
|
|
55
|
+
if document.is_a?(Lutaml::Model::Serializable) && document.class.attributes.key?(:title)
|
|
56
56
|
document.title
|
|
57
|
-
elsif document.
|
|
57
|
+
elsif document.is_a?(Lutaml::Model::Serializable) && document.class.attributes.key?(:metadata)
|
|
58
58
|
document.metadata&.title
|
|
59
59
|
end
|
|
60
60
|
end
|
|
@@ -65,8 +65,9 @@ module Uniword
|
|
|
65
65
|
def heading_paragraph?(paragraph)
|
|
66
66
|
return false unless paragraph.style
|
|
67
67
|
|
|
68
|
-
paragraph.style.
|
|
69
|
-
|
|
68
|
+
style_str = paragraph.style.to_s
|
|
69
|
+
style_str.match?(/^Heading\s*\d+$/i) ||
|
|
70
|
+
style_str.match?(/^h\d+$/i)
|
|
70
71
|
end
|
|
71
72
|
|
|
72
73
|
# Extract heading level from paragraph
|
|
@@ -74,7 +75,7 @@ module Uniword
|
|
|
74
75
|
# @param paragraph [Paragraph] Paragraph to extract from
|
|
75
76
|
# @return [Integer] Heading level
|
|
76
77
|
def extract_heading_level(paragraph)
|
|
77
|
-
match = paragraph.style.match(/(\d+)/)
|
|
78
|
+
match = paragraph.style.to_s.match(/(\d+)/)
|
|
78
79
|
match ? match[1].to_i : 1
|
|
79
80
|
end
|
|
80
81
|
|
|
@@ -43,9 +43,9 @@ module Uniword
|
|
|
43
43
|
# @return [String, nil] Document language code
|
|
44
44
|
def extract_language(document)
|
|
45
45
|
# Try to get language from document metadata/properties
|
|
46
|
-
if document.
|
|
46
|
+
if document.is_a?(Lutaml::Model::Serializable) && document.class.attributes.key?(:language)
|
|
47
47
|
document.language
|
|
48
|
-
elsif document.
|
|
48
|
+
elsif document.is_a?(Lutaml::Model::Serializable) && document.class.attributes.key?(:metadata)
|
|
49
49
|
document.metadata&.language
|
|
50
50
|
end
|
|
51
51
|
end
|
|
@@ -53,7 +53,7 @@ module Uniword
|
|
|
53
53
|
# @return [Boolean] True if caption exists
|
|
54
54
|
def table_has_caption?(table)
|
|
55
55
|
# Tables may have a caption property or title
|
|
56
|
-
table.
|
|
56
|
+
table.is_a?(Lutaml::Model::Serializable) && table.class.attributes.key?(:caption) && !table.caption.to_s.strip.empty?
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
end
|
|
@@ -104,33 +104,9 @@ module Uniword
|
|
|
104
104
|
# @param document [Document] Source document
|
|
105
105
|
# @return [void]
|
|
106
106
|
def collect_bookmarks(document)
|
|
107
|
-
# Process body paragraphs
|
|
108
107
|
document.paragraphs.each do |paragraph|
|
|
109
108
|
collect_paragraph_bookmarks(paragraph)
|
|
110
109
|
end
|
|
111
|
-
|
|
112
|
-
# Process sections (headers/footers)
|
|
113
|
-
return unless document.respond_to?(:sections)
|
|
114
|
-
|
|
115
|
-
document.sections.each do |section|
|
|
116
|
-
# Process headers if section has them
|
|
117
|
-
if section.respond_to?(:headers)
|
|
118
|
-
section.headers.each do |header|
|
|
119
|
-
header.paragraphs.each do |paragraph|
|
|
120
|
-
collect_paragraph_bookmarks(paragraph)
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
# Process footers if section has them
|
|
126
|
-
next unless section.respond_to?(:footers)
|
|
127
|
-
|
|
128
|
-
section.footers.each do |footer|
|
|
129
|
-
footer.paragraphs.each do |paragraph|
|
|
130
|
-
collect_paragraph_bookmarks(paragraph)
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
110
|
end
|
|
135
111
|
|
|
136
112
|
# Collect bookmarks from paragraph.
|
|
@@ -138,12 +114,7 @@ module Uniword
|
|
|
138
114
|
# @param paragraph [Paragraph] Source paragraph
|
|
139
115
|
# @return [void]
|
|
140
116
|
def collect_paragraph_bookmarks(paragraph)
|
|
141
|
-
paragraph.
|
|
142
|
-
# Check if run contains bookmark
|
|
143
|
-
next unless run.respond_to?(:bookmark_start)
|
|
144
|
-
next unless run.bookmark_start
|
|
145
|
-
|
|
146
|
-
bookmark = run.bookmark_start
|
|
117
|
+
paragraph.bookmark_starts.each do |bookmark|
|
|
147
118
|
@bookmark_registry[bookmark.id] = bookmark
|
|
148
119
|
end
|
|
149
120
|
end
|
|
@@ -153,33 +124,9 @@ module Uniword
|
|
|
153
124
|
# @param document [Document] Document to process
|
|
154
125
|
# @return [void]
|
|
155
126
|
def resolve_references(document)
|
|
156
|
-
# Process body paragraphs
|
|
157
127
|
document.paragraphs.each do |paragraph|
|
|
158
128
|
resolve_paragraph_references(paragraph)
|
|
159
129
|
end
|
|
160
|
-
|
|
161
|
-
# Process sections (headers/footers)
|
|
162
|
-
return unless document.respond_to?(:sections)
|
|
163
|
-
|
|
164
|
-
document.sections.each do |section|
|
|
165
|
-
# Process headers if section has them
|
|
166
|
-
if section.respond_to?(:headers)
|
|
167
|
-
section.headers.each do |header|
|
|
168
|
-
header.paragraphs.each do |paragraph|
|
|
169
|
-
resolve_paragraph_references(paragraph)
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
# Process footers if section has them
|
|
175
|
-
next unless section.respond_to?(:footers)
|
|
176
|
-
|
|
177
|
-
section.footers.each do |footer|
|
|
178
|
-
footer.paragraphs.each do |paragraph|
|
|
179
|
-
resolve_paragraph_references(paragraph)
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
end
|
|
183
130
|
end
|
|
184
131
|
|
|
185
132
|
# Resolve references in paragraph.
|
|
@@ -187,12 +134,12 @@ module Uniword
|
|
|
187
134
|
# @param paragraph [Paragraph] Source paragraph
|
|
188
135
|
# @return [void]
|
|
189
136
|
def resolve_paragraph_references(paragraph)
|
|
190
|
-
paragraph.
|
|
191
|
-
|
|
192
|
-
|
|
137
|
+
paragraph.hyperlinks.each do |hyperlink|
|
|
138
|
+
resolve_hyperlink(hyperlink)
|
|
139
|
+
end
|
|
193
140
|
|
|
194
|
-
|
|
195
|
-
resolve_field(
|
|
141
|
+
paragraph.simple_fields.each do |field|
|
|
142
|
+
resolve_field(field)
|
|
196
143
|
end
|
|
197
144
|
end
|
|
198
145
|
|
data/lib/uniword/assembly/toc.rb
CHANGED
|
@@ -174,7 +174,7 @@ module Uniword
|
|
|
174
174
|
return match[1].to_i if match
|
|
175
175
|
|
|
176
176
|
# Check for outline level in properties
|
|
177
|
-
if paragraph.properties.
|
|
177
|
+
if paragraph.properties.is_a?(Uniword::Wordprocessingml::ParagraphProperties)
|
|
178
178
|
outline = paragraph.properties.outline_level
|
|
179
179
|
return outline if outline.is_a?(Integer)
|
|
180
180
|
end
|
|
@@ -212,7 +212,7 @@ module Uniword
|
|
|
212
212
|
run.text = @title
|
|
213
213
|
|
|
214
214
|
# Set run properties
|
|
215
|
-
if run.
|
|
215
|
+
if run.is_a?(Uniword::Wordprocessingml::Run)
|
|
216
216
|
run.properties = Wordprocessingml::RunProperties.new(
|
|
217
217
|
bold: true,
|
|
218
218
|
size: 48, # 24pt = 48 half-points
|
|
@@ -66,34 +66,10 @@ module Uniword
|
|
|
66
66
|
# @example Process document
|
|
67
67
|
# sub.substitute_document(document)
|
|
68
68
|
def substitute_document(document)
|
|
69
|
-
# Process all paragraphs
|
|
70
69
|
document.paragraphs.each do |paragraph|
|
|
71
70
|
substitute_paragraph(paragraph)
|
|
72
71
|
end
|
|
73
72
|
|
|
74
|
-
# Process sections (headers/footers)
|
|
75
|
-
if document.respond_to?(:sections)
|
|
76
|
-
document.sections.each do |section|
|
|
77
|
-
# Process headers if section has them
|
|
78
|
-
if section.respond_to?(:headers)
|
|
79
|
-
section.headers.each do |header|
|
|
80
|
-
header.paragraphs.each do |paragraph|
|
|
81
|
-
substitute_paragraph(paragraph)
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
# Process footers if section has them
|
|
87
|
-
next unless section.respond_to?(:footers)
|
|
88
|
-
|
|
89
|
-
section.footers.each do |footer|
|
|
90
|
-
footer.paragraphs.each do |paragraph|
|
|
91
|
-
substitute_paragraph(paragraph)
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
73
|
document
|
|
98
74
|
end
|
|
99
75
|
|
|
@@ -155,8 +155,8 @@ module Uniword
|
|
|
155
155
|
def get_image_dimensions(image)
|
|
156
156
|
# Placeholder - would need to parse image data
|
|
157
157
|
# For now, return dimensions from image properties if available
|
|
158
|
-
width = image.
|
|
159
|
-
height = image.
|
|
158
|
+
width = image.is_a?(Uniword::Image) ? image.width : 800
|
|
159
|
+
height = image.is_a?(Uniword::Image) ? image.height : 600
|
|
160
160
|
[width || 800, height || 600]
|
|
161
161
|
end
|
|
162
162
|
|
|
@@ -89,7 +89,7 @@ module Uniword
|
|
|
89
89
|
props = paragraph.properties
|
|
90
90
|
|
|
91
91
|
# Check outline level for headings
|
|
92
|
-
if props
|
|
92
|
+
if props&.outline_level
|
|
93
93
|
case props.outline_level
|
|
94
94
|
when 0, 1
|
|
95
95
|
return :heading1
|
|
@@ -137,16 +137,16 @@ module Uniword
|
|
|
137
137
|
props = run.properties
|
|
138
138
|
|
|
139
139
|
# Preserve bold for emphasis
|
|
140
|
-
bold = props
|
|
140
|
+
bold = props&.bold
|
|
141
141
|
# Preserve italic for emphasis
|
|
142
|
-
italic = props
|
|
142
|
+
italic = props&.italic
|
|
143
143
|
|
|
144
144
|
# Clear all properties
|
|
145
145
|
clear_all_run_properties(run)
|
|
146
146
|
|
|
147
147
|
# Restore semantic properties
|
|
148
|
-
props.bold = bold if
|
|
149
|
-
return unless
|
|
148
|
+
props.bold = bold if bold
|
|
149
|
+
return unless italic
|
|
150
150
|
|
|
151
151
|
props.italic = italic
|
|
152
152
|
end
|
|
@@ -159,15 +159,15 @@ module Uniword
|
|
|
159
159
|
return unless props
|
|
160
160
|
|
|
161
161
|
# Reset font properties
|
|
162
|
-
props.font_size = nil
|
|
163
|
-
props.font_name = nil
|
|
164
|
-
props.color = nil
|
|
162
|
+
props.font_size = nil
|
|
163
|
+
props.font_name = nil
|
|
164
|
+
props.color = nil
|
|
165
165
|
|
|
166
166
|
# Reset text effects (keep if you want to preserve semantic formatting)
|
|
167
|
-
# props.bold = nil
|
|
168
|
-
# props.italic = nil
|
|
169
|
-
props.underline = nil
|
|
170
|
-
props.strike = nil
|
|
167
|
+
# props.bold = nil
|
|
168
|
+
# props.italic = nil
|
|
169
|
+
props.underline = nil
|
|
170
|
+
props.strike = nil
|
|
171
171
|
end
|
|
172
172
|
end
|
|
173
173
|
end
|
|
@@ -62,30 +62,45 @@ module Uniword
|
|
|
62
62
|
#
|
|
63
63
|
# @param document [Document] Document to update
|
|
64
64
|
def update_core_properties(document)
|
|
65
|
-
|
|
66
|
-
# This is a placeholder that shows the intended structure
|
|
65
|
+
return unless document.is_a?(Uniword::Wordprocessingml::DocumentRoot)
|
|
67
66
|
|
|
68
|
-
|
|
67
|
+
cp = document.core_properties
|
|
69
68
|
|
|
70
|
-
|
|
69
|
+
if @update_author
|
|
70
|
+
cp.creator = Uniword::Ooxml::Types::DcCreatorType.new(
|
|
71
|
+
@author || current_user,
|
|
72
|
+
)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
if @update_modified_date
|
|
76
|
+
cp.modified = Uniword::Ooxml::Types::DctermsModifiedType.new(
|
|
77
|
+
value: Time.now.to_s,
|
|
78
|
+
type: "dcterms:W3CDTF",
|
|
79
|
+
)
|
|
80
|
+
end
|
|
71
81
|
|
|
72
|
-
if @update_revision_number
|
|
73
|
-
|
|
74
|
-
|
|
82
|
+
if @update_revision_number
|
|
83
|
+
current = cp.revision.to_i
|
|
84
|
+
cp.revision = Uniword::Ooxml::Types::CpRevisionType.new(
|
|
85
|
+
(current + 1).to_s,
|
|
86
|
+
)
|
|
75
87
|
end
|
|
76
88
|
|
|
77
|
-
return unless @title
|
|
89
|
+
return unless @title
|
|
78
90
|
|
|
79
|
-
|
|
91
|
+
cp.title = Uniword::Ooxml::Types::DcTitleType.new(@title)
|
|
80
92
|
end
|
|
81
93
|
|
|
82
94
|
# Update extended document properties
|
|
83
95
|
#
|
|
84
96
|
# @param document [Document] Document to update
|
|
85
97
|
def update_extended_properties(document)
|
|
86
|
-
return unless @company && document.
|
|
98
|
+
return unless @company && document.is_a?(Uniword::Wordprocessingml::DocumentRoot)
|
|
99
|
+
|
|
100
|
+
app = document.app_properties
|
|
101
|
+
return unless app
|
|
87
102
|
|
|
88
|
-
|
|
103
|
+
app.company = @company
|
|
89
104
|
end
|
|
90
105
|
|
|
91
106
|
# Get current user name
|
|
@@ -160,7 +160,7 @@ module Uniword
|
|
|
160
160
|
# @param document [Document] Document to check
|
|
161
161
|
# @return [Boolean] true if bookmark exists
|
|
162
162
|
def bookmark_exists?(bookmark_name, document)
|
|
163
|
-
return true unless document.
|
|
163
|
+
return true unless document.is_a?(Uniword::Wordprocessingml::DocumentRoot)
|
|
164
164
|
return true if document.bookmarks.nil?
|
|
165
165
|
|
|
166
166
|
document.bookmarks.any? { |b| b.name == bookmark_name }
|
|
@@ -35,7 +35,7 @@ module Uniword
|
|
|
35
35
|
# @param document [DocumentBuilder, DocumentRoot] Target document
|
|
36
36
|
# @return [self]
|
|
37
37
|
def attach(document)
|
|
38
|
-
root = document.
|
|
38
|
+
root = document.is_a?(Uniword::Builder::DocumentBuilder) ? document.model : document
|
|
39
39
|
root.bibliography_sources = @sources
|
|
40
40
|
self
|
|
41
41
|
end
|
|
@@ -118,7 +118,7 @@ module Uniword
|
|
|
118
118
|
# @param document [DocumentBuilder, DocumentRoot] Target document
|
|
119
119
|
# @return [Wordprocessingml::Drawing]
|
|
120
120
|
def build_drawing(document)
|
|
121
|
-
root = document.
|
|
121
|
+
root = document.is_a?(Uniword::Builder::DocumentBuilder) ? document.model : document
|
|
122
122
|
root.chart_parts ||= {}
|
|
123
123
|
|
|
124
124
|
r_id = "rIdChart#{root.chart_parts.size + 1}"
|
|
@@ -265,7 +265,7 @@ module Uniword
|
|
|
265
265
|
|
|
266
266
|
# Build a chart axis
|
|
267
267
|
def build_axis(xml, tag, id, position, cross_id)
|
|
268
|
-
xml["c"].
|
|
268
|
+
xml["c"].public_send(tag) do
|
|
269
269
|
xml["c"].axId("val" => id)
|
|
270
270
|
xml["c"].scaling do
|
|
271
271
|
xml["c"].orientation("val" => "minMax")
|
|
@@ -33,7 +33,7 @@ module Uniword
|
|
|
33
33
|
# @param path [String] Path to image file
|
|
34
34
|
# @return [String] Relationship ID (e.g., 'rIdImg1')
|
|
35
35
|
def self.register_image(document, path)
|
|
36
|
-
root = document.
|
|
36
|
+
root = document.is_a?(Uniword::Builder::DocumentBuilder) ? document.model : document
|
|
37
37
|
if root
|
|
38
38
|
root.image_parts ||= {}
|
|
39
39
|
r_id = "rIdImg#{root.image_parts.size + 1}"
|
data/lib/uniword/cli/main.rb
CHANGED
|
@@ -211,7 +211,7 @@ module Uniword
|
|
|
211
211
|
require "json"
|
|
212
212
|
output = reports.transform_values do |r|
|
|
213
213
|
{ valid: r.valid?,
|
|
214
|
-
issues: r.
|
|
214
|
+
issues: r.is_a?(Uniword::Quality::CheckReport) ? r.issues.count : 0 }
|
|
215
215
|
end
|
|
216
216
|
puts JSON.pretty_generate(output)
|
|
217
217
|
else
|
|
@@ -461,9 +461,9 @@ module Uniword
|
|
|
461
461
|
if report.valid?
|
|
462
462
|
say("#{label}: No issues found", :green)
|
|
463
463
|
else
|
|
464
|
-
issue_count = report.
|
|
464
|
+
issue_count = report.is_a?(Uniword::Quality::CheckReport) ? report.issues.count : "?"
|
|
465
465
|
say("#{label}: #{issue_count} issue(s) found", :yellow)
|
|
466
|
-
if options[:verbose] && report.
|
|
466
|
+
if options[:verbose] && report.is_a?(Uniword::Quality::CheckReport)
|
|
467
467
|
report.issues.each do |issue|
|
|
468
468
|
say(" - #{issue}", :yellow)
|
|
469
469
|
end
|
|
@@ -511,7 +511,7 @@ module Uniword
|
|
|
511
511
|
setters.each do |opt, setter|
|
|
512
512
|
next unless options[opt]
|
|
513
513
|
|
|
514
|
-
core_properties&.
|
|
514
|
+
core_properties&.public_send(setter, options[opt])
|
|
515
515
|
updated = true
|
|
516
516
|
end
|
|
517
517
|
updated
|
|
@@ -442,8 +442,8 @@ module Uniword
|
|
|
442
442
|
def format_value(props, method)
|
|
443
443
|
return nil unless props
|
|
444
444
|
|
|
445
|
-
val = props.
|
|
446
|
-
val
|
|
445
|
+
val = props.public_send(method)
|
|
446
|
+
unwrap_value(val)
|
|
447
447
|
end
|
|
448
448
|
|
|
449
449
|
# Extract a value from run properties.
|
|
@@ -454,10 +454,10 @@ module Uniword
|
|
|
454
454
|
def run_prop_value(props, method)
|
|
455
455
|
return nil unless props
|
|
456
456
|
|
|
457
|
-
val = props.
|
|
457
|
+
val = props.public_send(method)
|
|
458
458
|
return nil if val.nil?
|
|
459
459
|
|
|
460
|
-
val
|
|
460
|
+
unwrap_value(val)
|
|
461
461
|
end
|
|
462
462
|
|
|
463
463
|
# Extract a metadata field value from core properties.
|
|
@@ -468,10 +468,10 @@ module Uniword
|
|
|
468
468
|
def metadata_value(cp, field)
|
|
469
469
|
return nil unless cp
|
|
470
470
|
|
|
471
|
-
val = cp.
|
|
471
|
+
val = cp.public_send(field)
|
|
472
472
|
return nil if val.nil?
|
|
473
473
|
|
|
474
|
-
val
|
|
474
|
+
unwrap_value(val).to_s
|
|
475
475
|
end
|
|
476
476
|
|
|
477
477
|
# Extract styles from a document as a hash of style_id => name.
|
|
@@ -489,13 +489,17 @@ module Uniword
|
|
|
489
489
|
styles.each do |style|
|
|
490
490
|
style_id = style.styleId&.to_s
|
|
491
491
|
name_obj = style.name
|
|
492
|
-
name = name_obj.
|
|
492
|
+
name = name_obj.is_a?(Lutaml::Model::Serializable) && name_obj.class.attributes.key?(:val) ? name_obj.val : name_obj.to_s
|
|
493
493
|
result[style_id] = name if style_id
|
|
494
494
|
end
|
|
495
495
|
|
|
496
496
|
result
|
|
497
497
|
end
|
|
498
498
|
|
|
499
|
+
def unwrap_value(val)
|
|
500
|
+
val.is_a?(Lutaml::Model::Serializable) && val.class.attributes.key?(:value) ? val.value : val
|
|
501
|
+
end
|
|
502
|
+
|
|
499
503
|
# Build a text change hash.
|
|
500
504
|
#
|
|
501
505
|
# @param change [Symbol] :added, :removed, or :modified
|
|
@@ -199,8 +199,8 @@ module Uniword
|
|
|
199
199
|
return unless document.is_a?(Uniword::Wordprocessingml::DocumentRoot)
|
|
200
200
|
|
|
201
201
|
PACKAGE_PART_MAPPINGS.each do |pkg_attr, doc_attr|
|
|
202
|
-
value = package.
|
|
203
|
-
document.
|
|
202
|
+
value = package.public_send(pkg_attr)
|
|
203
|
+
document.public_send(:"#{doc_attr}=", value) if value
|
|
204
204
|
end
|
|
205
205
|
end
|
|
206
206
|
|
|
@@ -232,7 +232,7 @@ module Uniword
|
|
|
232
232
|
return if path.is_a?(IO) || path.is_a?(StringIO)
|
|
233
233
|
|
|
234
234
|
# For strings, validate
|
|
235
|
-
if path.
|
|
235
|
+
if path.is_a?(String) && path.empty?
|
|
236
236
|
raise ArgumentError,
|
|
237
237
|
"Path cannot be empty"
|
|
238
238
|
end
|
|
@@ -50,13 +50,13 @@ module Uniword
|
|
|
50
50
|
|
|
51
51
|
# Recursively collect text from paragraphs, tables, and SDTs.
|
|
52
52
|
def collect_text(container, text_per_paragraph)
|
|
53
|
-
if container.
|
|
53
|
+
if container.is_a?(Uniword::Wordprocessingml::Body) || container.is_a?(Uniword::Wordprocessingml::DocumentRoot) || container.is_a?(Uniword::Wordprocessingml::TableCell)
|
|
54
54
|
container.paragraphs.each do |para|
|
|
55
55
|
text_per_paragraph << para.text
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
if container.
|
|
59
|
+
if container.is_a?(Uniword::Wordprocessingml::Body) || container.is_a?(Uniword::Wordprocessingml::DocumentRoot)
|
|
60
60
|
container.tables.each do |table|
|
|
61
61
|
table.rows.each do |row|
|
|
62
62
|
row.cells.each do |cell|
|
|
@@ -66,7 +66,7 @@ module Uniword
|
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
-
if container.
|
|
69
|
+
if container.is_a?(Uniword::Wordprocessingml::Body)
|
|
70
70
|
container.structured_document_tags.each do |sdt|
|
|
71
71
|
sdt.content&.paragraphs&.each do |para|
|
|
72
72
|
text = para.text
|
|
@@ -41,8 +41,8 @@ module Uniword
|
|
|
41
41
|
return unless document.is_a?(Uniword::Wordprocessingml::DocumentRoot)
|
|
42
42
|
|
|
43
43
|
DOCUMENT_TO_PACKAGE_MAPPINGS.each do |doc_attr, pkg_attr|
|
|
44
|
-
value = document.
|
|
45
|
-
package.
|
|
44
|
+
value = document.public_send(doc_attr)
|
|
45
|
+
package.public_send(:"#{pkg_attr}=", value) if value
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
package.numbering = document.numbering_configuration if document.numbering_configuration_loaded?
|
|
@@ -479,7 +479,7 @@ module Uniword
|
|
|
479
479
|
package.numbering.instances.each do |inst|
|
|
480
480
|
next unless inst.abstract_num_id
|
|
481
481
|
|
|
482
|
-
abs_id = inst.abstract_num_id.
|
|
482
|
+
abs_id = inst.abstract_num_id.is_a?(Uniword::Wordprocessingml::AbstractNumId) ? inst.abstract_num_id.val : inst.abstract_num_id
|
|
483
483
|
defn = package.numbering.definitions.find do |d|
|
|
484
484
|
d.abstract_num_id == abs_id
|
|
485
485
|
end
|
|
@@ -985,8 +985,8 @@ module Uniword
|
|
|
985
985
|
# 4. East Asian light font, 5. Major font (headings)
|
|
986
986
|
names << fs&.minor_font if fs&.minor_font
|
|
987
987
|
|
|
988
|
-
ea_font = loc
|
|
989
|
-
ea_light = loc
|
|
988
|
+
ea_font = loc&.east_asian_font
|
|
989
|
+
ea_light = loc&.east_asian_light_font
|
|
990
990
|
|
|
991
991
|
# Default East Asian fonts for zh-CN when locale profile omits them
|
|
992
992
|
if loc.east_asia_lang == "zh-CN"
|
|
@@ -15,7 +15,7 @@ module Uniword
|
|
|
15
15
|
# @param element_class [Class] The element class to register
|
|
16
16
|
# @return [void]
|
|
17
17
|
def register(element_class)
|
|
18
|
-
return if element_class
|
|
18
|
+
return if element_class <= Uniword::Element && element_class.abstract?
|
|
19
19
|
|
|
20
20
|
key = element_class_key(element_class)
|
|
21
21
|
return if key.nil? # Skip anonymous classes
|
data/lib/uniword/endnote.rb
CHANGED
|
@@ -50,7 +50,9 @@ module Uniword
|
|
|
50
50
|
#
|
|
51
51
|
# @return [String] The combined text of all paragraphs
|
|
52
52
|
def text
|
|
53
|
-
@content.map
|
|
53
|
+
@content.map do |p|
|
|
54
|
+
p.is_a?(Uniword::Wordprocessingml::Paragraph) ? p.text : p.to_s
|
|
55
|
+
end.join("\n")
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
# Convert to hash representation.
|
data/lib/uniword/footnote.rb
CHANGED
|
@@ -49,7 +49,9 @@ module Uniword
|
|
|
49
49
|
#
|
|
50
50
|
# @return [String] The combined text of all paragraphs
|
|
51
51
|
def text
|
|
52
|
-
@content.map
|
|
52
|
+
@content.map do |p|
|
|
53
|
+
p.is_a?(Uniword::Wordprocessingml::Paragraph) ? p.text : p.to_s
|
|
54
|
+
end.join("\n")
|
|
53
55
|
end
|
|
54
56
|
|
|
55
57
|
# Convert to hash representation.
|