uniword 1.6.0 → 1.7.0

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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/exe/uniword +9 -0
  3. data/lib/uniword/accessibility/accessibility_report.rb +8 -0
  4. data/lib/uniword/builder/chart_builder.rb +129 -134
  5. data/lib/uniword/cli/completions.rb +99 -0
  6. data/lib/uniword/cli/generate_cli.rb +5 -0
  7. data/lib/uniword/cli/help_switch.rb +45 -0
  8. data/lib/uniword/cli/helpers.rb +1 -0
  9. data/lib/uniword/cli/main.rb +118 -21
  10. data/lib/uniword/cli/no_color.rb +21 -0
  11. data/lib/uniword/diff/package_differ.rb +16 -15
  12. data/lib/uniword/document_factory.rb +2 -2
  13. data/lib/uniword/document_writer.rb +32 -10
  14. data/lib/uniword/docx/package_integrity_checker.rb +10 -11
  15. data/lib/uniword/docx/reconciler/body.rb +1 -0
  16. data/lib/uniword/docx/reconciler/helpers.rb +27 -12
  17. data/lib/uniword/docx/reconciler/parts.rb +5 -0
  18. data/lib/uniword/find_replace/paragraph_walker.rb +49 -12
  19. data/lib/uniword/find_replace/scope.rb +7 -4
  20. data/lib/uniword/infrastructure/mime_packager.rb +3 -10
  21. data/lib/uniword/infrastructure/mime_parser.rb +23 -1
  22. data/lib/uniword/math/plurimath_adapter.rb +28 -24
  23. data/lib/uniword/math_equation.rb +1 -1
  24. data/lib/uniword/mhtml/html_part.rb +19 -13
  25. data/lib/uniword/mhtml/math_converter.rb +18 -12
  26. data/lib/uniword/mhtml/mime_part.rb +5 -16
  27. data/lib/uniword/mhtml/xml_part.rb +3 -3
  28. data/lib/uniword/ooxml/additional_characteristics.rb +4 -4
  29. data/lib/uniword/ooxml/element_order.rb +21 -0
  30. data/lib/uniword/ooxml/schema/element_serializer.rb +27 -35
  31. data/lib/uniword/ooxml/schema_library.rb +2 -2
  32. data/lib/uniword/ooxml/types/characteristics_val.rb +16 -0
  33. data/lib/uniword/ooxml/types/schema_library_val.rb +17 -0
  34. data/lib/uniword/ooxml/types/variant_types.rb +10 -2
  35. data/lib/uniword/ooxml/types/vt_attr.rb +19 -0
  36. data/lib/uniword/ooxml/types/wml_int.rb +17 -0
  37. data/lib/uniword/ooxml/types/wml_val.rb +19 -0
  38. data/lib/uniword/ooxml/types.rb +12 -0
  39. data/lib/uniword/properties/alignment.rb +4 -0
  40. data/lib/uniword/properties/boolean_element_factory.rb +1 -1
  41. data/lib/uniword/properties/font_size.rb +3 -0
  42. data/lib/uniword/review/review_manager.rb +34 -5
  43. data/lib/uniword/review/revision_resolver.rb +190 -0
  44. data/lib/uniword/review.rb +1 -0
  45. data/lib/uniword/revision.rb +3 -3
  46. data/lib/uniword/serialization/ooxml_serializer.rb +3 -3
  47. data/lib/uniword/streaming_parser.rb +22 -20
  48. data/lib/uniword/theme/theme_xml_parser.rb +4 -6
  49. data/lib/uniword/transformation/html_element_builder.rb +62 -48
  50. data/lib/uniword/transformation/html_formatting_mapper.rb +3 -3
  51. data/lib/uniword/transformation/html_to_ooxml_converter.rb +11 -11
  52. data/lib/uniword/transformation/mhtml_element_renderer.rb +1 -2
  53. data/lib/uniword/validation/opc_validator.rb +6 -7
  54. data/lib/uniword/validation/rules/document_context.rb +3 -3
  55. data/lib/uniword/validation/rules/images_rule.rb +1 -1
  56. data/lib/uniword/validation/rules/theme_rule.rb +2 -2
  57. data/lib/uniword/validation/schema_registry.rb +10 -17
  58. data/lib/uniword/validation/validators/xml_schema_validator.rb +75 -26
  59. data/lib/uniword/validation/verify_orchestrator.rb +1 -1
  60. data/lib/uniword/version.rb +1 -1
  61. data/lib/uniword/wordprocessingml/deletion.rb +41 -0
  62. data/lib/uniword/wordprocessingml/insertion.rb +41 -0
  63. data/lib/uniword/wordprocessingml/page_margins.rb +7 -7
  64. data/lib/uniword/wordprocessingml/paragraph.rb +30 -4
  65. data/lib/uniword/wordprocessingml/settings.rb +3 -4
  66. data/lib/uniword/wordprocessingml/style_cleanup.rb +5 -14
  67. data/lib/uniword/wordprocessingml/table_borders.rb +1 -1
  68. data/lib/uniword/wordprocessingml/table_cell_borders.rb +1 -1
  69. data/lib/uniword/wordprocessingml/text.rb +0 -1
  70. data/lib/uniword/wordprocessingml.rb +5 -0
  71. data/lib/uniword/wp_drawing/position_h.rb +1 -1
  72. data/lib/uniword/wp_drawing/position_v.rb +1 -1
  73. data/lib/uniword/wp_drawing/size_rel_h.rb +1 -1
  74. data/lib/uniword/wp_drawing/size_rel_v.rb +1 -1
  75. data/lib/uniword.rb +9 -7
  76. metadata +19 -15
  77. data/lib/uniword/infrastructure/xml_namespace_normalizer.rb +0 -107
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uniword
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-09-20 00:00:00.000000000 Z
11
+ date: 2026-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logger
@@ -25,39 +25,33 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: lutaml-model
28
+ name: leptris
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.8.0
34
- - - ">="
35
- - !ruby/object:Gem::Version
36
- version: 0.8.6
33
+ version: 1.9.352
37
34
  type: :runtime
