proforma-html-renderer 1.0.0.pre.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +8 -0
  3. data/.gitignore +5 -0
  4. data/.rubocop.yml +11 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +20 -0
  7. data/CHANGELOG.md +3 -0
  8. data/Gemfile +5 -0
  9. data/Gemfile.lock +111 -0
  10. data/Guardfile +16 -0
  11. data/LICENSE +7 -0
  12. data/README.md +141 -0
  13. data/Rakefile +8 -0
  14. data/bin/console +11 -0
  15. data/bin/render +34 -0
  16. data/bin/snapshot +23 -0
  17. data/lib/proforma/html_renderer/object_writer.rb +42 -0
  18. data/lib/proforma/html_renderer/proforma_writer.rb +51 -0
  19. data/lib/proforma/html_renderer/version.rb +14 -0
  20. data/lib/proforma/html_renderer/writer.rb +77 -0
  21. data/lib/proforma/html_renderer.rb +47 -0
  22. data/proforma-html-renderer.gemspec +34 -0
  23. data/spec/fixtures/aloha.txt.erb +1 -0
  24. data/spec/fixtures/snapshot/config.yml +103 -0
  25. data/spec/fixtures/snapshot/images/logo.png +0 -0
  26. data/spec/fixtures/snapshot/output/0.User List.html +1936 -0
  27. data/spec/proforma/html_renderer/object_writer_spec.rb +40 -0
  28. data/spec/proforma/html_renderer/proforma_writer_spec.rb +19 -0
  29. data/spec/proforma/html_renderer/writer_spec.rb +49 -0
  30. data/spec/proforma/html_renderer_spec.rb +33 -0
  31. data/spec/rendering_helper.rb +98 -0
  32. data/spec/spec_helper.rb +25 -0
  33. data/templates/banner.html.erb +33 -0
  34. data/templates/header.html.erb +3 -0
  35. data/templates/pane.html.erb +36 -0
  36. data/templates/prototype.html.erb +73 -0
  37. data/templates/separator.html.erb +1 -0
  38. data/templates/spacer.html.erb +1 -0
  39. data/templates/table.html.erb +42 -0
  40. data/templates/text.html.erb +3 -0
  41. metadata +222 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 79926036ed97fef2c419bbed5dfe9928bc3d015d27375365519a77d086e02046
