combine_pdf 0.2.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e4bac3486fb9fc968d2ca625eb4ad9c0f9423cc7
4
- data.tar.gz: 5d7d3b20987af05c2cf71c2513bf09418125cae3
3
+ metadata.gz: 60f4dfc06ecb66c5c876b69028868bbd5bb7cde9
4
+ data.tar.gz: 5a0944cbfdbc39283fbb62a2205f5897ecbb6dd0
5
5
  SHA512:
6
- metadata.gz: cb03d4476aa78f13d783142c9f91263814d5c9dce299ceb5728dddc79cac0253f4d45ea048953dc69b04fa4ad8416926cd09f05c124ba3b6f3169b827fed86be
7
- data.tar.gz: c3dbbfc3716b9caa49ffc1b98282a266d20ebf66a126d2cd7d8a06699ed196a97491a51ad425e1d0d4dcc940eb87721e5114b9aed3d2511b4f0ae33ec05ebb6a
6
+ metadata.gz: fea4291167b6d5f0585bba371467e552dafbc32aeb957312a28fda7e0431bac20f35c49ee64bf36fac0b7c18ce5d1c89097db18e3af8170318c6401a56c07af7
7
+ data.tar.gz: 329afc35c2754b77b77fec6606be4e6938f535bff5e7bc1e0f1b02bf75dbf077174221448ec86cbcf0109a42e77446a9041079a75fc727bc16503b93d5151b8d
data/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ***
4
4
 
5
+ Change log v.0.2.1
6
+
7
+ **fix**: better page stamping... or, at least more secure (we hope).
8
+
9
+ **feature**: added the PDF#stamp shortcut method. Credit to Tania (@taniarv) for the concept.
10
+
11
+ **fix**: possible string encoding issues could have arose when strings were rendered to PDF format. Credit to Tania (@taniarv) for exposing the issue.
12
+
13
+ **feature**: Metadata is now easiyer to set by allowing fast access to the Information header when using PDF#save and PDF#to_pdf. Credit to Tania (@taniarv) for code.
14
+
15
+ ***
16
+
5
17
  Change log v.0.2.0
6
18
 
7
19
  Refractoring of code and API overhall.
@@ -73,15 +73,12 @@ module CombinePDF
73
73
  if top # if this is a stamp (overlay)
74
74
  insert_content CONTENT_CONTAINER_START, 0
75
75
  insert_content CONTENT_CONTAINER_MIDDLE
76
- obj[:Contents].each {|c| insert_content c }
76
+ self[:Contents].concat obj[:Contents]
77
77
  insert_content CONTENT_CONTAINER_END
78
78
  else #if this was a watermark (underlay? would be lost if the page was scanned, as white might not be transparent)
79
- old_contents = self[:Contents]
80
- self[:Contents] = []
81
- insert_content CONTENT_CONTAINER_START
82
- obj[:Contents].each {|c| insert_content c }
83
- insert_content CONTENT_CONTAINER_MIDDLE
84
- old_contents.each { |c| insert_content c }
79
+ insert_content CONTENT_CONTAINER_MIDDLE, 0
80
+ insert_content CONTENT_CONTAINER_START, 0
81
+ self[:Contents].insert 1, *obj[:Contents]
85
82
  insert_content CONTENT_CONTAINER_END
86
83
  end
87
84
  init_contents
@@ -106,7 +106,7 @@ module CombinePDF
106
106
 
107
107
  # general globals
108
108
  @set_start_id = 1
109
- @info[:Producer] = "Ruby CombinePDF #{CombinePDF::VERSION} Library by B. Segev"
109
+ @info[:Producer] = "Ruby CombinePDF #{CombinePDF::VERSION} Library"
110
110
  @info.delete :CreationDate
111
111
  @info.delete :ModDate
112
112
  end
@@ -149,8 +149,8 @@ module CombinePDF
149
149
  # file_name:: is a string or path object for the output.
150
150
  #
151
151
  # **Notice!** if the file exists, it **WILL** be overwritten.
152
- def save(file_name)
153
- IO.binwrite file_name, to_pdf
152
+ def save(file_name, options = {})
153
+ IO.binwrite file_name, to_pdf(options)
154
154
  end
155
155
 
156
156
  # Formats the data to PDF formats and returns a binary string that represents the PDF file content.
