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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a12d4646ce0b78cc0977eb4c1fa6a6d4082911dc1546c567b299a58f9b84e56
4
- data.tar.gz: 13197d06bd647197e7fb0857ce7f10c3d4f9c119c3e0a28503d2ad20c73a44fa
3
+ metadata.gz: 19c51c03274fab75ebaa533376a03bc2027f7c6c451885422fd324f986cdc654
4
+ data.tar.gz: 9e59f2367312b70e2f62c22da3117b36712641ee5c467fcf8650280f9fd5d00b
5
5
  SHA512:
6
- metadata.gz: 36580ca2af1ab880193203d304f8030125a53e6139e66c750d33f6f7846e33ccd0efe581d37eed5948708f8a933beef76d527922d3eadc018501028ca9521c51
7
- data.tar.gz: cd3a2fd33771dcfc717f0e2ecf5340125ec80e9be792ed073425c2126c5684c2a66fc7ecbf269b795c5593fa08bab8f256af608861de0d62624b57ca60836bbf
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
@@ -6,69 +6,46 @@ on:
6
6
 
7
7
  jobs:
8
8
 
9
- # lint:
10
- # name: Linters verification
11
- # runs-on: ubuntu-18.04
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
- # - name: Ruby gem cache
30
- # uses: actions/cache@v1
31
- # with:
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
- # - name: Linters
38
- # uses: ./.github/deployment/actions/linters/rails
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
- # test:
41
- # name: Run tests
42
- # needs: lint
43
- # runs-on: ubuntu-18.04
23
+ - name: Run security checks
24
+ run: bundle exec bundler-audit --update
44
25
 
45
- # services:
46
- # postgres:
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
- # steps:
52
- # - uses: actions/checkout@v2
29
+ test:
30
+ name: Run tests
31
+ needs: lint
32
+ runs-on: ubuntu-18.04
53
33
 
54
- # - name: Checkout deployment repo
55
- # uses: actions/checkout@v2
56
- # with:
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
- # - uses: ruby/setup-ruby@v1
62
- # with:
63
- # ruby-version: 2.7.2
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
- # - name: Tests
66
- # uses: ./.github/deployment/actions/tests/rails
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
- # needs: test
48
+ needs: test
72
49
  runs-on: ubuntu-18.04
73
50
  steps:
74
- - run: exit 0
51
+ - run: exit 0
data/.gitignore CHANGED
@@ -15,4 +15,4 @@
15
15
  docx-builder-*.gem
16
16
 
17
17
  # Ignore files created by Word
18
- ~$*.docx
18
+ ~$*.docx
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: double_quotes
14
+ EnforcedStyle: single_quotes
4
15
 
5
16
  Style/StringLiteralsInInterpolation:
6
17
  Enabled: true
