standard-procedure-consolidate 0.3.0 → 0.3.1

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: 1bd2015cc0f88bc4b16bae7d8ecd335fb7b28c2bc940f81b1479e4a58ecce647
4
- data.tar.gz: 44905254b9536f40f839d64d0448c4fb40b1a3720fb4d9ba3e2251468175eb9b
3
+ metadata.gz: e7a086625fa1f07169c2f9eba544538df266fbd83702efeedd13998d1a9e83b3
4
+ data.tar.gz: f80f0c11aa839c9dba9c4dc41758471ccfc31d7d38159e902e11d48cc8016c82
5
5
  SHA512:
6
- metadata.gz: 36dee64a5f21766e06e7b5eb213e5a5b4dee9ca04da8bde4b429c4d93c5bd49275226975c7e9887214ea5a3b5975c4f955b245ab45e0103656b928ab59854789
7
- data.tar.gz: 687bba668eb1f137b67c82819561ec2e8c2c3bc9a54f03aa4b6ac76958ae3a15988af8db5f78e7e95adb59968b5764b32c37e71d257b7885d1eb0e10d6e3f56a
6
+ metadata.gz: 72b26cbc5f54cc481ad49cbb604338591e27f1a503330372ab41920a05f3cbde4b1d6b6aa4b607b1189fbd8fd5ed30102d9741b8b6cf762c0cb39c900ac19327
7
+ data.tar.gz: 33ab5fbe36794cf24ca73ce70ec6da8f91cfe5430a438d5794da54bd668e72dd956331401ac983f5d15b7f77d60ef8ac6a3d438e4a0fb6279736c6dd79342931
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## [0.3.1] - 2024-11-22
2
+
3
+ Ensure that the substituted nodes are reinserted correctly into the output document, attempting to restore formatting at the paragraph level (although it does lose formatting at lower levels than this - so-called "run" nodes which represent arbitrary spans of characters within the paragraph).
4
+
5
+
1
6
  ## [0.3.0] - 2024-11-21
2
7
 
3
8
  Updated the code that examines the docx file for merge fields to deal with Word formatting tags being inserted in the middle of the merge fields.
@@ -0,0 +1 @@
1
+ ac1393002b538b8f000c1e4f1f7f4514f689434dad0889a77a0470bd839c58cb49d6218daafd4a8ca48675e220ab9c42147de78a40ec0fd59d5a19371b699eb0
@@ -30,8 +30,8 @@ module Consolidate
30
30
  # Read all documents within the docx and extract any merge fields
31
31
  def field_names
32
32
  tag_nodes.collect do |tag_node|
33
- field_name_from tag_node
34
- end.compact.uniq
33
+ field_names_from tag_node
34
+ end.flatten.compact.uniq
35
35
  end
36
36
 
37
37
  # List the documents stored within this docx
@@ -45,7 +45,7 @@ module Consolidate
45
45
 
46
46
  if verbose
47
47
  puts "...substitutions..."
48
- fields.each do |key, value|
48
+ mapping.each do |key, value|
49
49
  puts " #{key} => #{value}"
50
50
  end
51
51
  end
@@ -76,6 +76,7 @@ module Consolidate
76
76
  attr_reader :xml
77
77
  attr_reader :documents
78
78
  attr_accessor :output
79
+ TAG = /\{\{\s*(\S+)\s*\}\}/
79
80
 
80
81
  def load_documents
81
82
  @zip.entries.each_with_object({}) do |entry, documents|
@@ -100,40 +101,52 @@ module Consolidate
100
101
  # then find the ancestor node that also includes the ending "}}"
101
102
  # This collection of nodes contains all the merge fields for this document
102
103
  def tag_nodes_for document
103
- (document / "//w:t").collect do |node|
104
- (node.children.any? { |child| child.content.include? "{{" }) ? enclosing_node_for_start_tag(node) : nil
105
- end.compact
104
+ (document / "//w:p").select do |paragraph|
105
+ paragraph.content.match(TAG)
106
+ end
106
107
  end
107
108
 
108
109
  # Extract the merge field name from the node
109
- def field_name_from(tag_node)
110
- return nil unless (matches = tag_node.content.match(/{{\s*(\S+)\s*}}/))
111
- field_name = matches[1].strip
112
- puts "...field #{field_name} found in #{name}" if verbose
113
- field_name.to_s
110
+ def field_names_from(tag_node)
111
+ matches = tag_node.content.scan(TAG)
112
+ matches.empty? ? nil : matches.flatten.map(&:strip)
114
113
  end
115
114
 
116
115
  # Go through the given document, replacing any merge fields with the values provided
117
116
  # and storing the results in a new document
118
117
  def substitute document, document_name:, mapping: {}
119
118
  tag_nodes_for(document).each do |tag_node|
120
- field_name = field_name_from tag_node
121
- next unless mapping.has_key? field_name
122
- field_value = mapping[field_name]
123
- puts "...substituting #{field_name} with #{field_value} in #{document_name}" if verbose
124
- tag_node.content = tag_node.content.gsub(field_name, field_value).gsub(/{{\s*/, "").gsub(/\s*}}/, "")
119
+ field_names = field_names_from tag_node
120
+ puts "Original Node for #{field_names} is #{tag_node}" if verbose
121
+
122
+ # Extract the paragraph properties node if it exists
123
+ paragraph_properties = tag_node.search ".//w:pPr"
124
+ run_properties = tag_node.at_xpath ".//w:rPr"
125
+
126
+ text = tag_node.content
127
+ field_names.each do |field_name|
128
+ field_value = mapping[field_name].to_s
129
+ puts "...substituting #{field_name} with #{field_value} in #{document_name}" if verbose
130
+ text = text.gsub(/{{\s*#{field_name}\s*}}/, field_value)
131
+ end
132
+
133
+ # Create a new text node with the substituted text
134
+ text_node = Nokogiri::XML::Node.new("w:t", tag_node.document)
135
+ text_node.content = text
136
+
137
+ # Create a new run node to hold the substituted text and the paragraph properties
138
+ run_node = Nokogiri::XML::Node.new("w:r", tag_node.document)
139
+ run_node << run_properties if run_properties
140
+ run_node << text_node
141
+ tag_node.children = Nokogiri::XML::NodeSet.new(document, paragraph_properties.to_a + [run_node])
142
+
143
+ puts "TAG NODE FOR #{field_names} IS #{tag_node}" if verbose
125
144
  rescue => ex
126
145
  # Have to mangle the exception message otherwise it outputs the entire document
127
146
  puts ex.message.to_s[0..255]
128
147
  end
129
148
  document
130
149
  end
131
-
132
- # Find the ancestor node that contains both the start {{ text and the end }} text enclosing the merge field
133
- def enclosing_node_for_start_tag(node)
134
- return node if node.content.include? "}}"
135
- node.parent.nil? ? nil : enclosing_node_for_start_tag(node.parent)
136
- end
137
150
  end
138
151
  end
139
152
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Consolidate
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.1"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: standard-procedure-consolidate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rahoul Baruah
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-21 00:00:00.000000000 Z
11
+ date: 2024-11-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip
@@ -62,6 +62,7 @@ files:
62
62
  - checksums/standard-procedure-consolidate-0.1.4.gem.sha512
63
63
  - checksums/standard-procedure-consolidate-0.2.0.gem.sha512
64
64
  - checksums/standard-procedure-consolidate-0.3.0.gem.sha512
65
+ - checksums/standard-procedure-consolidate-0.3.1.gem.sha512
65
66
  - exe/consolidate
66
67
  - exe/examine
67
68
  - lib/consolidate.rb