uniword 1.5.3 → 1.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d06b448460972e577f4d1f22b11441d07949397a06fbe9002db6c4e71d091cc
4
- data.tar.gz: ae04c58467dd36288a5fdf08662496c5d99d2b2da1a7c8fa648fbedd234d9ad2
3
+ metadata.gz: f2355e85fc7e7ec5d55ada1d7f832ef323334131cc5d4573df06ff5db1f08b1d
4
+ data.tar.gz: 3ce0b3e201390c160c09513e85baebf3c1603f70fec278b6b90e8990710212d1
5
5
  SHA512:
6
- metadata.gz: 4d3146558aaf9df9228b7d54064b31aa5c050b3262542aae4075dbeddedea6c53b864c5bc41b065d26289f9c2196e8ee331ca24893b26bea0212f32b39c3fe34
7
- data.tar.gz: fcfa682da31b88784fd3ccabd152f5271f307f6046e5572093bc04789777c1dac23008ad8794d664282128301671c33b411660d5b12cdd5562773481e2adcc48
6
+ metadata.gz: 0c168e086f836c6c1f0120e7d654082c7cc159509db621b584de0e04eb042d0b48f976c63485566bdee5d0c10e367ca568d80cd5f864bca5b0b88940711400a7
7
+ data.tar.gz: 00dedb5f4183d03688a6765d95a550ec117e26325f0e2dfe0262ff77a4ff3b7473d6c816548e18ba46d70ebacd93274feb84d00c81ae280992fc40a061796e5c
@@ -302,7 +302,7 @@ alt_text: nil)
302
302
 
303
303
  # Non-visual properties
304
304
  pic.nv_pic_pr = Picture::NonVisualPictureProperties.new
