pdf_templator 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2ebb84707bebab41a336aff995fcf7d77de34b3f
4
+ data.tar.gz: 6dc527e163b6cf19e751816c885a9c82e56b60fa
5
+ SHA512:
6
+ metadata.gz: 48081d9ad88ccd712c987223a9dffa3247cea37bc045feedeba05cf691e24bc44f8e655f736cf46168a029775d28bcff925ba0c8e9f73dff092c3927666b78aa
7
+ data.tar.gz: 01e208604186f275e272bf89ce5bf6c686fedd40bbe8ef0af3a2c8044c1a7a8293a3aec41c6c08bb8174e853f792739904edcd7f756396f52c0ae66daa128757
@@ -0,0 +1,24 @@
1
+ # EditorConfig helps developers define and maintain consistent
2
+ # coding styles between different editors and IDEs
3
+ # editorconfig.org
4
+
5
+ root = true
6
+
7
+ [*]
8
+
9
+ # Change these settings to your own preference
10
+ indent_style = space
11
+ indent_size = 2
12
+
13
+ # We recommend you to keep these unchanged
14
+ end_of_line = lf
15
+ charset = utf-8
16
+ trim_trailing_whitespace = true
17
+ insert_final_newline = true
18
+
19
+ [*.md]
20
+ trim_trailing_whitespace = false
21
+
22
+ [nginx.conf.erb]
23
+ indent_style = tabs
24
+ indent_size = 4
@@ -0,0 +1,51 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ Gemfile.lock
46
+ .ruby-version
47
+ .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
51
+ *.sublime-workspace
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format documentation
3
+ --require spec_helper
@@ -0,0 +1,46 @@
1
+ require: rubocop-rspec
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 2.3.5
5
+
6
+ Style/Documentation:
7
+ Enabled: false
8
+
9
+ Style/HashSyntax:
10
+ EnforcedStyle: ruby19
11
+
12
+ Metrics/BlockLength:
13
+ Exclude:
14
+ - Guardfile
15
+ - 'spec/**/*'
16
+ - '*.gemspec'
17
+
18
+ Style/TrailingCommaInArguments:
19
+ EnforcedStyleForMultiline: consistent_comma
20
+
21
+ Style/TrailingCommaInArrayLiteral:
22
+ EnforcedStyleForMultiline: consistent_comma
23
+
24
+ Style/TrailingCommaInHashLiteral:
25
+ EnforcedStyleForMultiline: consistent_comma
26
+
27
+ Layout/AccessModifierIndentation:
28
+ EnforcedStyle: outdent
29
+
30
+ Style/SignalException:
31
+ EnforcedStyle: semantic
32
+
33
+ Metrics/LineLength:
34
+ Max: 120
35
+
36
+ Metrics/ClassLength:
37
+ Max: 150
38
+
39
+ Metrics/ModuleLength:
40
+ Max: 150
41
+
42
+ Style/Documentation:
43
+ Enabled: false
44
+
45
+ Style/HashSyntax:
46
+ EnforcedStyle: ruby19
@@ -0,0 +1,16 @@
1
+ language: ruby
2
+ sudo: false
3
+ rvm:
4
+ - 2.1
5
+ - 2.2
6
+ - 2.3
7
+ - 2.4
8
+ - 2.5
9
+ notifications:
10
+ email:
11
+ on_success: change
12
+ on_failure: always
13
+ script:
14
+ - bundle exec rubocop
15
+ - mkdir -p tmp
16
+ - bundle exec rspec
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in pdf_templator.gemspec
8
+ gemspec
9
+
10
+ gem 'guard'
11
+ gem 'guard-rspec', require: false
12
+ gem 'guard-rubocop', require: false
13
+ gem 'rubocop'
14
+ gem 'rubocop-rspec'
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ notification :terminal_notifier
4
+
5
+ rspec_options = {
6
+ all_after_pass: true,
7
+ cmd: 'rspec spec',
8
+ failed_mode: :focus,
9
+ }
10
+
11
+ clearing :on
12
+
13
+ guard :rspec, rspec_options do
14
+ require 'ostruct'
15
+
16
+ # Generic Ruby apps
17
+ rspec = OpenStruct.new
18
+ rspec.spec = ->(m) { "spec/#{m}_spec.rb" }
19
+ rspec.spec_dir = 'spec'
20
+ rspec.spec_helper = 'spec/spec_helper.rb'
21
+
22
+ watch(%r{^spec/.+_spec\.rb$})
23
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
24
+ watch(rspec.spec_helper) { rspec.spec_dir }
25
+ end
26
+
27
+ guard :rubocop, all_on_start: true do
28
+ watch(/.+\.rb$/)
29
+ watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
30
+ end
@@ -0,0 +1,96 @@
1
+ # PDF Templator
2
+
3
+ [![Gem Version][rubygems-image]][rubygems-url]
4
+ [![Build Status][travis-image]][travis-url]
5
+ [![Coverage Status][coverage-image]][coverage-url]
6
+
7
+ Create PDFs from HTML templates in a breeze.
8
+
9
+ ## Features
10
+
11
+ - Create a single HTML with `<field>` tags and PDF Templator will fill them for you.
12
+ - Field types include `date`, `number`, `date`, `money`, `accounting`.
13
+ - Create your own field type.
14
+ - Usage as a CLI in case you're not working on Ruby.
15
+ - It uses [wicked_pdf](https://github.com/mileszs/wicked_pdf) internally so you can use all its features too.
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ ```ruby
22
+ gem 'pdf_templator'
23
+ ```
24
+
25
+ And then execute:
26
+
27
+ $ bundle
28
+
29
+ Or install it yourself as:
30
+
31
+ $ gem install pdf_templator
32
+
33
+ ## Usage
34
+
35
+ ```ruby
36
+ require 'pdf_templator'
37
+
38
+ html = File.read('path/to/my/template.html')
39
+ # OR
40
+ html = '<html>' \
41
+ 'My name is <field name="name">' \
42
+ 'and today is <field name="date" type="date" data-format="%b %d, %Y">' \
43
+ '</html>'
44
+ args = {
45
+ name: 'My Name',
46
+ date: '06/18/2018',
47
+ }
48
+
49
+ reader = PdfTemplator::Reader.new(content: html, footer: footer)
50
+ pdf = reader.write(args)
51
+ File.open('path/to/file.pdf', 'wb') { |f| f.write(pdf) }
52
+ ```
53
+
54
+ ### Custom types
55
+
56
+ ```ruby
57
+ module PdfTemplator
58
+ class ListType < Type
59
+ def call
60
+ list = content.split(',')
61
+ html_items = list.map do |item|
62
+ "<li>#{item}</li>"
63
+ end
64
+ "<ul>#{html_items.join}</ul>"
65
+ end
66
+ end
67
+ end
68
+
69
+ # Then you could have an html like
70
+
71
+ <field name="my_list" type="list"></field>
72
+
73
+ # And pass the args like
74
+
75
+ args = {
76
+ my_list: 'car,helicopter,motorcycle'
77
+ }
78
+
79
+ ```
80
+
81
+ ## Development
82
+
83
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `rake console` for an interactive prompt that will allow you to experiment.
84
+
85
+ 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 tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
86
+
87
+ ## Contributing
88
+
89
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/pdf_templator.
90
+
91
+ [rubygems-image]: https://badge.fury.io/rb/pdf_templator.svg
92
+ [rubygems-url]: https://badge.fury.io/rb/pdf_templator
93
+ [travis-image]: https://travis-ci.org/Mifiel/pdf-templator.svg?branch=master
94
+ [travis-url]: https://travis-ci.org/Mifiel/pdf-templator
95
+ [coverage-image]: https://coveralls.io/repos/github/Mifiel/pdf-templator/badge.svg?branch=master
96
+ [coverage-url]: https://coveralls.io/github/Mifiel/pdf-templator?branch=master
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ task default: :spec
5
+
6
+ task :console do
7
+ exec 'pry -r pdf_templator -I ./lib'
8
+ end
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'pdf_templator'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/bump ADDED
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env python
2
+ import re, glob, sys, os
3
+
4
+ __USAGE__ = \
5
+ """BUMP is a semantic versioning bump script which accepts the following
6
+ mutually exclusive arguments:
7
+ -m - a "major" version bump equal to +1.0.0
8
+ -n - a "minor" version bump equal to +0.1.0
9
+ -p - a "patch" version bump equal to +0.0.1
10
+ -h - a "hot fix" version bump equal to +0.0.1
11
+
12
+ All of these options allow for the -r flag, which indicates that the state
13
+ is a RELEASE not a SNAPSHOT. If -r is not specified, then -SNAPSHOT is
14
+ appended to the updated version string."""
15
+
16
+ __INITIAL__ = ['0', '0', '1']
17
+
18
+
19
+ if __name__ == "__main__":
20
+ v = []
21
+ try:
22
+ version_file = glob.glob("lib/*/version.rb")[0]
23
+ raw_v = re.search(r'VERSION = \'(.*)\'', open(version_file).read(), re.M|re.I|re.S).group(1)
24
+ v = re.split(re.compile("\.|-"), raw_v)
25
+ v = v[0:3]
26
+ map(int, v)
27
+
28
+ except ValueError:
29
+ print("failed to parse the existing VERSION file, assuming v 0.0.1")
30
+ v = ['0', '0', '1']
31
+
32
+ except FileNotFoundError:
33
+ print("failed to find a VERSION file, assuming v 0.0.0")
34
+ v = ['0', '0', '0']
35
+
36
+ op = ''
37
+ try:
38
+ op = sys.argv[1]
39
+ except:
40
+ print(__USAGE__)
41
+ sys.exit(-1)
42
+
43
+ if(op == '-m'):
44
+ v = [str(int(v[0])+1), '0', '0']
45
+
46
+ elif(op == '-n'):
47
+ v = [v[0], str(int(v[1])+1), '0']
48
+
49
+ elif(op == '-p' or op == '-h'):
50
+ v = [v[0], v[1], str(int(v[2])+1)]
51
+
52
+ else:
53
+ print(__USAGE__)
54
+ sys.exit(-1)
55
+
56
+ v = '.'.join(v)
57
+
58
+ if(op == '-h'):
59
+ os.system("git checkout -b hotfix/v%s master" % v)
60
+
61
+ else:
62
+ os.system("git checkout -b release/v%s develop" % v)
63
+
64
+ os.system("bump set %s" % v)
65
+
66
+ v += "\n"
67
+
68
+ print(v)
69
+
70
+ sys.exit(0)
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'pdf_templator'
5
+ require 'slop'
6
+ require 'rake'
7
+ require 'json'
8
+
9
+ module Slop
10
+ NonExistentFile = Class.new Error
11
+
12
+ class FileOption < StringOption
13
+ attr_reader :content
14
+
15
+ def call(value)
16
+ fail NonExistentFile, "File '#{value}' does not exist" unless File.exist?(value)
17
+ self.content = File.read(value)
18
+ self.value = value
19
+ end
20
+
21
+ private
22
+
23
+ attr_writer :content
24
+ end
25
+
26
+ class JsonOption < FileOption
27
+ def call(value)
28
+ super
29
+ self.content = JSON.parse(content, symbolize_names: true)
30
+ self.value = value
31
+ end
32
+ end
33
+ end
34
+
35
+ opts = Slop::Options.new
36
+ opts.banner = 'Usage: pdftemplator [options]'
37
+ opts.file '--template', 'The path of the HTML/ERB template', required: true
38
+ opts.json '--in', 'The json with the variables to inject into the template', required: true
39
+ opts.string '--out', 'The path of the output PDF to be saved'
40
+ opts.on '-v', '--version', 'print the version' do
41
+ puts PdfTemplator::VERSION
42
+ exit
43
+ end
44
+ opts.on '--help', 'prints this help' do
45
+ puts opts
46
+ exit
47
+ end
48
+
49
+ begin
50
+ parser = Slop::Parser.new(opts)
51
+ result = parser.parse(ARGV)
52
+
53
+ vars = result.option(:in)
54
+ template = result.option(:template)
55
+
56
+ fields = vars.content[:fields]
57
+ footer = vars.content[:footer]
58
+ content = template.content
59
+
60
+ result[:out] ||= template.value.pathmap('%X.pdf')
61
+
62
+ reader = PdfTemplator::Reader.new(content: content, footer: footer)
63
+
64
+ pdf = reader.write(fields)
65
+ File.open(result[:out], 'wb') { |f| f.write(pdf) }
66
+ puts "PDF Generated in '#{result[:out]}'"
67
+ rescue PdfTemplator::Reader::FieldsMismatchError => e
68
+ puts "Error: #{e.message}"
69
+ exit 1
70
+ rescue Slop::MissingRequiredOption, Slop::NonExistentFile, Slop::UnknownOption => e
71
+ puts "Error: #{e.message}"
72
+ puts ''
73
+ puts opts
74
+ exit 1
75
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pdf_templator/version'
4
+
5
+ module PdfTemplator
6
+ autoload :Reader, 'pdf_templator/reader'
7
+ autoload :Formatter, 'pdf_templator/formatter'
8
+ autoload :Type, 'pdf_templator/type'
9
+
10
+ # Example:
11
+ #
12
+ # Slop.string_to_type("string") #=> "StringType"
13
+ # Slop.string_to_type("some_thing") #=> "SomeThingType"
14
+ #
15
+ # Returns a camel-cased class looking string with Type suffix.
16
+ def self.string_to_type(string)
17
+ string.to_s.gsub(/(?:^|_)([a-z])/) { Regexp.last_match(1).capitalize } + 'Type'
18
+ end
19
+
20
+ # Example:
21
+ #
22
+ # Slop.string_to_type_class("string") #=> Slop::StringType
23
+ # Slop.string_to_type_class("foo") #=> uninitialized constant FooType
24
+ #
25
+ # Returns the full qualified type class. Uses `#string_to_type`.
26
+ def self.string_to_type_class(string)
27
+ const_get(string_to_type(string))
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'types'
4
+
5
+ module PdfTemplator
6
+ class Formatter
7
+ def initialize(content)
8
+ @content = content
9
+ end
10
+
11
+ # Format content
12
+ # @param type [string] money | number | date | string
13
+ # @param args [hash] :locale, :format
14
+ #
15
+ # @return [string]
16
+ def apply(type, args = {})
17
+ # Symbolize keys
18
+ args = args.map { |k, v| [k.to_sym, v] }.to_h
19
+ I18n.locale = args[:locale] || :en
20
+ klass = PdfTemplator.string_to_type_class(type)
21
+ klass.new(@content, args).call
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'nokogiri'
4
+ require 'wicked_pdf'
5
+
6
+ module PdfTemplator
7
+ class Reader
8
+ FieldsMismatchError = Class.new ArgumentError
9
+
10
+ # Create a new Template Reader
11
+ # @param content [String] Content of the template
12
+ # @param header=nil [Hash] {
13
+ # center: 'TEXT',
14
+ # font_name: 'NAME',
15
+ # font_size: SIZE,
16
+ # left: 'TEXT',
17
+ # right: 'TEXT',
18
+ # spacing: REAL,
19
+ # line: true,
20
+ # content: 'HTML CONTENT ALREADY RENDERED'
21
+ # }
22
+ # @param footer=nil [Hash] {
23
+ # center: 'TEXT',
24
+ # font_name: 'NAME',
25
+ # font_size: SIZE,
26
+ # left: 'TEXT',
27
+ # right: 'TEXT',
28
+ # spacing: REAL,
29
+ # line: true,
30
+ # content: 'HTML CONTENT ALREADY RENDERED'
31
+ # }
32
+ #
33
+ # @see https://github.com/mileszs/wicked_pdf
34
+ # @return [type] [description]
35
+ def initialize(content:, header: nil, footer: nil)
36
+ @content = content
37
+ @header = header
38
+ @footer = footer
39
+ end
40
+
41
+ # Get all the <field>s of the template.
42
+ # @return [Hash] {
43
+ # type: text|number|money|date,
44
+ # value: 'The value of the field',
45
+ # name: 'the_name_of_the_field'
46
+ # }
47
+ def fields
48
+ return @fields if @fields
49
+ @fields = {}
50
+ nokogiri_fields.each do |field|
51
+ name = field.attr('name').downcase.gsub(/ |-/, '_')
52
+ type = field.attr('type')
53
+ args = extract_args(field)
54
+ value = field.text
55
+ @fields[name.to_sym] = { type: type, value: value, name: name, args: args }
56
+ end
57
+ @fields
58
+ end
59
+
60
+ def fields_array
61
+ @fields_array ||= fields.map { |_, element| element }
62
+ end
63
+
64
+ # Write a PDF with the fields,
65
+ # The type of the field will be taken from the original field.
66
+ #
67
+ # @param fields [Hash] with format
68
+ # {
69
+ # fecha: 'The content of the field'
70
+ # }
71
+ #
72
+ # @return [String] String of the PDF
73
+ def write(fields)
74
+ fields = clean_fields(fields)
75
+
76
+ fail FieldsMismatchError, "Missing fields #{missing_fields(fields)}" unless valid_fields?(fields)
77
+ build_doc && replace_fields(fields)
78
+ WickedPdf.new.pdf_from_string(
79
+ doc.to_html,
80
+ encoding: 'UTF-8',
81
+ footer: @footer,
82
+ dpi: 300,
83
+ )
84
+ end
85
+
86
+ def replace_fields(fields)
87
+ fields.each do |k, v|
88
+ k = k.downcase.gsub(/ |-/, '_')
89
+ field_selector = "field[name=#{k}]"
90
+ doc.css(field_selector).each do |field|
91
+ new_node = doc.create_element('span')
92
+ args = extract_args(field)
93
+ new_node.add_child(format_content(field.attr('type'), args, v))
94
+ field.replace(new_node)
95
+ end
96
+ end
97
+ end
98
+
99
+ def valid_fields?(fields)
100
+ a = fields_array.map { |field| field[:name] }
101
+ b = fields if fields.is_a?(Array)
102
+ b ||= fields.keys
103
+ a.sort == b.sort
104
+ end
105
+
106
+ def missing_fields(fields)
107
+ a = fields_array.map { |field| field[:name] }
108
+ b = fields if fields.is_a?(Array)
109
+ b ||= fields.keys
110
+ a - b
111
+ end
112
+
113
+ private
114
+
115
+ def extract_args(field)
116
+ data_attrs = field.attributes.select { |atr| atr.start_with?('data-') }
117
+ data_attrs.values.map { |atr| [atr.name.gsub('data-', ''), atr.value] }.to_h
118
+ end
119
+
120
+ # Cleans fields (lowercase, removes spaces and changes for underscores)
121
+ def clean_fields(fields)
122
+ fields.map { |k, v| [k.to_s.downcase.gsub(/ |-/, '_'), v] }.to_h
123
+ end
124
+
125
+ # Build content depending on the type
126
+ # @param type [String] One of text|number|money|date|accounting
127
+ # @param args [Hash] Extra variables to pass to the formatter
128
+ # @param content [String] The content to be formatted
129
+ #
130
+ # @return [String] The formatted content
131
+ def format_content(type, args, content)
132
+ Formatter.new(content).apply(type, args)
133
+ end
134
+
135
+ def doc
136
+ @doc ||= build_doc
137
+ end
138
+
139
+ def build_doc
140
+ @doc = Nokogiri::HTML(@content)
141
+ end
142
+
143
+ def nokogiri_fields
144
+ doc.css('field')
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PdfTemplator
4
+ class Type
5
+ attr_reader :content
6
+ attr_reader :args
7
+
8
+ def initialize(content, args = {})
9
+ @content = content
10
+ @args = args
11
+ end
12
+
13
+ # This method is called immediately when a type is found.
14
+ # Override it in sub-classes.
15
+ def call(_value)
16
+ fail NotImplementedError,
17
+ "you must override the `call' method for option #{self.class}"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'money'
4
+ require 'active_support/core_ext/string/conversions'
5
+ require 'numbers_and_words'
6
+
7
+ module PdfTemplator
8
+ class TextType < Type
9
+ def call
10
+ "<strong>#{content}</strong>"
11
+ end
12
+ end
13
+
14
+ class NumericType < Type
15
+ def initialize(content, args = {})
16
+ super
17
+ @content = cents
18
+ end
19
+
20
+ private
21
+
22
+ def cents
23
+ int, decimals = @content.to_s.split('.')
24
+ decimals = decimals[0..1]
25
+ "#{int}#{decimals}".to_i
26
+ end
27
+ end
28
+
29
+ class MoneyType < NumericType
30
+ def call
31
+ formatted = content.to_s[0..-3].to_i.to_words
32
+ "#{formatted} #{content.to_s[-2..-1]}/100"
33
+ end
34
+ end
35
+
36
+ class AccountingType < NumericType
37
+ def call
38
+ Money.new(content, args[:currency]).format
39
+ end
40
+ end
41
+
42
+ class NumberType < NumericType
43
+ def call
44
+ Money.new(content).format(symbol: false)
45
+ end
46
+ end
47
+
48
+ class DateType < TextType
49
+ def call
50
+ content.to_time.strftime(args[:format] || '%d/%b/%Y')
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PdfTemplator
4
+ VERSION = '0.0.1'
5
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'pdf_templator/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'pdf_templator'
9
+ spec.version = PdfTemplator::VERSION
10
+ spec.authors = ['Genaro Madrid']
11
+ spec.email = ['genmadrid@gmail.com']
12
+
13
+ spec.summary = 'Write a short summary, because RubyGems requires one.'
14
+ spec.description = 'Write a longer description or delete this line.'
15
+ spec.homepage = 'https://github.com/Mifiel/pdf-templator'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = 'exe'
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_dependency 'activesupport'
25
+ spec.add_dependency 'money'
26
+ spec.add_dependency 'nokogiri'
27
+ spec.add_dependency 'numbers_and_words'
28
+ spec.add_dependency 'wicked_pdf'
29
+ # 0.12.4 introduced a bug that rendered super a small font
30
+ spec.add_dependency 'slop', '~> 4.6'
31
+ spec.add_dependency 'wkhtmltopdf-binary', '< 0.12.3.1'
32
+
33
+ spec.add_development_dependency 'bump', '~> 0.6'
34
+ spec.add_development_dependency 'bundler', '~> 1.16'
35
+ spec.add_development_dependency 'coveralls', '~> 0.7'
36
+ spec.add_development_dependency 'rake', '~> 10.0'
37
+ spec.add_development_dependency 'rspec', '~> 3.7'
38
+ spec.add_development_dependency 'simplecov', '~> 0.16'
39
+ end
@@ -0,0 +1,13 @@
1
+ {
2
+ "folders":
3
+ [
4
+ {
5
+ "file_exclude_patterns": ["*.sublime-workspace"],
6
+ "folder_exclude_patterns": ["tmp", "coverage", "log", "pkg"],
7
+ "path": ".",
8
+ "follow_symlinks": true,
9
+ "tab_size": 2,
10
+ "translate_tabs_to_spaces": false,
11
+ }
12
+ ]
13
+ }
metadata ADDED
@@ -0,0 +1,247 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pdf_templator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Genaro Madrid
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-06-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: money
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: numbers_and_words
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: wicked_pdf
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: slop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '4.6'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '4.6'
97
+ - !ruby/object:Gem::Dependency
98
+ name: wkhtmltopdf-binary
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "<"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.12.3.1
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "<"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.12.3.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: bump
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.6'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.6'
125
+ - !ruby/object:Gem::Dependency
126
+ name: bundler
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.16'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.16'
139
+ - !ruby/object:Gem::Dependency
140
+ name: coveralls
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.7'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.7'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rake
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '10.0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '10.0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rspec
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '3.7'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '3.7'
181
+ - !ruby/object:Gem::Dependency
182
+ name: simplecov
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '0.16'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '0.16'
195
+ description: Write a longer description or delete this line.
196
+ email:
197
+ - genmadrid@gmail.com
198
+ executables:
199
+ - pdftemplator
200
+ extensions: []
201
+ extra_rdoc_files: []
202
+ files:
203
+ - ".editorconfig"
204
+ - ".gitignore"
205
+ - ".rspec"
206
+ - ".rubocop.yml"
207
+ - ".travis.yml"
208
+ - Gemfile
209
+ - Guardfile
210
+ - README.md
211
+ - Rakefile
212
+ - bin/console
213
+ - bin/setup
214
+ - bump
215
+ - exe/pdftemplator
216
+ - lib/pdf_templator.rb
217
+ - lib/pdf_templator/formatter.rb
218
+ - lib/pdf_templator/reader.rb
219
+ - lib/pdf_templator/type.rb
220
+ - lib/pdf_templator/types.rb
221
+ - lib/pdf_templator/version.rb
222
+ - pdf_templator.gemspec
223
+ - pdf_templator.sublime-project
224
+ homepage: https://github.com/Mifiel/pdf-templator
225
+ licenses: []
226
+ metadata: {}
227
+ post_install_message:
228
+ rdoc_options: []
229
+ require_paths:
230
+ - lib
231
+ required_ruby_version: !ruby/object:Gem::Requirement
232
+ requirements:
233
+ - - ">="
234
+ - !ruby/object:Gem::Version
235
+ version: '0'
236
+ required_rubygems_version: !ruby/object:Gem::Requirement
237
+ requirements:
238
+ - - ">="
239
+ - !ruby/object:Gem::Version
240
+ version: '0'
241
+ requirements: []
242
+ rubyforge_project:
243
+ rubygems_version: 2.5.2.1
244
+ signing_key:
245
+ specification_version: 4
246
+ summary: Write a short summary, because RubyGems requires one.
247
+ test_files: []