docx-builder 0.2.2 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|