docx-builder 0.2.2 → 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 +4 -4
- data/.github/workflows/cd.yaml +27 -0
- data/.github/workflows/ci.yaml +31 -54
- data/.gitignore +1 -1
- data/.rspec +0 -0
- data/.rubocop.yml +13 -5
- data/CODE_OF_CONDUCT.md +0 -0
- data/Gemfile +9 -7
- data/Gemfile.lock +11 -6
- data/LICENSE.txt +0 -0
- data/README.md +17 -13
- data/Rakefile +3 -7
- data/bin/console +3 -3
- data/docx-builder.gemspec +14 -14
- data/lib/docx/builder/cleaners.rb +40 -37
- data/lib/docx/builder/configuration.rb +16 -8
- data/lib/docx/builder/decoder.rb +11 -10
- data/lib/docx/builder/encoder.rb +14 -14
- data/lib/docx/builder/template.rb +61 -47
- data/lib/docx/builder/version.rb +1 -1
- data/lib/docx/builder/xml_processor.rb +37 -35
- data/lib/docx/builder.rb +32 -16
- data/lib/docx/logger.rb +25 -0
- data/tmp/.gitkeep +0 -0
- metadata +5 -4
- data/publish.sh +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 19c51c03274fab75ebaa533376a03bc2027f7c6c451885422fd324f986cdc654
|
|
4
|
+
data.tar.gz: 9e59f2367312b70e2f62c22da3117b36712641ee5c467fcf8650280f9fd5d00b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 67c44931b227c87c3c8234a969ff60c1722e00711d922e7d1a824653d461b8c8f26cf66016df92e652435ef91643d39fe584d52f54f0835a64dbbadd6f33fb1a
|
|
7
|
+
data.tar.gz: 1a36660a25365cbf978f54369daabb734a22096cfbd7bfc0364e605f37fc4e49003e2ed1ac8600608607ecbb7f2035bf3f6714b171dbe06475c330067f378209
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: CD - Publish
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches:
|
|
5
|
+
- master
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
|
|
9
|
+
publish:
|
|
10
|
+
name: Publish gem
|
|
11
|
+
runs-on: ubuntu-18.04
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout code
|
|
15
|
+
uses: actions/checkout@v2
|
|
16
|
+
|
|
17
|
+
- name: Set up ruby
|
|
18
|
+
uses: ruby/setup-ruby@v1
|
|
19
|
+
with:
|
|
20
|
+
ruby-version: 2.7.2
|
|
21
|
+
|
|
22
|
+
- name: Release gem
|
|
23
|
+
uses: discourse/publish-rubygems-action@v2
|
|
24
|
+
env:
|
|
25
|
+
RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
|
|
26
|
+
GIT_EMAIL: automated_release@cashme.com.br
|
|
27
|
+
GIT_NAME: Automated Release
|
data/.github/workflows/ci.yaml
CHANGED
|
@@ -6,69 +6,46 @@ on:
|
|
|
6
6
|
|
|
7
7
|
jobs:
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
# steps:
|
|
14
|
-
|
|
15
|
-
# - name: Checkout code
|
|
16
|
-
# uses: actions/checkout@v2
|
|
17
|
-
|
|
18
|
-
# - name: Checkout deployment repo
|
|
19
|
-
# uses: actions/checkout@v2
|
|
20
|
-
# with:
|
|
21
|
-
# repository: cash-me/deployment
|
|
22
|
-
# ssh-key: ${{ secrets.DEPLOYMENT_KEY }}
|
|
23
|
-
# path: '.github/deployment'
|
|
24
|
-
|
|
25
|
-
# - uses: ruby/setup-ruby@v1
|
|
26
|
-
# with:
|
|
27
|
-
# ruby-version: 2.7.2
|
|
9
|
+
lint:
|
|
10
|
+
name: Linters verification
|
|
11
|
+
runs-on: ubuntu-18.04
|
|
28
12
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
# path: vendor/bundle
|
|
33
|
-
# key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
|
|
34
|
-
# restore-keys: |
|
|
35
|
-
# ${{ runner.os }}-gems-
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout code
|
|
15
|
+
uses: actions/checkout@v2
|
|
36
16
|
|
|
37
|
-
|
|
38
|
-
|
|
17
|
+
- name: Set up ruby
|
|
18
|
+
uses: ruby/setup-ruby@v1
|
|
19
|
+
with:
|
|
20
|
+
ruby-version: 2.7.2
|
|
21
|
+
bundler-cache: true # Run "bundle install", and cache the result automatically.
|
|
39
22
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
# needs: lint
|
|
43
|
-
# runs-on: ubuntu-18.04
|
|
23
|
+
- name: Run security checks
|
|
24
|
+
run: bundle exec bundler-audit --update
|
|
44
25
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
# image: postgres:11.6
|
|
48
|
-
# ports: ["5432:5432"]
|
|
49
|
-
# options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
|
26
|
+
- name: Run rubocop
|
|
27
|
+
run: bundle exec rubocop
|
|
50
28
|
|
|
51
|
-
|
|
52
|
-
|
|
29
|
+
test:
|
|
30
|
+
name: Run tests
|
|
31
|
+
needs: lint
|
|
32
|
+
runs-on: ubuntu-18.04
|
|
53
33
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
# repository: cash-me/deployment
|
|
58
|
-
# ssh-key: ${{ secrets.DEPLOYMENT_KEY }}
|
|
59
|
-
# path: '.github/deployment'
|
|
34
|
+
steps:
|
|
35
|
+
- name: Checkout code
|
|
36
|
+
uses: actions/checkout@v2
|
|
60
37
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
38
|
+
- name: Set up ruby
|
|
39
|
+
uses: ruby/setup-ruby@v1
|
|
40
|
+
with:
|
|
41
|
+
ruby-version: 2.7.2
|
|
42
|
+
bundler-cache: true
|
|
64
43
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
# with:
|
|
68
|
-
# cc_reporter_id: ${{ secrets.CC_TEST_REPORTER_ID }}
|
|
44
|
+
- name: Run tests
|
|
45
|
+
run: bundle exec rake
|
|
69
46
|
|
|
70
47
|
ci-workflow:
|
|
71
|
-
|
|
48
|
+
needs: test
|
|
72
49
|
runs-on: ubuntu-18.04
|
|
73
50
|
steps:
|
|
74
|
-
- run: exit 0
|
|
51
|
+
- run: exit 0
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
|
File without changes
|
data/.rubocop.yml
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
|
+
Gemspec/RequiredRubyVersion:
|
|
2
|
+
Enabled: false
|
|
3
|
+
|
|
4
|
+
Layout/LineLength:
|
|
5
|
+
Max: 160
|
|
6
|
+
|
|
7
|
+
Metrics/BlockLength:
|
|
8
|
+
CountAsOne: ['array', 'hash']
|
|
9
|
+
CountComments: false
|
|
10
|
+
Max: 50
|
|
11
|
+
|
|
1
12
|
Style/StringLiterals:
|
|
2
13
|
Enabled: true
|
|
3
|
-
EnforcedStyle:
|
|
14
|
+
EnforcedStyle: single_quotes
|
|
4
15
|
|
|
5
16
|
Style/StringLiteralsInInterpolation:
|
|
6
17
|
Enabled: true
|
|
7
|
-
EnforcedStyle:
|
|
8
|
-
|
|
9
|
-
Layout/LineLength:
|
|
10
|
-
Max: 120
|
|
18
|
+
EnforcedStyle: single_quotes
|
data/CODE_OF_CONDUCT.md
CHANGED
|
File without changes
|
data/Gemfile
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
source
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
4
|
|
|
5
5
|
# Specify your gem's dependencies in docx-builder.gemspec
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
|
-
gem
|
|
9
|
-
gem
|
|
8
|
+
gem 'nokogiri', '~> 1.13.2'
|
|
9
|
+
gem 'rake', '~> 13.0'
|
|
10
10
|
gem 'rubyzip', require: 'zip'
|
|
11
|
-
gem "rubocop", "~> 0.80"
|
|
12
|
-
gem "nokogiri", "~> 1.11.1"
|
|
13
11
|
|
|
14
12
|
group :test do
|
|
15
|
-
|
|
13
|
+
gem 'bundler-audit'
|
|
14
|
+
gem 'byebug'
|
|
15
|
+
|
|
16
|
+
gem 'rspec', '~> 3.0'
|
|
17
|
+
gem 'rubocop', '~> 0.80'
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
group :development do
|
|
19
|
-
|
|
21
|
+
gem 'bump'
|
|
20
22
|
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
docx-builder (0.
|
|
4
|
+
docx-builder (0.3.1)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
8
8
|
specs:
|
|
9
9
|
ast (2.4.2)
|
|
10
10
|
bump (0.10.0)
|
|
11
|
+
bundler-audit (0.9.0.1)
|
|
12
|
+
bundler (>= 1.2.0, < 3)
|
|
13
|
+
thor (~> 1.0)
|
|
11
14
|
byebug (11.1.3)
|
|
12
15
|
diff-lcs (1.4.4)
|
|
13
|
-
mini_portile2 (2.
|
|
14
|
-
nokogiri (1.
|
|
15
|
-
mini_portile2 (~> 2.
|
|
16
|
+
mini_portile2 (2.8.0)
|
|
17
|
+
nokogiri (1.13.4)
|
|
18
|
+
mini_portile2 (~> 2.8.0)
|
|
16
19
|
racc (~> 1.4)
|
|
17
20
|
parallel (1.20.1)
|
|
18
21
|
parser (3.0.1.0)
|
|
19
22
|
ast (~> 2.4.1)
|
|
20
|
-
racc (1.
|
|
23
|
+
racc (1.6.0)
|
|
21
24
|
rainbow (3.0.0)
|
|
22
25
|
rake (13.0.3)
|
|
23
26
|
regexp_parser (2.1.1)
|
|
@@ -48,6 +51,7 @@ GEM
|
|
|
48
51
|
parser (>= 2.7.1.5)
|
|
49
52
|
ruby-progressbar (1.11.0)
|
|
50
53
|
rubyzip (2.3.0)
|
|
54
|
+
thor (1.2.1)
|
|
51
55
|
unicode-display_width (1.7.0)
|
|
52
56
|
|
|
53
57
|
PLATFORMS
|
|
@@ -55,9 +59,10 @@ PLATFORMS
|
|
|
55
59
|
|
|
56
60
|
DEPENDENCIES
|
|
57
61
|
bump
|
|
62
|
+
bundler-audit
|
|
58
63
|
byebug
|
|
59
64
|
docx-builder!
|
|
60
|
-
nokogiri (~> 1.
|
|
65
|
+
nokogiri (~> 1.13.2)
|
|
61
66
|
rake (~> 13.0)
|
|
62
67
|
rspec (~> 3.0)
|
|
63
68
|
rubocop (~> 0.80)
|
data/LICENSE.txt
CHANGED
|
File without changes
|
data/README.md
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
# Docx::Builder
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Gem used to create docx files based on a template.
|
|
4
|
+
Our idea is quite similar to an erb file (in fact, we use an erb file behind :P)
|
|
5
|
+
The only difference is:
|
|
6
|
+
* When we want to write conditions and loops, we write the code between "{{" and "}}"
|
|
7
|
+
* When we want to print a variable, we write it between "{{%" and "%}}"
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
For example, in our template file example.docx we could have:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
{{ items.each do |item| }}
|
|
13
|
+
Insert here some text: {{% item.property %}}
|
|
14
|
+
{{ end }}
|
|
15
|
+
```
|
|
6
16
|
|
|
7
17
|
## Installation
|
|
8
18
|
|
|
@@ -22,18 +32,12 @@ Or install it yourself as:
|
|
|
22
32
|
|
|
23
33
|
## Usage
|
|
24
34
|
|
|
35
|
+
```ruby
|
|
36
|
+
builder = Docx::Builder::Template.new('/path/to/input.docx')
|
|
37
|
+
new_xml = builder.render(variables_hash)
|
|
38
|
+
builder.save('/path/to/output.docx', new_xml)
|
|
39
|
+
# or memory_stream = builder.save_as_buffer(new_xml)
|
|
25
40
|
```
|
|
26
|
-
template_file = File.open('spec/files/example.docx', 'r')
|
|
27
|
-
builder = Docx::Builder::Template.new(template_file)
|
|
28
|
-
new_xml = builder.render({ numero_contrato: 101 })
|
|
29
|
-
builder.save('tmp/output.docx', new_xml)
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Development
|
|
33
|
-
|
|
34
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
35
|
-
|
|
36
|
-
To install this gem onto your local machine, run `bundle exec rake install`. 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).
|
|
37
41
|
|
|
38
42
|
## Contributing
|
|
39
43
|
|
data/Rakefile
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
5
|
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
RuboCop::RakeTask.new
|
|
11
|
-
|
|
12
|
-
task default: %i[spec rubocop]
|
|
8
|
+
task default: 'spec'
|
data/bin/console
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
require
|
|
5
|
-
require
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'docx/builder'
|
|
6
6
|
|
|
7
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
8
|
# with your gem easier. You can also use a different console, if you like.
|
|
@@ -11,5 +11,5 @@ require "docx/builder"
|
|
|
11
11
|
# require "pry"
|
|
12
12
|
# Pry.start
|
|
13
13
|
|
|
14
|
-
require
|
|
14
|
+
require 'irb'
|
|
15
15
|
IRB.start(__FILE__)
|
data/docx-builder.gemspec
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative 'lib/docx/builder/version'
|
|
4
4
|
|
|
5
5
|
Gem::Specification.new do |spec|
|
|
6
|
-
spec.name =
|
|
6
|
+
spec.name = 'docx-builder'
|
|
7
7
|
spec.version = Docx::Builder::VERSION
|
|
8
|
-
spec.authors = [
|
|
9
|
-
spec.email = [
|
|
8
|
+
spec.authors = ['Tecnologia Cashme']
|
|
9
|
+
spec.email = ['tecnologia@cashme.com.br']
|
|
10
10
|
|
|
11
|
-
spec.summary =
|
|
12
|
-
spec.description =
|
|
13
|
-
spec.homepage =
|
|
14
|
-
spec.license =
|
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new(
|
|
11
|
+
spec.summary = 'Builds a new docx file using ERB template'
|
|
12
|
+
spec.description = 'Builds a new docx file using ERB template'
|
|
13
|
+
spec.homepage = 'https://github.com/cash-me/docx-builder'
|
|
14
|
+
spec.license = 'MIT'
|
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
|
|
16
16
|
|
|
17
17
|
# spec.metadata["allowed_push_host"] = "Set to 'http://mygemserver.com'"
|
|
18
18
|
|
|
19
|
-
spec.metadata[
|
|
20
|
-
spec.metadata[
|
|
21
|
-
spec.metadata[
|
|
19
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
20
|
+
spec.metadata['source_code_uri'] = 'https://github.com/cash-me/docx-builder'
|
|
21
|
+
spec.metadata['changelog_uri'] = 'https://github.com/cash-me/docx-builder/CHANGELOG.md'
|
|
22
22
|
|
|
23
23
|
# Specify which files should be added to the gem when it is released.
|
|
24
24
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
25
25
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
26
26
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
|
27
27
|
end
|
|
28
|
-
spec.bindir =
|
|
28
|
+
spec.bindir = 'exe'
|
|
29
29
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
30
|
-
spec.require_paths = [
|
|
30
|
+
spec.require_paths = ['lib']
|
|
31
31
|
|
|
32
32
|
# Uncomment to register a new dependency of your gem
|
|
33
33
|
# spec.add_dependency "example-gem", "~> 1.0"
|
|
@@ -1,41 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Docx
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
end
|
|
4
|
+
module Builder
|
|
5
|
+
# Methods used for cleaning variables inside template
|
|
6
|
+
module Cleaners
|
|
7
|
+
def self.starting_tags_without_spaces_cleaner(str)
|
|
8
|
+
str&.gsub(/\{\s*\{\s*%/, '{{%')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.ending_tags_without_spaces_cleaner(str)
|
|
12
|
+
str&.gsub(/%\s*\}\s*\}/, '%}}')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.single_quote_cleaner(str)
|
|
16
|
+
str&.gsub(/‘/, '\'')&.gsub(/’/, '\'')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.var_without_duplicated_spaces_cleaner(str)
|
|
20
|
+
str&.gsub(/\s+/, ' ')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.var_without_spaces_inside_brackets_cleaner(str)
|
|
24
|
+
str&.gsub(/\[(.*?)\]/) { |match| match.gsub(/\s/, '') }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.no_spaces_around_undeline_cleaner(str)
|
|
28
|
+
str&.gsub(/\s*_\s*/, '_')
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.join_dots_and_brackets_cleaner(str)
|
|
32
|
+
str && str.gsub(/\s*\.\s*/, '.').gsub(/\s*\[\s*/, '[').gsub(/\s*\]/, ']')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.question_method_cleaner(str)
|
|
36
|
+
if str && str =~ /\A\{\{\s+if\s*(.*?)\s*\?\s+\}\}\Z/
|
|
37
|
+
"{{ if #{Regexp.last_match(1)}\? }}"
|
|
38
|
+
else
|
|
39
|
+
str
|
|
39
40
|
end
|
|
41
|
+
end
|
|
40
42
|
end
|
|
43
|
+
end
|
|
41
44
|
end
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Docx
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
module Builder
|
|
5
|
+
# Configuration for docx-builder gem
|
|
6
|
+
#
|
|
7
|
+
# There are two available settings:
|
|
8
|
+
# * null_placeholder: string placeholder to be put when the variable is null
|
|
9
|
+
# * logger: the logger object itself
|
|
10
|
+
class Configuration
|
|
11
|
+
attr_accessor :null_placeholder, :logger
|
|
5
12
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
13
|
+
def initialize
|
|
14
|
+
@null_placeholder = ''
|
|
15
|
+
@logger = Docx::Logger.new($stdout)
|
|
16
|
+
end
|
|
10
17
|
end
|
|
11
|
-
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/docx/builder/decoder.rb
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Docx
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
module Builder
|
|
5
|
+
# Unzips a docx file into a series of XML files
|
|
6
|
+
module Decoder
|
|
7
|
+
def self.to_xml(path)
|
|
8
|
+
Zip::File.open(path) do |file|
|
|
9
|
+
@zipfile = file
|
|
10
|
+
end
|
|
11
|
+
@zipfile
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
14
15
|
end
|
data/lib/docx/builder/encoder.rb
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Docx
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
4
|
+
module Builder
|
|
5
|
+
# Rebuild the docx file using the new xml strings for header and document
|
|
6
|
+
module Encoder
|
|
7
|
+
def self.build_docx_buffer(original_document, new_document_sections)
|
|
8
|
+
Zip::OutputStream.write_buffer(StringIO.new) do |out|
|
|
9
|
+
original_document.each do |entry|
|
|
10
|
+
entry_name = entry.name
|
|
11
|
+
out.put_next_entry(entry_name)
|
|
12
|
+
out.write(new_document_sections[entry_name] || entry.get_input_stream.read)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
18
|
end
|
|
@@ -1,50 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Docx
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
4
|
+
module Builder
|
|
5
|
+
# Represents a docx erb template
|
|
6
|
+
class Template
|
|
7
|
+
def initialize(path)
|
|
8
|
+
@document = Docx::Builder::Decoder.to_xml(path)
|
|
9
|
+
@sections = ['word/document.xml']
|
|
10
|
+
@document.each do |file|
|
|
11
|
+
@sections.push(file.name) if file.name.include? 'word/header'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Renders the hash data in the template xml
|
|
16
|
+
def render(data)
|
|
17
|
+
@sections.map do |section|
|
|
18
|
+
Docx::Builder.logger.debug("Cleaning template variables for section #{section}")
|
|
19
|
+
cleaned_document = clean(@document.read(section))
|
|
20
|
+
Docx::Builder.logger.debug("Replacing template tags ('{{%' -> '<%') for section #{section}")
|
|
21
|
+
erb_template = build_erb_template(cleaned_document)
|
|
22
|
+
Docx::Builder.logger.debug("Rendering template for section #{section} with data")
|
|
23
|
+
processed_document = render_erb_template(erb_template, data)
|
|
24
|
+
[section, processed_document]
|
|
25
|
+
end.to_h
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Cleans the xml nodes in the middle of the variables
|
|
29
|
+
def clean(document)
|
|
30
|
+
document.force_encoding(Encoding::UTF_8) if document.respond_to?(:force_encoding)
|
|
31
|
+
Docx::Builder::XmlProcessor.clean_variables(document)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Replaces the docx-builder's tags for those ones currently used in erb files
|
|
35
|
+
def build_erb_template(document)
|
|
36
|
+
ret = document.gsub(/\{\{%/, '<%=').gsub(/%\}\}/, '%>')
|
|
37
|
+
ret.gsub(/\{\{/, '<%').gsub(/\}\}/, '%>')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def render_erb_template(document, data)
|
|
41
|
+
erb_template = ERB.new(document)
|
|
42
|
+
erb_template.result_with_hash(data)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Saves the rendered template in a file
|
|
46
|
+
def save(path, new_document)
|
|
47
|
+
Docx::Builder.logger.info("Saving output file into path #{path}")
|
|
48
|
+
File.open(path, 'wb') do |f|
|
|
49
|
+
buffer = Docx::Builder::Encoder.build_docx_buffer(@document, new_document)
|
|
50
|
+
f.write(buffer.string)
|
|
51
|
+
end
|
|
52
|
+
@document.close
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Saves the rendered template in a memory stream (StringIO)
|
|
56
|
+
def save_as_buffer(new_document)
|
|
57
|
+
Docx::Builder.logger.info('Saving output file as buffer')
|
|
58
|
+
buffer = Docx::Builder::Encoder.build_docx_buffer(@document, new_document)
|
|
59
|
+
@document.close
|
|
60
|
+
buffer
|
|
61
|
+
end
|
|
49
62
|
end
|
|
63
|
+
end
|
|
50
64
|
end
|
data/lib/docx/builder/version.rb
CHANGED
|
@@ -1,40 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Docx
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
4
|
+
module Builder
|
|
5
|
+
# Class responsible for dealing with xml nodes in-between the variables
|
|
6
|
+
class XmlProcessor
|
|
7
|
+
def self.clean_variables(document)
|
|
8
|
+
document.gsub(/\{\{.*?\}\}/m) do |match|
|
|
9
|
+
ret = match.include?('>') ? join_variable_tags(match) : match
|
|
10
|
+
Docx::Builder.logger.debug("Before cleaning: #{ret}")
|
|
11
|
+
ret = clean_spaces_inside_variables(ret)
|
|
12
|
+
ret = insert_null_placeholder(ret)
|
|
13
|
+
Docx::Builder.logger.debug("After cleaning: #{ret}")
|
|
14
|
+
ret
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.join_variable_tags(match)
|
|
19
|
+
before = match.gsub(/<(.*)/m, '')
|
|
20
|
+
inside = match.scan(/<w:t.*?>([^>]*?)<.w:t>/m).join
|
|
21
|
+
after = match.gsub(/.*>([^>]+)$/m, '\\1')
|
|
22
|
+
[before, inside, after].join(' ')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.clean_spaces_inside_variables(match)
|
|
26
|
+
ret = match.dup
|
|
27
|
+
cleaner_methods = Docx::Builder::Cleaners.methods.grep(/_cleaner/)
|
|
28
|
+
cleaner_methods.each do |clean_method|
|
|
29
|
+
ret = Docx::Builder::Cleaners.send(clean_method, ret)
|
|
30
|
+
end
|
|
31
|
+
ret
|
|
32
|
+
end
|
|
29
33
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
end
|
|
35
|
-
end
|
|
34
|
+
def self.insert_null_placeholder(expression)
|
|
35
|
+
placeholder = Docx::Builder.configuration.null_placeholder
|
|
36
|
+
expression.gsub(/\{\{%\s(.+)\s%\}\}/) do |_m|
|
|
37
|
+
"{{% (#{Regexp.last_match(1)} || '#{placeholder}') %}}"
|
|
36
38
|
end
|
|
37
|
-
|
|
38
|
-
# {{% devedor[:pessoa_fisica][:cedula_identidade] %}},
|
|
39
|
+
end
|
|
39
40
|
end
|
|
41
|
+
end
|
|
40
42
|
end
|
data/lib/docx/builder.rb
CHANGED
|
@@ -4,24 +4,40 @@ require 'rubygems'
|
|
|
4
4
|
require 'zip'
|
|
5
5
|
require 'nokogiri'
|
|
6
6
|
|
|
7
|
-
require_relative
|
|
8
|
-
require_relative
|
|
9
|
-
require_relative
|
|
7
|
+
require_relative 'logger'
|
|
8
|
+
require_relative 'builder/version'
|
|
9
|
+
require_relative 'builder/decoder'
|
|
10
|
+
require_relative 'builder/encoder'
|
|
10
11
|
require_relative 'builder/cleaners'
|
|
11
|
-
require_relative
|
|
12
|
-
require_relative
|
|
13
|
-
require_relative
|
|
12
|
+
require_relative 'builder/xml_processor'
|
|
13
|
+
require_relative 'builder/template'
|
|
14
|
+
require_relative 'builder/configuration'
|
|
14
15
|
|
|
15
16
|
module Docx
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
# Main module of the gem
|
|
18
|
+
#
|
|
19
|
+
# @example configuring string placeholder
|
|
20
|
+
# Docx::Builder.configure do |config|
|
|
21
|
+
# config.null_placeholder = 'XXXX'
|
|
22
|
+
# end
|
|
23
|
+
#
|
|
24
|
+
# @example configuring log level
|
|
25
|
+
# Docx::Builder.configure do |config|
|
|
26
|
+
# config.logger.level = 1 #info
|
|
27
|
+
# end
|
|
28
|
+
module Builder
|
|
29
|
+
class << self
|
|
30
|
+
def configuration
|
|
31
|
+
@configuration ||= Configuration.new
|
|
32
|
+
end
|
|
21
33
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
34
|
+
def logger
|
|
35
|
+
configuration.logger
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def configure
|
|
39
|
+
yield(configuration)
|
|
40
|
+
end
|
|
26
41
|
end
|
|
27
|
-
end
|
|
42
|
+
end
|
|
43
|
+
end
|
data/lib/docx/logger.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'logger'
|
|
4
|
+
|
|
5
|
+
module Docx
|
|
6
|
+
# Simple logger for the gem
|
|
7
|
+
#
|
|
8
|
+
# Available levels (from 0 to 5):
|
|
9
|
+
# DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
|
|
10
|
+
class Logger < ::Logger
|
|
11
|
+
def initialize(*args, **kwargs)
|
|
12
|
+
super
|
|
13
|
+
@formatter = SimpleFormatter.new
|
|
14
|
+
@level = ENV['LOG_LEVEL'].to_i if ENV.keys.include?('LOG_LEVEL')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Simple formatter which only displays the message
|
|
18
|
+
class SimpleFormatter < ::Logger::Formatter
|
|
19
|
+
# This method is invoked when a log event occurs
|
|
20
|
+
def call(_severity, _timestamp, _progname, msg)
|
|
21
|
+
"#{msg.is_a?(String) ? msg : msg.inspect}\n"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/tmp/.gitkeep
CHANGED
|
File without changes
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: docx-builder
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tecnologia Cashme
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-04-
|
|
11
|
+
date: 2022-04-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Builds a new docx file using ERB template
|
|
14
14
|
email:
|
|
@@ -17,6 +17,7 @@ executables: []
|
|
|
17
17
|
extensions: []
|
|
18
18
|
extra_rdoc_files: []
|
|
19
19
|
files:
|
|
20
|
+
- ".github/workflows/cd.yaml"
|
|
20
21
|
- ".github/workflows/ci.yaml"
|
|
21
22
|
- ".gitignore"
|
|
22
23
|
- ".rspec"
|
|
@@ -38,7 +39,7 @@ files:
|
|
|
38
39
|
- lib/docx/builder/template.rb
|
|
39
40
|
- lib/docx/builder/version.rb
|
|
40
41
|
- lib/docx/builder/xml_processor.rb
|
|
41
|
-
-
|
|
42
|
+
- lib/docx/logger.rb
|
|
42
43
|
- tmp/.gitkeep
|
|
43
44
|
homepage: https://github.com/cash-me/docx-builder
|
|
44
45
|
licenses:
|
|
@@ -62,7 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
62
63
|
- !ruby/object:Gem::Version
|
|
63
64
|
version: '0'
|
|
64
65
|
requirements: []
|
|
65
|
-
rubygems_version: 3.
|
|
66
|
+
rubygems_version: 3.1.6
|
|
66
67
|
signing_key:
|
|
67
68
|
specification_version: 4
|
|
68
69
|
summary: Builds a new docx file using ERB template
|
data/publish.sh
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
bundle exec rake release
|