combine_pdf 0.1.1 → 0.1.2
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.
- checksums.yaml +4 -4
- data/lib/combine_pdf.rb +108 -0
- data/lib/combine_pdf/combine_pdf_basic_writer.rb +12 -7
- data/lib/combine_pdf/combine_pdf_fonts.rb +5 -1
- data/lib/combine_pdf/combine_pdf_pdf.rb +22 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5d50f2ddbf6142442857b65ec46d9565ae774e2
|
4
|
+
data.tar.gz: caaa8ac30c72919c54d28d21a4d30979a40ff41e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0814bd7cfdfbd06d58506dc83f2160099bb6741c60625279850b6d8f525fa970228ce99425223a54998136cecff3593e1530bd0e77f5071d931a173bc26128ff
|
7
|
+
data.tar.gz: 88230912c86e10a0949c63c0a10b358da411a96a615860bd8c62985c2c62ff4d98a05b0fb5982e9f6fab7a6fb3cd8d049254660d6c1c449e84c5922783cf7552
|
data/lib/combine_pdf.rb
CHANGED
@@ -184,6 +184,114 @@ module CombinePDF
|
|
184
184
|
PDFWriter.new mediabox
|
185
185
|
end
|
186
186
|
|
187
|
+
# makes a PDF object containing a table
|
188
|
+
#
|
189
|
+
# all the pages in this PDF object are PDFWriter objects and are
|
190
|
+
# writable using the texbox function (should you wish to add a title, or more info)
|
191
|
+
#
|
192
|
+
# the main intended use of this method is to create indexes (a table of contents) for merged data.
|
193
|
+
#
|
194
|
+
# example:
|
195
|
+
# pdf = CombinePDF.new_table headers: ["header 1", "another header"], table_data: [ ["this is one row", "with two columns"] , ["this is another row", "also two columns", "the third will be ignored"] ]
|
196
|
+
# pdf.save "table_file.pdf"
|
197
|
+
#
|
198
|
+
# accepts a Hash with any of the following keys as well as any of the PDFWriter#textbox options:
|
199
|
+
# headers:: an Array of strings with the headers (will be repeated every page).
|
200
|
+
# table_data:: as Array of Arrays, each containing a string for each column. the first row sets the number of columns. extra columns will be ignored.
|
201
|
+
# font:: a registered or standard font name (see PDFWriter). defaults to nil (:Helvetica).
|
202
|
+
# header_font:: a registered or standard font name for the headers (see PDFWriter). defaults to nil (the font for all the table rows).
|
203
|
+
# max_font_size:: the maximum font size. if the string doesn't fit, it will be resized. defaults to 14.
|
204
|
+
# column_widths:: an array of relative column widths ([1,2] will display only the first two columns, the second twice as big as the first). defaults to nil (even widths).
|
205
|
+
# header_color:: the header color. defaults to [0.8, 0.8, 0.8] (light gray).
|
206
|
+
# main_color:: main row color. defaults to nil (transparent / white).
|
207
|
+
# alternate_color: alternate row color. defaults to [0.95, 0.95, 0.95] (very light gray).
|
208
|
+
# font_color: font color. defaults to [0,0,0] (black).
|
209
|
+
# border_color: border color. defaults to [0,0,0] (black).
|
210
|
+
# border_width: border width in PDF units. defaults to 1.
|
211
|
+
# header_align: the header text alignment within each column (:right, :left, :center). defaults to :center.
|
212
|
+
# row_align:: the row text alignment within each column. defaults to :left (:right for RTL table).
|
213
|
+
# direction: the table's writing direction (:ltr or :rtl). this reffers to the direction of the columns and doesn't effect text (rtl text is automatically recognized). defaults to :ltr.
|
214
|
+
# rows_per_page: the number of rows per page, INCLUDING the header row. deafults to 25.
|
215
|
+
# page_size: the size of the page in PDF points. defaults to [0, 0, 595.3, 841.9] (A4).
|
216
|
+
def new_table (options = {})
|
217
|
+
defaults = {
|
218
|
+
headers: nil,
|
219
|
+
table_data: [[]],
|
220
|
+
font: nil,
|
221
|
+
header_font: nil,
|
222
|
+
max_font_size: 14,
|
223
|
+
column_widths: nil,
|
224
|
+
header_color: [0.8, 0.8, 0.8],
|
225
|
+
main_color: nil,
|
226
|
+
alternate_color: [0.95, 0.95, 0.95],
|
227
|
+
font_color: [0,0,0],
|
228
|
+
border_color: [0,0,0],
|
229
|
+
border_width: 1,
|
230
|
+
header_align: :center,
|
231
|
+
row_align: nil,
|
232
|
+
direction: :ltr,
|
233
|
+
rows_per_page: 25,
|
234
|
+
page_size: [0, 0, 595.3, 841.9] #A4
|
235
|
+
}
|
236
|
+
options = defaults.merge options
|
237
|
+
options[:header_font] = options[:font] unless options[:header_font]
|
238
|
+
options[:row_align] ||= ( (options[:direction] == :rtl) ? :right : :left )
|
239
|
+
# assert table_data is an array of arrays
|
240
|
+
return false unless (options[:table_data].select {|r| !r.is_a?(Array) }).empty?
|
241
|
+
# compute sizes
|
242
|
+
page_size = options[:page_size]
|
243
|
+
top = page_size[3] * 0.9
|
244
|
+
height = page_size[3] * 0.8 / options[:rows_per_page]
|
245
|
+
from_side = page_size[2] * 0.1
|
246
|
+
width = page_size[2] * 0.8
|
247
|
+
columns = options[:table_data][0].length
|
248
|
+
column_widths = []
|
249
|
+
columns.times {|i| column_widths << (width/columns) }
|
250
|
+
if options[:column_widths]
|
251
|
+
scale = 0
|
252
|
+
options[:column_widths].each {|w| scale += w}
|
253
|
+
column_widths = []
|
254
|
+
options[:column_widths].each { |w| column_widths << (width*w/scale) }
|
255
|
+
end
|
256
|
+
column_widths = column_widths.reverse if options[:direction] == :rtl
|
257
|
+
# set pdf object and start writing the data
|
258
|
+
table = PDF.new()
|
259
|
+
page = nil
|
260
|
+
rows_per_page = options[:rows_per_page]
|
261
|
+
row_number = rows_per_page + 1
|
262
|
+
|
263
|
+
options[:table_data].each do |row_data|
|
264
|
+
if row_number > rows_per_page
|
265
|
+
page = create_page page_size
|
266
|
+
table << page
|
267
|
+
row_number = 1
|
268
|
+
# add headers
|
269
|
+
if options[:headers]
|
270
|
+
x = from_side
|
271
|
+
headers = options[:headers]
|
272
|
+
headers = headers.reverse if options[:direction] == :rtl
|
273
|
+
column_widths.each_index do |i|
|
274
|
+
text = headers[i].to_s
|
275
|
+
page.textbox text, {x: x, y: (top - (height*row_number)), width: column_widths[i], height: height, box_color: options[:header_color], text_align: options[:header_align] }.merge(options).merge({font: options[:header_font]})
|
276
|
+
x += column_widths[i]
|
277
|
+
end
|
278
|
+
row_number += 1
|
279
|
+
end
|
280
|
+
end
|
281
|
+
x = from_side
|
282
|
+
row_data = row_data.reverse if options[:direction] == :rtl
|
283
|
+
column_widths.each_index do |i|
|
284
|
+
text = row_data[i].to_s
|
285
|
+
box_color = options[:main_color]
|
286
|
+
box_color = options[:alternate_color] if options[:alternate_color] && row_number.odd?
|
287
|
+
page.textbox text, {x: x, y: (top - (height*row_number)), width: column_widths[i], height: height, box_color: box_color, text_align: options[:row_align]}.merge(options)
|
288
|
+
x += column_widths[i]
|
289
|
+
end
|
290
|
+
row_number += 1
|
291
|
+
end
|
292
|
+
table
|
293
|
+
end
|
294
|
+
|
187
295
|
# adds a correctly formatted font object to the font library.
|
188
296
|
#
|
189
297
|
# registered fonts will remain in the library and will only be embeded in
|
@@ -72,6 +72,7 @@ module CombinePDF
|
|
72
72
|
# height:: the height of the box. negative values will be computed from edge of page. defaults to 0 (end of page).
|
73
73
|
# text_align:: symbol for horizontal text alignment, can be ":center" (default), ":right", ":left"
|
74
74
|
# text_valign:: symbol for vertical text alignment, can be ":center" (default), ":top", ":buttom"
|
75
|
+
# text_padding:: a Float between 0 and 1, setting the padding for the text. defaults to 0.05 (5%).
|
75
76
|
# font:: a registered font name or an Array of names. defaults to ":Helvetica". The 14 standard fonts names are:
|
76
77
|
# - :"Times-Roman"
|
77
78
|
# - :"Times-Bold"
|
@@ -105,6 +106,7 @@ module CombinePDF
|
|
105
106
|
height: -1,
|
106
107
|
text_align: :center,
|
107
108
|
text_valign: :center,
|
109
|
+
text_padding: 0.1,
|
108
110
|
font: nil,
|
109
111
|
font_size: :fit_text,
|
110
112
|
max_font_size: nil,
|
@@ -122,6 +124,9 @@ module CombinePDF
|
|
122
124
|
options[:width] = mediabox[2] - options[:x] + options[:width] if options[:width] <= 0
|
123
125
|
options[:height] = mediabox[3] - options[:y] + options[:height] if options[:height] <= 0
|
124
126
|
|
127
|
+
# reset the padding value
|
128
|
+
options[:text_padding] = 0 if options[:text_padding].to_f >= 1
|
129
|
+
|
125
130
|
# create box stream
|
126
131
|
box_stream = ""
|
127
132
|
# set graphic state for box
|
@@ -199,29 +204,29 @@ module CombinePDF
|
|
199
204
|
text_stream = ""
|
200
205
|
if text.to_s != "" && options[:font_size] != 0 && (options[:font_color] || options[:stroke_color])
|
201
206
|
# compute x and y position for text
|
202
|
-
x = options[:x]
|
203
|
-
y = options[:y]
|
207
|
+
x = options[:x] + (options[:width]*options[:text_padding])
|
208
|
+
y = options[:y] + (options[:height]*options[:text_padding])
|
204
209
|
|
205
210
|
# set the fonts (fonts array, with :Helvetica as fallback).
|
206
211
|
fonts = [*options[:font], :Helvetica]
|
207
212
|
# fit text in box, if requested
|
208
213
|
font_size = options[:font_size]
|
209
214
|
if options[:font_size] == :fit_text
|
210
|
-
font_size = self.fit_text text, fonts, options[:width], options[:height]
|
215
|
+
font_size = self.fit_text text, fonts, (options[:width]*(1-options[:text_padding])), (options[:height]*(1-options[:text_padding]))
|
211
216
|
font_size = options[:max_font_size] if options[:max_font_size] && font_size > options[:max_font_size]
|
212
217
|
end
|
213
218
|
|
214
219
|
text_size = dimensions_of text, fonts, font_size
|
215
220
|
|
216
221
|
if options[:text_align] == :center
|
217
|
-
x = (options[:width] - text_size[0])/2 + x
|
222
|
+
x = ( ( options[:width]*(1-(2*options[:text_padding])) ) - text_size[0] )/2 + x
|
218
223
|
elsif options[:text_align] == :right
|
219
|
-
x = (options[:width] - text_size[0]) + x
|
224
|
+
x = ( ( options[:width]*(1-(1.5*options[:text_padding])) ) - text_size[0] ) + x
|
220
225
|
end
|
221
226
|
if options[:text_valign] == :center
|
222
|
-
y = (options[:height] - text_size[1])/2 + y
|
227
|
+
y = ( ( options[:height]*(1-(2*options[:text_padding])) ) - text_size[1] )/2 + y
|
223
228
|
elsif options[:text_valign] == :top
|
224
|
-
y = (options[:height] - text_size[1]
|
229
|
+
y = ( options[:height]*(1-(1.5*options[:text_padding])) ) - text_size[1] + y
|
225
230
|
end
|
226
231
|
|
227
232
|
# set graphic state for text
|
@@ -217,7 +217,11 @@ module CombinePDF
|
|
217
217
|
old_widths = font_object[:DescendantFonts]
|
218
218
|
old_widths = old_widths[:referenced_object][:indirect_without_dictionary] if old_widths[:is_reference_only]
|
219
219
|
old_widths = old_widths[0][:referenced_object]
|
220
|
-
|
220
|
+
avrg_height = 360
|
221
|
+
avrg_height = old_widths[:XHeight] if old_widths[:XHeight]
|
222
|
+
avrg_height = (avrg_height + old_widths[:CapHeight])/2 if old_widths[:CapHeight]
|
223
|
+
avrg_width = old_widths[:AvgWidth] || 0
|
224
|
+
avarage_bbox = [0, 0, avrg_width, avrg_height] # data is missing for full box metrics, just ignore
|
221
225
|
end
|
222
226
|
|
223
227
|
# compute the metrics values using the appropiate system (TrueType vs. Type0 fonts)
|
@@ -87,17 +87,32 @@ module CombinePDF
|
|
87
87
|
@info = {}
|
88
88
|
if args[0].is_a? PDFParser
|
89
89
|
@objects = args[0].parse
|
90
|
+
# connecting references with original objects
|
91
|
+
serialize_objects_and_references
|
92
|
+
# make sure there is only one Catalog (the latest Catalog)
|
93
|
+
if args[0].root_object[:Root]
|
94
|
+
@objects.delete_if {|obj| obj[:Type] == :Catalog}
|
95
|
+
@objects << args[0].root_object[:Root]
|
96
|
+
else
|
97
|
+
last_calalog = (@objects.select {|obj| obj[:Type] == :Catalog}).last
|
98
|
+
unless last_calalog.nil?
|
99
|
+
@objects.delete_if {|obj| obj[:Type] == :Catalog}
|
100
|
+
@objects << last_calalog
|
101
|
+
end
|
102
|
+
end
|
90
103
|
@version = args[0].version if args[0].version.is_a? Float
|
91
104
|
@info = args[0].info_object || {}
|
92
105
|
elsif args[0].is_a? Array
|
93
106
|
# object initialization
|
94
107
|
@objects = args[0]
|
95
108
|
@version = args[1] if args[1].is_a? Float
|
109
|
+
# connecting references with original objects
|
110
|
+
serialize_objects_and_references
|
96
111
|
elsif args[0].is_a? Hash
|
97
112
|
@objects = args
|
113
|
+
# connecting references with original objects
|
114
|
+
serialize_objects_and_references
|
98
115
|
end
|
99
|
-
# connecting references with original objects
|
100
|
-
serialize_objects_and_references
|
101
116
|
# general globals
|
102
117
|
@string_output = :literal
|
103
118
|
@need_to_rebuild_resources = false
|
@@ -224,6 +239,10 @@ module CombinePDF
|
|
224
239
|
self
|
225
240
|
end
|
226
241
|
end
|
242
|
+
catalogs[:MediaBox] ||= catalogs[:Parent][:referenced_object][:MediaBox] if catalogs[:Parent].is_a?(Hash) && catalogs[:Parent][:referenced_object].is_a?(Hash) && catalogs[:Parent][:referenced_object][:MediaBox]
|
243
|
+
catalogs[:CropBox] ||= catalogs[:Parent][:referenced_object][:CropBox] if catalogs[:CropBox].is_a?(Hash) && catalogs[:CropBox][:referenced_object].is_a?(Hash) && catalogs[:Parent][:referenced_object][:CropBox]
|
244
|
+
catalogs[:MediaBox] = catalogs[:MediaBox][:referenced_object][:indirect_without_dictionary] if catalogs[:MediaBox].is_a?(Hash) && catalogs[:MediaBox][:referenced_object].is_a?(Hash) && catalogs[:MediaBox][:referenced_object][:indirect_without_dictionary]
|
245
|
+
catalogs[:CropBox] = catalogs[:CropBox][:referenced_object][:indirect_without_dictionary] if catalogs[:CropBox].is_a?(Hash) && catalogs[:CropBox][:referenced_object].is_a?(Hash) && catalogs[:CropBox][:referenced_object][:indirect_without_dictionary]
|
227
246
|
page_list << catalogs
|
228
247
|
when :Pages
|
229
248
|
page_list.push *(pages(catalogs[:Kids])) unless catalogs[:Kids].nil?
|
@@ -330,11 +349,8 @@ module CombinePDF
|
|
330
349
|
page_number = opt[:start_at]
|
331
350
|
pages.each do |page|
|
332
351
|
# create a "stamp" PDF page with the same size as the target page
|
333
|
-
mediabox = page[:MediaBox]
|
352
|
+
mediabox = page[:CropBox] || page[:MediaBox] || [0, 0, 595.3, 841.9]
|
334
353
|
stamp = PDFWriter.new mediabox
|
335
|
-
# set the visible dimensions to the CropBox, if it exists.
|
336
|
-
cropbox = page[:CropBox]
|
337
|
-
mediabox = cropbox if cropbox
|
338
354
|
# set stamp text
|
339
355
|
text = opt[:number_format] % page_number
|
340
356
|
# compute locations for text boxes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: combine_pdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-09-
|
12
|
+
date: 2014-09-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ruby-rc4
|