pdf_ravager 0.0.7 → 0.0.8

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