podoff 0.9.0 → 1.0.0
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.
- data/CHANGELOG.txt +10 -0
- data/README.md +3 -0
- data/lib/podoff.rb +400 -129
- data/spec/core_spec.rb +47 -0
- data/spec/document_spec.rb +198 -15
- data/spec/obj_spec.rb +153 -99
- data/spec/stream_spec.rb +67 -0
- data/spec/update_spec.rb +18 -18
- data/todo.txt +13 -0
- metadata +4 -2
    
        data/spec/core_spec.rb
    CHANGED
    
    | @@ -12,11 +12,58 @@ describe Podoff do | |
| 12 12 |  | 
| 13 13 | 
             
              describe '.load' do
         | 
| 14 14 |  | 
| 15 | 
            +
                it 'loads a PDF document' do
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  d = Podoff.load('pdfs/t0.pdf')
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  expect(d.class).to eq(Podoff::Document)
         | 
| 20 | 
            +
                  expect(d.xref).to eq(414)
         | 
| 21 | 
            +
                  expect(d.objs.keys).to eq([ '1 0', '2 0', '3 0', '4 0', '5 0', '6 0' ])
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  #pp d.objs.values.collect(&:to_a)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  expect(d.objs['1 0'].to_a).to eq(
         | 
| 26 | 
            +
                    [ '1 0', 9, 54, { type: '/Catalog' } ])
         | 
| 27 | 
            +
                  expect(d.objs['3 0'].to_a).to eq(
         | 
| 28 | 
            +
                    [ '3 0', 111, 213, { type: '/Page', contents: '6 0 R' } ])
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  expect(d.objs.values.first.document).not_to be(nil)
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  expect(d.obj_counters.keys).to eq(
         | 
| 33 | 
            +
                    [ '1 0', '2 0', '3 0', '4 0', '5 0', '6 0' ])
         | 
| 34 | 
            +
                  expect(d.obj_counters.values).to eq(
         | 
| 35 | 
            +
                    [ 1, 1, 1, 1, 1, 1 ])
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  expect(d.root).to eq('1 0')
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 15 40 | 
             
                it 'loads a PDF document' do
         | 
| 16 41 |  | 
| 17 42 | 
             
                  d = Podoff.load('pdfs/udocument0.pdf')
         | 
| 18 43 |  | 
| 19 44 | 
             
                  expect(d.class).to eq(Podoff::Document)
         | 
| 45 | 
            +
                  expect(d.xref).to eq(3138351)
         | 
| 46 | 
            +
                  expect(d.objs.size).to eq(273)
         | 
| 47 | 
            +
                  expect(d.objs.keys).to include('1 0')
         | 
| 48 | 
            +
                  expect(d.objs.keys).to include('273 0')
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  expect(d.root).to eq('65 0')
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                it 'loads a PDF document with incremental updates' do
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  d = Podoff.load('pdfs/t1.pdf')
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  expect(d.class).to eq(Podoff::Document)
         | 
| 58 | 
            +
                  expect(d.xref).to eq(698)
         | 
| 59 | 
            +
                  expect(d.objs.keys).to eq([ '1 0', '2 0', '3 0', '4 0', '5 0', '6 0' ])
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  expect(d.obj_counters.keys).to eq(
         | 
| 62 | 
            +
                    [ '1 0', '2 0', '3 0', '4 0', '5 0', '6 0' ])
         | 
| 63 | 
            +
                  expect(d.obj_counters.values).to eq(
         | 
| 64 | 
            +
                    [ 1, 1, 1, 1, 1, 2 ])
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                  expect(d.root).to eq('1 0')
         | 
| 20 67 | 
             
                end
         | 
| 21 68 |  | 
| 22 69 | 
             
                it 'rejects items that are not PDF documents' do
         | 
    
        data/spec/document_spec.rb
    CHANGED
    
    | @@ -39,9 +39,10 @@ describe Podoff::Document do | |
| 39 39 | 
             
                it 'returns a page given an index (starts at 1)' do
         | 
| 40 40 |  | 
| 41 41 | 
             
                  p = @d.page(1)
         | 
| 42 | 
            -
             | 
| 43 42 | 
             
                  expect(p.class).to eq(Podoff::Obj)
         | 
| 44 | 
            -
                  expect(p.type).to eq('Page')
         | 
| 43 | 
            +
                  expect(p.type).to eq('/Page')
         | 
| 44 | 
            +
                  expect(p.attributes[:pagenum]).to eq('1')
         | 
| 45 | 
            +
                  expect(p.page_number).to eq(1)
         | 
