standard-procedure-consolidate 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.devcontainer/devcontainer.json +20 -4
- data/.ruby-version +1 -1
- data/.standard.yml +1 -1
- data/CHANGELOG.md +4 -0
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/checksums/standard-procedure-consolidate-0.3.0.gem.sha512 +1 -0
- data/lib/consolidate/docx/merge.rb +70 -43
- data/lib/consolidate/version.rb +1 -1
- metadata +7 -7
- data/.nova/Configuration.json +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1bd2015cc0f88bc4b16bae7d8ecd335fb7b28c2bc940f81b1479e4a58ecce647
|
4
|
+
data.tar.gz: 44905254b9536f40f839d64d0448c4fb40b1a3720fb4d9ba3e2251468175eb9b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36dee64a5f21766e06e7b5eb213e5a5b4dee9ca04da8bde4b429c4d93c5bd49275226975c7e9887214ea5a3b5975c4f955b245ab45e0103656b928ab59854789
|
7
|
+
data.tar.gz: 687bba668eb1f137b67c82819561ec2e8c2c3bc9a54f03aa4b6ac76958ae3a15988af8db5f78e7e95adb59968b5764b32c37e71d257b7885d1eb0e10d6e3f56a
|
@@ -1,7 +1,23 @@
|
|
1
1
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
2
2
|
// README at: https://github.com/devcontainers/templates/tree/main/src/ruby
|
3
3
|
{
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
"name": "Ruby",
|
5
|
+
"image": "mcr.microsoft.com/devcontainers/ruby:1-3.2-bullseye",
|
6
|
+
"postCreateCommand": "bundle install",
|
7
|
+
"customizations": {
|
8
|
+
"vscode": {
|
9
|
+
"extensions": [
|
10
|
+
"Shopify.ruby-extensions-pack",
|
11
|
+
"testdouble.vscode-standard-ruby",
|
12
|
+
"manuelpuyol.erb-linter",
|
13
|
+
"Shopify.ruby-lsp",
|
14
|
+
"aki77.rails-db-schema",
|
15
|
+
"miguel-savignano.ruby-symbols",
|
16
|
+
"sibiraj-s.vscode-scss-formatter",
|
17
|
+
"Thadeu.vscode-run-rspec-file",
|
18
|
+
"Cronos87.yaml-symbols",
|
19
|
+
"aliariff.vscode-erb-beautify"
|
20
|
+
]
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.2.
|
1
|
+
3.2.5
|
data/.standard.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## [0.3.0] - 2024-11-21
|
2
|
+
|
3
|
+
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.
|
4
|
+
|
1
5
|
## [0.2.0] - 2023-09-13
|
2
6
|
|
3
7
|
Thrown away the mail-merge implementation and replaced it with a simple search/replace.
|
data/README.md
CHANGED
@@ -78,7 +78,7 @@ Consolidate looks for word/document.xml files, plus any files that match word/he
|
|
78
78
|
|
79
79
|
## Development
|
80
80
|
|
81
|
-
The repo contains a .devcontainer folder - this contains instructions for a development container that has everything needed to build the project. Once the container has started, you can use `bin/setup` to install dependencies. Then, run `rake
|
81
|
+
The repo contains a .devcontainer folder - this contains instructions for a development container that has everything needed to build the project. Once the container has started, you can use `bin/setup` to install dependencies. Then, run `bundle exec rake` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
82
82
|
|
83
83
|
`bundle exec rake install` will install the gem on your local machine (obviously not from within the devcontainer though). To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
84
84
|
|
data/Rakefile
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
098078b13e3bb4e3370cbc6bdb0195300489dfb33a5c27a201a4c5f1f0184bba73557264e674f49da41dbc62ad991e8ae99bef1debf417a5b1a363b1d56829f1
|
@@ -11,6 +11,15 @@ module Consolidate
|
|
11
11
|
path
|
12
12
|
end
|
13
13
|
|
14
|
+
def initialize(path, verbose: false, &block)
|
15
|
+
@verbose = verbose
|
16
|
+
@output = {}
|
17
|
+
@zip = Zip::File.open(path)
|
18
|
+
@documents = load_documents
|
19
|
+
block&.call self
|
20
|
+
end
|
21
|
+
|
22
|
+
# Helper method to display the contents of the document and the merge fields from the CLI
|
14
23
|
def examine
|
15
24
|
documents = document_names.join(", ")
|
16
25
|
fields = field_names.join(", ")
|
@@ -18,23 +27,21 @@ module Consolidate
|
|
18
27
|
puts "Merge fields: #{fields}"
|
19
28
|
end
|
20
29
|
|
30
|
+
# Read all documents within the docx and extract any merge fields
|
21
31
|
def field_names
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
field_name = matches[1].strip
|
26
|
-
puts "...field #{field_name} found in #{name}" if verbose
|
27
|
-
field_name
|
28
|
-
end.compact
|
29
|
-
end.flatten
|
32
|
+
tag_nodes.collect do |tag_node|
|
33
|
+
field_name_from tag_node
|
34
|
+
end.compact.uniq
|
30
35
|
end
|
31
36
|
|
37
|
+
# List the documents stored within this docx
|
32
38
|
def document_names
|
33
39
|
@zip.entries.collect { |entry| entry.name }
|
34
40
|
end
|
35
41
|
|
36
|
-
|
37
|
-
|
42
|
+
# Substitute the data from the merge fields with the values provided
|
43
|
+
def data mapping = {}
|
44
|
+
mapping = mapping.transform_keys(&:to_s)
|
38
45
|
|
39
46
|
if verbose
|
40
47
|
puts "...substitutions..."
|
@@ -44,13 +51,13 @@ module Consolidate
|
|
44
51
|
end
|
45
52
|
|
46
53
|
@documents.each do |name, document|
|
47
|
-
|
48
|
-
result = substitute result, fields, name
|
54
|
+
output_document = substitute document.dup, mapping: mapping, document_name: name
|
49
55
|
|
50
|
-
@output[name] =
|
56
|
+
@output[name] = output_document.serialize save_with: 0
|
51
57
|
end
|
52
58
|
end
|
53
59
|
|
60
|
+
# Write the new document to the given path
|
54
61
|
def write_to path
|
55
62
|
puts "...writing to #{path}" if verbose
|
56
63
|
Zip::File.open(path, Zip::File::CREATE) do |out|
|
@@ -62,7 +69,7 @@ module Consolidate
|
|
62
69
|
end
|
63
70
|
end
|
64
71
|
|
65
|
-
|
72
|
+
private
|
66
73
|
|
67
74
|
attr_reader :verbose
|
68
75
|
attr_reader :zip
|
@@ -70,42 +77,62 @@ module Consolidate
|
|
70
77
|
attr_reader :documents
|
71
78
|
attr_accessor :output
|
72
79
|
|
73
|
-
def
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
@zip = Zip::File.open(path)
|
80
|
-
@zip.entries.each do |entry|
|
81
|
-
next unless entry.name.match?(/word\/(document|header|footer|footnotes|endnotes).?\.xml/)
|
82
|
-
puts "...reading #{entry.name}" if verbose
|
83
|
-
xml = @zip.get_input_stream entry
|
84
|
-
@documents[entry.name] = Nokogiri::XML(xml) { |x| x.noent }
|
85
|
-
end
|
86
|
-
yield self
|
87
|
-
ensure
|
88
|
-
@zip.close
|
80
|
+
def load_documents
|
81
|
+
@zip.entries.each_with_object({}) do |entry, documents|
|
82
|
+
next unless entry.name.match?(/word\/(document|header|footer|footnotes|endnotes).?\.xml/)
|
83
|
+
puts "...reading #{entry.name}" if verbose
|
84
|
+
xml = @zip.get_input_stream entry
|
85
|
+
documents[entry.name] = Nokogiri::XML(xml) { |x| x.noent }
|
89
86
|
end
|
87
|
+
ensure
|
88
|
+
@zip.close
|
90
89
|
end
|
91
90
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
91
|
+
# Collect all the nodes that contain merge fields
|
92
|
+
def tag_nodes
|
93
|
+
documents.collect do |name, document|
|
94
|
+
tag_nodes_for document
|
95
|
+
end.flatten
|
96
|
+
end
|
97
|
+
|
98
|
+
# go through all w:t (Word Text???) nodes of the document
|
99
|
+
# find any nodes that contain "{{"
|
100
|
+
# then find the ancestor node that also includes the ending "}}"
|
101
|
+
# This collection of nodes contains all the merge fields for this document
|
102
|
+
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
|
106
|
+
end
|
107
|
+
|
108
|
+
# 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
|
114
|
+
end
|
115
|
+
|
116
|
+
# Go through the given document, replacing any merge fields with the values provided
|
117
|
+
# and storing the results in a new document
|
118
|
+
def substitute document, document_name:, mapping: {}
|
119
|
+
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*}}/, "")
|
125
|
+
rescue => ex
|
126
|
+
# Have to mangle the exception message otherwise it outputs the entire document
|
127
|
+
puts ex.message.to_s[0..255]
|
103
128
|
end
|
104
129
|
document
|
105
130
|
end
|
106
131
|
|
107
|
-
|
108
|
-
|
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)
|
109
136
|
end
|
110
137
|
end
|
111
138
|
end
|
data/lib/consolidate/version.rb
CHANGED
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.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rahoul Baruah
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
@@ -48,7 +48,6 @@ extensions: []
|
|
48
48
|
extra_rdoc_files: []
|
49
49
|
files:
|
50
50
|
- ".devcontainer/devcontainer.json"
|
51
|
-
- ".nova/Configuration.json"
|
52
51
|
- ".rspec"
|
53
52
|
- ".ruby-version"
|
54
53
|
- ".standard.yml"
|
@@ -62,6 +61,7 @@ files:
|
|
62
61
|
- checksums/standard-procedure-consolidate-0.1.3.gem.sha512
|
63
62
|
- checksums/standard-procedure-consolidate-0.1.4.gem.sha512
|
64
63
|
- checksums/standard-procedure-consolidate-0.2.0.gem.sha512
|
64
|
+
- checksums/standard-procedure-consolidate-0.3.0.gem.sha512
|
65
65
|
- exe/consolidate
|
66
66
|
- exe/examine
|
67
67
|
- lib/consolidate.rb
|
@@ -77,7 +77,7 @@ metadata:
|
|
77
77
|
homepage_uri: https://github.com/standard-procedure/standard-procedure-consolidate
|
78
78
|
source_code_uri: https://github.com/standard-procedure/standard-procedure-consolidate
|
79
79
|
changelog_uri: https://github.com/standard-procedure/standard-procedure-consolidate/blob/main/CHANGELOG.md
|
80
|
-
post_install_message:
|
80
|
+
post_install_message:
|
81
81
|
rdoc_options: []
|
82
82
|
require_paths:
|
83
83
|
- lib
|
@@ -92,8 +92,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
92
|
- !ruby/object:Gem::Version
|
93
93
|
version: '0'
|
94
94
|
requirements: []
|
95
|
-
rubygems_version: 3.4.
|
96
|
-
signing_key:
|
95
|
+
rubygems_version: 3.4.19
|
96
|
+
signing_key:
|
97
97
|
specification_version: 4
|
98
98
|
summary: Simple ruby mailmerge for Microsoft Word .docx files.
|
99
99
|
test_files: []
|
data/.nova/Configuration.json
DELETED