38
35
  prerelease: false
39
36
  version_requirements: !ruby/object:Gem::Requirement
40
37
  requirements:
41
38
  - - "~>"
42
39
  - !ruby/object:Gem::Version
43
- version: 0.8.0
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: 0.8.6
40
+ version: 1.9.352
47
41
  - !ruby/object:Gem::Dependency
48
- name: nokogiri
42
+ name: lutaml-model
49
43
  requirement: !ruby/object:Gem::Requirement
50
44
  requirements:
51
45
  - - "~>"
52
46
  - !ruby/object:Gem::Version
53
- version: '1.19'
47
+ version: '0.8'
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
51
  requirements:
58
52
  - - "~>"
59
53
  - !ruby/object:Gem::Version
60
- version: '1.19'
54
+ version: '0.8'
61
55
  - !ruby/object:Gem::Dependency
62
56
  name: omml
63
57
  requirement: !ruby/object:Gem::Requirement
@@ -741,13 +735,16 @@ files:
741
735
  - lib/uniword/chart/x_values.rb
742
736
  - lib/uniword/chart/y_values.rb
743
737
  - lib/uniword/cli.rb
738
+ - lib/uniword/cli/completions.rb
744
739
  - lib/uniword/cli/diff_cli.rb
745
740
  - lib/uniword/cli/fonts_cli.rb
746
741
  - lib/uniword/cli/generate_cli.rb
747
742
  - lib/uniword/cli/headers_cli.rb
743
+ - lib/uniword/cli/help_switch.rb
748
744
  - lib/uniword/cli/helpers.rb
749
745
  - lib/uniword/cli/images_cli.rb
750
746
  - lib/uniword/cli/main.rb
747
+ - lib/uniword/cli/no_color.rb
751
748
  - lib/uniword/cli/page_cli.rb
