uniword 1.0.8 → 1.0.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a62022223f8643943947659aae4d0e27b5d8566cab7486e0c688566cc0428208
4
- data.tar.gz: 61727290e9fac98b2e4cf3b43bb1fd70f09c4b9648206eb861d1bc3766b964d9
3
+ metadata.gz: 8b3b37b9a1642f94a634c42b754630ca35cd7167ddc1415223dd65848a379c48
4
+ data.tar.gz: 011ddc8e381521e2d161cd0cf9fd0dd9eee791e9f28026fd63e89cf9386bfa03
5
5
  SHA512:
6
- metadata.gz: f99053000864fae5910ee3c34f07504daf4afb061093aced4a5589f0a80c335cca44fa48a72bad5f1725d87a82346dc5abc577c14e6238875a9a175bfd33c788
7
- data.tar.gz: cf9546e5ad9b15a3d4973785b922589d29bbd8bea8a34c75b1012f10a2a9190988abaccae1c5e0f41217589fc9f27151342210373ca9a00c355f86ad2218b15c
6
+ metadata.gz: 1c6c8785a7fe56480f0d7bdda19ec56e50704653016d4146c561e401c8e98b856cf99a1205411521b78cd19b701e794dfbc75c4d4c844b87e2b8fe3d44fb514e
7
+ data.tar.gz: 9275ea155ee7af2ee9cd0e24d6534a0124f0f8501583206fb98eb3c63e7736c280552336a47bad97a31e50b235805c5fba904d1a80c0cee9bbe6f216f7e49f02
@@ -11,7 +11,8 @@ module Uniword
11
11
  class CommentBuilder
12
12
  attr_reader :model
13
13
 
