pdf_ravager 0.0.1-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ Gemfile.lock
2
+ pkg/
3
+ *.gem
4
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+
3
+ group :development, :test do
4
+ gem "minitest", "~> 4.1.0"
5
+ gem "rspec", "~> 2.11.0"
6
+ gem "turn", "~> 0.9.6", :require => false
7
+ gem "bundler", "~> 1.2.1"
8
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 Abe Voelker
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,50 @@
1
+ # PDF Ravager
2
+
3
+ Provides a simple DSL for easily filling out AcroForms PDF or XFA documents.
4
+
5
+ ## Description
6
+
7
+ This library uses a combination of a simple DSL and a minimal veneer over the
8
+ last free version of the iText library to aid in filling out AcroForms PDF or
9
+ XFA documents.
10
+
11
+ ## Synopsis
12
+
13
+ ```ruby
14
+ require 'pdf_ravager'
15
+
16
+ data = {:name => 'Bob', :gender => 'm', :relation => 'Uncle' }
17
+
18
+ info = pdf do
19
+ text 'name', data[:name]
20
+ radio_group 'sex' do
21
+ fill 'male', :if => data[:gender] == 'm'
22
+ fill 'female', :if => data[:gender] == 'f'
23
+ end
24
+ checkbox_group 'relation' do
25
+ check 'parent', :if => ['Mom', 'Dad'].include?(data[:relation])
26
+ check 'sibling', :if => ['Brother', 'Sister'].include?(data[:relation])
27
+ check 'other', :unless => ['Brother', 'Sister', 'Mom', 'Dad'].include?(data[:relation])
28
+ # OR
29
+ case data[:relation]
30
+ when 'Mom', 'Dad'
31
+ check 'parent'
32
+ when 'Brother', 'Sister'
33
+ check 'sibling'
34
+ else
35
+ check 'other'
36
+ end
37
+ end
38
+ end
39
+
40
+ info.ravage '/tmp/info.pdf', :out_file => '/tmp/info_filled.pdf'
41
+ ```
42
+
43
+ ## Usage
44
+
45
+ To find the names of the fields, use a tool such as Adobe LiveCycle.
46
+
47
+ ## Copyright
48
+
49
+ Copyright (c) 2012 Abe Voelker. Released under the terms of the
50
+ MIT license. See LICENSE for details.
@@ -0,0 +1,10 @@
1
+ require 'rspec'
2
+ require 'rake/testtask'
3
+ require 'bundler'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << ["lib", "spec"]
7
+ t.pattern = "spec/*_spec.rb"
8
+ end
9
+
10
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,3 @@
1
+ require 'pdf_ravager/version'
2
+ require 'pdf_ravager/pdf'
3
+ require 'pdf_ravager/ravager' if RUBY_PLATFORM =~ /java/
@@ -0,0 +1,97 @@
1
+ require 'json'
2
+ require 'pdf_ravager/ravager' if RUBY_PLATFORM =~ /java/
3
+
4
+ module PDFRavager
5
+ class PDF
6
+ attr_reader :name, :fields
7
+
8
+ def initialize(name=nil, opts={})
9
+ @name = name if name
10
+ @fields = opts[:fields] || []
11
+ end
12
+
13
+ def text(name, value, opts={})
14
+ return if opts.has_key?(:when) && !opts[:when]
15
+ return if opts.has_key?(:if) && !opts[:if]
16
+ return if opts.has_key?(:unless) && opts[:unless]
17
+ @fields << {:name => name, :value => value, :type => :text}
18
+ end
19
+
20
+ def radio_group(name, &blk)
21
+ fields = []
22
+ # TODO: replace w/ singleton method?
23
+ PDF.instance_eval do
24
+ send(:define_method, :fill) do |value, opts={}|
25
+ return if opts.has_key?(:when) && !opts[:when]
26
+ return if opts.has_key?(:if) && !opts[:if]
27
+ return if opts.has_key?(:unless) && opts[:unless]
28
+ fields << {:name => name, :value => value, :type => :radio}
29
+ end
30
+ blk.call
31
+ send(:undef_method, :fill)
32
+ end
33
+
34
+ @fields += fields
35
+ end
36
+
37
+ def checkbox_group(name, &blk)
38
+ fields = []
39
+ # TODO: replace w/ singleton method?
40
+ PDF.instance_eval do
41
+ send(:define_method, :check) do |value, opts={}|
42
+ return if opts.has_key?(:when) && !opts[:when]
43
+ return if opts.has_key?(:if) && !opts[:if]
44
+ return if opts.has_key?(:unless) && opts[:unless]
45
+ fields << {:name => name, :value => value, :type => :checkbox}
46
+ end
47
+ blk.call
48
+ send(:undef_method, :check)
49
+ end
50
+
51
+ @fields += fields
52
+ end
53
+
54
+ if RUBY_PLATFORM =~ /java/
55
+ def ravage(file, opts={})
56
+ PDFRavager::Ravager.open(opts.merge(:in_file => file)) do |pdf|
57
+ @fields.each do |f|
58
+ pdf.set_field_value(f[:name], f[:value])
59
+ end
60
+ end
61
+ end
62
+ else
63
+ def ravage(file, opts={})
64
+ raise "You can only ravage .pdfs using JRuby, not #{RUBY_PLATFORM}!"
65
+ end
66
+ end
67
+
68
+ def ==(other)
69
+ self.name == other.name && self.fields == other.fields
70
+ end
71
+
72
+ def to_json(*args)
73
+ {
74
+ "json_class" => self.class.name,
75
+ "data" => {"name" => @name, "fields" => @fields }
76
+ }.to_json(*args)
77
+ end
78
+
79
+ def self.json_create(obj)
80
+ fields = obj["data"]["fields"].map do |f|
81
+ # symbolize the keys
82
+ f = f.inject({}){|h,(k,v)| h[k.to_sym] = v; h}
83
+ f[:type] = f[:type].to_sym if f[:type]
84
+ f
85
+ end
86
+ o = new(obj["data"]["name"], :fields => fields)
87
+ end
88
+ end
89
+ end
90
+
91
+ module Kernel
92
+ def pdf(name=nil, opts={}, &blk)
93
+ r = PDFRavager::PDF.new(name, opts)
94
+ r.instance_eval(&blk)
95
+ r
96
+ end
97
+ end
@@ -0,0 +1,90 @@
1
+ require 'java'
2
+ require File.dirname(__FILE__) + '/../../vendor/iText-4.2.0'
3
+
4
+ include_class "com.lowagie.text.pdf.AcroFields"
5
+ include_class "com.lowagie.text.pdf.PdfArray"
6
+ include_class "com.lowagie.text.pdf.PdfDictionary"
7
+ include_class "com.lowagie.text.pdf.PdfName"
8
+ include_class "com.lowagie.text.pdf.PdfObject"
9
+ include_class "com.lowagie.text.pdf.PdfReader"
10
+ include_class "com.lowagie.text.pdf.PdfStamper"
11
+ include_class "com.lowagie.text.pdf.PdfStream"
12
+ include_class "com.lowagie.text.pdf.PdfWriter"
13
+ include_class "com.lowagie.text.pdf.XfaForm"
14
+ include_class "com.lowagie.text.pdf.XfdfReader"
15
+
16
+ module PDFRavager
17
+ class Ravager
18
+ private_class_method :new
19
+
20
+ def self.open(opts={}, &block)
21
+ opts = {:in_file => opts} if opts.is_a? String
22
+ out = if opts[:out_file]
23
+ java.io.FileOutputStream.new(opts[:out_file])
24
+ else
25
+ java.io.ByteArrayOutputStream.new
26
+ end
27
+ raise "You must pass a block" unless block_given?
28
+ ravager = new(opts[:in_file], out)
29
+ yield ravager
30
+ ravager.destroy
31
+ out
32
+ end
33
+
34
+ def set_field_value(name, value)
35
+ # Transform boolean checkbox value to 1 or 0 char
36
+ if get_field_type(name) == AcroFields::FIELD_TYPE_CHECKBOX && !!value
37
+ value = value == true ? '1' : '0'
38
+ end
39
+ # First use AcroForms method
40
+ begin
41
+ @afields.setField(XfaForm::Xml2Som::getShortName(SOM.escape(name)), value)
42
+ rescue java.lang.NullPointerException
43
+ # If the AcroForms method doesn't work, we'll set the XDP
44
+ doc = Nokogiri::XML::Document.wrap(@xfa.getDomDocument)
45
+ doc.xpath("//*[local-name()='field'][@name='#{name}']").each do |node|
46
+ # Create an XML node in the XDP basically like this: "<value><text>#{value}</text></value>"
47
+ Nokogiri::XML::Builder.with(node) do |xml|
48
+ xml.value_ do |v|
49
+ v.text_ value
50
+ end
51
+ end
52
+ end
53
+ @xfa.setDomDocument(doc.to_java)
54
+ @xfa.setChanged(true)
55
+ end
56
+ end
57
+
58
+ def get_field_type(name)
59
+ short_name = XfaForm::Xml2Som::getShortName(SOM.escape(name))
60
+ begin
61
+ @afields.getFieldType(short_name)
62
+ rescue java.lang.NullPointerException
63
+ nil
64
+ end
65
+ end
66
+
67
+ def destroy
68
+ @stamper.close
69
+ end
70
+
71
+ private
72
+
73
+ def initialize(in_file, out)
74
+ @reader = PdfReader.new(in_file)
75
+ @out = out
76
+ @stamper = PdfStamper.new(@reader, @out)
77
+ @afields = @stamper.getAcroFields
78
+ @xfa = @afields.getXfa
79
+ @som = @xfa.getDatasetsSom
80
+ @som_template = @xfa.getTemplateSom
81
+ end
82
+
83
+ end
84
+
85
+ class SOM
86
+ def self.escape(str)
87
+ XfaForm::Xml2Som.escapeSom(str) # just does: str.gsub(/\./) { '\\.' }
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,3 @@
1
+ module PDFRavager
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/pdf_ravager/version", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "pdf_ravager"
6
+ s.version = PDFRavager::VERSION
7
+ s.platform = 'java'
8
+ s.authors = ['Abe Voelker']
9
+ s.email = 'abe@abevoelker.com'
10
+ s.date = '2012-10-17'
11
+ s.homepage = 'https://github.com/abevoelker/pdf_ravager'
12
+ s.summary = %q{DSL to aid filling out AcroForms PDF and XFA documents}
13
+ s.description = %q{DSL to aid filling out AcroForms PDF and XFA documents}
14
+
15
+ s.add_runtime_dependency "json"
16
+ s.add_development_dependency "bundler", ">= 1.0.0"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+ end
@@ -0,0 +1,140 @@
1
+ require 'spec_helper'
2
+ require 'pdf_ravager/pdf'
3
+
4
+ class TestPDF < MiniTest::Unit::TestCase
5
+ def setup
6
+ @pdf = pdf 'foo.pdf' do
7
+ text 'text_always', 'foo'
8
+ text 'text_when_true', 'foo', :when => true
9
+ text 'text_when_false', 'foo', :when => false
10
+ text 'text_if_true', 'foo', :if => true
11
+ text 'text_if_false', 'foo', :if => false
12
+ text 'text_unless_true', 'foo', :unless => true
13
+ text 'text_unless_false', 'foo', :unless => false
14
+ radio_group 'radio_group_always_filled' do
15
+ fill 'foo'
16
+ end
17
+ radio_group 'radio_group_if' do
18
+ fill 'true', :if => true
19
+ fill 'false', :if => false
20
+ end
21
+ radio_group 'radio_group_when' do
22
+ fill 'true', :when => true
23
+ fill 'false', :when => false
24
+ end
25
+ radio_group 'radio_group_unless' do
26
+ fill 'true', :unless => true
27
+ fill 'false', :unless => false
28
+ end
29
+ checkbox_group 'checkbox_group_always_checked' do
30
+ check 'foo'
31
+ end
32
+ checkbox_group 'checkbox_group_if' do
33
+ check 'true', :if => true
34
+ check 'false', :if => false
35
+ end
36
+ checkbox_group 'checkbox_group_when' do
37
+ check 'true', :when => true
38
+ check 'false', :when => false
39
+ end
40
+ checkbox_group 'checkbox_group_unless' do
41
+ check 'true', :unless => true
42
+ check 'false', :unless => false
43
+ end
44
+ end
45
+
46
+ @pdf_from_json = JSON.parse(@pdf.to_json)
47
+ end
48
+
49
+ def test_that_name_is_set
50
+ assert_equal @pdf.name, 'foo.pdf'
51
+ end
52
+
53
+ def test_that_text_is_set
54
+ assert_includes @pdf.fields, {:name => 'text_always', :value => 'foo', :type => :text}
55
+ end
56
+
57
+ def test_that_text_when_true_is_set
58
+ assert_includes @pdf.fields, {:name => 'text_when_true', :value => 'foo', :type => :text}
59
+ end
60
+
61
+ def test_that_text_when_false_is_not_set
62
+ refute_includes @pdf.fields, {:name => 'text_when_false', :value => 'foo', :type => :text}
63
+ end
64
+
65
+ def test_that_text_if_true_is_set
66
+ assert_includes @pdf.fields, {:name => 'text_if_true', :value => 'foo', :type => :text}
67
+ end
68
+
69
+ def test_that_text_if_false_is_not_set
70
+ refute_includes @pdf.fields, {:name => 'text_if_false', :value => 'foo', :type => :text}
71
+ end
72
+
73
+ def test_that_text_unless_true_is_not_set
74
+ refute_includes @pdf.fields, {:name => 'text_unless_true', :value => 'foo', :type => :text}
75
+ end
76
+
77
+ def test_that_text_unless_false_is_set
78
+ assert_includes @pdf.fields, {:name => 'text_unless_false', :value => 'foo', :type => :text}
79
+ end
80
+
81
+ def test_that_radio_group_always_filled_is_filled
82
+ assert_includes @pdf.fields, {:name => 'radio_group_always_filled', :value => 'foo', :type => :radio}
83
+ end
84
+
85
+ def test_that_radio_group_when_true_is_set
86
+ assert_includes @pdf.fields, {:name => 'radio_group_when', :value => 'true', :type => :radio}
87
+ end
88
+
89
+ def test_that_radio_group_when_false_is_not_set
90
+ refute_includes @pdf.fields, {:name => 'radio_group_when', :value => 'false', :type => :radio}
91
+ end
92
+
93
+ def test_that_radio_group_if_true_is_set
94
+ assert_includes @pdf.fields, {:name => 'radio_group_if', :value => 'true', :type => :radio}
95
+ end
96
+
97
+ def test_that_radio_group_if_false_is_not_set
98
+ refute_includes @pdf.fields, {:name => 'radio_group_if', :value => 'false', :type => :radio}
99
+ end
100
+
101
+ def test_that_radio_group_unless_true_is_not_set
102
+ refute_includes @pdf.fields, {:name => 'radio_group_unless', :value => 'true', :type => :radio}
103
+ end
104
+
105
+ def test_that_radio_group_unless_false_is_set
106
+ assert_includes @pdf.fields, {:name => 'radio_group_unless', :value => 'false', :type => :radio}
107
+ end
108
+
109
+ def test_that_checkbox_group_always_checked_is_checked
110
+ assert_includes @pdf.fields, {:name => 'checkbox_group_always_checked', :value => 'foo', :type => :checkbox}
111
+ end
112
+
113
+ def test_that_checkbox_group_when_true_is_set
114
+ assert_includes @pdf.fields, {:name => 'checkbox_group_when', :value => 'true', :type => :checkbox}
115
+ end
116
+
117
+ def test_that_checkbox_group_when_false_is_not_set
118
+ refute_includes @pdf.fields, {:name => 'checkbox_group_when', :value => 'false', :type => :checkbox}
119
+ end
120
+
121
+ def test_that_checkbox_group_if_true_is_set
122
+ assert_includes @pdf.fields, {:name => 'checkbox_group_if', :value => 'true', :type => :checkbox}
123
+ end
124
+
125
+ def test_that_checkbox_group_if_false_is_not_set
126
+ refute_includes @pdf.fields, {:name => 'checkbox_group_if', :value => 'false', :type => :checkbox}
127
+ end
128
+
129
+ def test_that_checkbox_group_unless_true_is_not_set
130
+ refute_includes @pdf.fields, {:name => 'checkbox_group_unless', :value => 'true', :type => :checkbox}
131
+ end
132
+
133
+ def test_that_checkbox_group_unless_false_is_set
134
+ assert_includes @pdf.fields, {:name => 'checkbox_group_unless', :value => 'false', :type => :checkbox}
135
+ end
136
+
137
+ def test_json_serialization
138
+ assert_equal @pdf, @pdf_from_json
139
+ end
140
+ end
@@ -0,0 +1 @@
1
+ require 'turn/autorun'
Binary file
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pdf_ravager
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: java
7
+ authors:
8
+ - Abe Voelker
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ! '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ none: false
22
+ requirement: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ none: false
28
+ prerelease: false
29
+ type: :runtime
30
+ - !ruby/object:Gem::Dependency
31
+ name: bundler
32
+ version_requirements: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ! '>='
35
+ - !ruby/object:Gem::Version
36
+ version: 1.0.0
37
+ none: false
38
+ requirement: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: 1.0.0
43
+ none: false
44
+ prerelease: false
45
+ type: :development
46
+ description: DSL to aid filling out AcroForms PDF and XFA documents
47
+ email: abe@abevoelker.com
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - .gitignore
53
+ - Gemfile
54
+ - LICENSE
55
+ - README.md
56
+ - Rakefile
57
+ - lib/pdf_ravager.rb
58
+ - lib/pdf_ravager/pdf.rb
59
+ - lib/pdf_ravager/ravager.rb
60
+ - lib/pdf_ravager/version.rb
61
+ - pdf_ravager.gemspec
62
+ - spec/pdf_spec.rb
63
+ - spec/spec_helper.rb
64
+ - vendor/iText-4.2.0.jar
65
+ homepage: https://github.com/abevoelker/pdf_ravager
66
+ licenses: []
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ none: false
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ none: false
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 1.8.24
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: DSL to aid filling out AcroForms PDF and XFA documents
89
+ test_files: []
90
+ ...