pdf_ravager 0.0.7 → 0.0.8

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/.travis.yml CHANGED
@@ -2,7 +2,13 @@ language: ruby
2
2
  rvm:
3
3
  - "1.9.2"
4
4
  - "1.9.3"
5
- - jruby-19mode # JRuby in 1.9 mode
5
+ - jruby-19mode
6
6
  - rbx-19mode
7
- # uncomment this line if your project needs to run something other than `rake`:
8
- script: bundle exec rake test
7
+ matrix:
8
+ allow_failures:
9
+ - rvm: jruby-19mode
10
+ before_install:
11
+ - sudo add-apt-repository "deb http://archive.canonical.com/ $(lsb_release -sc) partner" -y
12
+ - sudo apt-get update -y
13
+ - sudo apt-get install acroread ghostscript -y
14
+
data/README.md CHANGED
@@ -82,4 +82,7 @@ check 'relation.parent'
82
82
  Copyright (c) 2012 Abe Voelker. Released under the terms of the
83
83
  MIT license. See LICENSE for details.
84
84
 
85
- [1]: http://partners.adobe.com/public/developer/xml/index_arch.html
85
+ The [version of iText][2] vendored is licensed under the LGPL.
86
+
87
+ [1]: http://partners.adobe.com/public/developer/xml/index_arch.html
88
+ [2]: http://itext.svn.sourceforge.net/viewvc/itext/tags/iText_4_2_0/
data/Rakefile CHANGED
@@ -1,10 +1,25 @@
1
1
  require 'rspec'
2
+ require 'rspec/core/rake_task'
2
3
  require 'rake/testtask'
3
4
  require 'bundler'
4
5
 
5
- Rake::TestTask.new do |t|
6
+ Rake::TestTask.new('spec:unit') do |t|
6
7
  t.libs << ["lib", "spec"]
7
- t.pattern = "spec/*_spec.rb"
8
- end
8
+ t.pattern = "spec/**/*_spec.rb"
9
+ end
9
10
 
10
- Bundler::GemHelper.install_tasks
11
+ if RUBY_PLATFORM =~ /java/
12
+ # Integration tests can only run on JRuby
13
+ RSpec::Core::RakeTask.new('spec:integration') do |spec|
14
+ spec.pattern = "spec/**/*spec.rb"
15
+ spec.rspec_opts = ['--backtrace']
16
+ end
17
+
18
+ task :spec => ['spec:unit', 'spec:integration']
19
+ else
20
+ task :spec => ['spec:unit']
21
+ end
22
+
23
+ task :default => :spec
24
+
25
+ Bundler::GemHelper.install_tasks
@@ -38,23 +38,40 @@ module PDFRavager
38
38
  # First try AcroForms method of setting value
39
39
  @afields.setField(SOM.short_name(name), value)
40
40
  rescue java.lang.NullPointerException
41
- # If the AcroForms method doesn't work, we'll set the XDP
42
- # Note: the double-load is to work around a Nokogiri bug I found:
43
- # https://github.com/sparklemotion/nokogiri/issues/781
44
- doc = Nokogiri::XML(Nokogiri::XML::Document.wrap(@xfa.getDomDocument).to_xml)
45
- doc.xpath("//*[local-name()='field'][@name='#{name}']").each do |node|
46
- # Create an XML node in the XDP like this: "<value><text>#{value}</text></value>"
41
+ end
42
+ # Also look for the XDP node and set that value
43
+ # Note: the double-load is to work around a Nokogiri bug I found:
44
+ # https://github.com/sparklemotion/nokogiri/issues/781
45
+ doc = Nokogiri::XML(Nokogiri::XML::Document.wrap(@xfa.getDomDocument).to_xml)
46
+ node_type = type == :checkbox ? 'integer' : 'text'
47
+ doc.xpath("//*[local-name()='field'][@name='#{name}']").each do |node|
48
+ value_node = node.at_xpath("*[local-name()='value']")
49
+ if value_node
50
+ text_node = value_node.at_xpath("*[local-name()='#{node_type}']")
51
+ if text_node
52
+ # Complete node structure already exists - just set the value
53
+ text_node.content = value
54
+ else
55
+ # <value> node exists, but without child <text> node
56
+ Nokogiri::XML::Builder.with(value_node) do |xml|
57
+ xml.text_ {
58
+ xml.send("#{node_type}_", value)
59
+ }
60
+ end
61
+ end
62
+ else
63
+ # No <value> node exists - create whole structure
47
64
  Nokogiri::XML::Builder.with(node) do |xml|