| 45 46 | 
             
                end
         | 
| 46 47 |  | 
| 47 48 | 
             
                it 'returns nil if the page doesn\'t exist' do
         | 
| @@ -49,14 +50,30 @@ describe Podoff::Document do | |
| 49 50 | 
             
                  expect(@d.page(0)).to eq(nil)
         | 
| 50 51 | 
             
                  expect(@d.page(9)).to eq(nil)
         | 
| 51 52 | 
             
                end
         | 
| 52 | 
            -
              end
         | 
| 53 53 |  | 
| 54 | 
            -
             | 
| 54 | 
            +
                it 'returns the page, even for a doc without pdftk_PageNum' do
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  d = Podoff::Document.load('pdfs/t2.pdf')
         | 
| 55 57 |  | 
| 56 | 
            -
             | 
| 58 | 
            +
                  expect(d.page(1).ref).to eq('3 0')
         | 
| 59 | 
            +
                  expect(d.page(1).page_number).to eq(nil)
         | 
| 57 60 |  | 
| 58 | 
            -
                  expect( | 
| 59 | 
            -
                  expect( | 
| 61 | 
            +
                  expect(d.page(0)).to eq(nil)
         | 
| 62 | 
            +
                  expect(d.page(2)).to eq(nil)
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                it 'returns pages from the last when the index is negative' do
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                  expect(@d.page(-1).ref).to eq('33 0')
         | 
| 68 | 
            +
                  expect(@d.page(-1).page_number).to eq(3)
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                it 'returns pages from the last when the index is negative (no PageNum)' do
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  d = Podoff::Document.load('pdfs/t2.pdf')
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  expect(d.page(-1).ref).to eq('3 0')
         | 
| 76 | 
            +
                  expect(d.page(-1).page_number).to eq(nil)
         | 
| 60 77 | 
             
                end
         | 
| 61 78 | 
             
              end
         | 
| 62 79 |  | 
| @@ -72,6 +89,29 @@ describe Podoff::Document do | |
| 72 89 | 
             
                  expect(lines.first).to match(/^%PDF-1.7$/)
         | 
| 73 90 | 
             
                  expect(lines.last).to match(/^%%EOF$/)
         | 
| 74 91 | 
             
                end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                it 'writes open streams as well' do
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                  d = Podoff.load('pdfs/t0.pdf')
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  pa = d.re_add(d.page(1))
         | 
| 98 | 
            +
                  st = d.add_stream
         | 
| 99 | 
            +
                  st.bt(10, 20, 'hello open stream')
         | 
| 100 | 
            +
                  pa.insert_contents(st)
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  s = d.write(:string)
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                  expect(
         | 
| 105 | 
            +
                    d.write(:string).index(%{
         | 
| 106 | 
            +
            7 0 obj
         | 
| 107 | 
            +
            << /Length 37 >>
         | 
| 108 | 
            +
            stream
         | 
| 109 | 
            +
            BT 10 20 Td (hello open stream) Tj ET
         | 
| 110 | 
            +
            endstream
         | 
| 111 | 
            +
            endobj
         | 
| 112 | 
            +
                    }.strip)
         | 
| 113 | 
            +
                  ).to eq(722)
         | 
| 114 | 
            +
                end
         | 
| 75 115 | 
             
              end
         | 
| 76 116 |  | 
| 77 117 | 
             
              describe '#dup' do
         | 
| @@ -80,15 +120,158 @@ describe Podoff::Document do | |
| 80 120 |  | 
| 81 121 | 
             
                  d = @d.dup
         | 
| 82 122 |  | 
| 83 | 
            -
                  expect(d.class
         | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 123 | 
            +
                  expect(d.class).to eq(Podoff::Document)
         | 
| 124 | 
            +
                  expect(d.hash).not_to eq(@d.hash)
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                  expect(d.objs.hash).not_to eq(@d.objs.hash)
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                  expect(d.objs.values.first.hash).not_to eq(@d.objs.values.first.hash)
         | 
| 129 | 
            +
                  expect(d.objs.values.first.class).to eq(Podoff::Obj)
         | 
| 130 | 
            +
                  expect(d.objs.values.first.document.class).to eq(Podoff::Document)
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                  expect(d.objs.values.first.document).to equal(d)
         | 
| 133 | 
            +
                  expect(@d.objs.values.first.document).to equal(@d)
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                  expect(d.root).to eq('65 0')
         | 
| 136 | 
            +
                end
         | 
| 137 | 
            +
              end
         | 
| 138 | 
            +
             | 
| 139 | 
            +
              context 'additions' do
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                before :each do
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                  @d = Podoff.load('pdfs/t0.pdf')
         | 
| 144 | 
            +
                end
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                describe '#add_base_font' do
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                  it 'adds a new /Font obj to the document' do
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                    fo = @d.add_base_font('Helvetica')
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                    expect(@d.additions.size).to eq(1)
         | 
| 153 | 
            +
                    expect(@d.objs.keys).to eq((1..7).map { |i| "#{i} 0" })
         | 
| 154 | 
            +
                    expect(@d.additions.keys).to eq([ '7 0' ])
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                    expect(fo.document).to eq(@d)
         | 
| 157 | 
            +
                    expect(fo.ref).to eq('7 0')
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                    expect(fo.source).to eq(
         | 
| 160 | 
            +
                      '7 0 obj ' +
         | 
| 161 | 
            +
                      '<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >> endobj')
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                    s = @d.write(:string)
         | 
| 164 | 
            +
                    d = Podoff.parse(s)
         | 
| 165 | 
            +
             | 
| 166 | 
            +
                    expect(d.xref).to eq(682)
         | 
| 167 | 
            +
                  end
         | 
| 168 | 
            +
             | 
| 169 | 
            +
                  it 'doesn\'t mind a slash in front of the font name' do
         | 
| 170 | 
            +
             | 
| 171 | 
            +
                    fo = @d.add_base_font('/Helvetica')
         | 
| 172 | 
            +
             | 
| 173 | 
            +
                    expect(@d.additions.size).to eq(1)
         | 
| 174 | 
            +
                    expect(@d.objs.keys).to eq((1..7).map { |i| "#{i} 0" })
         | 
| 175 | 
            +
                    expect(@d.additions.keys).to eq([ '7 0' ])
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                    expect(fo.document).to eq(@d)
         | 
| 178 | 
            +
                    expect(fo.ref).to eq('7 0')
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                    expect(fo.source).to eq(
         | 
| 181 | 
            +
                      '7 0 obj ' +
         | 
| 182 | 
            +
                      '<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >> endobj')
         | 
| 183 | 
            +
                  end
         | 
| 184 | 
            +
                end
         | 
| 185 | 
            +
             | 
| 186 | 
            +
                describe '#add_stream' do
         | 
| 187 | 
            +
             | 
| 188 | 
            +
                  it 'adds a new obj with a stream to the document' do
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                    st = @d.add_stream('BT 70 80 Td /Helvetica 35 Tf (Hello!) Tj ET')
         | 
| 191 | 
            +
             | 
| 192 | 
            +
                    expect(@d.additions.size).to eq(1)
         | 
| 193 | 
            +
                    expect(@d.objs.keys).to eq((1..7).map { |i| "#{i} 0" })
         | 
| 194 | 
            +
                    expect(@d.additions.keys).to eq([ '7 0' ])
         | 
| 195 | 
            +
             | 
| 196 | 
            +
                    expect(st.document).to eq(@d)
         | 
| 197 | 
            +
                    expect(st.ref).to eq('7 0')
         | 
| 198 | 
            +
             | 
| 199 | 
            +
                    expect(st.source).to eq(%{
         | 
| 200 | 
            +
            7 0 obj
         | 
| 201 | 
            +
            << /Length 43 >>
         | 
| 202 | 
            +
            stream
         | 
| 203 | 
            +
            BT 70 80 Td /Helvetica 35 Tf (Hello!) Tj ET
         | 
| 204 | 
            +
            endstream
         | 
| 205 | 
            +
            endobj
         | 
| 206 | 
            +
                    }.strip)
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                    d = Podoff.parse(@d.write(:string))
         | 
| 209 | 
            +
             | 
| 210 | 
            +
                    expect(d.xref).to eq(705)
         | 
| 211 | 
            +
                  end
         | 
| 212 | 
            +
             | 
| 213 | 
            +
                  it 'accepts a block' do
         | 
| 214 | 
            +
             | 
| 215 | 
            +
                    st =
         | 
| 216 | 
            +
                      @d.add_stream {
         | 
| 217 | 
            +
                        tf '/Helvetica', 35
         | 
| 218 | 
            +
                        bt 10, 20, 'thirty here'
         | 
| 219 | 
            +
                        bt 40, 50, 'sixty there'
         | 
| 220 | 
            +
                      }
         | 
| 221 | 
            +
             | 
| 222 | 
            +
                    expect(st.obj.document).to eq(@d)
         | 
| 223 | 
            +
                    expect(st.obj.ref).to eq('7 0')
         | 
| 224 | 
            +
             | 
| 225 | 
            +
                    expect(st.obj.source.to_s).to eq(%{
         | 
| 226 | 
            +
            BT /Helvetica 35 Tf 10 20 Td (thirty here) Tj ET
         | 
| 227 | 
            +
            BT /Helvetica 35 Tf 40 50 Td (sixty there) Tj ET
         | 
| 228 | 
            +
                    }.strip)
         | 
| 229 | 
            +
             | 
| 230 | 
            +
                    d = Podoff.parse(@d.write(:string))
         | 
| 231 | 
            +
             | 
| 232 | 
            +
                    expect(d.source.index('<< /Length 97 >>')).to eq(618)
         | 
| 233 | 
            +
                    expect(d.xref).to eq(759)
         | 
| 234 | 
            +
                  end
         | 
| 235 | 
            +
             | 
| 236 | 
            +
                  it 'returns the open stream when no arg given' do
         | 
| 237 | 
            +
             | 
| 238 | 
            +
                    st = @d.add_stream
         | 
| 239 | 
            +
             | 
| 240 | 
            +
                    expect(st.class).to eq(Podoff::Stream)
         | 
| 241 | 
            +
                  end
         | 
| 242 | 
            +
                end
         | 
| 243 | 
            +
             | 
| 244 | 
            +
                describe '#re_add' do
         | 
| 245 | 
            +
             | 
| 246 | 
            +
                  it 'replicates an obj and adds the replica to the document' do
         | 
| 247 | 
            +
             | 
| 248 | 
            +
                    pa = @d.page(1)
         | 
| 249 | 
            +
                    re = @d.re_add(pa)
         | 
| 250 | 
            +
             | 
| 251 | 
            +
                    expect(@d.additions.size).to eq(1)
         | 
| 252 | 
            +
                    expect(@d.objs.keys).to eq((1..6).map { |i| "#{i} 0" })
         | 
| 253 | 
            +
                    expect(@d.additions.keys).to eq([ '3 0' ])
         | 
| 254 | 
            +
             | 
| 255 | 
            +
                    expect(re.document).to eq(@d)
         | 
| 256 | 
            +
                    expect(re.ref).to eq(pa.ref)
         | 
| 257 | 
            +
                    expect(re.source).to eq(pa.source)
         | 
| 258 | 
            +
                    expect(re.source).not_to equal(pa.source)
         | 
| 259 | 
            +
                  end
         | 
| 260 | 
            +
             | 
| 261 | 
            +
                  it 'accepts a ref' do
         | 
| 262 | 
            +
             | 
| 263 | 
            +
                    pa = @d.page(1)
         | 
| 264 | 
            +
                    re = @d.re_add(pa.ref)
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                    expect(@d.additions.size).to eq(1)
         | 
| 267 | 
            +
                    expect(@d.objs.keys).to eq((1..6).map { |i| "#{i} 0" })
         | 
| 268 | 
            +
                    expect(@d.additions.keys).to eq([ '3 0' ])
         | 
| 89 269 |  | 
| 90 | 
            -
             | 
| 91 | 
            -
             | 
| 270 | 
            +
                    expect(re.document).to eq(@d)
         | 
| 271 | 
            +
                    expect(re.ref).to eq(pa.ref)
         | 
| 272 | 
            +
                    expect(re.source).to eq(pa.source)
         | 
| 273 | 
            +
                    expect(re.source).not_to equal(pa.source)
         | 
| 274 | 
            +
                  end
         | 
| 92 275 | 
             
                end
         | 
| 93 276 | 
             
              end
         | 
| 94 277 | 
             
            end
         | 
    
        data/spec/obj_spec.rb
    CHANGED
    
    | @@ -23,160 +23,214 @@ describe Podoff::Obj do | |
| 23 23 | 
             
                end
         | 
| 24 24 | 
             
              end
         | 
| 25 25 |  | 
| 26 | 
            -
              describe '# | 
| 26 | 
            +
              describe '#source' do
         | 
| 27 27 |  | 
| 28 | 
            -
                it 'returns the  | 
| 28 | 
            +
                it 'returns the source behind the obj' do
         | 
| 29 29 |  | 
| 30 | 
            -
                   | 
| 31 | 
            -
                end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                it 'returns nil if there is no type' do
         | 
| 30 | 
            +
                  o = @d.objs['20 0']
         | 
| 34 31 |  | 
| 35 | 
            -
                  expect( | 
| 32 | 
            +
                  expect(o.source).to eq(%{
         | 
| 33 | 
            +
            20 0 obj [21 0 R]
         | 
| 34 | 
            +
            endobj
         | 
| 35 | 
            +
                  }.strip)
         | 
| 36 36 | 
             
                end
         | 
| 37 37 | 
             
              end
         | 
| 38 38 |  | 
| 39 | 
            -
              describe '# | 
| 40 | 
            -
             | 
| 41 | 
            -
                it 'returns  | 
| 42 | 
            -
             | 
| 43 | 
            -
                   | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
                  expect( | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 39 | 
            +
            #  describe '#match' do
         | 
| 40 | 
            +
            #
         | 
| 41 | 
            +
            #    it 'returns a MatchData instance if there is a match' do
         | 
| 42 | 
            +
            #
         | 
| 43 | 
            +
            #      o = @d.objs['1 0']
         | 
| 44 | 
            +
            #
         | 
| 45 | 
            +
            #      m = o.match(/\/Contents ([^\n]+)/)
         | 
| 46 | 
            +
            #
         | 
| 47 | 
            +
            #      expect(m).not_to eq(nil)
         | 
| 48 | 
            +
            #      expect(m[1]).to eq('3 0 R')
         | 
| 49 | 
            +
            #      expect(m.offset(0)).to eq([ 123, 138 ]) # /!\
         | 
| 50 | 
            +
            #    end
         | 
| 51 | 
            +
            #
         | 
| 52 | 
            +
            #    it 'returns nil if the match exits the obj' do
         | 
| 53 | 
            +
            #
         | 
| 54 | 
            +
            #      o = @d.objs['1 0']
         | 
| 55 | 
            +
            #
         | 
| 56 | 
            +
            #      m = o.match(/3 0 obj/)
         | 
| 57 | 
            +
            #
         | 
| 58 | 
            +
            #      expect(m).to eq(nil)
         | 
| 59 | 
            +
            #    end
         | 
| 60 | 
            +
            #
         | 
| 61 | 
            +
            #    it 'returns nil if there is no match' do
         | 
| 62 | 
            +
            #
         | 
| 63 | 
            +
            #      o = @d.objs['1 0']
         | 
| 64 | 
            +
            #
         | 
| 65 | 
            +
            #      m = o.match(/nada/)
         | 
| 66 | 
            +
            #
         | 
| 67 | 
            +
            #      expect(m).to eq(nil)
         | 
| 68 | 
            +
            #    end
         | 
| 69 | 
            +
            #  end
         | 
| 70 | 
            +
            #
         | 
| 71 | 
            +
            #  describe '#dmatch' do
         | 
| 72 | 
            +
            #
         | 
| 73 | 
            +
            #    it 'matches with the zero offset set to the document' do
         | 
| 74 | 
            +
            #
         | 
| 75 | 
            +
            #      o = @d.objs['1 0']
         | 
| 76 | 
            +
            #
         | 
| 77 | 
            +
            #      m = o.dmatch(/\/Contents ([^\n]+)/)
         | 
| 78 | 
            +
            #
         | 
| 79 | 
            +
            #      expect(m).not_to eq(nil)
         | 
| 80 | 
            +
            #      expect(m[1]).to eq('3 0 R')
         | 
| 81 | 
            +
            #      expect(m.offset(0)).to eq([ 138, 153 ]) # /!\
         | 
| 82 | 
            +
            #    end
         | 
| 83 | 
            +
            #  end
         | 
| 51 84 |  | 
| 52 | 
            -
              describe '# | 
| 85 | 
            +
              describe '#type' do
         | 
| 53 86 |  | 
| 54 | 
            -
                it 'returns  | 
| 87 | 
            +
                it 'returns the type of the obj' do
         | 
| 55 88 |  | 
| 56 | 
            -
                  expect(@d.objs[' | 
| 89 | 
            +
                  expect(@d.objs['23 0'].type).to eq('/Font')
         | 
| 57 90 | 
             
                end
         | 
| 58 91 |  | 
| 59 | 
            -
                it 'returns  | 
| 92 | 
            +
                it 'returns nil if there is no type' do
         | 
| 60 93 |  | 
| 61 | 
            -
                  expect(@d.objs[' | 
| 94 | 
            +
                  expect(@d.objs['17 0'].type).to eq(nil)
         | 
| 62 95 | 
             
                end
         | 
| 63 | 
            -
              end
         | 
| 64 96 |  | 
| 65 | 
            -
             | 
| 97 | 
            +
                it 'works on open streams' do
         | 
| 66 98 |  | 
| 67 | 
            -
             | 
| 99 | 
            +
                  st = @d.add_stream
         | 
| 68 100 |  | 
| 69 | 
            -
                  expect( | 
| 70 | 
            -
                end
         | 
| 71 | 
            -
             | 
| 72 | 
            -
                it 'returns nil if none' do
         | 
| 73 | 
            -
             | 
| 74 | 
            -
                  expect(@d.objs['224 0'].contents).to eq(nil)
         | 
| 101 | 
            +
                  expect(st.obj.type).to eq(nil)
         | 
| 75 102 | 
             
                end
         | 
| 76 103 | 
             
              end
         | 
| 77 104 |  | 
| 78 | 
            -
              describe '# | 
| 79 | 
            -
             | 
| 80 | 
            -
                it 'returns  | 
| 81 | 
            -
             | 
| 82 | 
            -
                  expect(
         | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 105 | 
            +
            #  describe '#parent' do
         | 
| 106 | 
            +
            #
         | 
| 107 | 
            +
            #    it 'returns the parent ref if any' do
         | 
| 108 | 
            +
            #
         | 
| 109 | 
            +
            #      expect(@d.objs.values.first.parent).to eq('2 0')
         | 
| 110 | 
            +
            #    end
         | 
| 111 | 
            +
            #
         | 
| 112 | 
            +
            #    it 'returns nil if there is no parent' do
         | 
| 113 | 
            +
            #
         | 
| 114 | 
            +
            #      expect(@d.objs['2 0'].parent).to eq(nil)
         | 
| 115 | 
            +
            #    end
         | 
| 116 | 
            +
            #  end
         | 
| 89 117 |  | 
| 90 | 
            -
              describe '# | 
| 118 | 
            +
            #  describe '#kids' do
         | 
| 119 | 
            +
            #
         | 
| 120 | 
            +
            #    it 'returns a list of refs' do
         | 
| 121 | 
            +
            #
         | 
| 122 | 
            +
            #      expect(@d.objs['2 0'].kids).to eq([ '1 0', '16 0', '33 0' ])
         | 
| 123 | 
            +
            #    end
         | 
| 124 | 
            +
            #
         | 
| 125 | 
            +
            #    it 'returns an empty list if there are no kids' do
         | 
| 126 | 
            +
            #
         | 
| 127 | 
            +
            #      expect(@d.objs['224 0'].kids).to eq([])
         | 
| 128 | 
            +
            #    end
         | 
| 129 | 
            +
            #  end
         | 
| 130 | 
            +
            #
         | 
| 131 | 
            +
            #  describe '#contents' do
         | 
| 132 | 
            +
            #
         | 
| 133 | 
            +
            #    it 'returns the Contents references (single)' do
         | 
| 134 | 
            +
            #
         | 
| 135 | 
            +
            #      expect(@d.objs['1 0'].contents).to eq([ '3 0' ])
         | 
| 136 | 
            +
            #    end
         | 
| 137 | 
            +
            #
         | 
| 138 | 
            +
            #    it 'returns the Contents references (array)' do
         | 
| 139 | 
            +
            #
         | 
| 140 | 
            +
            #      expect(@d.objs['16 0'].contents).to eq([ '17 0' ])
         | 
| 141 | 
            +
            #    end
         | 
| 142 | 
            +
            #
         | 
| 143 | 
            +
            #    it 'returns an empty list if none' do
         | 
| 144 | 
            +
            #
         | 
| 145 | 
            +
            #      expect(@d.objs['224 0'].contents).to eq([])
         | 
| 146 | 
            +
            #    end
         | 
| 147 | 
            +
            #  end
         | 
| 91 148 |  | 
| 92 | 
            -
             | 
| 149 | 
            +
              context 'insertions' do
         | 
| 93 150 |  | 
| 94 | 
            -
             | 
| 151 | 
            +
                before :each do
         | 
| 95 152 |  | 
| 96 | 
            -
                   | 
| 97 | 
            -
                  expect(o.index('BT')).to eq(14)
         | 
| 153 | 
            +
                  @d = Podoff.load('pdfs/udocument0.pdf')
         | 
| 98 154 | 
             
                end
         | 
| 99 155 |  | 
| 100 | 
            -
                 | 
| 156 | 
            +
                describe '#insert_contents' do
         | 
| 101 157 |  | 
| 102 | 
            -
                   | 
| 158 | 
            +
                  it 'fails if the target hasn\'t been replicated' do
         | 
| 103 159 |  | 
| 104 | 
            -
             | 
| 105 | 
            -
             | 
| 160 | 
            +
                    expect {
         | 
| 161 | 
            +
                      @d.objs['23 0'].insert_contents('-1 0')
         | 
| 162 | 
            +
                    }.to raise_error(ArgumentError, "target '23 0' not a replica")
         | 
| 163 | 
            +
                  end
         | 
| 106 164 |  | 
| 107 | 
            -
             | 
| 165 | 
            +
                  it 'fails if the target doesn\'t have /Contents' do
         | 
| 108 166 |  | 
| 109 | 
            -
             | 
| 167 | 
            +
                    expect {
         | 
| 168 | 
            +
                      ta = @d.re_add('23 0')
         | 
| 169 | 
            +
                      ta.insert_contents('-1 0')
         | 
| 170 | 
            +
                    }.to raise_error(ArgumentError, "target '23 0' doesn't have /Contents")
         | 
| 171 | 
            +
                  end
         | 
| 110 172 |  | 
| 111 | 
            -
                   | 
| 173 | 
            +
                  it 'accepts an obj' do
         | 
| 112 174 |  | 
| 113 | 
            -
             | 
| 114 | 
            -
                  expect(o.lines[i]).to eq('/BleedBox [0.0 0.0 612.0 792.0]')
         | 
| 115 | 
            -
                end
         | 
| 116 | 
            -
             | 
| 117 | 
            -
                it 'accepts a start index' do
         | 
| 175 | 
            +
                    pa = @d.re_add(@d.page(1))
         | 
| 118 176 |  | 
| 119 | 
            -
             | 
| 177 | 
            +
                    st = @d.add_stream('BT 70 80 Td /Font0 35 Tf (content is king!) Tj ET')
         | 
| 120 178 |  | 
| 121 | 
            -
             | 
| 179 | 
            +
                    pa.insert_contents(st)
         | 
| 122 180 |  | 
| 123 | 
            -
             | 
| 124 | 
            -
                   | 
| 125 | 
            -
                end
         | 
| 126 | 
            -
              end
         | 
| 181 | 
            +
                    expect(pa.source).to match(/\/Contents \[3 0 R #{st.ref} R\]\n/)
         | 
| 182 | 
            +
                  end
         | 
| 127 183 |  | 
| 128 | 
            -
             | 
| 184 | 
            +
                  it 'accepts an obj ref' do
         | 
| 129 185 |  | 
| 130 | 
            -
             | 
| 186 | 
            +
                    pa = @d.re_add(@d.page(1))
         | 
| 131 187 |  | 
| 132 | 
            -
             | 
| 188 | 
            +
                    st = @d.add_stream('BT 70 80 Td /Font0 35 Tf (content is king!) Tj ET')
         | 
| 133 189 |  | 
| 134 | 
            -
             | 
| 190 | 
            +
                    pa.insert_contents(st.ref)
         | 
| 135 191 |  | 
| 136 | 
            -
             | 
| 137 | 
            -
                   | 
| 192 | 
            +
                    expect(pa.source).to match(/\/Contents \[3 0 R #{st.ref} R\]\n/)
         | 
| 193 | 
            +
                  end
         | 
| 138 194 | 
             
                end
         | 
| 139 195 |  | 
| 140 | 
            -
                 | 
| 141 | 
            -
              end
         | 
| 142 | 
            -
             | 
| 143 | 
            -
              describe '#gather' do
         | 
| 144 | 
            -
             | 
| 145 | 
            -
                it 'returns a list of sub obj that match the given block'
         | 
| 146 | 
            -
                it 'accept a :skip_root option'
         | 
| 147 | 
            -
              end
         | 
| 196 | 
            +
                describe '#insert_font' do
         | 
| 148 197 |  | 
| 149 | 
            -
             | 
| 198 | 
            +
                  it 'fails if the target hasn\'t been replicated' do
         | 
| 150 199 |  | 
| 151 | 
            -
             | 
| 200 | 
            +
                    expect {
         | 
| 201 | 
            +
                      @d.objs['23 0'].insert_font('/Helvetica', '-1 0')
         | 
| 202 | 
            +
                    }.to raise_error(ArgumentError, "target '23 0' not a replica")
         | 
| 203 | 
            +
                  end
         | 
| 152 204 |  | 
| 153 | 
            -
                   | 
| 205 | 
            +
                  it 'accepts name, obj' do
         | 
| 154 206 |  | 
| 155 | 
            -
             | 
| 156 | 
            -
             | 
| 207 | 
            +
                    fo = @d.add_base_font('/Helvetica')
         | 
| 208 | 
            +
                    pa = @d.re_add(@d.page(1))
         | 
| 157 209 |  | 
| 158 | 
            -
             | 
| 210 | 
            +
                    pa.insert_font('MyHelv', fo)
         | 
| 159 211 |  | 
| 160 | 
            -
             | 
| 212 | 
            +
                    expect(pa.source).to match(/\/Font\s+<<\s+\/MyHelv #{fo.ref} R\s+/)
         | 
| 213 | 
            +
                  end
         | 
| 161 214 |  | 
| 162 | 
            -
                   | 
| 163 | 
            -
                end
         | 
| 164 | 
            -
              end
         | 
| 215 | 
            +
                  it 'accepts name, obj ref' do
         | 
| 165 216 |  | 
| 166 | 
            -
             | 
| 217 | 
            +
                    fo = @d.add_base_font('/Helvetica')
         | 
| 218 | 
            +
                    pa = @d.re_add(@d.page(1))
         | 
| 167 219 |  | 
| 168 | 
            -
             | 
| 220 | 
            +
                    pa.insert_font('MyHelv', fo.ref)
         | 
| 169 221 |  | 
| 170 | 
            -
             | 
| 222 | 
            +
                    expect(pa.source).to match(/\/Font\s+<<\s+\/MyHelv #{fo.ref} R\s+/)
         | 
| 223 | 
            +
                  end
         | 
| 171 224 |  | 
| 172 | 
            -
                   | 
| 173 | 
            -
                end
         | 
| 225 | 
            +
                  it 'accepts a slash in front of the name' do
         | 
| 174 226 |  | 
| 175 | 
            -
             | 
| 227 | 
            +
                    fo = @d.add_base_font('/Helvetica')
         | 
| 228 | 
            +
                    pa = @d.re_add(@d.page(1))
         | 
| 176 229 |  | 
| 177 | 
            -
             | 
| 230 | 
            +
                    pa.insert_font('/MyHelv', fo.ref)
         | 
| 178 231 |  | 
| 179 | 
            -
             | 
| 232 | 
            +
                    expect(pa.source).to match(/\/Font\s+<<\s+\/MyHelv #{fo.ref} R\s+/)
         | 
| 233 | 
            +
                  end
         | 
| 180 234 | 
             
                end
         | 
| 181 235 | 
             
              end
         | 
| 182 236 | 
             
            end
         | 
    
        data/spec/stream_spec.rb
    ADDED
    
    | @@ -0,0 +1,67 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # specifying podoff
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
            # Fri Oct 23 08:36:38 JST 2015
         | 
| 6 | 
            +
            #
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            require 'spec_helper'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
             | 
| 11 | 
            +
            describe Podoff::Stream do
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              describe '#tf' do
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                it 'sets the current font' do
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  st = Podoff::Stream.new
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  st.tf('/Helvetica', 35)
         | 
| 20 | 
            +
                  st.bt(10, 20, 'helvetic')
         | 
| 21 | 
            +
                  st.tf('/ZapfDingbats', 21)
         | 
| 22 | 
            +
                  st.bt(10, 50, 'zapfesque')
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  expect(st.to_s).to eq(%{
         | 
| 25 | 
            +
            BT /Helvetica 35 Tf 10 20 Td (helvetic) Tj ET
         | 
| 26 | 
            +
            BT /ZapfDingbats 21 Tf 10 50 Td (zapfesque) Tj ET
         | 
| 27 | 
            +
                  }.strip)
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              describe '#bt' do
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                it 'works' do
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  st = Podoff::Stream.new
         | 
| 36 | 
            +
                  st.bt(10, 20, 'hello world')
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  expect(st.to_s).to eq('BT 10 20 Td (hello world) Tj ET')
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                it 'escapes the text' do
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  st = Podoff::Stream.new
         | 
| 44 | 
            +
                  st.bt(10, 20, 'hello()world')
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  expect(st.to_s).to eq('BT 10 20 Td (hello\(\)world) Tj ET')
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              describe '#write' do
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                it 'injects text into the stream' do
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  st = Podoff::Stream.new
         | 
| 55 | 
            +
                  st.bt(10, 20, 'abc')
         | 
| 56 | 
            +
                  st.write("\nBT 25 35 Td (ABC) Tj ET")
         | 
| 57 | 
            +
                  st.bt(30, 40, 'def')
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                  expect(st.to_s).to eq(%{
         | 
| 60 | 
            +
            BT 10 20 Td (abc) Tj ET
         | 
| 61 | 
            +
            BT 25 35 Td (ABC) Tj ET
         | 
| 62 | 
            +
            BT 30 40 Td (def) Tj ET
         | 
| 63 | 
            +
                  }.strip)
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
            end
         | 
| 67 | 
            +
             |