combine_pdf 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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.