48
65
  xml.value_ {
49
- xml.text_ {
66
+ xml.send("#{node_type}_") {
50
67
  xml.text value
51
68
  }
52
69
  }
53
70
  end
54
71
  end
55
- @xfa.setDomDocument(doc.to_java)
56
- @xfa.setChanged(true)
57
72
  end
73
+ @xfa.setDomDocument(doc.to_java)
74
+ @xfa.setChanged(true)
58
75
  end
59
76
 
60
77
  def destroy
@@ -81,14 +98,27 @@ module PDFRavager
81
98
  def set_rich_text_field(name, value)
82
99
  doc = Nokogiri::XML(Nokogiri::XML::Document.wrap(@xfa.getDomDocument).to_xml)
83
100
  doc.xpath("//*[local-name()='field'][@name='#{name}']").each do |node|
84
- Nokogiri::XML::Builder.with(node) do |xml|
85
- xml.value_ do
101
+ value_node = node.at_xpath("*[local-name()='value']")
102
+ if value_node
103
+ # <value> node exists - just create <exData>
104
+ Nokogiri::XML::Builder.with(value_node) do |xml|
86
105
  xml.exData('contentType' => 'text/html') do
87
106
  xml.body_('xmlns' => "http://www.w3.org/1999/xhtml", 'xmlns:xfa' => "http://www.xfa.org/schema/xfa-data/1.0/") do
88
107
  xml << value # Note: this value is not sanitized/escaped!
89
108
  end
90
109
  end
91
110
  end
111
+ else
112
+ # No <value> node exists - create whole structure
113
+ Nokogiri::XML::Builder.with(node) do |xml|
114
+ xml.value_ do
115
+ xml.exData('contentType' => 'text/html') do
116
+ xml.body_('xmlns' => "http://www.w3.org/1999/xhtml", 'xmlns:xfa' => "http://www.xfa.org/schema/xfa-data/1.0/") do
117
+ xml << value # Note: this value is not sanitized/escaped!
118
+ end
119
+ end
120
+ end
121
+ end
92
122
  end
93
123
  end
94
124
  @xfa.setDomDocument(doc.to_java)
@@ -1,3 +1,3 @@
1
1
  module PDFRavager
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
data/pdf_ravager.gemspec CHANGED
@@ -12,10 +12,11 @@ Gem::Specification.new do |s|
12
12
 
13
13
  s.add_dependency "json"
14
14
  s.add_dependency "nokogiri"
15
- s.add_development_dependency "bundler", "~> 1.0"
16
- s.add_development_dependency "minitest", "~> 4.1"
17
- s.add_development_dependency "rspec", "~> 2.11"
18
- s.add_development_dependency "rake", "~> 0.9"
15
+ s.add_development_dependency "bundler", "~> 1.0"
16
+ s.add_development_dependency "minitest", "~> 4.1"
17
+ s.add_development_dependency "rspec", "~> 2.11"
18
+ s.add_development_dependency "rake", "~> 0.9"
19
+ s.add_development_dependency "chunky_png", "~> 1.2"
19
20
 
20
21
  s.files = `git ls-files`.split("\n")
21
22
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -0,0 +1,58 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'rspec'
3
+ require 'pdf_ravager'
4
+ require 'securerandom'
5
+ require 'chunky_png'
6
+
7
+ def mktemp
8
+ # the tests are already dependent on Linux, so /tmp/ usage should be OK
9
+ "/tmp/#{SecureRandom.uuid}"
10
+ end
11
+
12
+ def pdf_to_ps(pdf_file, out_file=nil)
13
+ out_file ||= "#{mktemp}.ps"
14
+ system("acroread -toPostScript -markupsOn -pairs #{pdf_file} #{out_file} >/dev/null 2>&1")
15
+ out_file
16
+ end
17
+
18
+ def ps_to_png(ps_file, out_file=nil)
19
+ out_file ||= "#{mktemp}.png"
20
+ system("gs -dSAFER -dBATCH -dNOPAUSE -r150 -sDEVICE=png16m -dTextAlphaBits=4 -sOutputFile=#{out_file} #{ps_file} >/dev/null 2>&1")
21
+ out_file
22
+ end
23
+
24
+ def pdf_to_png(pdf_file)
25
+ ps_to_png(pdf_to_ps(pdf_file))
26
+ end
27
+
28
+ # code taken from http://jeffkreeftmeijer.com/2011/comparing-images-and-creating-image-diffs/
29
+ def png_diff(img1, img2)
30
+ images = [
31
+ ChunkyPNG::Image.from_file(img1),
32
+ ChunkyPNG::Image.from_file(img2)
33
+ ]
34
+
35
+ output = ChunkyPNG::Image.new(images.first.width, images.last.width, ChunkyPNG::Color::WHITE)
36
+
37
+ diff = []
38
+
39
+ images.first.height.times do |y|
40
+ images.first.row(y).each_with_index do |pixel, x|
41
+ unless pixel == images.last[x,y]
42
+ score = Math.sqrt(
43
+ (ChunkyPNG::Color::r(images.last[x,y]) - ChunkyPNG::Color::r(pixel)) ** 2 +
44
+ (ChunkyPNG::Color::g(images.last[x,y]) - ChunkyPNG::Color::g(pixel)) ** 2 +
45
+ (ChunkyPNG::Color::b(images.last[x,y]) - ChunkyPNG::Color::b(pixel)) ** 2
46
+ ) / Math.sqrt(ChunkyPNG::Color::MAX ** 2 * 3)
47
+
48
+ output[x,y] = ChunkyPNG::Color::grayscale(ChunkyPNG::Color::MAX - (score * ChunkyPNG::Color::MAX).round)
49
+ diff << score
50
+ end
51
+ end
52
+ end
53
+
54
+ num_pixels_changed = diff.length
55
+ pct_changed = (num_pixels_changed == 0) ? 0 : (diff.inject(:+) / images.first.pixels.length) * 100
56
+
57
+ [num_pixels_changed, pct_changed]
58
+ end
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/../integration_helper'
2
+
3
+ describe 'a PDF with a multiline text field' do
4
+ describe 'filled with FOO' do
5
+ before(:each) do
6
+ p = pdf do
7
+ text 'multilinetext', 'FOO' * 10000
8
+ end
9
+ pdf_file = File.join(File.dirname(__FILE__), "pdf")
10
+ @pdf_file = "#{mktemp}.pdf"
11
+ @pdf = p.ravage pdf_file, :out_file => @pdf_file
12
+ end
13
+
14
+ it 'should match expected.png when rendered' do
15
+ png = pdf_to_png(@pdf_file)
16
+ pix_diff, pct_diff = png_diff(png, File.join(File.dirname(__FILE__), "expected.png"))
17
+ pix_diff.should == 0
18
+ end
19
+ end
20
+ end
Binary file
@@ -0,0 +1,20 @@
1
+ require 'integration/integration_helper'
2
+
3
+ describe 'a PDF with a text field' do
4
+ describe 'filled with foo' do
5
+ before(:each) do
6
+ p = pdf do
7
+ text 'text_field', 'foo'
8
+ end
9
+ pdf_file = File.join(File.dirname(__FILE__), "pdf")
10
+ @pdf_file = "#{mktemp}.pdf"
11
+ @pdf = p.ravage pdf_file, :out_file => @pdf_file
12
+ end
13
+
14
+ it 'should match expected.png when rendered' do
15
+ png = pdf_to_png(@pdf_file)
16
+ pix_diff, pct_diff = png_diff(png, File.join(File.dirname(__FILE__), "expected.png"))
17
+ pix_diff.should be 0
18
+ end
19
+ end
20
+ end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require File.dirname(__FILE__) + '/unit_helper'
2
2
  require 'pdf_ravager/pdf'
3
3
 
4
4
  class TestPDF < MiniTest::Unit::TestCase
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'minitest/autorun'
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pdf_ravager
3
3
  version: !ruby/object:Gem::Version
4
+ version: 0.0.8
4
5
  prerelease:
5
- version: 0.0.7
6
6
  platform: ruby
7
7
  authors:
8
8
  - Abe Voelker
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-30 00:00:00.000000000 Z
12
+ date: 2012-11-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -17,13 +17,15 @@ dependencies:
17
17
  requirements:
18
18
  - - ! '>='
19
19
  - !ruby/object:Gem::Version
20
- version: '0'
20
+ version: !binary |-
21
+ MA==
21
22
  none: false
22
23
  requirement: !ruby/object:Gem::Requirement
23
24
  requirements:
24
25
  - - ! '>='
25
26
  - !ruby/object:Gem::Version
26
- version: '0'
27
+ version: !binary |-
28
+ MA==
27
29
  none: false
28
30
  prerelease: false
29
31
  type: :runtime
@@ -33,13 +35,15 @@ dependencies:
33
35
  requirements:
34
36
  - - ! '>='
35
37
  - !ruby/object:Gem::Version
36
- version: '0'
38
+ version: !binary |-
39
+ MA==
37
40
  none: false
38
41
  requirement: !ruby/object:Gem::Requirement
39
42
  requirements:
40
43
  - - ! '>='
41
44
  - !ruby/object:Gem::Version
42
- version: '0'
45
+ version: !binary |-
46
+ MA==
43
47
  none: false
44
48
  prerelease: false
45
49
  type: :runtime
@@ -107,6 +111,22 @@ dependencies:
107
111
  none: false
108
112
  prerelease: false
109
113
  type: :development
114
+ - !ruby/object:Gem::Dependency
115
+ name: chunky_png
116
+ version_requirements: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ~>
119
+ - !ruby/object:Gem::Version
120
+ version: '1.2'
121
+ none: false
122
+ requirement: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ~>
125
+ - !ruby/object:Gem::Version
126
+ version: '1.2'
127
+ none: false
128
+ prerelease: false
129
+ type: :development
110
130
  description: DSL to aid filling out AcroForms PDF and XFA documents
111
131
  email: abe@abevoelker.com
112
132
  executables: []
@@ -124,8 +144,16 @@ files:
124
144
  - lib/pdf_ravager/ravager.rb
125
145
  - lib/pdf_ravager/version.rb
126
146
  - pdf_ravager.gemspec
127
- - spec/pdf_spec.rb
147
+ - spec/integration/integration_helper.rb
148
+ - spec/integration/multiline_text_field/expected.png
149
+ - spec/integration/multiline_text_field/pdf
150
+ - spec/integration/multiline_text_field/spec.rb
151
+ - spec/integration/text_field/expected.png
152
+ - spec/integration/text_field/pdf
153
+ - spec/integration/text_field/spec.rb
128
154
  - spec/spec_helper.rb
155
+ - spec/unit/pdf_spec.rb
156
+ - spec/unit/unit_helper.rb
129
157
  - vendor/iText-4.2.0.jar
130
158
  homepage: https://github.com/abevoelker/pdf_ravager
131
159
  licenses: []
@@ -137,13 +165,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
137
165
  requirements:
138
166
  - - ! '>='
139
167
  - !ruby/object:Gem::Version
140
- version: '0'
168
+ segments:
169
+ - 0
170
+ version: !binary |-
171
+ MA==
172
+ hash: 2
141
173
  none: false
142
174
  required_rubygems_version: !ruby/object:Gem::Requirement
143
175
  requirements:
144
176
  - - ! '>='
145
177
  - !ruby/object:Gem::Version
146
- version: '0'
178
+ segments:
179
+ - 0
180
+ version: !binary |-
181
+ MA==
182
+ hash: 2
147
183
  none: false
148
184
  requirements: []
149
185
  rubyforge_project:
@@ -152,4 +188,3 @@ signing_key:
152
188
  specification_version: 3
153
189
  summary: DSL to aid filling out AcroForms PDF and XFA documents
154
190
  test_files: []
155
- ...