prawn_cocktail 0.5.4 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 61d84eedd5dfe30a88044ffc489cb3045888cdc2d55ce2418ee1f7c1a8069034
4
+ data.tar.gz: 64c8bf00e8398dbf2f66c545c0c287633104b7fa9087694fb24ad3cabae60a90
5
+ SHA512:
6
+ metadata.gz: 75f3e9779418238920e385563ec5b451e7dfd23d1be4379973ef6ac4f30eebbccdce798cae7a8116c3d33de7a1e8a5a52d093f2e385a39278ebddecf9b4e7824
7
+ data.tar.gz: be55301fdc96c7cc719a8a5f79b38de2a456c191f668a91fd14f8c24f75424de45712c5ab904e264ddf04b10943cf9a5f90c2e63ce20792c200b9d30ec6d8878
@@ -0,0 +1,26 @@
1
+ name: Ruby CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ test:
11
+
12
+ runs-on: ubuntu-latest
13
+
14
+ strategy:
15
+ matrix:
16
+ ruby-version: ["3.0", "2.7", "2.6", "2.5"]
17
+
18
+ steps:
19
+ - uses: actions/checkout@v2
20
+ - name: Set up Ruby ${{ matrix.ruby-version }}
21
+ uses: ruby/setup-ruby@ae9cb3b565e36682a2c6045e4f664388da4c73aa
22
+ with:
23
+ ruby-version: ${{ matrix.ruby-version }}
24
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
25
+ - name: Run tests
26
+ run: bundle exec rake
data/.rubocop.yml ADDED
@@ -0,0 +1,5 @@
1
+ AllCops:
2
+ Exclude:
3
+ - "tmp/**/*"
4
+ inherit_gem:
5
+ barsoom_utils: shared_rubocop.yml
data/Gemfile CHANGED
@@ -1,4 +1,9 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in prawn_cocktail.gemspec
4
4
  gemspec
5
+
6
+ group :development do
7
+ gem "barsoom_utils", github: "barsoom/barsoom_utils"
8
+ gem "rubocop"
9
+ end
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # PrawnCocktail
2
2
 