752
749
  - lib/uniword/cli/protect_cli.rb
753
750
  - lib/uniword/cli/resources_cli.rb
@@ -1075,7 +1072,6 @@ files:
1075
1072
  - lib/uniword/infrastructure.rb
1076
1073
  - lib/uniword/infrastructure/mime_packager.rb
1077
1074
  - lib/uniword/infrastructure/mime_parser.rb
1078
- - lib/uniword/infrastructure/xml_namespace_normalizer.rb
1079
1075
  - lib/uniword/infrastructure/zip_extractor.rb
1080
1076
  - lib/uniword/infrastructure/zip_packager.rb
1081
1077
  - lib/uniword/lazy_loader.rb
@@ -1189,6 +1185,7 @@ files:
1189
1185
  - lib/uniword/ooxml/theme_package.rb
1190
1186
  - lib/uniword/ooxml/thmx_package.rb
1191
1187
  - lib/uniword/ooxml/types.rb
1188
+ - lib/uniword/ooxml/types/characteristics_val.rb
1192
1189
  - lib/uniword/ooxml/types/cp_description_type.rb
1193
1190
  - lib/uniword/ooxml/types/cp_keywords_type.rb
1194
1191
  - lib/uniword/ooxml/types/cp_last_modified_by_type.rb
@@ -1204,9 +1201,13 @@ files:
1204
1201
  - lib/uniword/ooxml/types/ooxml_boolean.rb
1205
1202
  - lib/uniword/ooxml/types/ooxml_boolean_optional.rb
1206
1203
  - lib/uniword/ooxml/types/relationship_id.rb
1204
+ - lib/uniword/ooxml/types/schema_library_val.rb
1207
1205
  - lib/uniword/ooxml/types/theme_color_value.rb
1208
1206
  - lib/uniword/ooxml/types/unsigned_decimal_number.rb
1209
1207
  - lib/uniword/ooxml/types/variant_types.rb
1208
+ - lib/uniword/ooxml/types/vt_attr.rb
1209
+ - lib/uniword/ooxml/types/wml_int.rb
1210
+ - lib/uniword/ooxml/types/wml_val.rb
1210
1211
  - lib/uniword/page_borders.rb
1211
1212
  - lib/uniword/paragraph_border.rb
1212
1213
  - lib/uniword/picture.rb
@@ -1368,6 +1369,7 @@ files:
1368
1369
  - lib/uniword/review/accept_reject.rb
1369
1370
  - lib/uniword/review/interactive_review.rb
1370
1371
  - lib/uniword/review/review_manager.rb
1372
+ - lib/uniword/review/revision_resolver.rb
1371
1373
  - lib/uniword/revision.rb
1372
1374
  - lib/uniword/schema.rb
1373
1375
  - lib/uniword/schema/model_generator.rb
@@ -1725,6 +1727,7 @@ files:
1725
1727
  - lib/uniword/wordprocessingml/def_jc.rb
1726
1728
  - lib/uniword/wordprocessingml/default_tab_stop.rb
1727
1729
  - lib/uniword/wordprocessingml/deleted_text.rb
1730
+ - lib/uniword/wordprocessingml/deletion.rb
1728
1731
  - lib/uniword/wordprocessingml/disp_def.rb
1729
1732
  - lib/uniword/wordprocessingml/div_border.rb
1730
1733
  - lib/uniword/wordprocessingml/div_borders.rb
@@ -1774,6 +1777,7 @@ files:
1774
1777
  - lib/uniword/wordprocessingml/hyphenation_zone.rb
1775
1778
  - lib/uniword/wordprocessingml/imprint.rb
1776
1779
  - lib/uniword/wordprocessingml/inline.rb
1780
+ - lib/uniword/wordprocessingml/insertion.rb
1777
1781
  - lib/uniword/wordprocessingml/instr_text.rb
1778
1782
  - lib/uniword/wordprocessingml/int_lim.rb