@@ -158,7 +158,7 @@ module CombinePDF
158
158
  # This method is used by the save(file_name) method to save the content to a file.
159
159
  #
160
160
  # use this to export the PDF file without saving to disk (such as sending through HTTP ect').
161
- def to_pdf
161
+ def to_pdf options = {}
162
162
  #reset version if not specified
163
163
  @version = 1.5 if @version.to_f == 0.0
164
164
  #set creation date for merged file
@@ -193,6 +193,9 @@ module CombinePDF
193
193
  out << "/Size #{indirect_object_count.to_s}"
194
194
  if @info.is_a?(Hash)
195
195
  PRIVATE_HASH_KEYS.each {|key| @info.delete key} # make sure the dictionary is rendered inline, without stream
196
+ @info[:CreationDate] = @info[:ModDate] = Time.now.strftime "D:%Y%m%d%H%M%S%:::z'00"
197
+ @info[:Subject] = options[:subject] if options[:subject]
198
+ @info[:Producer] = options[:producer] if options[:producer]
196
199
  out << "/Info #{object_to_pdf @info}"
197
200
  end
198
201
  out << ">>\nstartxref\n#{xref_location.to_s}\n%%EOF"
@@ -336,16 +339,16 @@ module CombinePDF
336
339
  #
337
340
  # options:: a Hash of options setting the behavior and format of the page numbers:
338
341
  # - :number_format a string representing the format for page number. defaults to ' - %s - ' (allows for letter numbering as well, such as "a", "b"...).
339
- # - :number_location an Array containing the location for the page numbers, can be :top, :buttom, :top_left, :top_right, :bottom_left, :bottom_right. defaults to [:top, :buttom].
342
+ # - :location an Array containing the location for the page numbers, can be :top, :buttom, :top_left, :top_right, :bottom_left, :bottom_right or :center (:center == full page). defaults to [:top, :buttom].
340
343
  # - :start_at a Fixnum that sets the number for first page number. also accepts a letter ("a") for letter numbering. defaults to 1.
341
344
  # - :margin_from_height a number (PDF points) for the top and buttom margins. defaults to 45.
342
345
  # - :margin_from_side a number (PDF points) for the left and right margins. defaults to 15.
343
- # the options Hash can also take all the options for PDFWriter#textbox.
346
+ # - :page_range a range of pages to be numbered (i.e. (2..-1) ) defaults to all the pages (nil). Remember to set the :start_at to the correct value.
347
+ # the options Hash can also take all the options for {Page_Methods#textbox}.
344
348
  # defaults to font: :Helvetica, font_size: 12 and no box (:border_width => 0, :box_color => nil).
345
349
  def number_pages(options = {})
346
350
  opt = {
347
351
  number_format: ' - %s - ',
348
- number_location: [:top, :bottom],
349
352
  start_at: 1,
350
353
  font_size: 12,
351
354
  font: :Helvetica,
@@ -353,12 +356,15 @@ module CombinePDF
353
356
  margin_from_side: 15
354
357
  }
355
358
  opt.update options
359
+ opt[:number_location] ||= opt[:stamp_location] ||= opt[:location] ||= [:top, :bottom]
356
360
  page_number = opt[:start_at]
357
- pages.each do |page|
361
+ format_repeater = opt[:number_format].count('%')
362
+ (opt[:page_range] ? pages[opt[:page_range]] : pages).each do |page|
358
363
  # Get page dimensions
359
364
  mediabox = page[:CropBox] || page[:MediaBox] || [0, 0, 595.3, 841.9]
360
365
  # set stamp text
361
- text = opt[:number_format] % page_number
366
+ text = opt[:number_format] % (Array.new(format_repeater) {page_number})
367
+ # text = opt[:number_format] % page_number
362
368
  # compute locations for text boxes
363
369
  text_dimantions = page.dimensions_of( text, opt[:font], opt[:font_size] )
364
370
  box_width = text_dimantions[0] * 1.2
@@ -392,8 +398,36 @@ module CombinePDF
392
398
  if opt[:number_location].include? :bottom_right
393
399
  page.textbox text, {x: right_position, y: bottom_position }.merge(opt)
394
400
  end
401
+ if opt[:number_location].include? :center
402
+ page.textbox text, opt
403
+ end
395
404
  page_number = page_number.succ
