combine_pdf 1.0.13 → 1.0.19
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/CHANGELOG.md +28 -0
- data/README.md +40 -1
- data/combine_pdf.gemspec +2 -2
- data/lib/combine_pdf.rb +1 -0
- data/lib/combine_pdf/api.rb +6 -6
- data/lib/combine_pdf/fonts.rb +13 -4
- data/lib/combine_pdf/page_methods.rb +8 -8
- data/lib/combine_pdf/parser.rb +28 -2
- data/lib/combine_pdf/pdf_protected.rb +41 -11
- data/lib/combine_pdf/pdf_public.rb +4 -4
- data/lib/combine_pdf/version.rb +1 -1
- metadata +7 -22
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: acb1b817f13695dc04d7e0a3575ef90a9cc93408400c7aa3aab58a6bb42495b5
         | 
| 4 | 
            +
              data.tar.gz: 18a65db68ae2f75e9778ddfdd4ca9fbb6ad0f606420bac9632dc492e5310ccc6
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: c54f717182c8d1403be7e2019bc2a97b491b08a08c45e0e9cb2c66d334495cff6c15c78916654ea776469d8d2d764b20ab5c9074d313b62eaa0d41dcc1d21dd1
         | 
| 7 | 
            +
              data.tar.gz: a9b4989550754718a2799547484e20b94a4515631bdab15e67002a574b2f33b9b32485f11c273bde0321d8f314e9b57620f0b48fdf41bc4694fc6b8098dc7b92
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -2,6 +2,34 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            ***
         | 