305
- pic.nv_pic_pr.c_nv_pr = Drawingml::NonVisualDrawingProperties.new(
305
+ pic.nv_pic_pr.c_nv_pr = Picture::NonVisualDrawingProperties.new(
306
306
  id: deterministic_id("pic", r_id),
307
307
  name: "Picture",
308
308
  )
@@ -112,7 +112,7 @@ module Uniword
112
112
  rels = Ooxml::Relationships::PackageRelationships.new
113
113
  rels.relationships = part_keys.each_with_index.map do |key, idx|
114
114
  defn = Ooxml::PartRegistry.find_by_key(key)
115
- Ooxml::Relationships::Relationship.new(
115
+ Ooxml::Relationships::PackageRelationship.new(
116
116
  id: "rId#{idx + 1}",
117
117
  type: defn.rel_type,
118
118
  target: defn.target,
@@ -260,7 +260,7 @@ document_rels)
260
260
 
261
261
  # The reconciler runs before injection; register the rId with
262
262
  # the allocator (single authority) and append the rel here.
263
- package_rels.relationships << Ooxml::Relationships::Relationship.new(
263
+ package_rels.relationships << Ooxml::Relationships::PackageRelationship.new(
264
264
  id: allocator.alloc_rid(target: definition.target,
265
265
  type: definition.rel_type,
266
266
  scope: :package),
@@ -236,7 +236,7 @@ module Uniword
236
236
  def build_rel(id, type, target, target_mode: nil)
237
237
  attrs = { id: id, type: type, target: target }
238
238
  attrs[:target_mode] = target_mode if target_mode
239
- Ooxml::Relationships::Relationship.new(**attrs)
239
+ Ooxml::Relationships::PackageRelationship.new(**attrs)
240
240
  end
241
241
 
242
242
  def run_properties_match?(a, b)
@@ -317,7 +317,7 @@ module Uniword
317
317
  new_rid = allocator.alloc_rid(target: url, type: rel_type,
318
318
  target_mode: "External")
319
319
  unless valid_rids.include?(new_rid)
320
- rels.relationships << Ooxml::Relationships::Relationship.new(
320
+ rels.relationships << Ooxml::Relationships::PackageRelationship.new(
321
321
  id: new_rid,
322
322
  type: rel_type,
323
323
  target: url,
@@ -38,9 +38,8 @@ module Uniword
38
38
  protected
39
39
 
40
40
  # Yield every Text element inside a run. A run carries its
41
- # `<w:t>` Text element on the `text` accessor (lutaml-model
42
- # returns the instance directly even when the attribute is
43
- # declared as a collection).
41
+ # `<w:t>` Text elements on the `text` accessor (declared as a
42
+ # collection; lutaml-model 0.8.32+ returns an Array).
44
43
  #
45
44
  # @param run [Wordprocessingml::Run, nil]
46
45
  # @yieldparam text_element [Wordprocessingml::Text]
@@ -49,14 +48,13 @@ module Uniword
49
48
  def each_text_in_run(run)
50
49
  return unless run
51
50
 
52
- text_element = run.text
53
- return unless text_element
54
-
55
- accessor = TextAccessor.new(
56
- -> { text_element.content },
57
- ->(value) { text_element.content = value },
58
- )
59
- yield text_element, accessor
51
+ run.text&.each do |text_element|
52
+ accessor = TextAccessor.new(
53
+ -> { text_element.content },
54
+ ->(value) { text_element.content = value },
55
+ )
56
+ yield text_element, accessor
57
+ end
60
58
  end
61
59
 
62
60
  # Walk every paragraph in `containers` and yield each run's
@@ -86,7 +86,7 @@ module Uniword
86
86
  # Ensure output directory exists
87
87
  FileUtils.mkdir_p(File.dirname(output_path))
88
88
 
89
- Zip::File.open(output_path, Zip::File::CREATE) do |zipfile|
89
+ Zip::File.open(output_path, create: true) do |zipfile|
90
90
  Dir.glob(File.join(@extracted_dir, "**", "*")).each do |file_path|
91
91
  next if File.directory?(file_path)
92
92
 
@@ -7,7 +7,7 @@ module Uniword
7
7
  # Fill rectangle insets
8
8
  #
9
9
  # Generated from OOXML schema: picture.yml
10
- # Element: <pic:fillRect>
10
+ # Element: <a:fillRect> (child of a:stretch in CT_BlipFillProperties)
11
11
  class FillRect < Lutaml::Model::Serializable
12
12
  attribute :l, :integer
13
13
  attribute :t, :integer
@@ -16,7 +16,7 @@ module Uniword
16
16
 
17
17
  xml do
18
18
  element "fillRect"
19
- namespace Uniword::Ooxml::Namespaces::Picture
19
+ namespace Uniword::Ooxml::Namespaces::DrawingML
20
20
 
21
21
  map_attribute "l", to: :l
22
22
  map_attribute "t", to: :t
@@ -7,7 +7,8 @@ module Uniword
7
7
  # Source rectangle for picture cropping
8
8
  #
9
9
  # Generated from OOXML schema: picture.yml
10
- # Element: <pic:srcRect>
10
+ # Element: <a:srcRect> (CT_BlipFillProperties reuses DrawingML
11
+ # children inside pic:blipFill)
11
12
  class PictureSourceRect < Lutaml::Model::Serializable
12
13
  attribute :l, :integer
13
14
  attribute :t, :integer
@@ -16,7 +17,7 @@ module Uniword
16
17
 
17
18
  xml do
18
19
  element "srcRect"
19
- namespace Uniword::Ooxml::Namespaces::Picture
20
+ namespace Uniword::Ooxml::Namespaces::DrawingML
20
21
 
21
22
  map_attribute "l", to: :l
22
23
  map_attribute "t", to: :t
@@ -7,13 +7,14 @@ module Uniword
7
7
  # Stretch fill properties
8
8
  #
9
9
  # Generated from OOXML schema: picture.yml
10
- # Element: <pic:stretch>
10
+ # Element: <a:stretch> (CT_BlipFillProperties reuses DrawingML
11
+ # children inside pic:blipFill)
11
12
  class PictureStretch < Lutaml::Model::Serializable
12
13
  attribute :fill_rect, FillRect
13
14
 
14
15
  xml do
15
16
  element "stretch"
16
- namespace Uniword::Ooxml::Namespaces::Picture
17
+ namespace Uniword::Ooxml::Namespaces::DrawingML
17
18
  mixed_content
18
19
 
19
20
  map_element "fillRect", to: :fill_rect, render_nil: false
@@ -7,7 +7,8 @@ module Uniword
7
7
  # Tile properties for picture fill
8
8
  #
9
9
  # Generated from OOXML schema: picture.yml
10
- # Element: <pic:tile>
10
+ # Element: <a:tile> (CT_BlipFillProperties reuses DrawingML
11
+ # children inside pic:blipFill)
11
12
  class Tile < Lutaml::Model::Serializable
12
13
  attribute :tx, :integer
13
14
  attribute :ty, :integer
@@ -17,7 +18,7 @@ module Uniword
17
18
 
18
19
  xml do
19
20
  element "tile"
20
- namespace Uniword::Ooxml::Namespaces::Picture
21
+ namespace Uniword::Ooxml::Namespaces::DrawingML
21
22
 
22
23
  map_attribute "tx", to: :tx
23
24
  map_attribute "ty", to: :ty
@@ -4,13 +4,13 @@ require "lutaml/model"
4
4
 
5
5
  module Uniword
6
6
  module Properties
7
- # Namespaced custom type for Word 2010 (wp14) attributes
7
+ # Namespaced custom type for Word 2010 Drawing (wp14) attributes
8
8
  # Used for wp14:anchorId and wp14:editId attributes
9
9
  class Word2010IdValue < Lutaml::Model::Type::String
10
10
  include Lutaml::Xml::Type::Configurable
11
11
 
12
12
  xml do
13
- namespace Uniword::Ooxml::Namespaces::Word2010
13
+ namespace Uniword::Ooxml::Namespaces::Word2010Drawing
14
14
  end
15
15
  end
16
16
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Uniword
4
- VERSION = "1.5.3"
4
+ VERSION = "1.5.4"
5
5
  end
@@ -32,15 +32,54 @@ module Uniword
32
32
  map_element "bookmarkEnd", to: :bookmark_ends, render_nil: false
33
33
  end
34
34
 
35
- # Get all elements in body
35
+ # Get all elements in body, in document order.
36
36
  #
37
- # @return [Array<Paragraph, Table, SectionProperties, StructuredDocumentTag>] All block-level content
37
+ # Walks `element_order` (populated by lutaml-model when mixed_content
38
+ # is parsed) and dispatches each tag to its typed collection —
39
+ # `p` -> paragraphs, `tbl` -> tables, `sdt` -> structured_document_tags,
40
+ # `bookmarkStart` -> bookmark_starts, `bookmarkEnd` -> bookmark_ends,
41
+ # `sectPr` -> section_properties. Whitespace/comment entries are
42
+ # skipped. Elements not represented in `element_order` are appended
43
+ # at the end in collection order (the only order available when
44
+ # `element_order` is empty or nil).
45
+ #
46
+ # @return [Array] Block-level content in document order
38
47
  def elements
48
+ return concatenate_typed_collections if element_order.nil? || element_order.empty?
49
+
39
50
  result = []
40
- result.concat(paragraphs || [])
41
- result.concat(structured_document_tags || [])
42
- result.concat(tables || [])
43
- result << section_properties if section_properties
51
+ counters = Hash.new(0)
52
+ sectpr_seen = false
53
+ collections = {
54
+ "p" => paragraphs,
55
+ "tbl" => tables,
56
+ "sdt" => structured_document_tags,
57
+ "bookmarkStart" => bookmark_starts,
58
+ "bookmarkEnd" => bookmark_ends,
59
+ }
60
+
61
+ element_order.each do |entry|
62
+ name = entry.name
63
+ if collections.key?(name)
64
+ collection = collections[name]
65
+ index = counters[name]
66
+ if collection && index < collection.size
67
+ result << collection[index]
68
+ counters[name] = index + 1
69
+ end
70
+ elsif name == "sectPr"
71
+ sectpr_seen = true
72
+ result << section_properties if section_properties
73
+ end
74
+ end
75
+
76
+ collections.each do |name, collection|
77
+ next unless collection && counters[name] < collection.size
78
+
79
+ result.concat(collection[counters[name]..])
80
+ end
81
+
82
+ result << section_properties if section_properties && !sectpr_seen
44
83
  result
45
84
  end
46
85
 
@@ -80,6 +119,15 @@ module Uniword
80
119
 
81
120
  private
82
121
 
122
+ def concatenate_typed_collections
123
+ result = []
124
+ result.concat(paragraphs || [])
125
+ result.concat(structured_document_tags || [])
126
+ result.concat(tables || [])
127
+ result << section_properties if section_properties
128
+ result
129
+ end
130
+
83
131
  def sync_element_order
84
132
  return if element_order.nil? || element_order.empty?
85
133
 
@@ -157,7 +157,7 @@ module Uniword
157
157
  #
158
158
  # @return [Array<Style>] Custom styles
159
159
  def custom_styles
160
- styles.select(&:custom)
160
+ styles.select(&:custom?)
161
161
  end
162
162
 
163
163
  # Get the number of styles
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.5.3
4
+ version: 1.5.4
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-08-01 00:00:00.000000000 Z
11
+ date: 2026-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logger
@@ -92,14 +92,14 @@ dependencies:
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: '2.3'
95
+ version: '3.4'
96
96
  type: :runtime
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
100
  - - "~>"
101
101
  - !ruby/object:Gem::Version
102
- version: '2.3'
102
+ version: '3.4'
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: thor
105
105
  requirement: !ruby/object:Gem::Requirement