pdf_tempura 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +342 -0
  8. data/Rakefile +1 -0
  9. data/example/my_pdf.rb +37 -0
  10. data/lib/pdf_tempura.rb +8 -0
  11. data/lib/pdf_tempura/document.rb +121 -0
  12. data/lib/pdf_tempura/document/boxed_characters.rb +70 -0
  13. data/lib/pdf_tempura/document/boxed_characters/groups.rb +53 -0
  14. data/lib/pdf_tempura/document/character_field.rb +37 -0
  15. data/lib/pdf_tempura/document/checkbox_field.rb +15 -0
  16. data/lib/pdf_tempura/document/default_commands.rb +40 -0
  17. data/lib/pdf_tempura/document/field/base.rb +55 -0
  18. data/lib/pdf_tempura/document/field_set.rb +51 -0
  19. data/lib/pdf_tempura/document/page.rb +33 -0
  20. data/lib/pdf_tempura/document/table.rb +95 -0
  21. data/lib/pdf_tempura/document/table/boxed_character_column.rb +20 -0
  22. data/lib/pdf_tempura/document/table/checkbox_column.rb +9 -0
  23. data/lib/pdf_tempura/document/table/column.rb +18 -0
  24. data/lib/pdf_tempura/document/table/spacer.rb +13 -0
  25. data/lib/pdf_tempura/document/table/text_column.rb +9 -0
  26. data/lib/pdf_tempura/document/text_field.rb +18 -0
  27. data/lib/pdf_tempura/document/validation.rb +79 -0
  28. data/lib/pdf_tempura/extensions/hash/stringify_keys.rb +35 -0
  29. data/lib/pdf_tempura/render.rb +18 -0
  30. data/lib/pdf_tempura/render/boxed_characters.rb +42 -0
  31. data/lib/pdf_tempura/render/character_field.rb +49 -0
  32. data/lib/pdf_tempura/render/checkbox_field.rb +35 -0
  33. data/lib/pdf_tempura/render/debug.rb +16 -0
  34. data/lib/pdf_tempura/render/debug/annotation/base.rb +83 -0
  35. data/lib/pdf_tempura/render/debug/character_field_annotation.rb +13 -0
  36. data/lib/pdf_tempura/render/debug/checkbox_field_annotation.rb +24 -0
  37. data/lib/pdf_tempura/render/debug/field_set_annotation.rb +23 -0
  38. data/lib/pdf_tempura/render/debug/grid.rb +59 -0
  39. data/lib/pdf_tempura/render/debug/outside_annotation.rb +42 -0
  40. data/lib/pdf_tempura/render/debug/table_annotation.rb +19 -0
  41. data/lib/pdf_tempura/render/debug/text_field_annotation.rb +42 -0
  42. data/lib/pdf_tempura/render/field.rb +40 -0
  43. data/lib/pdf_tempura/render/field_bounds.rb +26 -0
  44. data/lib/pdf_tempura/render/field_data_mapper.rb +15 -0
  45. data/lib/pdf_tempura/render/field_set.rb +31 -0
  46. data/lib/pdf_tempura/render/option_access.rb +21 -0
  47. data/lib/pdf_tempura/render/page.rb +23 -0
  48. data/lib/pdf_tempura/render/table.rb +35 -0
  49. data/lib/pdf_tempura/render/text_field.rb +13 -0
  50. data/lib/pdf_tempura/renderer.rb +39 -0
  51. data/lib/pdf_tempura/version.rb +3 -0
  52. data/pdf_tempura.gemspec +27 -0
  53. data/spec/assets/sample_pdf_form.odg +0 -0
  54. data/spec/assets/sample_pdf_form.pdf +0 -0
  55. data/spec/integration_spec.rb +88 -0
  56. data/spec/lib/pdf_tempura/document/boxed_characters_spec.rb +125 -0
  57. data/spec/lib/pdf_tempura/document/checkbox_field_spec.rb +54 -0
  58. data/spec/lib/pdf_tempura/document/field_common.rb +12 -0
  59. data/spec/lib/pdf_tempura/document/field_set_spec.rb +38 -0
  60. data/spec/lib/pdf_tempura/document/page_spec.rb +57 -0
  61. data/spec/lib/pdf_tempura/document/table_spec.rb +161 -0
  62. data/spec/lib/pdf_tempura/document/text_field_spec.rb +195 -0
  63. data/spec/lib/pdf_tempura/document_spec.rb +131 -0
  64. data/spec/lib/pdf_tempura/extensions/hash/stringify_keys_spec.rb +42 -0
  65. data/spec/lib/pdf_tempura/render/boxed_characters_spec.rb +68 -0
  66. data/spec/lib/pdf_tempura/render/checkbox_field_spec.rb +39 -0
  67. data/spec/lib/pdf_tempura/render/debug/annotation_renderer/base_spec.rb +45 -0
  68. data/spec/lib/pdf_tempura/render/debug/checkbox_field_annotation_spec.rb +45 -0
  69. data/spec/lib/pdf_tempura/render/debug/grid_spec.rb +15 -0
  70. data/spec/lib/pdf_tempura/render/debug/text_field_annotation_spec.rb +46 -0
  71. data/spec/lib/pdf_tempura/render/field_data_mapper_spec.rb +31 -0
  72. data/spec/lib/pdf_tempura/render/field_set_spec.rb +41 -0
  73. data/spec/lib/pdf_tempura/render/field_spec.rb +37 -0
  74. data/spec/lib/pdf_tempura/render/page_spec.rb +77 -0
  75. data/spec/lib/pdf_tempura/render/table_spec.rb +44 -0
  76. data/spec/lib/pdf_tempura/render/text_field_spec.rb +39 -0
  77. data/spec/lib/pdf_tempura/renderer_spec.rb +79 -0
  78. data/spec/spec_helper.rb +29 -0
  79. data/spec/support/shared_examples/field_examples.rb +265 -0
  80. metadata +219 -0
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OTExNjA1ZWY2NjkwZDA5YmY4Y2NhODhiMmRjMzZhZTJiY2IzN2M0OQ==
5
+ data.tar.gz: !binary |-
6
+ MDczNGQ5NzJkYmNjODA3YThkZWZlYTExNzU1OWI3NTU1ZGM0YTc4ZA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZGI2ZWZiNGJiMjNmMjUxOTJkOGYyOTBjYTkyMjFiYmVjOTM4Mjk1NzVlOWE2
10
+ MjdhNTg4MTQwZDcxNmQ4MjE3NDIxZDZkMDE1ZjI3MDNmYWRlZmU2NDZkM2Iy
11
+ ZjFjMTFjYTM5Zjk3ZWIwMGI5ZjNiZTA0YmRkYzZiZjMwYzYwYzc=
12
+ data.tar.gz: !binary |-
13
+ MzY4YjU3ZjFiMWU0ODBmYTA3NDNhZjc3N2NjMTVkYWIyODkwYjFhZjk3ZjM0
14
+ NWFjY2JiODI4ODA2ZDMwYTk2ZTYyM2ViYjY1ODhlOWUwZmU3MzUyYTg0ZDE1
15
+ Y2Q2N2NjMDdjMzhjZmFhYzBlNTlkNGE0YWEwN2Q5NjdkOGM5YzQ=
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .ruby-*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
5
+ script: "bundle exec rspec"
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pdf_tempura.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 PayrollHero
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,342 @@
1
+ # PdfTempura
2
+
3
+ [![Code Climate](https://codeclimate.com/github/payrollhero/pdf_tempura.png)](https://codeclimate.com/github/payrollhero/pdf_tempura)
4
+ [![Build Status](https://travis-ci.org/payrollhero/pdf_tempura.png?branch=master)](https://travis-ci.org/payrollhero/pdf_tempura)
5
+ [![Dependency Status](https://gemnasium.com/payrollhero/pdf_tempura.png)](https://gemnasium.com/payrollhero/pdf_tempura)
6
+
7
+
8
+ A gem for overlaying text and other fields onto PDF templates using Prawn.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'pdf_tempura'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install pdf_tempura
23
+
24
+ ## Usage
25
+
26
+ ### Building your overlayed PDF template
27
+
28
+ Inherit from `PdfTempura::Document` to start off your pdf.
29
+
30
+ #### Specifying the template
31
+
32
+ Specify your template using:
33
+
34
+ ```ruby
35
+ template "/some/path/to/template.pdf"
36
+ ```
37
+
38
+ #### Specifying pages
39
+
40
+ The `page` method can be used to specify a page. It takes number to specify the page,
41
+ and a block where you specify your fields.
42
+
43
+ You may also specify default options for layout by passing them into the "page" method.
44
+ They will be inherited into all the page elements unless overridden by the options
45
+ of that element.
46
+
47
+ ```ruby
48
+ page 1, alignment: "left" do
49
+ # fields ...
50
+ end
51
+ ```
52
+
53
+ #### Specifying fields
54
+
55
+ Fields should be specified inside pages using the `page` method. Fields can be specified by using one of the following fields methods.
56
+
57
+ ##### Text fields
58
+
59
+ You can specify a text field using the `text_field` method. It requires a name, an array of coordinates (x and y), and an array of dimensions (width and height).
60
+ Coordinates and dimensions are numbers referencing PDF units, starting from bottom left.
61
+
62
+ ```ruby
63
+ text_field(name, coordinates, dimensions, options)
64
+ ```
65
+
66
+ It also takes an options hash where you can set the following options:
67
+
68
+ Common Options:
69
+
70
+ - **type**: "text", "checkbox" or "box-list". Defines the type of the field and draws the appropriate type. A box-list will create a box field for each character of the passed text. Default is "text".
71
+ - **default_value**: The default value for the field. Default is nil.
72
+
73
+ TextField options:
74
+
75
+ - **font_size**: A number in pixels (i.e. 13), or auto to change the font to fit the field size. Default is 10px.
76
+ - **font_name**: The name of the font to use. Default: "Helvetica"
77
+ - **italic**: True or false. Makes the text italic when set to true. Default to false.
78
+ - **bold**: True or false. Makes the text bold when set to true. Default is false.
79
+ - **alignment**: "left", "center" or "right". Aligns the text in the boundaries of the field. Default is "left".
80
+ - **multi_line**: True or false. Forces the text to wrap to the next line when it hits the boundaries of the field. Default is false.
81
+ - **padding**: An array of 4 numbers, representing top, right, bottom, left. It adds padding in pdf units inside the field.
82
+ - **valign**: Defines vertical alignment of the text in the box, top, center, or bottom.
83
+ - **leading**: When multi_line is true, this will add top_margin to each wrapped line of text.
84
+
85
+ ```ruby
86
+ page 1 do
87
+ text_field :country, [10, 20], [200, 400], default_value: "USA", font_size: 13, bold: true, alignment: left, multi_line:true
88
+ end
89
+ ```
90
+
91
+ ##### Checkbox fields
92
+ You can specify a checkbox field using the `checkbox_field` method. It requires a name, an array of coordinates (x and y), and an array of dimensions (width and height).
93
+ Coordinates and dimensions are numbers referencing PDF units, starting from bottom left.
94
+
95
+ ```ruby
96
+ checkbox_field(name, coordinates, dimensions, options)
97
+ ```
98
+
99
+ It also takes an options hash where you can set the following options:
100
+
101
+ - **default_value**: True or false. The default value for the checkbox. Default is false.
102
+
103
+ ```ruby
104
+ page 1 do
105
+ checkbox_field :send_me_snacks, [10, 20], [20, 20], default_value: true
106
+ end
107
+ ```
108
+
109
+ ##### Boxed Characters
110
+ This is a field which helps you to display a field which needs to be printed
111
+ in a boxed fashion. E.g. [H][E][L][L][O]-[W][O][R][L][D].
112
+
113
+ ```ruby
114
+ boxed_characters :name, [10,20], 20, box_spacing: 1, box_width: 10 do
115
+ characters 4
116
+ space 2
117
+ characters 4
118
+ end
119
+ ```
120
+
121
+ Boxed Characters options:
122
+
123
+ - **box_spacing**: Required, amount of space between each individual box
124
+ - **box_width**: Required, the width of each individual box
125
+ - **other**: You may use any of the options that are also in use with text_field
126
+ EXCEPT for alignment, and multi-line.
127
+
128
+ ##### Tables
129
+
130
+ ```ruby
131
+ class MyDoc < PdfTempura::Document
132
+ page 1 do
133
+ table :stuff, [500,50], height: 300, number_of_rows: 10, row_height: 25, cell_padding: 1 do
134
+ text_column :pin, 50
135
+ space 5
136
+ checkbox_column :last_name, 100
137
+ end
138
+ end
139
+ end
140
+ ```
141
+
142
+ The table construct allows the creation of a repeating set of fields.
143
+
144
+ Table options:
145
+
146
+ - **height**: Optional, height of the overall table.
147
+ - **number_of_rows**: The number of rows in the table, required
148
+ - **row_height**: The height of each row
149
+ - **cell_padding**: Padding between each cell, optional
150
+
151
+ The `table` call takes a name, the x,y position of the top-left corner
152
+ of the table, the number of rows, either row_height or height (or both), and
153
+ cell padding.
154
+
155
+ Inside the table block, you define columns or spaces. Columns themselves have
156
+ amalgamous names to those you may use in "page" to describe fields. Use
157
+ "text_column" for a column containing text, "checkbox_column" for a cell
158
+ containing a checkbox.
159
+
160
+ Space only takes one parameter, its width.
161
+
162
+ Column mimicks 'field', except you only specify the width of the column,
163
+ the rest is figured out by the table.
164
+
165
+ Table data is assigned through assigning an array of hashes to the key
166
+ named after the name of the table.
167
+
168
+ eg:
169
+
170
+ ```ruby
171
+ data = {
172
+ 1 => {
173
+ stuff: [
174
+ { pin: "12 3456789 6", last_name: "Doe"}
175
+ ]
176
+ }
177
+ }
178
+ ```
179
+
180
+ ##### Field Sets
181
+ A field set allows you to group pieces of data under a particular heading. You
182
+ define a field set simply by the name of the heading it will be contained under
183
+ in the data. This is to help you organize your data logically.
184
+
185
+ You may also specify default options for layout by passing them into the `field_set` method.
186
+ They will be inherited into all the page elements unless overridden by the options
187
+ of that element.
188
+
189
+ ```ruby
190
+ class MyPdf < PdfTempura::Document
191
+ ...
192
+
193
+ page 1 do
194
+ field_set "customer", font_size: 12 do
195
+ text_field "name", [0,0], [10,20]
196
+ text_field "address", [0,10], [10,20]
197
+ end
198
+ end
199
+
200
+ end
201
+
202
+ data = {
203
+ 1 => {
204
+ "customer" => { "name" => "John Bazdaritch", "address" => "123 Hollywood Blvd" }
205
+ }
206
+ }
207
+ ```
208
+
209
+ ##### Specifying default options for a few elements
210
+ The `with_default_options` block can be used to provide default options for all elements
211
+ within it's specified block. These default options will be merged with the default options
212
+ of the enclosing page, field set or table. Elements can override these default options
213
+ by explicitly passing the option to the element.
214
+
215
+ ```ruby
216
+ page 1, alignment: "left" do
217
+ text_field :aligned_left, [10,20], [100,50]
218
+
219
+ with_default_options alignment: "right" do
220
+ text_field :aligned_right, [40,60], [100,50]
221
+ text_field :also_aligned_left, [70,80], [100,50], alignment: "right"
222
+ end
223
+ end
224
+
225
+ #### Specifying reusable groups
226
+
227
+ If you have the same fields on multiple pages, you can use the `group` method to DRY your template.
228
+
229
+ ```ruby
230
+ group :employee_details do
231
+ field :first_name, [10, 20], [100, 30]
232
+ field :surname, [120, 20], [200, 30], bold: true
233
+ field :company, [330, 20], [300, 30], alignment: right
234
+ end
235
+ ```
236
+
237
+ Then you can use the `include_group` method to add that group to pages.
238
+
239
+ ```ruby
240
+ page 1 do
241
+ include_group :employee_details
242
+ field :address, [10, 20], [500, 60]
243
+ ...
244
+ end
245
+
246
+ page 2 do
247
+ include_group :employee_details
248
+ field :emergency_contact, [10, 20], [500, 60]
249
+ ...
250
+ end
251
+ ```
252
+
253
+ ### Rendering your PDF
254
+
255
+ #### Loading field data
256
+
257
+ You can load the field data by creating a new instance of your overlayed template and passing a data hash.
258
+ The data hash should be a hash of hashes, the keys at the first level matching the page numbers and groups of your template,
259
+ and the keys inside the nested hashes matching the names of the fields in those pages.
260
+
261
+ ```ruby
262
+ data_hash = {
263
+ :employee_details => {
264
+ :first_name => "Stan",
265
+ :surname => "Smith",
266
+ :company => "CIA"
267
+ },
268
+ 1 => {
269
+ :address => "The Pentagon, Washington, DC"
270
+ },
271
+ 2 => {
272
+ :emergency_contact => "Francine Smith"
273
+ }
274
+ }
275
+
276
+ my_pdf = MyPdf.new(data_hash)
277
+ ```
278
+
279
+ You can override group values by including the key in a specific page's data hash. Keys can be either strings or symbols.
280
+
281
+ #### Rendering your overlayed PDF
282
+
283
+ After loading the field data, you can then render the PDF using the `render` method. The render method takes a block,
284
+ and provides the opened pdf file as an argument. The pdf file will be closed when the block terminates and the value of the block
285
+ will be returned.
286
+
287
+ ```ruby
288
+ mypdf.render do |pdf|
289
+ # save PDF to file
290
+ File.new("/path/to/file". "w+") do |file|
291
+ file.write(pdf.read)
292
+ end
293
+ end
294
+ ```
295
+
296
+ ### Repeating data
297
+ If you would like the template you have specified to be repeated on matching pages
298
+ then you need to use the "repeatable" option in your Document class. If repeatable is set
299
+ then if you specify pages 1,2 in your document, and then specify 1,2,3,4 in your data
300
+ the produced page will reuse the template's page 1 for page 3 and page 2 for page 4, etc.
301
+ ```ruby
302
+ class MyPdf < PdfTempura::Document
303
+
304
+ template "/some/path/to/template.pdf"
305
+ repeatable
306
+
307
+ ...
308
+
309
+ end
310
+
311
+ data = {1 => ... data for page 1,
312
+ 2 => ... data for page 2,
313
+ 3 => ... data for page 3,
314
+ 4 => ... data for page 4}
315
+ ```
316
+
317
+ ### Debug mode
318
+
319
+ You can set your template to debug mode to help you position your fields using the `debug` method. The debug options are:
320
+
321
+ - **grid**: This will overlay a grid on the document, each box representing a 10x10 unit area.
322
+ - **outlines**: This will outline each field with a black border.
323
+
324
+ ```ruby
325
+ class MyPdf < PdfTempura::Document
326
+
327
+ template "/some/path/to/template.pdf"
328
+
329
+ debug :grid, :outlines
330
+
331
+ ...
332
+
333
+ end
334
+ ```
335
+
336
+ ## Contributing
337
+
338
+ 1. Fork it
339
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
340
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
341
+ 4. Push to the branch (`git push origin my-new-feature`)
342
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,37 @@
1
+ class MyPdf < PdfTempura::Document
2
+ template "spec/assets/sample_pdf_form.pdf"
3
+
4
+ debug :outlines
5
+ debug :grid
6
+ repeatable
7
+
8
+ page 1 do
9
+ text_field "name", [193,641.5], [311.5,25], padding: [0,5,0,5]
10
+ text_field "email", [193,602], [311.5,25.25], padding: [0,5,0,5], bold: true, font_name: "Courier"
11
+ text_field "reason", [54,481], [502,311], padding: [5,5,5,5], multi_line: true, font_size: 18
12
+ checkbox_field "accept", [192,554], [22,22]
13
+
14
+ boxed_characters "pin", [139,146], 20, box_width: 19.75, box_spacing: 0 do
15
+ characters 2
16
+ space 8.5
17
+ characters 3
18
+ space 8
19
+ characters 2
20
+ end
21
+ end
22
+
23
+ page 2 do
24
+ with_default_options alignment: "center" do
25
+ table "table", [57,688], number_of_rows: 16, height: 550,cell_padding: 1 do
26
+ text_column "id",42
27
+ text_column "name",232, padding: [5,5,5,5]
28
+ text_column "email",224, padding: [5,5,5,5]
29
+ end
30
+ end
31
+
32
+ field_set "form" do
33
+ text_field "id", [122,60], [125,27], padding: [5,5,5,5], font_size: 2
34
+ end
35
+ end
36
+
37
+ end