1779
1783
  - lib/uniword/wordprocessingml/l_margin.rb
@@ -1,107 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "nokogiri"
4
-
5
- module Uniword
6
- module Infrastructure
7
- # XML normalization utilities for round-trip fidelity
8
- #
9
- # Ensures that serialized XML matches the expected namespace declaration format
10
- # by adding missing prefixed namespace declarations to root elements.
11
- module XmlNamespaceNormalizer
12
- # Prefixed namespaces that should be declared at root level in OOXML documents
13
- PREFIXED_NAMESPACES = {
14
- "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" => "wp",
15
- "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" => "wp14",
16
- }.freeze
17
-
18
- # Normalize XML to ensure prefixed namespace declarations are at root level
19
- #
20
- # @param xml [String] XML content
21
- # @return [String] Normalized XML content
22
- def self.normalize(xml)
23
- doc = Nokogiri::XML(xml)
24
- return xml unless doc.root
25
-
26
- # Check if any prefixed namespaces are used but not declared at root
27
- root = doc.root
28
- root_ns = root.namespace_definitions.to_h { |ns| [ns.prefix, ns.href] }
29
-
30
- PREFIXED_NAMESPACES.each do |uri, expected_prefix|
31
- # Check if this namespace URI is used in the document
32
- elements_with_ns = doc.xpath("//*[namespace-uri()='#{uri}']")
33
- next if elements_with_ns.empty?
34
-
35
- # Check if the expected prefix is already declared at root
36
- if root_ns.key?(expected_prefix) && (root_ns[expected_prefix] == uri)
37
- # Check if the URI matches
38
- next
39
- end
40
-
41
- # Check if default namespace with this URI exists
42
- default_ns = root_ns.find { |k, v| k.nil? && v == uri }
43
-
44
- if default_ns
45
- # Replace default namespace with prefixed namespace
46
- # Find the default xmlns attribute and rename it
47
- root.attributes.each do |name, attr|
48
- next unless name == "xmlns" && attr.value == uri
49
-
50
- # Remove the default namespace
51
- root.remove_attribute("xmlns")
52
- # Add the prefixed namespace
53
- root["xmlns:#{expected_prefix}"] = uri
54
-
55
- # Update all elements that use this namespace to use the prefix
56
- update_elements_namespace(elements_with_ns, expected_prefix)
57
- break
58
- end
59
- else
60
- # Namespace is used but not declared at root - add it
61
- root["xmlns:#{expected_prefix}"] = uri
62
- end
63
- end
64
-
65
- doc.to_xml(indent: 0, save_with: Nokogiri::XML::Node::SaveOptions::AS_XML)
66
- end
67
-
68
- # Update elements to use the correct namespace prefix
69
- #
70
- # @param elements [Nokogiri::XML::NodeSet] Elements to update
71
- # @param prefix [String] The prefix to use
72
- def self.update_elements_namespace(elements, prefix)
73
- elements.each do |el|
74
- # Update the element's namespace
75
- ns = el.document.root.namespaces.find do |_k, v|
76
- v == el.namespace.href
77
- end
78
- next unless ns
79
-
80
- # Change namespace key from default to prefixed
81
- el.document.root.namespaces.delete(ns[0])
82
- el.document.root["xmlns:#{prefix}"] = ns[1]
83
- end
84
- end
85
-
86
- # Normalize namespace declarations in a ZIP content hash
87
- #
88
- # @param zip_content [Hash] File path => content mapping
89
- # @param target_files [Array<String>] Files to normalize
90
- # @return [Hash] Updated zip content
91
- def self.normalize_zip_content(zip_content, target_files = nil)
92
- result = zip_content.dup
93
- target_files ||= result.keys.select do |k|
94
- k.end_with?(".xml", ".rels")
95
- end
96
-
97
- target_files.each do |path|
98
- next unless result[path]
99
-
100
- result[path] = normalize(result[path])
101
- end
102
-
103
- result
104
- end
105
- end
106
- end
107
- end