396
405
  end
406
+
407
+ end
408
+ # This method stamps all (or some) of the pages is the PDF with the requested stamp.
409
+ #
410
+ # The method accept:
411
+ # stamp:: either a String or a PDF page. If this is a String, you can add formating to add page numbering (i.e. "page number %i"). otherwise remember to escape any percent ('%') sign (i.e. "page \%number not shown\%").
412
+ # options:: an options Hash.
413
+ #
414
+ # If the stamp is a String, than all the options used by {#number_pages} or {Page_Methods#textbox} can be used.
415
+ #
416
+ # If the stamp is a PDF page, only :page_range and :underlay (to reverse-stamp) are valid options.
417
+ def stamp_pages stamp, options = {}
418
+ case stamp
419
+ when String
420
+ number_pages({number_format: stamp}.merge(options))
421
+ when Page_Methods
422
+ # stamp = stamp.copy(true)
423
+ if options[:underlay]
424
+ (options[:page_range] ? pages[options[:page_range]] : pages).each {|p| p >> stamp}
425
+ else
426
+ (options[:page_range] ? pages[options[:page_range]] : pages).each {|p| p << stamp}
427
+ end
428
+ else
429
+ raise TypeError, "expecting a String or a PDF page as the stamp."
430
+ end
397
431
  end
398
432
 
399
433
  end
@@ -34,11 +34,7 @@ module CombinePDF
34
34
  end
35
35
  end
36
36
 
37
- def format_string_to_pdf(object)
38
- object.force_encoding(Encoding::ASCII_8BIT)
39
- if !object.force_encoding(Encoding::ASCII_8BIT).match(/[^D\:\d\+\-\Z\']/) #if format is set to Literal
40
- #### can be better...
41
- replacement_hash = {
37
+ STRING_REPLACEMENT_HASH = {
42
38
  "\x0A" => "\\n",
43
39
  "\x0D" => "\\r",
44
40
  "\x09" => "\\t",
@@ -48,9 +44,13 @@ module CombinePDF
48
44
  "\x29" => "\\)",
49
45
  "\x5C" => "\\\\"
50
46
  }
51
- 32.times {|i| replacement_hash[i.chr] ||= "\\#{i}"}
52
- (256-128).times {|i| replacement_hash[(i + 127).chr] ||= "\\#{i+127}"}
53
- ("(" + ([].tap {|out| object.bytes.each {|byte| replacement_hash[ byte.chr ] ? (replacement_hash[ byte.chr ].bytes.each {|b| out << b}) : out << byte } }).pack('C*') + ")").force_encoding(Encoding::ASCII_8BIT)
47
+ 32.times {|i| STRING_REPLACEMENT_HASH[i.chr] ||= "\\#{i}"}
48
+ (256-128).times {|i| STRING_REPLACEMENT_HASH[(i + 127).chr] ||= "\\#{i+127}"}
49
+
50
+ def format_string_to_pdf(object)
51
+ # object.force_encoding(Encoding::ASCII_8BIT)
52
+ if !object.match(/[^D\:\d\+\-\Z\']/) #if format is set to Literal
53
+ ("(" + ([].tap {|out| object.bytes.each {|byte| STRING_REPLACEMENT_HASH[ byte.chr ] ? (STRING_REPLACEMENT_HASH[ byte.chr ].bytes.each {|b| out << b}) : out << byte } }).pack('C*') + ")").force_encoding(Encoding::ASCII_8BIT)
54
54
  else
55
55
  # A hexadecimal string shall be written as a sequence of hexadecimal digits (0–9 and either A–F or a–f)
56
56
  # encoded as ASCII characters and enclosed within angle brackets (using LESS-THAN SIGN (3Ch) and GREATER- THAN SIGN (3Eh)).
@@ -1,3 +1,3 @@
1
1
  module CombinePDF
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: combine_pdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-26 00:00:00.000000000 Z
11
+ date: 2015-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-rc4
@@ -101,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
101
  version: '0'
102
102
  requirements: []
103
103
  rubyforge_project:
104
- rubygems_version: 2.4.6
104
+ rubygems_version: 2.4.7
105
105
  signing_key:
106
106
  specification_version: 4
107
107
  summary: Combine, stamp and watermark PDF files in pure Ruby.