| 4 4 |  | 
| 5 | 
            +
            #### Change log v.1.0.19
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            **Fix**: fixes font height and width detection issue. Issue #179. Credit to @5anchezzz for opening the issue.
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            **Fix**: fixes an indentation warning. Issue #173. Credit to @rubyFeedback for exposing this issue.
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            #### Change log v.1.0.18
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            **Fix**: fixed issue with the 1.0.17 release where `ProcSet` PDF Arrays should have been expected but where ignored and a PDF Object was assumed instead (issue #171) - credit to @chuchiperriman (Jesús Barbero Rodríguez).
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            #### Change log v.1.0.17
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            NB: yanked from RubyGems.org.
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            **Fix**: fixed issue where nested structure equality tests might provide false positives, resulting in lost data (issue #166) - credit to @cschilbe (Conrad Schilbe).
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            #### Change log v.1.0.16
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            **Fix**: some documentation typos were fixed (PR #147) - credit to @djhopper01 (Derek Hopper).
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            #### Change log v.1.0.15
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            **Fix**: An attempt to fix JRuby compatibility concerns (issue #127).
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            #### Change log v.1.0.14
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            **Fix**: Fixed an issue related to PDF XRef table data, where a malformed EOL marker would cause the parser to fail. Credit to @dangerous (David Rainsford) for exposing this issue in a comment to issue #140.
         | 
| 32 | 
            +
             | 
| 5 33 | 
             
            #### Change log v.1.0.13
         | 
| 6 34 |  | 
| 7 35 | 
             
            **Fix**: Fixed an issue related to PDF object streams (version 1.6) where a numerical object at the beginning of the stream might be mis-parsed as an object reference number rather than an object. Credit to @Defoncesko for reporting issue #141.
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,8 +1,10 @@ | |
| 1 1 | 
             
            # CombinePDF - the ruby way for merging PDF files
         | 
| 2 2 | 
             
            [](http://badge.fury.io/rb/combine_pdf)
         | 
| 3 3 | 
             
            [](https://github.com/boazsegev/combine_pdf)
         | 
| 4 | 
            +
            [](https://www.rubydoc.info/github/boazsegev/combine_pdf)
         | 
| 4 5 | 
             
            [](https://github.com/pickhardt/maintainers-wanted)
         | 
| 5 6 |  | 
| 7 | 
            +
             | 
| 6 8 | 
             
            CombinePDF is a nifty model, written in pure Ruby, to parse PDF files and combine (merge) them with other PDF files, watermark them or stamp them (all using the PDF file format and pure Ruby code).
         | 
| 7 9 |  | 
| 8 10 | 
             
            ## Install
         | 
| @@ -41,6 +43,8 @@ Quick rundown: | |
| 41 43 |  | 
| 42 44 | 
             
            * Sometimes the CombinePDF will raise an exception even if the PDF could be parsed (i.e., when PDF optional content exists)... I find it better to err on the side of caution, although for optional content PDFs an exception is avoidable using `CombinePDF.load(pdf_file, allow_optional_content: true)`.
         | 
| 43 45 |  | 
| 46 | 
            +
            * The CombinePDF gem runs recursive code to both parse and format the PDF files. Hence, PDF files that have heavily nested objects, as well as those that where combined in a way that results in cyclic nesting, might explode the stack - resulting in an exception or program failure.
         | 
| 47 | 
            +
             | 
| 44 48 | 
             
            CombinePDF is written natively in Ruby and should (presumably) work on all Ruby platforms that follow Ruby 2.0 compatibility.
         | 
| 45 49 |  | 
| 46 50 | 
             
            However, PDF files are quite complex creatures and no guaranty is provided.
         | 
| @@ -112,7 +116,42 @@ pdf.number_pages | |
| 112 116 | 
             
            pdf.save "file_with_numbering.pdf"
         | 
| 113 117 | 
             
            ```
         | 
| 114 118 |  | 
| 115 | 
            -
            Numbering can be done with many different options, with different formating, with or without a box object, and even with opacity values - see documentation.
         | 
| 119 | 
            +
            Numbering can be done with many different options, with different formating, with or without a box object, and even with opacity values - [see documentation](https://www.rubydoc.info/github/boazsegev/combine_pdf/CombinePDF/PDF#number_pages-instance_method).
         | 
| 120 | 
            +
             | 
| 121 | 
            +
            For example, should you prefer to place the page number on the bottom right side of all PDF pages, do:
         | 
| 122 | 
            +
             | 
| 123 | 
            +
            ```ruby
         | 
| 124 | 
            +
            pdf.number_pages(location: [:bottom_right])
         | 
| 125 | 
            +
            ```
         | 
| 126 | 
            +
             | 
| 127 | 
            +
            As another example, the dashes around the number are removed and a box is placed around it. The numbering is semi-transparent and the first 3 pages are numbered using letters (a,b,c) rather than numbers:
         | 
| 128 | 
            +
             | 
| 129 | 
            +
             | 
| 130 | 
            +
            ```ruby
         | 
| 131 | 
            +
            # number first 3 pages as "a", "b", "c"
         | 
| 132 | 
            +
            pdf.number_pages(number_format: " %s ",
         | 
| 133 | 
            +
                             location: [:top, :bottom, :top_left, :top_right, :bottom_left, :bottom_right],
         | 
| 134 | 
            +
                             start_at: "a",
         | 
| 135 | 
            +
                             page_range: (0..2),
         | 
| 136 | 
            +
                             box_color: [0.8,0.8,0.8],
         | 
| 137 | 
            +
                             border_color: [0.4, 0.4, 0.4],
         | 
| 138 | 
            +
                             border_width: 1,
         | 
| 139 | 
            +
                             box_radius: 6,
         | 
| 140 | 
            +
                             opacity: 0.75)
         | 
| 141 | 
            +
            # number the rest of the pages as 4, 5, ... etc'
         | 
| 142 | 
            +
            pdf.number_pages(number_format: " %s ",
         | 
| 143 | 
            +
                             location: [:top, :bottom, :top_left, :top_right, :bottom_left, :bottom_right],
         | 
| 144 | 
            +
                             start_at: 4,
         | 
| 145 | 
            +
                             page_range: (3..-1),
         | 
| 146 | 
            +
                             box_color: [0.8,0.8,0.8],
         | 
| 147 | 
            +
                             border_color: [0.4, 0.4, 0.4],
         | 
| 148 | 
            +
                             border_width: 1,
         | 
| 149 | 
            +
                             box_radius: 6,
         | 
| 150 | 
            +
                             opacity: 0.75)
         | 
| 151 | 
            +
            ```
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                pdf.number_pages(number_format: " %s ", location: :bottom_right, font_size: 44)
         | 
| 154 | 
            +
             | 
| 116 155 |  | 
| 117 156 | 
             
            ## Loading and Parsing PDF data
         | 
| 118 157 |  | 
    
        data/combine_pdf.gemspec
    CHANGED
    
    | @@ -20,7 +20,7 @@ Gem::Specification.new do |spec| | |
| 20 20 |  | 
| 21 21 | 
             
              spec.add_runtime_dependency 'ruby-rc4', '>= 0.1.5'
         | 
| 22 22 |  | 
| 23 | 
            -
              spec.add_development_dependency "bundler", " | 
| 24 | 
            -
              spec.add_development_dependency "rake", " | 
| 23 | 
            +
              # spec.add_development_dependency "bundler", ">= 1.7"
         | 
| 24 | 
            +
              spec.add_development_dependency "rake", ">= 12.3.3"
         | 
| 25 25 | 
             
              spec.add_development_dependency "minitest"
         | 
| 26 26 | 
             
            end
         | 
    
        data/lib/combine_pdf.rb
    CHANGED
    
    
    
        data/lib/combine_pdf/api.rb
    CHANGED
    
    | @@ -24,11 +24,11 @@ module CombinePDF | |
| 24 24 | 
             
                raise TypeError, "couldn't create PDF object, expecting type String" unless string.is_a?(String) || string.is_a?(Pathname)
         | 
| 25 25 | 
             
                begin
         | 
| 26 26 | 
             
                  (begin
         | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 27 | 
            +
                    File.file? string
         | 
| 28 | 
            +
                  rescue
         | 
| 29 | 
            +
                    false
         | 
| 30 | 
            +
                  end) ? load(string) : parse(string)
         | 
| 31 | 
            +
                rescue => _e
         | 
| 32 32 | 
             
                  raise 'General PDF error - Use CombinePDF.load or CombinePDF.parse for a non-general error message (the requested file was not found OR the string received is not a valid PDF stream OR the file was found but not valid).'
         | 
| 33 33 | 
             
                end
         | 
| 34 34 | 
             
              end
         | 
| @@ -140,7 +140,7 @@ module CombinePDF | |
| 140 140 | 
             
              # this function enables plug-ins to expend the font functionality of CombinePDF.
         | 
| 141 141 | 
             
              #
         | 
| 142 142 | 
             
              # font_name:: a Symbol with the name of the font. if the fonts exists in the library, it will be overwritten!
         | 
| 143 | 
            -
              # font_metrics:: a Hash of font metrics, of the format char => {wx: char_width, boundingbox: [left_x,  | 
| 143 | 
            +
              # font_metrics:: a Hash of font metrics, of the format char => {wx: char_width, boundingbox: [left_x, bottom_y, right_x, top_y]} where char == character itself (i.e. " " for space). The Hash should contain a special value :missing for the metrics of missing characters. an optional :wy might be supported in the future, for up to down fonts.
         | 
| 144 144 | 
             
              # font_pdf_object:: a Hash in the internal format recognized by CombinePDF, that represents the font object.
         | 
| 145 145 | 
             
              # font_cmap:: a CMap dictionary Hash) which maps unicode characters to the hex CID for the font (i.e. {"a" => "61", "z" => "7a" }).
         | 
| 146 146 | 
             
              def register_font(font_name, font_metrics, font_pdf_object, font_cmap = nil)
         | 
    
        data/lib/combine_pdf/fonts.rb
    CHANGED
    
    | @@ -100,7 +100,7 @@ module CombinePDF | |
| 100 100 |  | 
| 101 101 | 
             
                # adds a correctly formatted font object to the font library.
         | 
| 102 102 | 
             
                # font_name:: a Symbol with the name of the font. if the fonts name exists, the font will be overwritten!
         | 
| 103 | 
            -
                # font_metrics:: a Hash of ont metrics, of the format char => {wx: char_width, boundingbox: [left_x,  | 
| 103 | 
            +
                # font_metrics:: a Hash of ont metrics, of the format char => {wx: char_width, boundingbox: [left_x, bottom_y, right_x, top_y]} where i == character code (i.e. 32 for space). The Hash should contain a special value :missing for the metrics of missing characters. an optional :wy will be supported in the future, for up to down fonts.
         | 
| 104 104 | 
             
                # font_pdf_object:: a Hash in the internal format recognized by CombinePDF, that represents the font object.
         | 
| 105 105 | 
             
                # font_cmap:: a CMap dictionary Hash) which maps unicode characters to the hex CID for the font (i.e. {"a" => "61", "z" => "7a" }).
         | 
| 106 106 | 
             
                def register_font(font_name, font_metrics, font_pdf_object, font_cmap = nil)
         | 
| @@ -138,12 +138,21 @@ module CombinePDF | |
| 138 138 | 
             
                  text.each_char do |c|
         | 
| 139 139 | 
             
                    metrics_array << (merged_metrics[c] || { wx: 0, boundingbox: [0, 0, 0, 0] })
         | 
| 140 140 | 
             
                  end
         | 
| 141 | 
            -
                   | 
| 142 | 
            -
                   | 
| 141 | 
            +
                  metrics_array_mapped_top = [].dup
         | 
| 142 | 
            +
                  metrics_array_mapped_bottom = [].dup
         | 
| 143 143 | 
             
                  width = 0.0
         | 
| 144 144 | 
             
                  metrics_array.each do |m|
         | 
| 145 | 
            -
                     | 
| 145 | 
            +
                    if (m && m[:boundingbox])
         | 
| 146 | 
            +
                      metrics_array_mapped_top << m[:boundingbox][3]
         | 
| 147 | 
            +
                      metrics_array_mapped_bottom << m[:boundingbox][1]
         | 
| 148 | 
            +
                    else
         | 
| 149 | 
            +
                      metrics_array_mapped_top << 0
         | 
| 150 | 
            +
                      metrics_array_mapped_bottom << 0
         | 
| 151 | 
            +
                    end
         | 
| 152 | 
            +
                    width += (m[:wx] || m[:wy] || 0) if m
         | 
| 146 153 | 
             
                  end
         | 
| 154 | 
            +
                  height = metrics_array_mapped_top.max
         | 
| 155 | 
            +
                  height -=metrics_array_mapped_bottom.min
         | 
| 147 156 | 
             
                  return [height.to_f / 1000 * size, width.to_f / 1000 * size] if metrics_array[0][:wy]
         | 
| 148 157 | 
             
                  [width.to_f / 1000 * size, height.to_f / 1000 * size]
         | 
| 149 158 | 
             
                end
         | 
| @@ -94,7 +94,7 @@ module CombinePDF | |
| 94 94 | 
             
                  # end
         | 
| 95 95 |  | 
| 96 96 | 
             
                  # set ProcSet to recommended value
         | 
| 97 | 
            -
                  resources[:ProcSet]  | 
| 97 | 
            +
                  resources[:ProcSet] ||= [:PDF, :Text, :ImageB, :ImageC, :ImageI] # this was recommended by the ISO. 32000-1:2008
         | 
| 98 98 |  | 
| 99 99 | 
             
                  if top # if this is a stamp (overlay)
         | 
| 100 100 | 
             
                    insert_content CONTENT_CONTAINER_START, 0
         | 
| @@ -147,15 +147,15 @@ module CombinePDF | |
| 147 147 |  | 
| 148 148 | 
             
                # This method adds a simple text box to the Page represented by the PDFWriter class.
         | 
| 149 149 | 
             
                # This function takes two values:
         | 
| 150 | 
            -
                # text:: the text to  | 
| 150 | 
            +
                # text:: the text to write in the box.
         | 
| 151 151 | 
             
                # properties:: a Hash of box properties.
         | 
| 152 152 | 
             
                # the symbols and values in the properties Hash could be any or all of the following:
         | 
| 153 153 | 
             
                # x:: the left position of the box.
         | 
| 154 | 
            -
                # y:: the  | 
| 154 | 
            +
                # y:: the BOTTOM position of the box.
         | 
| 155 155 | 
             
                # width:: the width/length of the box. negative values will be computed from edge of page. defaults to 0 (end of page).
         | 
| 156 156 | 
             
                # height:: the height of the box. negative values will be computed from edge of page. defaults to 0 (end of page).
         | 
| 157 157 | 
             
                # text_align:: symbol for horizontal text alignment, can be ":center" (default), ":right", ":left"
         | 
| 158 | 
            -
                # text_valign:: symbol for vertical text alignment, can be ":center" (default), ":top", ": | 
| 158 | 
            +
                # text_valign:: symbol for vertical text alignment, can be ":center" (default), ":top", ":bottom"
         | 
| 159 159 | 
             
                # text_padding:: a Float between 0 and 1, setting the padding for the text. defaults to 0.05 (5%).
         | 
| 160 160 | 
             
                # font:: a registered font name or an Array of names. defaults to ":Helvetica". The 14 standard fonts names are:
         | 
| 161 161 | 
             
                # - :"Times-Roman"
         | 
| @@ -244,8 +244,8 @@ module CombinePDF | |
| 244 244 | 
             
                    half_radius = (radius.to_f / 2).round 4
         | 
| 245 245 | 
             
                    ## set starting point
         | 
| 246 246 | 
             
                    box_stream << "#{options[:x] + radius} #{options[:y]} m\n"
         | 
| 247 | 
            -
                    ##  | 
| 248 | 
            -
                    box_stream << "#{options[:x] + options[:width] - radius} #{options[:y]} l\n" #  | 
| 247 | 
            +
                    ## bottom and right corner - first line and first corner
         | 
| 248 | 
            +
                    box_stream << "#{options[:x] + options[:width] - radius} #{options[:y]} l\n" # bottom
         | 
| 249 249 | 
             
                    if options[:box_radius] != 0 # make first corner, if not straight.
         | 
| 250 250 | 
             
                      box_stream << "#{options[:x] + options[:width] - half_radius} #{options[:y]} "
         | 
| 251 251 | 
             
                      box_stream << "#{options[:x] + options[:width]} #{options[:y] + half_radius} "
         | 
| @@ -265,7 +265,7 @@ module CombinePDF | |
| 265 265 | 
             
                      box_stream << "#{options[:x]} #{options[:y] + options[:height] - half_radius} "
         | 
| 266 266 | 
             
                      box_stream << "#{options[:x]} #{options[:y] + options[:height] - radius} c\n"
         | 
| 267 267 | 
             
                    end
         | 
| 268 | 
            -
                    ## left and  | 
| 268 | 
            +
                    ## left and bottom-left corner
         | 
| 269 269 | 
             
                    box_stream << "#{options[:x]} #{options[:y] + radius} l\n"
         | 
| 270 270 | 
             
                    if options[:box_radius] != 0
         | 
| 271 271 | 
             
                      box_stream << "#{options[:x]} #{options[:y] + half_radius} "
         | 
| @@ -287,7 +287,7 @@ module CombinePDF | |
| 287 287 | 
             
                  end
         | 
| 288 288 | 
             
                  contents << box_stream
         | 
| 289 289 |  | 
| 290 | 
            -
                  # reset x,y by text alignment - x,y are calculated from the  | 
| 290 | 
            +
                  # reset x,y by text alignment - x,y are calculated from the bottom left
         | 
| 291 291 | 
             
                  # each unit (1) is 1/72 Inch
         | 
| 292 292 | 
             
                  # create text stream
         | 
| 293 293 | 
             
                  text_stream = ''
         | 
    
        data/lib/combine_pdf/parser.rb
    CHANGED
    
    | @@ -233,16 +233,18 @@ module CombinePDF | |
| 233 233 | 
             
                    # all characters that aren't white space or special: /[^\x00\x09\x0a\x0c\x0d\x20\x28\x29\x3c\x3e\x5b\x5d\x7b\x7d\x2f\x25]+
         | 
| 234 234 | 
             
                    elsif str = @scanner.scan(/\/[^\x00\x09\x0a\x0c\x0d\x20\x28\x29\x3c\x3e\x5b\x5d\x7b\x7d\x2f\x25]*/)
         | 
| 235 235 | 
             
                      out << (str[1..-1].gsub(/\#[0-9a-fA-F]{2}/) { |a| a[1..2].hex.chr }).to_sym
         | 
| 236 | 
            +
                      # warn "CombinePDF detected name: #{out.last.to_s}"
         | 
| 236 237 | 
             
                    ##########################################
         | 
| 237 238 | 
             
                    ## Parse a Number
         | 
| 238 239 | 
             
                    ##########################################
         | 
| 239 240 | 
             
                    elsif str = @scanner.scan(/[\+\-\.\d]+/)
         | 
| 240 241 | 
             
                      str =~ /\./ ? (out << str.to_f) : (out << str.to_i)
         | 
| 242 | 
            +
                      # warn "CombinePDF detected number: #{out.last.to_s}"
         | 
| 241 243 | 
             
                    ##########################################
         | 
| 242 244 | 
             
                    ## parse a Hex String
         | 
| 243 245 | 
             
                    ##########################################
         | 
| 244 246 | 
             
                    elsif str = @scanner.scan(/\<[0-9a-fA-F]*\>/)
         | 
| 245 | 
            -
                      # warn "Found a hex string"
         | 
| 247 | 
            +
                      # warn "Found a hex string #{str}"
         | 
| 246 248 | 
             
                      str = str.slice(1..-2).force_encoding(Encoding::ASCII_8BIT)
         | 
| 247 249 | 
             
                      # str = "0#{str}" if str.length.odd?
         | 
| 248 250 | 
             
                      out << unify_string([str].pack('H*').force_encoding(Encoding::ASCII_8BIT))
         | 
| @@ -336,6 +338,7 @@ module CombinePDF | |
| 336 338 | 
             
                        end
         | 
| 337 339 | 
             
                      end
         | 
| 338 340 | 
             
                      out << unify_string(str.pack('C*').force_encoding(Encoding::ASCII_8BIT))
         | 
| 341 | 
            +
                      # warn "Found Literal String: #{out.last}"
         | 
| 339 342 | 
             
                    ##########################################
         | 
| 340 343 | 
             
                    ## parse a Dictionary
         | 
| 341 344 | 
             
                    ##########################################
         | 
| @@ -348,6 +351,7 @@ module CombinePDF | |
| 348 351 | 
             
                    ## return content of array or dictionary
         | 
| 349 352 | 
             
                    ##########################################
         | 
| 350 353 | 
             
                    elsif @scanner.scan(/\]/) || @scanner.scan(/>>/)
         | 
| 354 | 
            +
                      # warn "Dictionary / Array ended with #{@scanner.peek(5)}"
         | 
| 351 355 | 
             
                      return out
         | 
| 352 356 | 
             
                    ##########################################
         | 
| 353 357 | 
             
                    ## parse a Stream
         | 
| @@ -364,6 +368,8 @@ module CombinePDF | |
| 364 368 | 
             
                        raise ParsingError, "Parsing Error: PDF file error - a stream object wasn't properly closed using 'endstream'!"
         | 
| 365 369 | 
             
                      end
         | 
| 366 370 |  | 
| 371 | 
            +
                      # warn "CombinePDF parser: detected Stream #{str.length} bytes long #{str[0..3]}...#{str[-4..-1]}"
         | 
| 372 | 
            +
             | 
| 367 373 | 
             
                      # need to remove end of stream
         | 
| 368 374 | 
             
                      if out.last.is_a? Hash
         | 
| 369 375 | 
             
                        # out.last[:raw_stream_content] = str[0...-10] #cuts only one EON char (\n or \r)
         | 
| @@ -418,7 +424,7 @@ module CombinePDF | |
| 418 424 | 
             
                    ##########################################
         | 
| 419 425 | 
             
                    elsif @scanner.scan(/xref/)
         | 
| 420 426 | 
             
                      # skip list indetifier lines or list lines ([\d] [\d][\r\n]) ot ([\d] [\d] [nf][\r\n])
         | 
| 421 | 
            -
                      while @scanner.scan(/[\s]*[\d]+[ \t]+[\d]+[ \t | 
| 427 | 
            +
                      while @scanner.scan(/[\s]*[\d]+[ \t]+[\d]+[ \t]*[\n\r]+/) || @scanner.scan(/[ \t]*[\d]+[ \t]+[\d]+[ \t]+[nf][\s]*/)
         | 
| 422 428 | 
             
                        nil
         | 
| 423 429 | 
             
                      end
         | 
| 424 430 | 
             
                    ##########################################
         | 
| @@ -528,6 +534,14 @@ module CombinePDF | |
| 528 534 | 
             
                          inheritance_hash[:Resources] ||= { referenced_object: {}, is_reference_only: true }.dup
         | 
| 529 535 | 
             
                          (inheritance_hash[:Resources][:referenced_object] || inheritance_hash[:Resources]).update((catalogs[:Resources][:referenced_object] || catalogs[:Resources]), &HASH_UPDATE_PROC_FOR_OLD)
         | 
| 530 536 | 
             
                        end
         | 
| 537 | 
            +
                        if catalogs[:ProcSet].is_a?(Array)
         | 
| 538 | 
            +
                          if(inheritance_hash[:ProcSet])
         | 
| 539 | 
            +
                            inheritance_hash[:ProcSet][:referenced_object].concat(catalogs[:ProcSet])
         | 
| 540 | 
            +
                            inheritance_hash[:ProcSet][:referenced_object].uniq!
         | 
| 541 | 
            +
                          else
         | 
| 542 | 
            +
                            inheritance_hash[:ProcSet] ||= { referenced_object: catalogs[:ProcSet], is_reference_only: true }.dup
         | 
| 543 | 
            +
                          end
         | 
| 544 | 
            +
                        end
         | 
| 531 545 | 
             
                        if catalogs[:ColorSpace]
         | 
| 532 546 | 
             
                          inheritance_hash[:ColorSpace] ||= { referenced_object: {}, is_reference_only: true }.dup
         | 
| 533 547 | 
             
                          (inheritance_hash[:ColorSpace][:referenced_object] || inheritance_hash[:ColorSpace]).update((catalogs[:ColorSpace][:referenced_object] || catalogs[:ColorSpace]), &HASH_UPDATE_PROC_FOR_OLD)
         | 
| @@ -556,6 +570,18 @@ module CombinePDF | |
| 556 570 | 
             
                          catalogs[:ColorSpace] = { referenced_object: catalogs[:ColorSpace], is_reference_only: true } unless catalogs[:ColorSpace][:referenced_object]
         | 
| 557 571 | 
             
                          catalogs[:ColorSpace][:referenced_object].update((inheritance_hash[:ColorSpace][:referenced_object] || inheritance_hash[:ColorSpace]), &HASH_UPDATE_PROC_FOR_OLD)
         | 
| 558 572 | 
             
                        end
         | 
| 573 | 
            +
                        if inheritance_hash[:ProcSet]
         | 
| 574 | 
            +
                          if(catalogs[:ProcSet])
         | 
| 575 | 
            +
                            if catalogs[:ProcSet].is_a?(Array)
         | 
| 576 | 
            +
                              catalogs[:ProcSet] = { referenced_object: catalogs[:ProcSet], is_reference_only: true }
         | 
| 577 | 
            +
                            end
         | 
| 578 | 
            +
                            catalogs[:ProcSet][:referenced_object].concat(inheritance_hash[:ProcSet][:referenced_object])
         | 
| 579 | 
            +
                            catalogs[:ProcSet][:referenced_object].uniq!
         | 
| 580 | 
            +
                          else
         | 
| 581 | 
            +
                            catalogs[:ProcSet] = { is_reference_only: true }.dup
         | 
| 582 | 
            +
                            catalogs[:ProcSet][:referenced_object] = catalogs[:ProcSet][:referenced_object].dup
         | 
| 583 | 
            +
                          end
         | 
| 584 | 
            +
                        end
         | 
| 559 585 | 
             
                        # (catalogs[:ColorSpace] ||= {}).update(inheritance_hash[:ColorSpace], &HASH_UPDATE_PROC_FOR_OLD) if inheritance_hash[:ColorSpace]
         | 
| 560 586 | 
             
                        # catalogs[:Order] ||= inheritance_hash[:Order] if inheritance_hash[:Order]
         | 
| 561 587 | 
             
                        # catalogs[:AS] ||= inheritance_hash[:AS] if inheritance_hash[:AS]
         | 
| @@ -232,15 +232,42 @@ module CombinePDF | |
| 232 232 | 
             
                # @private
         | 
| 233 233 | 
             
                # this method reviews a Hash and updates it by merging Hash data,
         | 
| 234 234 | 
             
                # preffering the new over the old.
         | 
| 235 | 
            -
                def self.hash_merge_new_no_page(_key, old_data, new_data)
         | 
| 236 | 
            -
             | 
| 237 | 
            -
             | 
| 238 | 
            -
             | 
| 239 | 
            -
             | 
| 240 | 
            -
             | 
| 235 | 
            +
                # def self.hash_merge_new_no_page(_key = nil, old_data = nil, new_data = nil)
         | 
| 236 | 
            +
                #   return old_data unless new_data
         | 
| 237 | 
            +
                #   return new_data unless old_data
         | 
| 238 | 
            +
                #   if old_data.is_a?(Hash) && new_data.is_a?(Hash)
         | 
| 239 | 
            +
                #     return old_data if (old_data[:Type] == :Page)
         | 
| 240 | 
            +
                #     old_data.merge(new_data, &(@hash_merge_new_no_page_proc ||= method(:hash_merge_new_no_page)))
         | 
| 241 | 
            +
                #   elsif old_data.is_a? Array
         | 
| 242 | 
            +
                #     return old_data + new_data if new_data.is_a?(Array)
         | 
| 243 | 
            +
                #     return old_data.dup << new_data
         | 
| 244 | 
            +
                #   elsif new_data.is_a? Array
         | 
| 245 | 
            +
                #     new_data + [old_data]
         | 
| 246 | 
            +
                #   else
         | 
| 247 | 
            +
                #     new_data
         | 
| 248 | 
            +
                #   end
         | 
| 249 | 
            +
                # end
         | 
| 250 | 
            +
             | 
| 251 | 
            +
                # @private
         | 
| 252 | 
            +
                # JRuby Alternative this method reviews a Hash and updates it by merging Hash data,
         | 
| 253 | 
            +
                # preffering the new over the old.
         | 
| 254 | 
            +
                HASH_MERGE_NEW_NO_PAGE = Proc.new do |_key = nil, old_data = nil, new_data = nil|
         | 
| 255 | 
            +
                  if !new_data
         | 
| 256 | 
            +
                    old_data
         | 
| 257 | 
            +
                  elsif !old_data
         | 
| 258 | 
            +
                    new_data
         | 
| 259 | 
            +
                  elsif old_data.is_a?(Hash) && new_data.is_a?(Hash)
         | 
| 260 | 
            +
                    if (old_data[:Type] == :Page)
         | 
| 261 | 
            +
                      old_data
         | 
| 262 | 
            +
                    else
         | 
| 263 | 
            +
                      old_data.merge(new_data, &HASH_MERGE_NEW_NO_PAGE)
         | 
| 264 | 
            +
                    end
         | 
| 241 265 | 
             
                  elsif old_data.is_a? Array
         | 
| 242 | 
            -
                     | 
| 243 | 
            -
             | 
| 266 | 
            +
                    if new_data.is_a?(Array)
         | 
| 267 | 
            +
                      old_data + new_data
         | 
| 268 | 
            +
                    else
         | 
| 269 | 
            +
                      old_data.dup << new_data
         | 
| 270 | 
            +
                    end
         | 
| 244 271 | 
             
                  elsif new_data.is_a? Array
         | 
| 245 272 | 
             
                    new_data + [old_data]
         | 
| 246 273 | 
             
                  else
         | 
| @@ -346,16 +373,19 @@ module CombinePDF | |
| 346 373 | 
             
                private
         | 
| 347 374 |  | 
| 348 375 | 
             
                def equal_layers obj1, obj2, layer = CombinePDF.eq_depth_limit
         | 
| 349 | 
            -
                  return true   if(layer == 0)
         | 
| 350 376 | 
             
                  return true if obj1.object_id == obj2.object_id
         | 
| 351 377 | 
             
                  if obj1.is_a? Hash
         | 
| 352 378 | 
             
                    return false unless obj2.is_a? Hash
         | 
| 379 | 
            +
                    return false unless obj1.length == obj2.length
         | 
| 353 380 | 
             
                    keys = obj1.keys;
         | 
| 354 | 
            -
                     | 
| 381 | 
            +
                    keys2 = obj2.keys;
         | 
| 382 | 
            +
                    return false if (keys - keys2).any? || (keys2 - keys).any?
         | 
| 383 | 
            +
                    return (warn("CombinePDF nesting limit reached") || true) if(layer == 0)
         | 
| 355 384 | 
             
                    keys.each {|k| return false unless equal_layers( obj1[k], obj2[k], layer-1) }
         | 
| 356 385 | 
             
                  elsif obj1.is_a? Array
         | 
| 357 386 | 
             
                    return false unless obj2.is_a? Array
         | 
| 358 | 
            -
                     | 
| 387 | 
            +
                    return false unless obj1.length == obj2.length
         | 
| 388 | 
            +
                    (obj1-obj2).any? || (obj2-obj1).any?
         | 
| 359 389 | 
             
                  else
         | 
| 360 390 | 
             
                    obj1 == obj2
         | 
| 361 391 | 
             
                  end
         | 
| @@ -306,10 +306,10 @@ module CombinePDF | |
| 306 306 | 
             
                  if data.is_a? PDF
         | 
| 307 307 | 
             
                    @version = [@version, data.version].max
         | 
| 308 308 | 
             
                    pages_to_add = data.pages
         | 
| 309 | 
            -
                    actual_value(@names ||= {}.dup).update data.names, & | 
| 309 | 
            +
                    actual_value(@names ||= {}.dup).update data.names, &HASH_MERGE_NEW_NO_PAGE
         | 
| 310 310 | 
             
                    merge_outlines((@outlines ||= {}.dup), actual_value(data.outlines), location) unless actual_value(data.outlines).empty?
         | 
| 311 311 | 
             
                    if actual_value(@forms_data)
         | 
| 312 | 
            -
                      actual_value(@forms_data).update actual_value(data.forms_data), & | 
| 312 | 
            +
                      actual_value(@forms_data).update actual_value(data.forms_data), &HASH_MERGE_NEW_NO_PAGE if data.forms_data
         | 
| 313 313 | 
             
                    else
         | 
| 314 314 | 
             
                      @forms_data = data.forms_data
         | 
| 315 315 | 
             
                    end
         | 
| @@ -358,9 +358,9 @@ module CombinePDF | |
| 358 358 | 
             
                #
         | 
| 359 359 | 
             
                # options:: a Hash of options setting the behavior and format of the page numbers:
         | 
| 360 360 | 
             
                # - :number_format a string representing the format for page number. defaults to ' - %s - ' (allows for letter numbering as well, such as "a", "b"...).
         | 
| 361 | 
            -
                # - :location an Array containing the location for the page numbers, can be :top, : | 
| 361 | 
            +
                # - :location an Array containing the location for the page numbers, can be :top, :bottom, :top_left, :top_right, :bottom_left, :bottom_right or :center (:center == full page). defaults to [:top, :bottom].
         | 
| 362 362 | 
             
                # - :start_at an Integer that sets the number for first page number. also accepts a letter ("a") for letter numbering. defaults to 1.
         | 
| 363 | 
            -
                # - :margin_from_height a number (PDF points) for the top and  | 
| 363 | 
            +
                # - :margin_from_height a number (PDF points) for the top and bottom margins. defaults to 45.
         | 
| 364 364 | 
             
                # - :margin_from_side a number (PDF points) for the left and right margins. defaults to 15.
         | 
| 365 365 | 
             
                # - :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.
         | 
| 366 366 | 
             
                # the options Hash can also take all the options for {Page_Methods#textbox}.
         | 
    
        data/lib/combine_pdf/version.rb
    CHANGED
    
    
    
        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: 1.0. | 
| 4 | 
            +
              version: 1.0.19
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Boaz Segev
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2020-10-23 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: ruby-rc4
         | 
| @@ -24,34 +24,20 @@ dependencies: | |
| 24 24 | 
             
                - - ">="
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 26 | 
             
                    version: 0.1.5
         | 
| 27 | 
            -
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            -
              name: bundler
         | 
| 29 | 
            -
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            -
                requirements:
         | 
| 31 | 
            -
                - - "~>"
         | 
| 32 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            -
                    version: '1.7'
         | 
| 34 | 
            -
              type: :development
         | 
| 35 | 
            -
              prerelease: false
         | 
| 36 | 
            -
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            -
                requirements:
         | 
| 38 | 
            -
                - - "~>"
         | 
| 39 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            -
                    version: '1.7'
         | 
| 41 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 28 | 
             
              name: rake
         | 
| 43 29 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 30 | 
             
                requirements:
         | 
| 45 | 
            -
                - - " | 
| 31 | 
            +
                - - ">="
         | 
| 46 32 | 
             
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            -
                    version:  | 
| 33 | 
            +
                    version: 12.3.3
         | 
| 48 34 | 
             
              type: :development
         | 
| 49 35 | 
             
              prerelease: false
         | 
| 50 36 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 37 | 
             
                requirements:
         | 
| 52 | 
            -
                - - " | 
| 38 | 
            +
                - - ">="
         | 
| 53 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            -
                    version:  | 
| 40 | 
            +
                    version: 12.3.3
         | 
| 55 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 56 42 | 
             
              name: minitest
         | 
| 57 43 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -118,8 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 118 104 | 
             
                - !ruby/object:Gem::Version
         | 
| 119 105 | 
             
                  version: '0'
         | 
| 120 106 | 
             
            requirements: []
         | 
| 121 | 
            -
             | 
| 122 | 
            -
            rubygems_version: 2.7.6
         | 
| 107 | 
            +
            rubygems_version: 3.1.2
         | 
| 123 108 | 
             
            signing_key: 
         | 
| 124 109 | 
             
            specification_version: 4
         | 
| 125 110 | 
             
            summary: Combine, stamp and watermark PDF files in pure Ruby.
         |