3
- [![Build status](https://secure.travis-ci.org/barsoom/prawn_cocktail.png)](https://travis-ci.org/#!/barsoom/prawn_cocktail/builds)
3
+ [![Ruby CI](https://github.com/barsoom/prawn_cocktail/actions/workflows/ci.yml/badge.svg)](https://github.com/barsoom/prawn_cocktail/actions/workflows/ci.yml)
4
4
 
5
5
  Simple documents, templates and helpers on top of Prawn.
6
6
 
@@ -8,8 +8,6 @@ Because writing Prawn documents PHP 4 style is no fun.
8
8
 
9
9
  If you're using this with Ruby on Rails, get [`PrawnCocktailRails`](http://github.com/barsoom/prawn_cocktail_rails).
10
10
 
11
- Ruby 1.9 only since we use and love instance\_exec.
12
-
13
11
  ![](http://upload.wikimedia.org/wikipedia/commons/f/f8/Cocktail_1_bg_060702.jpg)
14
12
 
15
13
  ## Usage
@@ -42,7 +40,7 @@ class InvoiceDocument < PrawnCocktail::Document
42
40
  {
43
41
  number: @invoice.id,
44
42
  amount: @invoice.amount,
45
- customer_name: @invoice.customer_name
43
+ customer: { name: @invoice.customer_name }
46
44
  }
47
45
  end
48
46
  end
@@ -54,7 +52,7 @@ The document has `render` and `render_file(name)` methods, just like `Prawn::Doc
54
52
 
55
53
  The filename is not required. Other libraries like `PrawnCocktailRails` may make use of it.
56
54
 
57
- The `data` value is passed to the template as an `OpenStruct`.
55
+ The `data` value is passed to the template as a recursive `OpenStruct`-like object.
58
56
 
59
57
  If the data becomes complex, you are advised to extract one or many builder classes like `InvoiceDocument::Data` and call those from `data`.
60
58
 
@@ -72,13 +70,15 @@ content do |data|
72
70
  move_down 10
73
71
  text "Amount: #{data.amount}"
74
72
  move_down 10
75
- text data.customer_name
73
+ text data.customer.name
76
74
  end
77
75
  ```
78
76
 
79
77
  The `meta` declaration is optional. It takes a hash which will be passed to `Prawn::Document.new`. This is where you specify `page_size`, `page_layout` and such.
80
78
 
81
- The `content` block will be passed the data from the document as an `OpenStruct`, and will be rendered in the context of a `Prawn::Document` instance.
79
+ The `content` block will be passed the data from the document as a recursive `OpenStruct`-type object (actually a `RecursiveClosedStruct` utility class).
80
+
81
+ The `content` block will be rendered in the context of a `Prawn::Document` instance.
82
82
 
83
83
  ### Helpers
84
84
 
@@ -112,19 +112,19 @@ module BaseDocumentHelper
112
112
  end
113
113
  ```
114
114
 
115
- Any loaded module can be used as a helper, as long as its code can be run in the context of a Prawn document.
115
+ Any loaded module can be used as a helper, as long as its methods can run in the context of a Prawn document.
116
116
 
117
117
  If you use `PrawnCocktailRails`, you can put modules in `app/documents/helpers`, e.g. `app/documents/helpers/base_document_helper.rb`, and they will be autoloaded.
118
118
 
119
119
  Note that you must explicitly declare the helpers you want. No helpers are automatically included. You can declare base helpers in a base document class, though, and they will be inherited.
120
120
 
121
- ### `initialize_document`
121
+ ### `initialize_template`
122
122
 
123
- If you want to run some code in every document, use an `initialize_document` block:
123
+ If you want to run some code in every template, use an `initialize_template` block:
124
124
 
125
125
  ``` ruby
126
126
  class BaseDocument < PrawnCocktail::Document
127
- initialize_document do
127
+ initialize_template do
128
128
  font "Courier"
129
129
  end
130
130
  end
@@ -134,10 +134,14 @@ This is incidentally how helpers are implemented:
134
134
 
135
135
  ```
136
136
  def self.helper(mod)
137
- initialize_document { extend mod }
137
+ initialize_template { extend mod }
138
138
  end
139
139
  ```
140
140
 
141
+ You can have any number of template initializers, not just one.
142
+
143
+ Template initializers in a superclass are inherited by subclasses, and the subclass can add its own.
144
+
141
145
  ## Installation
142
146
 
143
147
  Add this line to your application's Gemfile:
data/Rakefile CHANGED
@@ -5,4 +5,4 @@ Rake::TestTask.new do |t|
5
5
  t.pattern = "spec/*_spec.rb"
6
6
  end
7
7
 
8
- task :default => :test
8
+ task default: :test
@@ -1,20 +1,18 @@
1
- require "prawn"
2
1
  require "active_support/core_ext/class/attribute"
3
2
  require "active_support/inflector"
4
-
5
3
  require_relative "renderer"
6
4
 
7
5
  module PrawnCocktail
8
6
  class Document
9
- class_attribute :doc_initializers
10
- self.doc_initializers = []
7
+ class_attribute :initializers
8
+ self.initializers = []
11
9
 
12
- def self.initialize_document(&block)
13
- self.doc_initializers += [block]
10
+ def self.initialize_template(&block)
11
+ self.initializers += [ block ]
14
12
  end
15
13
 
16
14
  def self.helper(mod)
17
- initialize_document { extend mod }
15
+ initialize_template { extend mod }
18
16
  end
19
17
 
20
18
  def render
@@ -33,7 +31,7 @@ module PrawnCocktail
33
31
  private
34
32
 
35
33
  def renderer
36
- @renderer ||= Renderer.new(template_name, data, self.class.doc_initializers)
34
+ @renderer ||= Renderer.new(template_name, data, initializers)
37
35
  end
38
36
 
39
37
  def template_name
@@ -44,5 +42,9 @@ module PrawnCocktail
44
42
  # Override in your subclass.
45
43
  {}
46
44
  end
45
+
46
+ def initializers
47
+ self.class.initializers
48
+ end
47
49
  end
48
50
  end
@@ -1,19 +1,22 @@
1
+ require "prawn"
1
2
  require_relative "template"
3
+ require_relative "utils/recursive_closed_struct"
2
4
 
3
5
  module PrawnCocktail
4
6
  class Renderer
5
- def initialize(template_name, data, doc_initializers)
7
+ def initialize(template_name, data, initializers)
8
+ @prawn_document_options = {}
6
9
  @template_name = template_name
7
10
  @data = data
8
- @doc_initializers = doc_initializers
11
+ @initializers = initializers
9
12
  end
10
13
 
11
14
  def meta(opts)
12
- @prawn_document_options = opts
15
+ @prawn_document_options.merge!(opts)
13
16
  end
14
17
 
15
18
  def content(&block)
16
- @doc_initializers.each do |proc|
19
+ @initializers.each do |proc|
17
20
  prawn_document.instance_eval(&proc)
18
21
  end
19
22
 
@@ -37,11 +40,15 @@ module PrawnCocktail
37
40
  end
38
41
 
39
42
  def prawn_document
40
- @doc ||= Prawn::Document.new(@prawn_document_options || {})
43
+ @doc ||= Prawn::Document.new(prawn_document_options)
44
+ end
45
+
46
+ def prawn_document_options
47
+ @prawn_document_options || {}
41
48
  end
42
49
 
43
50
  def data_object
44
- OpenStruct.new(@data)
51
+ RecursiveClosedStruct.new(@data)
45
52
  end
46
53
  end
47
54
  end
@@ -0,0 +1,26 @@
1
+ class RecursiveClosedStruct
2
+ def initialize(hash)
3
+ @hash = hash
4
+ end
5
+
6
+ def include?(key)
7
+ @hash.include?(key)
8
+ end
9
+
10
+ def method_missing(name, *)
11
+ value = fetch(name)
12
+ if value.is_a?(Hash)
13
+ self.class.new(value)
14
+ else
15
+ value
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def fetch(name)
22
+ @hash.fetch(name) do
23
+ raise NoMethodError.new("undefined method `#{name}' for #{self}")
24
+ end
25
+ end
26
+ end
@@ -1,3 +1,3 @@
1
1
  module PrawnCocktail
2
- VERSION = "0.5.4"
2
+ VERSION = "0.8.1"
3
3
  end
@@ -1,20 +1,21 @@
1
1
  # -*- encoding: utf-8 -*-
2
- lib = File.expand_path('../lib', __FILE__)
2
+ lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'prawn_cocktail/version'
4
+ require "prawn_cocktail/version"
5
5
 
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = "prawn_cocktail"
8
8
  gem.version = PrawnCocktail::VERSION
9
- gem.authors = ["Henrik Nyh"]
10
- gem.email = ["henrik@barsoom.se"]
9
+ gem.authors = [ "Henrik Nyh" ]
10
+ gem.email = [ "henrik@barsoom.se" ]
11
11
  gem.summary = "Simple documents, templates and helpers on top of Prawn."
12
12
  gem.homepage = ""
13
+ gem.metadata = { "rubygems_mfa_required" => "true" }
14
+
13
15
 
14
16
  gem.files = `git ls-files`.split($/)
15
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
- gem.require_paths = ["lib"]
18
+ gem.require_paths = [ "lib" ]
18
19
 
19
20
  gem.add_dependency "prawn"
20
21
  gem.add_dependency "activesupport"
@@ -6,7 +6,7 @@ end
6
6
 
7
7
  class TestDocument < PrawnCocktail::Document
8
8
  helper TestDocumentHelper
9
- initialize_document { text "Init works." }
9
+ initialize_template { text "Init works." }
10
10
 
11
11
  def initialize(status)
12
12
  @status = status
@@ -15,10 +15,10 @@ class TestDocument < PrawnCocktail::Document
15
15
  private
16
16
 
17
17
  def data
18
- { status: @status }
18
+ { nested: { status: @status } }
19
19
  end
20
20
  end
21
21
 
22
22
  class SubTestDocument < TestDocument
23
- initialize_document { text "Sub-init works." }
23
+ initialize_template { text "Sub-init works." }
24
24
  end
@@ -2,5 +2,5 @@ meta page_size: "A4"
2
2
 
3
3
  content do |data|
4
4
  text "Sub test document"
5
- status_line data.status
5
+ status_line data.nested.status
6
6
  end
@@ -2,5 +2,5 @@ meta page_size: "A4"
2
2
 
3
3
  content do |data|
4
4
  text "Test document"
5
- status_line data.status
5
+ status_line data.nested.status
6
6
  end
@@ -1,5 +1,4 @@
1
- require "minitest/autorun"
2
- require "minitest/pride"
1
+ require_relative "spec_helper"
3
2
  require "pdf/inspector"
4
3
 
5
4
  require "prawn_cocktail"
@@ -14,11 +13,14 @@ describe PrawnCocktail do
14
13
 
15
14
  describe "#render" do
16
15
  it "has the right contents" do
17
- assert_document_has_the_right_contents
16
+ assert_equal(
17
+ [ "Init works.", "Test document", "Status: success" ],
18
+ parse_strings(data),
19
+ )
18
20
  end
19
21
 
20
22
  it "has the right geometry" do
21
- assert_document_has_the_right_geometry
23
+ assert_equal expected_geometry("A4"), parse_geometry(data)
22
24
  end
23
25
  end
24
26
 
@@ -29,11 +31,14 @@ describe PrawnCocktail do
29
31
  end
30
32
 
31
33
  it "has the right contents" do
32
- assert_document_has_the_right_contents
34
+ assert_equal(
35
+ [ "Init works.", "Test document", "Status: success" ],
36
+ parse_strings(data),
37
+ )
33
38
  end
34
39
 
35
40
  it "has the right geometry" do
36
- assert_document_has_the_right_geometry
41
+ assert_equal expected_geometry("A4"), parse_geometry(data)
37
42
  end
38
43
  end
39
44
 
@@ -45,27 +50,12 @@ describe PrawnCocktail do
45
50
  it "inherits initializers and helpers" do
46
51
  assert_equal(
47
52
  [ "Init works.", "Sub-init works.", "Sub test document", "Status: success" ],
48
- parse_strings(data)
53
+ parse_strings(data),
49
54
  )
50
55
  end
51
56
  end
52
57
  end
53
58
 
54
-
55
- def assert_document_has_the_right_contents
56
- assert_equal(
57
- [ "Init works.", "Test document", "Status: success" ],
58
- parse_strings(data)
59
- )
60
- end
61
-
62
- def assert_document_has_the_right_geometry
63
- assert_equal(
64
- parse_geometry(data),
65
- expected_geometry("A4")
66
- )
67
- end
68
-
69
59
  def parse_strings(pdf_data)
70
60
  PDF::Inspector::Text.analyze(pdf_data).strings
71
61
  end
@@ -75,5 +65,5 @@ def parse_geometry(pdf_data)
75
65
  end
76
66
 
77
67
  def expected_geometry(name)
78
- Prawn::Document::PageGeometry::SIZES[name]
68
+ PDF::Core::PageGeometry::SIZES[name]
79
69
  end
@@ -0,0 +1,41 @@
1
+ require_relative "spec_helper"
2
+
3
+ require_relative "../lib/prawn_cocktail/utils/recursive_closed_struct"
4
+
5
+ describe RecursiveClosedStruct do
6
+ it "provides readers from a hash" do
7
+ subject = RecursiveClosedStruct.new(key: "value")
8
+ assert_equal "value", subject.key
9
+ end
10
+
11
+ it "raises when there's no such key" do
12
+ subject = RecursiveClosedStruct.new(key: "value")
13
+ assert_raises(NoMethodError) do
14
+ subject.other_key
15
+ end
16
+ end
17
+
18
+ it "recurses through hashes" do
19
+ subject = RecursiveClosedStruct.new({
20
+ one: { two: { three: "four" } },
21
+ })
22
+ assert_equal "four", subject.one.two.three
23
+ end
24
+
25
+ describe "#include?" do
26
+ it "is true if that key exists" do
27
+ subject = RecursiveClosedStruct.new(real: true)
28
+ assert subject.include?(:real)
29
+ end
30
+
31
+ it "is false if that key does not exist" do
32
+ subject = RecursiveClosedStruct.new(real: true)
33
+ refute subject.include?(:imaginary)
34
+ end
35
+
36
+ it "recurses" do
37
+ subject = RecursiveClosedStruct.new(one: { two: "three" })
38
+ assert subject.one.include?(:two)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,14 @@
1
+ require_relative "spec_helper"
2
+
3
+ describe PrawnCocktail::Renderer do
4
+ describe "#meta" do
5
+ it "merges options if run multiple times" do
6
+ subject = PrawnCocktail::Renderer.new(nil, nil, nil)
7
+ subject.meta one: nil, two: 2
8
+ subject.meta one: 1, three: 3
9
+
10
+ expected = { one: 1, two: 2, three: 3 }
11
+ assert_equal expected, subject.send(:prawn_document_options)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,2 @@
1
+ require "minitest/autorun"
2
+ require "minitest/pride"
metadata CHANGED
@@ -1,60 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prawn_cocktail
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
5
- prerelease:
4
+ version: 0.8.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Henrik Nyh
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-02-23 00:00:00.000000000 Z
11
+ date: 2021-11-19 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: prawn
16
- requirement: &70243544258740 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *70243544258740
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
25
27
  - !ruby/object:Gem::Dependency
26
28
  name: activesupport
27
- requirement: &70243544274560 !ruby/object:Gem::Requirement
28
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ! '>='
31
+ - - ">="
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0'
33
34
  type: :runtime
34
35
  prerelease: false
35
- version_requirements: *70243544274560
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
36
41
  - !ruby/object:Gem::Dependency
37
42
  name: rake
38
- requirement: &70243544274080 !ruby/object:Gem::Requirement
39
- none: false
43
+ requirement: !ruby/object:Gem::Requirement
40
44
  requirements:
41
- - - ! '>='
45
+ - - ">="
42
46
  - !ruby/object:Gem::Version
43
47
  version: '0'
44
48
  type: :development
45
49
  prerelease: false
46
- version_requirements: *70243544274080
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
47
55
  - !ruby/object:Gem::Dependency
48
56
  name: pdf-inspector
49
- requirement: &70243544273600 !ruby/object:Gem::Requirement
50
- none: false
57
+ requirement: !ruby/object:Gem::Requirement
51
58
  requirements:
52
- - - ! '>='
59
+ - - ">="
53
60
  - !ruby/object:Gem::Version
54
61
  version: '0'
55
62
  type: :development
56
63
  prerelease: false
57
- version_requirements: *70243544273600
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
58
69
  description:
59
70
  email:
60
71
  - henrik@barsoom.se
@@ -62,8 +73,9 @@ executables: []
62
73
  extensions: []
63
74
  extra_rdoc_files: []
64
75
  files:
65
- - .gitignore
66
- - .travis.yml
76
+ - ".github/workflows/ci.yml"
77
+ - ".gitignore"
78
+ - ".rubocop.yml"
67
79
  - Gemfile
68
80
  - README.md
69
81
  - Rakefile
@@ -72,39 +84,44 @@ files:
72
84
  - lib/prawn_cocktail/document.rb
73
85
  - lib/prawn_cocktail/renderer.rb
74
86
  - lib/prawn_cocktail/template.rb
87
+ - lib/prawn_cocktail/utils/recursive_closed_struct.rb
75
88
  - lib/prawn_cocktail/version.rb
76
89
  - prawn_cocktail.gemspec
77
90
  - spec/fixtures/document.rb
78
91
  - spec/fixtures/sub_test_document.pdf.rb
79
92
  - spec/fixtures/test_document.pdf.rb
80
93
  - spec/integration_spec.rb
94
+ - spec/recursive_closed_struct_spec.rb
95
+ - spec/renderer_spec.rb
96
+ - spec/spec_helper.rb
81
97
  homepage: ''
82
98
  licenses: []
99
+ metadata:
100
+ rubygems_mfa_required: 'true'
83
101
  post_install_message:
84
102
  rdoc_options: []
85
103
  require_paths:
86
104
  - lib
87
105
  required_ruby_version: !ruby/object:Gem::Requirement
88
- none: false
89
106
  requirements:
90
- - - ! '>='
107
+ - - ">="
91
108
  - !ruby/object:Gem::Version
92
109
  version: '0'
93
110
  required_rubygems_version: !ruby/object:Gem::Requirement
94
- none: false
95
111
  requirements:
96
- - - ! '>='
112
+ - - ">="
97
113
  - !ruby/object:Gem::Version
98
114
  version: '0'
99
115
  requirements: []
100
- rubyforge_project:
101
- rubygems_version: 1.8.5
116
+ rubygems_version: 3.2.31
102
117
  signing_key:
103
- specification_version: 3
118
+ specification_version: 4
104
119
  summary: Simple documents, templates and helpers on top of Prawn.
105
120
  test_files:
106
121
  - spec/fixtures/document.rb
107
122
  - spec/fixtures/sub_test_document.pdf.rb
108
123
  - spec/fixtures/test_document.pdf.rb
109
124
  - spec/integration_spec.rb
110
- has_rdoc:
125
+ - spec/recursive_closed_struct_spec.rb
126
+ - spec/renderer_spec.rb
127
+ - spec/spec_helper.rb
data/.travis.yml DELETED
@@ -1,4 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 1.9.3
4
- - rbx-19mode