7
- EnforcedStyle: double_quotes
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 "https://rubygems.org"
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 "rake", "~> 13.0"
9
- gem "rspec", "~> 3.0"
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
- gem "byebug"
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
- gem "bump"
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.2.2)
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.5.0)
14
- nokogiri (1.11.3)
15
- mini_portile2 (~> 2.5.0)
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.5.2)
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.11.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
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/docx/builder`. To experiment with that code, run `bin/console` for an interactive prompt.
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
- TODO: Delete this and the text above, and describe your gem
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 "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
- require "rubocop/rake_task"
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 "bundler/setup"
5
- require "docx/builder"
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 "irb"
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 "lib/docx/builder/version"
3
+ require_relative 'lib/docx/builder/version'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = "docx-builder"
6
+ spec.name = 'docx-builder'
7
7
  spec.version = Docx::Builder::VERSION
8
- spec.authors = ["Tecnologia Cashme"]
9
- spec.email = ["tecnologia@cashme.com.br"]
8
+ spec.authors = ['Tecnologia Cashme']
9
+ spec.email = ['tecnologia@cashme.com.br']
10
10
 
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")
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["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"
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 = "exe"
28
+ spec.bindir = 'exe'
29
29
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
30
- spec.require_paths = ["lib"]
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
- module Builder
3
- module Cleaners
4
- def self.starting_tags_without_spaces_cleaner(str)
5
- str && str.gsub(/\{\s*\{\s*%/, '{{%')
6
- end
7
-
8
- def self.ending_tags_without_spaces_cleaner(str)
9
- str && str.gsub(/%\s*\}\s*\}/, '%}}')
10
- end
11
-
12
- def self.single_quote_cleaner(str)
13
- str && str.gsub(/\‘/, '\'').gsub(/\’/, '\'')
14
- end
15
-
16
- def self.var_without_duplicated_spaces_cleaner(str)
17
- str && str.gsub(/\s+/, ' ')
18
- end
19
-
20
- def self.var_without_spaces_inside_brackets_cleaner(str)
21
- str && str.gsub(/\[(.*?)\]/) { |match| match.gsub(/\s/, '')}
22
- end
23
-
24
- def self.no_spaces_around_undeline_cleaner(str)
25
- str && str.gsub(/\s*\_\s*/, "_")
26
- end
27
-
28
- def self.join_dots_and_brackets_cleaner(str)
29
- str && str.gsub(/\s*\.\s*/, '.').gsub(/\s*\[\s*/, '[').gsub(/\s*\]/, ']')
30
- end
31
-
32
- def self.question_method_cleaner(str)
33
- if str && str =~ /\A\{\{\s+if\s*(.*?)\s*\?\s+\}\}\Z/
34
- "{{ if #{$1}\? }}"
35
- else
36
- str
37
- end
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
- module Builder
3
- class Configuration
4
- attr_accessor :null_placeholder
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
- def initialize
7
- @null_placeholder = ''
8
- end
9
- end
13
+ def initialize
14
+ @null_placeholder = ''
15
+ @logger = Docx::Logger.new($stdout)
16
+ end
10
17
  end
11
- end
18
+ end
19
+ end
@@ -1,14 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Docx
4
- module Builder
5
- module Decoder
6
- def self.to_xml(path)
7
- Zip::File.open(path) do |file|
8
- @zipfile = file
9
- end
10
- @zipfile
11
- end
12
- end
13
- end
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
@@ -1,18 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Docx
4
- module Builder
5
- module Encoder
6
- def self.build_new_document_xml(original_document, new_document_sections)
7
- output = Zip::OutputStream.write_buffer(StringIO.new) do |out|
8
- original_document.each do |entry|
9
- entry_name = entry.name
10
- out.put_next_entry(entry_name)
11
- out.write(new_document_sections[entry_name] || entry.get_input_stream.read)
12
- end
13
- end
14
- output.string
15
- end
16
- end
17
- end
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
- module Builder
3
- class Template
4
- def initialize(path)
5
- @document = Docx::Builder::Decoder.to_xml(path)
6
- @sections = ["word/document.xml"]
7
- @document.each do |file|
8
- if file.name.include? "word/header"
9
- @sections.push(file.name)
10
- end
11
- end
12
- end
13
-
14
- def render(data)
15
- @sections.map do |section|
16
- cleaned_document = clean(@document.read(section))
17
- erb_template = build_erb_template(cleaned_document)
18
- processed_document = render_erb_template(erb_template, data)
19
- [section, processed_document]
20
- end.to_h
21
- end
22
-
23
- def clean(document)
24
- document.force_encoding(Encoding::UTF_8) if document.respond_to?(:force_encoding)
25
- Docx::Builder::XmlProcessor.clean_variables(document)
26
- end
27
-
28
- def build_erb_template(document)
29
- ret = document.gsub(/\{\{%/, '<%=').gsub(/%\}\}/, '%>')
30
- ret = ret.gsub(/\{\{/, '<%').gsub(/\}\}/, '%>')
31
- ret
32
- end
33
-
34
- def render_erb_template(document, data)
35
- erb_template = ERB.new(document)
36
- ret = erb_template.result_with_hash(data)
37
- ret
38
- end
39
-
40
- # creates xml template keys in input docx (template file)
41
- def save(path, new_document)
42
- File.open(path, 'wb') do |f|
43
- new_document_xml_string = Docx::Builder::Encoder.build_new_document_xml(@document, new_document)
44
- f.write(new_document_xml_string)
45
- end
46
- @document.close
47
- end
48
- end
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Docx
4
4
  module Builder
5
- VERSION = "0.2.2"
5
+ VERSION = '0.3.1'
6
6
  end
7
7
  end
@@ -1,40 +1,42 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Docx
2
- module Builder
3
- class XmlProcessor
4
- def self.clean_variables(document)
5
- document.gsub(/\{\{.*?\}\}/m) do |match|
6
- ret = match.include?('>') ? join_variable_tags(match) : match
7
- ret = clean_spaces_inside_variables(ret)
8
- ret = insert_null_placeholder(ret)
9
- ret
10
- end
11
- end
12
-
13
- def self.join_variable_tags(match)
14
- before = match.gsub(/<(.*)/m, '')
15
- inside = match.scan(/<w:t.*?>([^>]*?)<.w:t>/m).join
16
- after = match.gsub(/.*>([^>]+)$/m, "\\1")
17
- [before, inside, after].join(' ')
18
- end
19
-
20
- def self.clean_spaces_inside_variables(match)
21
- ret = match.dup
22
- cleaner_methods = Docx::Builder::Cleaners.methods.grep /_cleaner/
23
- cleaner_methods.each do |clean_method|
24
- ret = Docx::Builder::Cleaners.send(clean_method, ret)
25
- end
26
- puts "Returning cleaned variable: #{ret}"
27
- ret
28
- end
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
- def self.insert_null_placeholder(expression)
31
- placeholder = Docx::Builder.configuration.null_placeholder
32
- expression.gsub(/\{\{%\s(.+)\s%\}\}/) do |m|
33
- "{{% (#{$1} || '#{placeholder}') %}}"
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 "builder/version"
8
- require_relative "builder/decoder"
9
- require_relative "builder/encoder"
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 "builder/xml_processor"
12
- require_relative "builder/template"
13
- require_relative "builder/configuration"
12
+ require_relative 'builder/xml_processor'
13
+ require_relative 'builder/template'
14
+ require_relative 'builder/configuration'
14
15
 
15
16
  module Docx
16
- module Builder
17
- class << self
18
- def configuration
19
- @configuration ||= Configuration.new
20
- end
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
- def configure
23
- yield(configuration)
24
- end
25
- end
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
@@ -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.2.2
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-06 00:00:00.000000000 Z
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
- - publish.sh
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.3.9
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