4
+ data.tar.gz: 74ff658a1839b254b0ced3cdfce8e903377fdf0fd7f5cf44813d73f33f33da7e
5
+ SHA512:
6
+ metadata.gz: 656f4a759082ceebeb3f0e6872db1a478b74612ea2851841c22c620b555015ec2f78256dc7e3590835d089cb99b6a98debb55e85673b69739e4f68d2bcb3b082
7
+ data.tar.gz: 40a291e58e3023310a9414f0238f261d479137a6e9ca092cab6fba15a4f574bdd9f6a5b916d47fcfcc89f4a5c70a9812d947737ade741ed1bb301bc29619aef5
data/.editorconfig ADDED
@@ -0,0 +1,8 @@
1
+ # See http://editorconfig.org/
2
+
3
+ [*]
4
+ trim_trailing_whitespace = true
5
+ indent_style = space
6
+ indent_size = 2
7
+ insert_final_newline = true
8
+ end_of_line = lf
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .DS_Store
2
+ *.gem
3
+ /tmp
4
+ /coverage
5
+ /pkg
data/.rubocop.yml ADDED
@@ -0,0 +1,11 @@
1
+ Metrics/LineLength:
2
+ Max: 100
3
+
4
+ Metrics/BlockLength:
5
+ ExcludedMethods: ['let', 'it', 'describe', 'context', 'specify']
6
+
7
+ Metrics/MethodLength:
8
+ Max: 25
9
+
10
+ AllCops:
11
+ TargetRubyVersion: 2.3
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.6.0
data/.travis.yml ADDED
@@ -0,0 +1,20 @@
1
+ env:
2
+ global:
3
+ - CC_TEST_REPORTER_ID=90489daeea95c563237fc1b698ecc4bb2b2f421937c646ca1ee4eb1e22e03e70
4
+ language: ruby
5
+ rvm:
6
+ # Build on the latest stable of all supported Rubies (https://www.ruby-lang.org/en/downloads/):
7
+ - 2.3.8
8
+ - 2.4.5
9
+ - 2.5.3
10
+ - 2.6.0
11
+ cache: bundler
12
+ before_script:
13
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
14
+ - chmod +x ./cc-test-reporter
15
+ - ./cc-test-reporter before-build
16
+ script:
17
+ - bundle exec rubocop
18
+ - bundle exec rspec spec --format documentation
19
+ after_script:
20
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # 1.0.0-alpha (June 6th, 2019)
2
+
3
+ Initial alpha release.
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,111 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ proforma-html-renderer (1.0.0.pre.alpha)
5
+ proforma (~> 1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ acts_as_hashable (1.1.0)
11
+ ansi (1.5.0)
12
+ ast (2.4.0)
13
+ byebug (11.0.1)
14
+ coderay (1.1.2)
15
+ diff-lcs (1.3)
16
+ docile (1.3.1)
17
+ ffi (1.9.25)
18
+ formatador (0.2.5)
19
+ guard (2.15.0)
20
+ formatador (>= 0.2.4)
21
+ listen (>= 2.7, < 4.0)
22
+ lumberjack (>= 1.0.12, < 2.0)
23
+ nenv (~> 0.1)
24
+ notiffany (~> 0.0)
25
+ pry (>= 0.9.12)
26
+ shellany (~> 0.0)
27
+ thor (>= 0.18.1)
28
+ guard-compat (1.2.1)
29
+ guard-rspec (4.7.3)
30
+ guard (~> 2.1)
31
+ guard-compat (~> 1.1)
32
+ rspec (>= 2.99.0, < 4.0)
33
+ hirb (0.7.3)
34
+ jaro_winkler (1.5.2)
35
+ json (2.1.0)
36
+ listen (3.1.5)
37
+ rb-fsevent (~> 0.9, >= 0.9.4)
38
+ rb-inotify (~> 0.9, >= 0.9.7)
39
+ ruby_dep (~> 1.2)
40
+ lumberjack (1.0.13)
41
+ method_source (0.9.2)
42
+ nenv (0.3.0)
43
+ notiffany (0.1.1)
44
+ nenv (~> 0.1)
45
+ shellany (~> 0.0)
46
+ parallel (1.13.0)
47
+ parser (2.6.0.0)
48
+ ast (~> 2.4.0)
49
+ powerpack (0.1.2)
50
+ proforma (1.0.2)
51
+ acts_as_hashable (~> 1, >= 1.1.0)
52
+ pry (0.12.2)
53
+ coderay (~> 1.1.0)
54
+ method_source (~> 0.9.0)
55
+ pry-byebug (3.7.0)
56
+ byebug (~> 11.0)
57
+ pry (~> 0.10)
58
+ rainbow (3.0.0)
59
+ rake (10.5.0)
60
+ rb-fsevent (0.10.3)
61
+ rb-inotify (0.9.10)
62
+ ffi (>= 0.5.0, < 2)
63
+ rspec (3.8.0)
64
+ rspec-core (~> 3.8.0)
65
+ rspec-expectations (~> 3.8.0)
66
+ rspec-mocks (~> 3.8.0)
67
+ rspec-core (3.8.0)
68
+ rspec-support (~> 3.8.0)
69
+ rspec-expectations (3.8.2)
70
+ diff-lcs (>= 1.2.0, < 2.0)
71
+ rspec-support (~> 3.8.0)
72
+ rspec-mocks (3.8.0)
73
+ diff-lcs (>= 1.2.0, < 2.0)
74
+ rspec-support (~> 3.8.0)
75
+ rspec-support (3.8.0)
76
+ rubocop (0.63.1)
77
+ jaro_winkler (~> 1.5.1)
78
+ parallel (~> 1.10)
79
+ parser (>= 2.5, != 2.5.1.1)
80
+ powerpack (~> 0.1)
81
+ rainbow (>= 2.2.2, < 4.0)
82
+ ruby-progressbar (~> 1.7)
83
+ unicode-display_width (~> 1.4.0)
84
+ ruby-progressbar (1.10.0)
85
+ ruby_dep (1.5.0)
86
+ shellany (0.0.1)
87
+ simplecov (0.16.1)
88
+ docile (~> 1.1)
89
+ json (>= 1.8, < 3)
90
+ simplecov-html (~> 0.10.0)
91
+ simplecov-console (0.4.2)
92
+ ansi
93
+ hirb
94
+ simplecov
95
+ simplecov-html (0.10.2)
96
+ thor (0.20.3)
97
+ unicode-display_width (1.4.1)
98
+
99
+ PLATFORMS
100
+ ruby
101
+
102
+ DEPENDENCIES
103
+ guard-rspec (~> 4.7)
104
+ proforma-html-renderer!
105
+ pry (~> 0)
106
+ pry-byebug (~> 3)
107
+ rake (~> 10.0)
108
+ rspec (~> 3.8)
109
+ rubocop (~> 0.63.1)
110
+ simplecov (~> 0.16.1)
111
+ simplecov-console (~> 0.4.2)
data/Guardfile ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ guard :rspec, cmd: 'DISABLE_SIMPLECOV=true bundle exec rspec --format=documentation' do
4
+ require 'guard/rspec/dsl'
5
+ dsl = Guard::RSpec::Dsl.new(self)
6
+
7
+ # RSpec files
8
+ rspec = dsl.rspec
9
+ watch(rspec.spec_helper) { rspec.spec_dir }
10
+ watch(rspec.spec_support) { rspec.spec_dir }
11
+ watch(rspec.spec_files)
12
+
13
+ # Ruby files
14
+ ruby = dsl.ruby
15
+ dsl.watch_spec_files_for(ruby.lib_files)
16
+ end
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright 2019 Blue Marble Payroll, LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # Proforma HTML Renderer
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/proforma-html-renderer.svg)](https://badge.fury.io/rb/proforma-html-renderer) [![Build Status](https://travis-ci.org/bluemarblepayroll/proforma-html-renderer.svg?branch=master)](https://travis-ci.org/bluemarblepayroll/proforma-html-renderer) [![Maintainability](https://api.codeclimate.com/v1/badges/ea2b788b45fcc7d0a183/maintainability)](https://codeclimate.com/github/bluemarblepayroll/proforma-html-renderer/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/ea2b788b45fcc7d0a183/test_coverage)](https://codeclimate.com/github/bluemarblepayroll/proforma-html-renderer/test_coverage) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
+
5
+ [Proforma](https://github.com/bluemarblepayroll/proforma) ships with a basic plain-text renderer. Luckily we can plug in different rendering engines to provide additional business value. This library gives Proforma the ability to render HTML instead of simple plain-text.
6
+
7
+ ## Installation
8
+
9
+ To install through Rubygems:
10
+
11
+ ````
12
+ gem install install proforma-html-renderer
13
+ ````
14
+
15
+ You can also add this to your Gemfile:
16
+
17
+ ````
18
+ bundle add proforma-html-renderer
19
+ ````
20
+
21
+ Note: If you are using bundler for auto-requiring then you need to specify as:
22
+
23
+ ```
24
+ gem 'proforma-html-renderer', require: 'proforma/html_renderer'
25
+ ```
26
+
27
+ ## Examples
28
+
29
+ ### Connecting to Proforma Rendering Pipeline
30
+
31
+ To use this plugin within Proforma:
32
+
33
+ 1. Install [Proforma](https://github.com/bluemarblepayroll/proforma)
34
+ 2. Install this library
35
+ 3. Require both libraries
36
+ 4. Pass in an instance of Proforma::HtmlRenderer into the Proforma#render method
37
+
38
+ ````ruby
39
+ require 'proforma'
40
+ require 'proforma/html_renderer'
41
+
42
+ data = [
43
+ { id: 1, name: 'Chicago Bulls' },
44
+ { id: 2, name: 'Indiana Pacers' },
45
+ { id: 3, name: 'Boston Celtics' }
46
+ ]
47
+
48
+ template = {
49
+ title: 'nba_team_list',
50
+ children: [
51
+ { type: 'Header', value: 'NBA Teams' },
52
+ { type: 'Separator' },
53
+ {
54
+ type: 'DataTable',
55
+ columns: [
56
+ { header: 'Team ID #', body: '$id' },
57
+ { header: 'Team Name', body: '$name' },
58
+ ]
59
+ }
60
+ ]
61
+ }
62
+
63
+ documents = Proforma.render(data, template, renderer: Proforma::HtmlRenderer.new)
64
+ ````
65
+
66
+ The `documents` attribute will now be an array with one object:
67
+
68
+ ```ruby
69
+ expected_documents = [
70
+ {
71
+ contents: "...", # HTML Data
72
+ extension: '.html',
73
+ title: 'nba_team_list'
74
+ }
75
+ ]
76
+ ```
77
+
78
+ The `contents` attribute will contain the HTML.
79
+
80
+ ### Customization
81
+
82
+ All options are passed into Proforma::HtmlRenderer#initialize as a hash:
83
+
84
+ Name | Default
85
+ -------------------- | -------
86
+ bold_weight | bold
87
+ font_family | sans-serif
88
+ header_font_size | 18
89
+ line_height_increase | 5
90
+ text_font_size | 13
91
+
92
+ These options will be used during the rendering process.
93
+
94
+ ## Contributing
95
+
96
+ ### Development Environment Configuration
97
+
98
+ Basic steps to take to get this repository compiling:
99
+
100
+ 1. Install [Ruby](https://www.ruby-lang.org/en/documentation/installation/) (check proforma-html-renderer.gemspec for versions supported)
101
+ 2. Install bundler (gem install bundler)
102
+ 3. Clone the repository (git clone git@github.com:bluemarblepayroll/proforma-html-renderer.git)
103
+ 4. Navigate to the root folder (cd proforma)
104
+ 5. Install dependencies (bundle)
105
+
106
+ ### Running Tests
107
+
108
+ To execute the test suite run:
109
+
110
+ ````
111
+ bundle exec rspec spec --format documentation
112
+ ````
113
+
114
+ Alternatively, you can have Guard watch for changes:
115
+
116
+ ````
117
+ bundle exec guard
118
+ ````
119
+
120
+ Also, do not forget to run Rubocop:
121
+
122
+ ````
123
+ bundle exec rubocop
124
+ ````
125
+
126
+ ### Publishing
127
+
128
+ Note: ensure you have proper authorization before trying to publish new versions.
129
+
130
+ After code changes have successfully gone through the Pull Request review process then the following steps should be followed for publishing new versions:
131
+
132
+ 1. Merge Pull Request into master
133
+ 2. Update `lib/proforma/html_renderer/version.rb` using [semantic versioning](https://semver.org/)
134
+ 3. Install dependencies: `bundle`
135
+ 4. Update `CHANGELOG.md` with release notes
136
+ 5. Commit & push master to remote and ensure CI builds master successfully
137
+ 6. 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).
138
+
139
+ ## License
140
+
141
+ This project is MIT Licensed.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'proforma/html_renderer'
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
+ require 'pry'
11
+ Pry.start
data/bin/render ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
6
+ #
7
+ # This source code is licensed under the MIT license found in the
8
+ # LICENSE file in the root directory of this source tree.
9
+ #
10
+
11
+ require 'bundler/setup'
12
+ require 'pry'
13
+
14
+ require_relative '../spec/rendering_helper'
15
+
16
+ jobs_dir = File.expand_path(File.join(__dir__, '..', 'tmp', 'jobs'))
17
+ jobs = RenderingHelper.folders(jobs_dir)
18
+
19
+ if jobs.empty?
20
+ puts "No jobs detected in the path: #{jobs_dir}"
21
+ puts '-------------------------------------------------------------------'
22
+ puts "To use, place folders into #{jobs_dir} directory."
23
+ puts 'Each folder should contain a config.yml file and an images folder'
24
+ puts 'You can find example YAML files in: spec/fixtures/snapshot'
25
+ puts '-------------------------------------------------------------------'
26
+
27
+ exit
28
+ end
29
+
30
+ jobs.each do |job|
31
+ path = File.join(jobs_dir, job)
32
+ puts "Rendering: #{path}"
33
+ RenderingHelper.new(path).render_and_save
34
+ end
data/bin/snapshot ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
6
+ #
7
+ # This source code is licensed under the MIT license found in the
8
+ # LICENSE file in the root directory of this source tree.
9
+ #
10
+
11
+ # This script will generate the snapshot to be used for testing.
12
+ # After modifying any internal part that changes the rendered HTML output
13
+ # you should manually verify the output and once satisfied, use this script to
14
+ # regenerate the snapshot.
15
+
16
+ require 'bundler/setup'
17
+ require 'pry'
18
+
19
+ require_relative '../spec/rendering_helper'
20
+
21
+ snapshot_dir = File.join(__dir__, '..', 'spec', 'fixtures', 'snapshot')
22
+
23
+ RenderingHelper.new(snapshot_dir).render_and_save
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require_relative 'writer'
11
+
12
+ module Proforma
13
+ class HtmlRenderer
14
+ # Each object should have its own ERB template. This class understands the connection of
15
+ # objects and templates and knows how to render the template for the respective object
16
+ # passed in.
17
+ class ObjectWriter
18
+ attr_reader :names_by_class, :writer
19
+
20
+ def initialize(names_by_class: {}, writer: Writer.new)
21
+ @names_by_class = names_by_class
22
+ @writer = writer
23
+ end
24
+
25
+ def render(object, options = {})
26
+ writer.render(
27
+ resolve_name(object),
28
+ object: object,
29
+ options: options
30
+ )
31
+ end
32
+
33
+ private
34
+
35
+ def resolve_name(object)
36
+ names_by_class[object.class].tap do |name|
37
+ raise ArgumentError, "object cannot be rendered: #{object.class}" unless name
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require_relative 'object_writer'
11
+
12
+ module Proforma
13
+ class HtmlRenderer
14
+ # This class connects each Proforma object to its proper template for rendering.
15
+ class ProformaWriter
16
+ extend Forwardable
17
+
18
+ # The singleton is provided as a global helper since we want to expose the same
19
+ # static functionality across the entire app. The real value is the caching of the
20
+ # Writer's files so we are only reading each template the initial time.
21
+ class << self
22
+ extend Forwardable
23
+
24
+ def_delegators :instance, :render
25
+
26
+ def instance
27
+ @instance ||= new
28
+ end
29
+ end
30
+
31
+ NAMES_BY_CLASS = {
32
+ Modeling::Banner => 'banner.html.erb',
33
+ Modeling::Header => 'header.html.erb',
34
+ Modeling::Pane => 'pane.html.erb',
35
+ Modeling::Separator => 'separator.html.erb',
36
+ Modeling::Spacer => 'spacer.html.erb',
37
+ Modeling::Table => 'table.html.erb',
38
+ Modeling::Text => 'text.html.erb',
39
+ Prototype => 'prototype.html.erb'
40
+ }.freeze
41
+
42
+ attr_reader :object_writer
43
+
44
+ def_delegators :object_writer, :render
45
+
46
+ def initialize(object_writer: ObjectWriter.new(names_by_class: NAMES_BY_CLASS))
47
+ @object_writer = object_writer
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ module Proforma
11
+ class HtmlRenderer
12
+ VERSION = '1.0.0-alpha'
13
+ end
14
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ module Proforma
11
+ class HtmlRenderer
12
+ # This class can render ERB templates.
13
+ class Writer
14
+ # This nested class is an internal intermediate only used by the encapsulating Writer class.
15
+ # It is simply used to convert an OpenStruct object to a Binding object which can be used
16
+ # for ERB template rendering.
17
+ class ErbBinding < OpenStruct
18
+ def expose_binding
19
+ binding
20
+ end
21
+ end
22
+
23
+ BACK_DIR = '..'
24
+ ERB_OPTIONS = '-'
25
+ TEMPLATE_DIR = 'templates'
26
+
27
+ def initialize(directory: nil, files: {})
28
+ @directory = directory || default_directory
29
+ @files = to_erb_hash(files)
30
+ end
31
+
32
+ def render(name, context = {})
33
+ erb_template(name).result(hash_to_binding(context))
34
+ end
35
+
36
+ private
37
+
38
+ attr_reader :directory, :files
39
+
40
+ def hash_to_binding(hash)
41
+ ErbBinding.new(hash).expose_binding
42
+ end
43
+
44
+ def erb_template(name)
45
+ files[name.to_s] ||= read(name)
46
+ end
47
+
48
+ def read(name)
49
+ text = IO.read(path(name)).chop
50
+ ERB.new(text, nil, ERB_OPTIONS)
51
+ end
52
+
53
+ def default_directory
54
+ File.join(
55
+ __dir__,
56
+ BACK_DIR,
57
+ BACK_DIR,
58
+ BACK_DIR,
59
+ TEMPLATE_DIR
60
+ )
61
+ end
62
+
63
+ def path(name)
64
+ File.join(directory, name.to_s)
65
+ end
66
+
67
+ def to_erb_hash(hash)
68
+ (hash || {}).map do |(name, file)|
69
+ [
70
+ name.to_s,
71
+ file.is_a?(ERB) ? file : ERB.new(file)
72
+ ]
73
+ end.to_h
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'base64'
11
+ require 'erb'
12
+ require 'forwardable'
13
+ require 'ostruct'
14
+ require 'proforma'
15
+
16
+ require_relative 'html_renderer/proforma_writer'
17
+
18
+ module Proforma
19
+ # This main class to use as a Proforma renderer.
20
+ class HtmlRenderer
21
+ EXTENSION = '.html'
22
+
23
+ DEFAULT_OPTIONS = {
24
+ bold_weight: 'bold',
25
+ font_family: 'sans-serif',
26
+ header_font_size: 18,
27
+ line_height_increase: 5,
28
+ text_font_size: 13
29
+ }.freeze
30
+
31
+ attr_reader :options
32
+
33
+ def initialize(options = {})
34
+ @options = OpenStruct.new(DEFAULT_OPTIONS.merge(options))
35
+ end
36
+
37
+ def render(prototype)
38
+ contents = ProformaWriter.render(prototype, options)
39
+
40
+ Proforma::Document.new(
41
+ contents: contents,
42
+ extension: EXTENSION,
43
+ title: prototype.title
44
+ )
45
+ end
46
+ end
47
+ end