14
- def initialize(model: nil, author: nil, comment_id: nil, date: nil, initials: nil)
14
+ def initialize(model: nil, author: nil, comment_id: nil, date: nil,
15
+ initials: nil)
15
16
  @model = model || Comment.new(
16
17
  author: author,
17
18
  comment_id: comment_id,
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uniword
4
+ # Tagging module for document types accepted by DocumentWriter and FormatConverter.
5
+ module DocumentInput
6
+ end
7
+ end
@@ -136,11 +136,7 @@ module Uniword
136
136
  # @raise [ArgumentError] if document is invalid
137
137
  def validate_document(doc)
138
138
  raise ArgumentError, "Document cannot be nil" if doc.nil?
139
-
140
- # Accept OOXML Document
141
- return if doc.is_a?(Uniword::Wordprocessingml::DocumentRoot)
142
- # Accept MHTML Document
143
- return if doc.is_a?(Uniword::Mhtml::Document)
139
+ return if doc.is_a?(Uniword::DocumentInput)
144
140
 
145
141
  raise ArgumentError, "Must be a Document instance"
146
142
  end
@@ -93,6 +93,7 @@ module Uniword
93
93
  part.instance_variable_set(:@xml_input_namespaces, nil)
94
94
  end
95
95
  end
96
+
96
97
  def reconcile_section_properties
97
98
  return unless package.document&.body
98
99
 
@@ -277,30 +277,15 @@ module Uniword
277
277
  # @param document [Object] Document (OOXML or MHTML)
278
278
  # @return [Hash] Statistics hash
279
279
  def document_stats(document)
280
- # Handle OOXML document
281
- if document.is_a?(Uniword::Wordprocessingml::DocumentRoot) || document.is_a?(Uniword::Wordprocessingml::Body)
280
+ if document.is_a?(Uniword::Wordprocessingml::Body)
282
281
  return {
283
282
  paragraphs: document.paragraphs.count,
284
- tables: document.is_a?(Uniword::Wordprocessingml::DocumentRoot) ? document.tables.count : 0,
285
- images: document.is_a?(Uniword::Wordprocessingml::DocumentRoot) ? document.images.count : 0
283
+ tables: 0,
284
+ images: 0
286
285
  }
287
286
  end
288
287
 
289
- # Handle MHTML document - estimate from HTML content
290
- html = if document.is_a?(Mhtml::Document) && document.raw_html
291
- document.raw_html
292
- elsif document.is_a?(Mhtml::Document) && document.html_content
293
- document.html_content
294
- end
295
- if html
296
- {
297
- paragraphs: html.scan(/<p[\s>]/i).count,
298
- tables: html.scan(/<table/i).count,
299
- images: html.scan(/<img/i).count
300
- }
301
- else
302
- { paragraphs: 0, tables: 0, images: 0 }
303
- end
288
+ document.document_stats
304
289
  end
305
290
 
306
291
  # Validate conversion parameters
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uniword
4
+ # Tagging module for elements that track their position among sibling runs.
5
+ # Used by the MHTML renderer to interleave hyperlinks and math objects
6
+ # at the correct position within a paragraph.
7
+ module HasRunPosition
8
+ end
9
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "lutaml/model"
4
+ require_relative "../has_run_position"
4
5
 
5
6
  module Uniword
6
7
  module Math
@@ -9,6 +10,8 @@ module Uniword
9
10
  # Generated from OOXML schema: math.yml
10
11
  # Element: <m:oMath>
11
12
  class OMath < Lutaml::Model::Serializable
13
+ include Uniword::HasRunPosition
14
+
12
15
  # Pattern 0: Attributes BEFORE xml mappings
13
16
  attribute :runs, MathRun, collection: true, initialize_empty: true
14
17
  attribute :functions, Function, collection: true, initialize_empty: true
@@ -2,6 +2,8 @@
2
2
 
3
3
  require "lutaml/model"
4
4
 
5
+ require_relative "../document_input"
6
+
5
7
  module Uniword
6
8
  module Mhtml
7
9
  # MHTML Document — top-level model for .mht/.mhtml/.doc files.
@@ -17,6 +19,8 @@ module Uniword
17
19
  # ├── word_document_settings (Metadata::WordDocumentSettings)
18
20
  # └── filelist_xml (String)
19
21
  class Document < Lutaml::Model::Serializable
22
+ include Uniword::DocumentInput
23
+
20
24
  # MIME headers
21
25
  attribute :mime_version, :string, default: -> { "1.0" }
22
26
  attribute :boundary, :string
@@ -161,6 +165,20 @@ module Uniword
161
165
  "#<#{self.class} parts=#{parts.length} images=#{image_parts.length} " \
162
166
  "xml=#{xml_parts.length} theme=#{theme_part ? 'yes' : 'no'}>"
163
167
  end
168
+
169
+ # @return [Hash] Document statistics (paragraphs, tables, images)
170
+ def document_stats
171
+ html = raw_html || html_content
172
+ if html
173
+ {
174
+ paragraphs: html.scan(/<p[\s>]/i).count,
175
+ tables: html.scan(/<table/i).count,
176
+ images: html.scan(/<img/i).count,
177
+ }
178
+ else
179
+ { paragraphs: 0, tables: 0, images: 0 }
180
+ end
181
+ end
164
182
  end
165
183
  end
166
184
  end
@@ -1,40 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "lutaml/model"
3
+ require_relative "boolean_element_factory"
4
4
 
5
5
  module Uniword
6
6
  module Properties
7
- # Bold formatting element
8
- #
9
- # OOXML: <w:b/> means bold=true (absence of val= means true)
10
- # <w:b w:val="false"/> means bold=false
11
- #
12
- # Model: nil = true (no val attribute), 'false' = explicit false
13
- class Bold < Lutaml::Model::Serializable
14
- include Uniword::Properties::BooleanElement
15
-
16
- attribute :val, :string, default: nil
17
- include Uniword::Properties::BooleanValSetter
18
-
19
- xml do
20
- element "b"
21
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
22
- map_attribute "val", to: :val, render_nil: false, render_default: false
23
- end
24
- end
25
-
26
- # Complex script bold
27
- class BoldCs < Lutaml::Model::Serializable
28
- include Uniword::Properties::BooleanElement
29
-
30
- attribute :val, :string, default: nil
31
- include Uniword::Properties::BooleanValSetter
32
-
33
- xml do
34
- element "bCs"
35
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
36
- map_attribute "val", to: :val, render_nil: false, render_default: false
37
- end
38
- end
7
+ BooleanElementFactory.define("b", "Bold")
8
+ BooleanElementFactory.define("bCs", "BoldCs")
39
9
  end
40
10
  end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lutaml/model"
4
+
5
+ module Uniword
6
+ module Properties
7
+ # OOXML boolean element mixin for value/val getter logic only.
8
+ # The val= setter must be defined AFTER attribute :val to override
9
+ # the generated setter.
10
+ module BooleanElement
11
+ def value
12
+ val != "false"
13
+ end
14
+ end
15
+
16
+ # Helper to define val= override after attribute declaration.
17
+ # Uses alias_method to save the generated setter, then overrides it.
18
+ module BooleanValSetter
19
+ def self.included(base)
20
+ base.class_eval do
21
+ alias_method :__original_val_setter=, :val= if method_defined?(:val=)
22
+ define_method(:val=) do |v|
23
+ @val = if v.nil?
24
+ nil
25
+ elsif v == false || v.to_s == "false"
26
+ "false"
27
+ elsif v == true || v.to_s == "true"
28
+ nil
29
+ else
30
+ v
31
+ end
32
+ value_set_for(:val)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ # Factory for OOXML boolean element classes.
39
+ #
40
+ # Generates a lutaml-model class that maps to an XML element like
41
+ # <w:b/> (true) or <w:b w:val="false"/> (false).
42
+ #
43
+ # @param element_name [String] XML element name (e.g. "b", "i", "strike")
44
+ # @param class_name [String] Ruby class name (e.g. "Bold", "Italic")
45
+ # @return [Class] The generated class, also assigned as a constant
46
+ #
47
+ # @example
48
+ # BooleanElementFactory.define("b", "Bold")
49
+ # BooleanElementFactory.define("bCs", "BoldCs")
50
+ module BooleanElementFactory
51
+ WML_NS = Uniword::Ooxml::Namespaces::WordProcessingML
52
+
53
+ def self.define(element_name, class_name)
54
+ klass = Class.new(Lutaml::Model::Serializable) do
55
+ include BooleanElement
56
+
57
+ attribute :val, :string, default: nil
58
+ include BooleanValSetter
59
+
60
+ xml do
61
+ element element_name
62
+ namespace WML_NS
63
+ map_attribute "val", to: :val, render_nil: false,
64
+ render_default: false
65
+ end
66
+ end
67
+
68
+ Properties.const_set(class_name, klass)
69
+ klass
70
+ end
71
+ end
72
+ end
73
+ end
@@ -1,224 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "lutaml/model"
3
+ require_relative "boolean_element_factory"
4
4
 
5
5
  module Uniword
6
6
  module Properties
7
- # OOXML boolean element mixin for value/val getter logic only.
8
- # The val= setter must be defined AFTER attribute :val to override
9
- # the generated setter.
10
- module BooleanElement
11
- def value
12
- val != "false"
13
- end
14
- end
15
-
16
- # Helper to define val= override after attribute declaration.
17
- # Uses alias_method to save the generated setter, then overrides it.
18
- module BooleanValSetter
19
- def self.included(base)
20
- base.class_eval do
21
- # Save the generated val= method
22
- alias_method :__original_val_setter=, :val= if method_defined?(:val=)
23
- # Override val= with our custom logic
24
- define_method(:val=) do |v|
25
- @val = if v.nil?
26
- nil
27
- elsif v == false || v.to_s == "false"
28
- "false"
29
- elsif v == true || v.to_s == "true"
30
- nil
31
- else
32
- v
33
- end
34
- value_set_for(:val)
35
- end
36
- end
37
- end
38
- end
39
-
40
- # Strike-through formatting
41
- class Strike < Lutaml::Model::Serializable
42
- include BooleanElement
43
-
44
- attribute :val, :string, default: nil
45
- include BooleanValSetter
46
-
47
- xml do
48
- element "strike"
49
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
50
- map_attribute "val", to: :val, render_nil: false, render_default: false
51
- end
52
- end
53
-
54
- # Double strike-through formatting
55
- class DoubleStrike < Lutaml::Model::Serializable
56
- include BooleanElement
57
-
58
- attribute :val, :string, default: nil
59
- include BooleanValSetter
60
-
61
- xml do
62
- element "dstrike"
63
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
64
- map_attribute "val", to: :val, render_nil: false, render_default: false
65
- end
66
- end
67
-
68
- # Small caps formatting
69
- class SmallCaps < Lutaml::Model::Serializable
70
- include BooleanElement
71
-
72
- attribute :val, :string, default: nil
73
- include BooleanValSetter
74
-
75
- xml do
76
- element "smallCaps"
77
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
78
- map_attribute "val", to: :val, render_nil: false, render_default: false
79
- end
80
- end
81
-
82
- # All caps formatting
83
- class Caps < Lutaml::Model::Serializable
84
- include BooleanElement
85
-
86
- attribute :val, :string, default: nil
87
- include BooleanValSetter
88
-
89
- xml do
90
- element "caps"
91
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
92
- map_attribute "val", to: :val, render_nil: false, render_default: false
93
- end
94
- end
95
-
96
- # Hidden text
97
- class Vanish < Lutaml::Model::Serializable
98
- include BooleanElement
99
-
100
- attribute :val, :string, default: nil
101
- include BooleanValSetter
102
-
103
- xml do
104
- element "vanish"
105
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
106
- map_attribute "val", to: :val, render_nil: false, render_default: false
107
- end
108
- end
109
-
110
- # Web hidden text (hidden from web view)
111
- class WebHidden < Lutaml::Model::Serializable
112
- include BooleanElement
113
-
114
- attribute :val, :string, default: nil
115
- include BooleanValSetter
116
-
117
- xml do
118
- element "webHidden"
119
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
120
- map_attribute "val", to: :val, render_nil: false, render_default: false
121
- end
122
- end
123
-
124
- # No proofing (disable spell/grammar check)
125
- class NoProof < Lutaml::Model::Serializable
126
- include BooleanElement
127
-
128
- attribute :val, :string, default: nil
129
- include BooleanValSetter
130
-
131
- xml do
132
- element "noProof"
133
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
134
- map_attribute "val", to: :val, render_nil: false, render_default: false
135
- end
136
- end
137
-
138
- # Shadow formatting
139
- class Shadow < Lutaml::Model::Serializable
140
- include BooleanElement
141
-
142
- attribute :val, :string, default: nil
143
- include BooleanValSetter
144
-
145
- xml do
146
- element "shadow"
147
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
148
- map_attribute "val", to: :val, render_nil: false, render_default: false
149
- end
150
- end
151
-
152
- # Emboss formatting
153
- class Emboss < Lutaml::Model::Serializable
154
- include BooleanElement
155
-
156
- attribute :val, :string, default: nil
157
- include BooleanValSetter
158
-
159
- xml do
160
- element "emboss"
161
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
162
- map_attribute "val", to: :val, render_nil: false, render_default: false
163
- end
164
- end
165
-
166
- # Imprint formatting
167
- class Imprint < Lutaml::Model::Serializable
168
- include BooleanElement
169
-
170
- attribute :val, :string, default: nil
171
- include BooleanValSetter
172
-
173
- xml do
174
- element "imprint"
175
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
176
- map_attribute "val", to: :val, render_nil: false, render_default: false
177
- end
178
- end
7
+ # Run-level boolean formatting elements
8
+ BooleanElementFactory.define("strike", "Strike")
9
+ BooleanElementFactory.define("dstrike", "DoubleStrike")
10
+ BooleanElementFactory.define("smallCaps", "SmallCaps")
11
+ BooleanElementFactory.define("caps", "Caps")
12
+ BooleanElementFactory.define("vanish", "Vanish")
13
+ BooleanElementFactory.define("webHidden", "WebHidden")
14
+ BooleanElementFactory.define("noProof", "NoProof")
15
+ BooleanElementFactory.define("shadow", "Shadow")
16
+ BooleanElementFactory.define("emboss", "Emboss")
17
+ BooleanElementFactory.define("imprint", "Imprint")
179
18
 
180
19
  # Style-level boolean elements
181
-
182
- # Quick format flag
183
- class QuickFormat < Lutaml::Model::Serializable
184
- include BooleanElement
185
-
186
- attribute :val, :string, default: nil
187
- include BooleanValSetter
188
-
189
- xml do
190
- element "qFormat"
191
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
192
- map_attribute "val", to: :val, render_nil: false, render_default: false
193
- end
194
- end
195
-
196
- # Keep with next paragraph
197
- class KeepNext < Lutaml::Model::Serializable
198
- include BooleanElement
199
-
200
- attribute :val, :string, default: nil
201
- include BooleanValSetter
202
-
203
- xml do
204
- element "keepNext"
205
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
206
- map_attribute "val", to: :val, render_nil: false, render_default: false
207
- end
208
- end
209
-
210
- # Keep lines together
211
- class KeepLines < Lutaml::Model::Serializable
212
- include BooleanElement
213
-
214
- attribute :val, :string, default: nil
215
- include BooleanValSetter
216
-
217
- xml do
218
- element "keepLines"
219
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
220
- map_attribute "val", to: :val, render_nil: false, render_default: false
221
- end
222
- end
20
+ BooleanElementFactory.define("qFormat", "QuickFormat")
21
+ BooleanElementFactory.define("keepNext", "KeepNext")
22
+ BooleanElementFactory.define("keepLines", "KeepLines")
223
23
  end
224
24
  end
@@ -1,40 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "lutaml/model"
3
+ require_relative "boolean_element_factory"
4
4
 
5
5
  module Uniword
6
6
  module Properties
7
- # Italic formatting element
8
- #
9
- # OOXML: <w:i/> means italic=true (absence of val= means true)
10
- # <w:i w:val="false"/> means italic=false
11
- #
12
- # Model: nil = true (no val attribute), 'false' = explicit false
13
- class Italic < Lutaml::Model::Serializable
14
- include Uniword::Properties::BooleanElement
15
-
16
- attribute :val, :string, default: nil
17
- include Uniword::Properties::BooleanValSetter
18
-
19
- xml do
20
- element "i"
21
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
22
- map_attribute "val", to: :val, render_nil: false, render_default: false
23
- end
24
- end
25
-
26
- # Complex script italic
27
- class ItalicCs < Lutaml::Model::Serializable
28
- include Uniword::Properties::BooleanElement
29
-
30
- attribute :val, :string, default: nil
31
- include Uniword::Properties::BooleanValSetter
32
-
33
- xml do
34
- element "iCs"
35
- namespace Uniword::Ooxml::Namespaces::WordProcessingML
36
- map_attribute "val", to: :val, render_nil: false, render_default: false
37
- end
38
- end
7
+ BooleanElementFactory.define("i", "Italic")
8
+ BooleanElementFactory.define("iCs", "ItalicCs")
39
9
  end
40
10
  end
@@ -23,10 +23,13 @@ module Uniword
23
23
  autoload :NumberingProperties, "uniword/properties/numbering_properties"
24
24
  autoload :Tabs, "uniword/properties/tabs"
25
25
 
26
+ # Boolean element infrastructure
27
+ autoload :BooleanElement, "uniword/properties/boolean_element_factory"
28
+ autoload :BooleanValSetter, "uniword/properties/boolean_element_factory"
29
+ autoload :BooleanElementFactory,
30
+ "uniword/properties/boolean_element_factory"
31
+
26
32
  # Boolean formatting classes (from boolean_formatting.rb)
27
- # Note: BooleanElement and BooleanValSetter are also in boolean_formatting.rb
28
- autoload :BooleanElement, "uniword/properties/boolean_formatting"
29
- autoload :BooleanValSetter, "uniword/properties/boolean_formatting"
30
33
  autoload :Strike, "uniword/properties/boolean_formatting"
31
34
  autoload :DoubleStrike, "uniword/properties/boolean_formatting"
32
35
  autoload :SmallCaps, "uniword/properties/boolean_formatting"
@@ -49,7 +52,9 @@ module Uniword
49
52
 
50
53
  # Bold and Italic (from bold.rb and italic.rb)
51
54
  autoload :Bold, "uniword/properties/bold"
55
+ autoload :BoldCs, "uniword/properties/bold"
52
56
  autoload :Italic, "uniword/properties/italic"
57
+ autoload :ItalicCs, "uniword/properties/italic"
53
58
 
54
59
  # Complex objects
55
60
  autoload :Spacing, "uniword/properties/spacing"
@@ -547,7 +547,7 @@ module Uniword
547
547
  def build_position_map(elements, fallback_pos)
548
548
  by_pos = {}
549
549
  elements.each do |el|
550
- pos = el.run_position if el.is_a?(Uniword::Wordprocessingml::Hyperlink) || el.is_a?(Uniword::Math::OMath)
550
+ pos = el.run_position if el.is_a?(Uniword::HasRunPosition)
551
551
  pos ||= fallback_pos
552
552
  by_pos[pos] ||= []
553
553
  by_pos[pos] << el
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Uniword
4
- VERSION = "1.0.8"
4
+ VERSION = "1.0.9"
5
5
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "lutaml/model"
4
4
 
5
+ require_relative "../document_input"
5
6
  require_relative "document_root/feature_facade"
6
7
 
7
8
  module Uniword
@@ -12,6 +13,7 @@ module Uniword
12
13
  # Element: <w:document>
13
14
  class DocumentRoot < Lutaml::Model::Serializable
14
15
  include FeatureFacade
16
+ include Uniword::DocumentInput
15
17
 
16
18
  attribute :mc_ignorable, Uniword::Ooxml::Types::McIgnorable
17
19
  attribute :body, Body, default: -> { Body.new }
@@ -210,6 +212,15 @@ module Uniword
210
212
  end.compact
211
213
  end
212
214
 
215
+ # @return [Hash] Document statistics (paragraphs, tables, images)
216
+ def document_stats
217
+ {
218
+ paragraphs: paragraphs.count,
219
+ tables: tables.count,
220
+ images: images.count,
221
+ }
222
+ end
223
+
213
224
  # Check if document structure is valid.
214
225
  # Runs structural checks via Validation::StructuralValidator.
215
226
  # Use the verify CLI command for full OPC + XSD + semantic validation.
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "lutaml/model"
4
+ require_relative "../has_run_position"
4
5
 
5
6
  module Uniword
6
7
  module Wordprocessingml
@@ -9,6 +10,8 @@ module Uniword
9
10
  # Generated from OOXML schema: wordprocessingml.yml
10
11
  # Element: <w:hyperlink>
11
12
  class Hyperlink < Lutaml::Model::Serializable
13
+ include Uniword::HasRunPosition
14
+
12
15
  attribute :id, :string
13
16
  attribute :anchor, :string
14
17
  attribute :tooltip, :string
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.0.8
4
+ version: 1.0.9
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-05-11 00:00:00.000000000 Z
11
+ date: 2026-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logger
@@ -771,6 +771,7 @@ files:
771
771
  - lib/uniword/diff/package_diff_result.rb
772
772
  - lib/uniword/diff/package_differ.rb
773
773
  - lib/uniword/document_factory.rb
774
+ - lib/uniword/document_input.rb
774
775
  - lib/uniword/document_variables.rb
775
776
  - lib/uniword/document_variables/data_type.rb
776
777
  - lib/uniword/document_variables/default_value.rb
@@ -966,6 +967,7 @@ files:
966
967
  - lib/uniword/glossary/glossary_document.rb
967
968
  - lib/uniword/glossary/style_id.rb
968
969
  - lib/uniword/glossary/text_box.rb
970
+ - lib/uniword/has_run_position.rb
969
971
  - lib/uniword/header.rb
970
972
  - lib/uniword/headers_footers.rb
971
973
  - lib/uniword/headers_footers/manager.rb
@@ -1157,7 +1159,6 @@ files:
1157
1159
  - lib/uniword/ooxml/types/dcterms_modified_type.rb
1158
1160
  - lib/uniword/ooxml/types/dcterms_w3cdtf_type.rb
1159
1161
  - lib/uniword/ooxml/types/mc_ignorable_type.rb
1160
- - lib/uniword/ooxml/types/on_off_type.rb
1161
1162
  - lib/uniword/ooxml/types/ooxml_boolean.rb
1162
1163
  - lib/uniword/ooxml/types/ooxml_boolean_optional.rb
1163
1164
  - lib/uniword/ooxml/types/relationship_id.rb
@@ -1232,6 +1233,7 @@ files:
1232
1233
  - lib/uniword/properties/auto_space_de.rb
1233
1234
  - lib/uniword/properties/auto_space_dn.rb
1234
1235
  - lib/uniword/properties/bold.rb
1236
+ - lib/uniword/properties/boolean_element_factory.rb
1235
1237
  - lib/uniword/properties/boolean_formatting.rb
1236
1238
  - lib/uniword/properties/border.rb
1237
1239
  - lib/uniword/properties/borders.rb
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "lutaml/model"
4
-
5
- module Uniword
6
- module Ooxml
7
- module Types
8
- # OOXML On/Off (boolean) type for attributes.
9
- #
10
- # OOXML uses "0" and "1" for boolean attribute values, not "false"/"true".
11
- # When an attribute is not present (nil), it should remain nil, not be
12
- # serialized as "0". This preserves the original document structure.
13
- #
14
- # @example Serialize a boolean attribute
15
- # # Ruby true → XML "1"
16
- # # Ruby false → XML "0"
17
- # # Ruby nil → attribute not rendered
18
- class OnOffType < Lutaml::Model::Type::String
19
- # Bypass parent's initialize to avoid infinite recursion.
20
- # Parent calls self.class.cast(value) which calls self.new(value).
21
- def initialize(value)
22
- @value = value
23
- end
24
-
25
- # Cast value to OnOffType instance (for attribute serialization).
26
- # nil remains nil (not present in source), preserving original structure.
27
- # Already-wrapped OnOffType instances are returned as-is.
28
- def self.cast(value, _options = {})
29
- return nil if value.nil?
30
- return value if value.is_a?(OnOffType)
31
-
32
- raw = case value
33
- when true, "true", "1", 1
34
- true
35
- when false, "false", "0", 0
36
- false
37
- else
38
- false
39
- end
40
- new(raw)
41
- end
42
-
43
- # Convert stored boolean to OOXML "1" or "0"
44
- def to_xml
45
- return nil if @value.nil?
46
-
47
- @value == true ? "1" : "0"
48
- end
49
-
50
- # Fallback to_s also returns "1"/"0" for compatibility
51
- def to_s
52
- return "" if @value.nil?
53
-
54
- to_xml
55
- end
56
-
57
- # Return the raw boolean value for Ruby comparisons
58
- def to_bool
59
- @value == true
60
- end
61
- end
62
- end
63
- end
64
- end