pdf_ravager 0.0.7
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/.gitignore +4 -0
- data/.travis.yml +8 -0
- data/Gemfile +13 -0
- data/LICENSE +20 -0
- data/README.md +85 -0
- data/Rakefile +10 -0
- data/lib/pdf_ravager.rb +3 -0
- data/lib/pdf_ravager/pdf.rb +105 -0
- data/lib/pdf_ravager/ravager.rb +126 -0
- data/lib/pdf_ravager/version.rb +3 -0
- data/pdf_ravager.gemspec +24 -0
- data/spec/pdf_spec.rb +48 -0
- data/spec/spec_helper.rb +1 -0
- data/vendor/iText-4.2.0.jar +0 -0
- metadata +155 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
platforms :jruby do
|
6
|
+
# Necessary for `rake release` on JRuby
|
7
|
+
gem "jruby-openssl", "~> 0.7.7"
|
8
|
+
end
|
9
|
+
|
10
|
+
group :test do
|
11
|
+
# Formats and colorizes test output
|
12
|
+
gem "turn", "~> 0.9.6", :require => false
|
13
|
+
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.
|
data/README.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# PDF Ravager [](http://travis-ci.org/abevoelker/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 façade 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
|
+
text 'name_stylized', "<b>#{data[:name]}</b>", :rich => true
|
21
|
+
radio_group 'sex' do
|
22
|
+
fill 'male' if data[:gender] == 'm'
|
23
|
+
fill 'female' if data[:gender] == 'f'
|
24
|
+
end
|
25
|
+
check 'related' if data[:relation]
|
26
|
+
checkbox_group 'relation' do
|
27
|
+
case data[:relation]
|
28
|
+
when 'Mom', 'Dad'
|
29
|
+
check 'parent'
|
30
|
+
when 'Brother', 'Sister'
|
31
|
+
check 'sibling'
|
32
|
+
else
|
33
|
+
check 'other'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
info.ravage '/tmp/info.pdf', :out_file => '/tmp/info_filled.pdf'
|
39
|
+
# if you'd like the populated form to be read-only:
|
40
|
+
info.ravage '/tmp/info.pdf', :out_file => '/tmp/info_filled.pdf', :read_only => true
|
41
|
+
```
|
42
|
+
|
43
|
+
## Usage
|
44
|
+
|
45
|
+
### Field Names
|
46
|
+
To query and modify a form's field names, use a tool such as Adobe
|
47
|
+
LiveCycle.
|
48
|
+
|
49
|
+
### Rich Text
|
50
|
+
Rich text is specific to XFA forms. To understand how it should be used,
|
51
|
+
see the "Rich Text Reference" section of [Adobe's XFA standard][1].
|
52
|
+
Rich Text is defined there as a subset of
|
53
|
+
XHTML and CSS which uses some custom restrictions and extensions by
|
54
|
+
Adobe. The minimum XHTML and CSS elements that a standards-compliant
|
55
|
+
XFA processor (e.g. Adobe Reader) must support are also listed there
|
56
|
+
and can be used as a guide.
|
57
|
+
|
58
|
+
**Note**: Rich text values are not HTML-escaped or sanitized in any
|
59
|
+
way. It is suggested that you call `CGI.escape_html` on user-supplied
|
60
|
+
input.
|
61
|
+
|
62
|
+
### Checkbox Groups
|
63
|
+
Because there is no such thing as a "checkbox group," the
|
64
|
+
`checkbox_group` syntax is simply syntactic sugar for calling
|
65
|
+
`check` with the group name and a `.` prepended to the name. For
|
66
|
+
example,
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
checkbox_group 'relation' do
|
70
|
+
check 'parent'
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
is equivalent to
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
check 'relation.parent'
|
78
|
+
```
|
79
|
+
|
80
|
+
## Copyright
|
81
|
+
|
82
|
+
Copyright (c) 2012 Abe Voelker. Released under the terms of the
|
83
|
+
MIT license. See LICENSE for details.
|
84
|
+
|
85
|
+
[1]: http://partners.adobe.com/public/developer/xml/index_arch.html
|
data/Rakefile
ADDED
data/lib/pdf_ravager.rb
ADDED
@@ -0,0 +1,105 @@
|
|
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
|
+
if opts.empty?
|
15
|
+
@fields << {:name => name, :value => value, :type => :text}
|
16
|
+
else
|
17
|
+
@fields << {:name => name, :value => value, :type => :text, :options => opts}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def check(name, opts={})
|
22
|
+
@fields << {:name => name, :value => true, :type => :checkbox}
|
23
|
+
end
|
24
|
+
|
25
|
+
def radio_group(gname, &blk)
|
26
|
+
fields = []
|
27
|
+
# TODO: replace w/ singleton method?
|
28
|
+
PDF.instance_eval do
|
29
|
+
send(:define_method, :fill) do |name, opts={}|
|
30
|
+
fields << {:name => gname, :value => name, :type => :radio}
|
31
|
+
end
|
32
|
+
blk.call
|
33
|
+
send(:undef_method, :fill)
|
34
|
+
end
|
35
|
+
|
36
|
+
@fields += fields
|
37
|
+
end
|
38
|
+
|
39
|
+
def checkbox_group(gname, &blk)
|
40
|
+
# TODO: replace w/ singleton method?
|
41
|
+
PDF.instance_eval do
|
42
|
+
alias_method :__check_original__, :check
|
43
|
+
send(:define_method, :check) do |name, opts={}|
|
44
|
+
__check_original__("#{gname}.#{name}", opts)
|
45
|
+
end
|
46
|
+
blk.call
|
47
|
+
# restore check method back to normal
|
48
|
+
alias_method :check, :__check_original__
|
49
|
+
send(:undef_method, :__check_original__)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
if RUBY_PLATFORM =~ /java/
|
54
|
+
def ravage(file, opts={})
|
55
|
+
PDFRavager::Ravager.open(opts.merge(:in_file => file)) do |pdf|
|
56
|
+
@fields.each do |f|
|
57
|
+
value = if f[:type] == :checkbox
|
58
|
+
!!f[:value] ? '1' : '0' # Checkbox default string values
|
59
|
+
else
|
60
|
+
f[:value]
|
61
|
+
end
|
62
|
+
pdf.set_field_value(f[:name], value, f[:type], f[:options])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
else
|
67
|
+
def ravage(file, opts={})
|
68
|
+
raise "You can only ravage .pdfs using JRuby, not #{RUBY_PLATFORM}!"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def ==(other)
|
73
|
+
self.name == other.name && self.fields == other.fields
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_json(*args)
|
77
|
+
{
|
78
|
+
"json_class" => self.class.name,
|
79
|
+
"data" => {"name" => @name, "fields" => @fields }
|
80
|
+
}.to_json(*args)
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.json_create(obj)
|
84
|
+
fields = obj["data"]["fields"].map do |f|
|
85
|
+
# symbolize the root keys
|
86
|
+
f = f.inject({}){|h,(k,v)| h[k.to_sym] = v; h}
|
87
|
+
f[:type] = f[:type].to_sym if f[:type]
|
88
|
+
# symbolize the :options keys
|
89
|
+
if f[:options]
|
90
|
+
f[:options] = f[:options].inject({}){|h,(k,v)| h[k.to_sym] = v; h}
|
91
|
+
end
|
92
|
+
f
|
93
|
+
end
|
94
|
+
o = new(obj["data"]["name"], :fields => fields)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
module Kernel
|
100
|
+
def pdf(name=nil, opts={}, &blk)
|
101
|
+
r = PDFRavager::PDF.new(name, opts)
|
102
|
+
r.instance_eval(&blk)
|
103
|
+
r
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'java'
|
2
|
+
require 'nokogiri'
|
3
|
+
require File.dirname(__FILE__) + '/../../vendor/iText-4.2.0'
|
4
|
+
|
5
|
+
java_import "com.lowagie.text.pdf.AcroFields"
|
6
|
+
java_import "com.lowagie.text.pdf.PdfArray"
|
7
|
+
java_import "com.lowagie.text.pdf.PdfDictionary"
|
8
|
+
java_import "com.lowagie.text.pdf.PdfName"
|
9
|
+
java_import "com.lowagie.text.pdf.PdfObject"
|
10
|
+
java_import "com.lowagie.text.pdf.PdfReader"
|
11
|
+
java_import "com.lowagie.text.pdf.PdfStamper"
|
12
|
+
java_import "com.lowagie.text.pdf.PdfStream"
|
13
|
+
java_import "com.lowagie.text.pdf.PdfWriter"
|
14
|
+
java_import "com.lowagie.text.pdf.XfaForm"
|
15
|
+
java_import "com.lowagie.text.pdf.XfdfReader"
|
16
|
+
|
17
|
+
module PDFRavager
|
18
|
+
class Ravager
|
19
|
+
private_class_method :new
|
20
|
+
|
21
|
+
def self.open(opts={}, &block)
|
22
|
+
opts = {:in_file => opts} if opts.is_a? String
|
23
|
+
out = if opts[:out_file]
|
24
|
+
java.io.FileOutputStream.new(opts[:out_file])
|
25
|
+
else
|
26
|
+
java.io.ByteArrayOutputStream.new
|
27
|
+
end
|
28
|
+
raise "You must pass a block" unless block_given?
|
29
|
+
ravager = new(opts.merge({:out => out}))
|
30
|
+
yield ravager
|
31
|
+
ravager.destroy
|
32
|
+
out
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_field_value(name, value, type=nil, options={})
|
36
|
+
return set_rich_text_field(name, value) if options && options[:rich]
|
37
|
+
begin
|
38
|
+
# First try AcroForms method of setting value
|
39
|
+
@afields.setField(SOM.short_name(name), value)
|
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>"
|
47
|
+
Nokogiri::XML::Builder.with(node) do |xml|
|
48
|
+
xml.value_ {
|
49
|
+
xml.text_ {
|
50
|
+
xml.text value
|
51
|
+
}
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
@xfa.setDomDocument(doc.to_java)
|
56
|
+
@xfa.setChanged(true)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def destroy
|
61
|
+
read_only! if @opts[:read_only]
|
62
|
+
@stamper.close
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def initialize(opts={})
|
68
|
+
@opts = opts
|
69
|
+
@reader = PdfReader.new(opts[:in_file])
|
70
|
+
@stamper = PdfStamper.new(@reader, opts[:out])
|
71
|
+
@afields = @stamper.getAcroFields
|
72
|
+
@xfa = @afields.getXfa
|
73
|
+
@som = @xfa.getDatasetsSom
|
74
|
+
@som_template = @xfa.getTemplateSom
|
75
|
+
@type = @xfa.isXfaPresent ? :xfa : :acro_forms
|
76
|
+
if @type == :xfa
|
77
|
+
@xfa_type = @afields.getFields.empty? ? :dynamic : :static
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def set_rich_text_field(name, value)
|
82
|
+
doc = Nokogiri::XML(Nokogiri::XML::Document.wrap(@xfa.getDomDocument).to_xml)
|
83
|
+
doc.xpath("//*[local-name()='field'][@name='#{name}']").each do |node|
|
84
|
+
Nokogiri::XML::Builder.with(node) do |xml|
|
85
|
+
xml.value_ do
|
86
|
+
xml.exData('contentType' => 'text/html') do
|
87
|
+
xml.body_('xmlns' => "http://www.w3.org/1999/xhtml", 'xmlns:xfa' => "http://www.xfa.org/schema/xfa-data/1.0/") do
|
88
|
+
xml << value # Note: this value is not sanitized/escaped!
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
@xfa.setDomDocument(doc.to_java)
|
95
|
+
@xfa.setChanged(true)
|
96
|
+
end
|
97
|
+
|
98
|
+
def read_only!
|
99
|
+
case @type
|
100
|
+
when :acro_forms
|
101
|
+
@stamper.setFormFlattening(true)
|
102
|
+
when :xfa
|
103
|
+
if @xfa_type == :static
|
104
|
+
@stamper.setFormFlattening(true)
|
105
|
+
else
|
106
|
+
doc = Nokogiri::XML(Nokogiri::XML::Document.wrap(@xfa.getDomDocument).to_xml)
|
107
|
+
doc.xpath("//*[local-name()='field']").each do |node|
|
108
|
+
node["access"] = "readOnly"
|
109
|
+
end
|
110
|
+
@xfa.setDomDocument(doc.to_java)
|
111
|
+
@xfa.setChanged(true)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class SOM
|
118
|
+
def self.short_name(str)
|
119
|
+
XfaForm::Xml2Som.getShortName(self.escape(str))
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.escape(str)
|
123
|
+
XfaForm::Xml2Som.escapeSom(str) # just does: str.gsub(/\./) { '\\.' }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/pdf_ravager.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
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.authors = ['Abe Voelker']
|
8
|
+
s.email = 'abe@abevoelker.com'
|
9
|
+
s.homepage = 'https://github.com/abevoelker/pdf_ravager'
|
10
|
+
s.summary = %q{DSL to aid filling out AcroForms PDF and XFA documents}
|
11
|
+
s.description = %q{DSL to aid filling out AcroForms PDF and XFA documents}
|
12
|
+
|
13
|
+
s.add_dependency "json"
|
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"
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
end
|
data/spec/pdf_spec.rb
ADDED
@@ -0,0 +1,48 @@
|
|
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', 'foo'
|
8
|
+
text 'rich_text', '<b>foo</b>', :rich => true
|
9
|
+
check 'checkbox'
|
10
|
+
checkbox_group 'checkbox_group' do
|
11
|
+
check 'foo'
|
12
|
+
end
|
13
|
+
radio_group 'radio_group' do
|
14
|
+
fill 'foo'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
@pdf_from_json = JSON.parse(@pdf.to_json)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_that_name_is_set
|
22
|
+
assert_equal @pdf.name, 'foo.pdf'
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_that_text_is_set
|
26
|
+
assert_includes @pdf.fields, {:name => 'text', :value => 'foo', :type => :text}
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_that_rich_text_is_set
|
30
|
+
assert_includes @pdf.fields, {:name => 'rich_text', :value => '<b>foo</b>', :type => :text, :options => {:rich => true}}
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_that_checkbox_is_set
|
34
|
+
assert_includes @pdf.fields, {:name => 'checkbox', :value => true, :type => :checkbox}
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_that_checkbox_group_is_set
|
38
|
+
assert_includes @pdf.fields, {:name => 'checkbox_group.foo', :value => true, :type => :checkbox}
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_that_radio_group_is_set
|
42
|
+
assert_includes @pdf.fields, {:name => 'radio_group', :value => 'foo', :type => :radio}
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_json_serialization
|
46
|
+
assert_equal @pdf, @pdf_from_json
|
47
|
+
end
|
48
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'turn/autorun'
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pdf_ravager
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.7
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Abe Voelker
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-10-30 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: nokogiri
|
32
|
+
version_requirements: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ! '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
none: false
|
38
|
+
requirement: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ! '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
none: false
|
44
|
+
prerelease: false
|
45
|
+
type: :runtime
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: bundler
|
48
|
+
version_requirements: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ~>
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '1.0'
|
53
|
+
none: false
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ~>
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '1.0'
|
59
|
+
none: false
|
60
|
+
prerelease: false
|
61
|
+
type: :development
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: minitest
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.1'
|
69
|
+
none: false
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ~>
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '4.1'
|
75
|
+
none: false
|
76
|
+
prerelease: false
|
77
|
+
type: :development
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ~>
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '2.11'
|
85
|
+
none: false
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '2.11'
|
91
|
+
none: false
|
92
|
+
prerelease: false
|
93
|
+
type: :development
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rake
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ~>
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0.9'
|
101
|
+
none: false
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ~>
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0.9'
|
107
|
+
none: false
|
108
|
+
prerelease: false
|
109
|
+
type: :development
|
110
|
+
description: DSL to aid filling out AcroForms PDF and XFA documents
|
111
|
+
email: abe@abevoelker.com
|
112
|
+
executables: []
|
113
|
+
extensions: []
|
114
|
+
extra_rdoc_files: []
|
115
|
+
files:
|
116
|
+
- .gitignore
|
117
|
+
- .travis.yml
|
118
|
+
- Gemfile
|
119
|
+
- LICENSE
|
120
|
+
- README.md
|
121
|
+
- Rakefile
|
122
|
+
- lib/pdf_ravager.rb
|
123
|
+
- lib/pdf_ravager/pdf.rb
|
124
|
+
- lib/pdf_ravager/ravager.rb
|
125
|
+
- lib/pdf_ravager/version.rb
|
126
|
+
- pdf_ravager.gemspec
|
127
|
+
- spec/pdf_spec.rb
|
128
|
+
- spec/spec_helper.rb
|
129
|
+
- vendor/iText-4.2.0.jar
|
130
|
+
homepage: https://github.com/abevoelker/pdf_ravager
|
131
|
+
licenses: []
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ! '>='
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
none: false
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ! '>='
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
none: false
|
148
|
+
requirements: []
|
149
|
+
rubyforge_project:
|
150
|
+
rubygems_version: 1.8.24
|
151
|
+
signing_key:
|
152
|
+
specification_version: 3
|
153
|
+
summary: DSL to aid filling out AcroForms PDF and XFA documents
|
154
|
+
test_files: []
|
155
|
+
...
|