pdf-forms 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,69 @@
1
+ = pdf-forms
2
+ http://github.com/jkraemer/pdf-forms/
3
+ by Jens Kraemer, jk@jkraemer.net
4
+
5
+ == DESCRIPTION:
6
+
7
+ Fill out PDF forms with pdftk (http://www.accesspdf.com/pdftk/).
8
+
9
+ == EXAMPLE:
10
+
11
+ === FDF creation
12
+
13
+ fdf = PdfForms::Fdf.new :key => 'value', :other_key => 'other value'
14
+ # use to_fdf if you just want the fdf data, without writing it to a file
15
+ puts fdf.to_fdf
16
+ # write fdf file
17
+ fdf.save_to 'path/to/file.fdf'
18
+
19
+ === Query form fields and fill out PDF forms with pdftk
20
+
21
+ First get pdftk from http://www.accesspdf.com/pdftk/ and install it.
22
+
23
+ # adjust the pdftk path to suit your pdftk installation
24
+ pdftk = PdfForms.new('/usr/local/bin/pdftk')
25
+
26
+ # find out the field names that are present in form.pdf
27
+ pdftk.get_field_names 'path/to/form.pdf'
28
+
29
+ # take form.pdf, set the 'foo' field to 'bar' and save the document to myform.pdf
30
+ pdftk.fill_form '/path/to/form.pdf', 'myform.pdf', :foo => 'bar'
31
+
32
+
33
+
34
+ == INSTALL:
35
+
36
+ $ sudo gem install jkraemer-pdf-forms
37
+
38
+ == CODE:
39
+
40
+ $ git clone http://github.com/jkraemer/pdf-forms.git
41
+
42
+ == Prior Art
43
+
44
+ The FDF generation part is a straight port of Steffen Schwigon's PDF::FDF::Simple perl module. Didn't port the FDF parsing, though ;-)
45
+
46
+ == LICENSE:
47
+
48
+ (The MIT License)
49
+
50
+ Copyright (c) 2009 Jens Kraemer
51
+
52
+ Permission is hereby granted, free of charge, to any person obtaining
53
+ a copy of this software and associated documentation files (the
54
+ 'Software'), to deal in the Software without restriction, including
55
+ without limitation the rights to use, copy, modify, merge, publish,
56
+ distribute, sublicense, and/or sell copies of the Software, and to
57
+ permit persons to whom the Software is furnished to do so, subject to
58
+ the following conditions:
59
+
60
+ The above copyright notice and this permission notice shall be
61
+ included in all copies or substantial portions of the Software.
62
+
63
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
64
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
65
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
66
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
67
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
68
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
69
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,11 @@
1
+ require 'pdf_forms/version'
2
+ require 'pdf_forms/fdf'
3
+ require 'pdf_forms/pdf'
4
+ require 'pdf_forms/pdftk_wrapper'
5
+
6
+ module PdfForms
7
+ # shorthand for PdfForms::PdftkWrapper.new(...)
8
+ def self.new(*args)
9
+ PdftkWrapper.new *args
10
+ end
11
+ end
@@ -0,0 +1,89 @@
1
+ module PdfForms
2
+
3
+ # Map keys and values to Adobe's FDF format.
4
+ #
5
+ # Straight port of Perl's PDF::FDF::Simple by Steffen Schwigon.
6
+ # Parsing FDF files is not supported (yet).
7
+ class Fdf
8
+
9
+ attr_reader :options
10
+
11
+ def initialize(data = {}, options = {})
12
+ @data = data
13
+ @options = {
14
+ :file => nil,
15
+ :ufile => nil,
16
+ :id => nil
17
+ }.merge(options)
18
+ end
19
+
20
+ # generate FDF content
21
+ def to_fdf
22
+ fdf = header
23
+
24
+ @data.each do |key, value|
25
+ if Hash === value
26
+ value.each do |sub_key, sub_value|
27
+ fdf << field("#{key}_#{sub_key}", sub_value)
28
+ end
29
+ else
30
+ fdf << field(key, value)
31
+ end
32
+ end
33
+
34
+ fdf << footer
35
+ return fdf
36
+ end
37
+
38
+ # write fdf content to path
39
+ def save_to(path)
40
+ (File.open(path, 'w') << to_fdf).close
41
+ end
42
+
43
+ protected
44
+
45
+ def header
46
+ header = "%FDF-1.2\n\n1 0 obj\n<<\n/FDF << /Fields 2 0 R"
47
+
48
+ # /F
49
+ header << "/F (#{options[:file]})" if options[:file]
50
+ # /UF
51
+ header << "/UF (#{options[:ufile]})" if options[:ufile]
52
+ # /ID
53
+ header << "/ID[" << options[:id].join << "]" if options[:id]
54
+
55
+ header << ">>\n>>\nendobj\n2 0 obj\n["
56
+ return header
57
+ end
58
+
59
+ def field(key, value)
60
+ "<</T(#{key})/V" +
61
+ (Array === value ? "[#{value.map{ |v|"(#{quote(v)})" }.join}]" : "(#{quote(value)})") +
62
+ ">>\n"
63
+ end
64
+
65
+ def quote(value)
66
+ value.to_s.strip.
67
+ gsub( /\\/, '\\' ).
68
+ gsub( /\(/, '\(' ).
69
+ gsub( /\)/, '\)' ).
70
+ gsub( /\n/, '\r' )
71
+ end
72
+
73
+ FOOTER =<<-EOFOOTER
74
+ ]
75
+ endobj
76
+ trailer
77
+ <<
78
+ /Root 1 0 R
79
+
80
+ >>
81
+ %%EOF
82
+ EOFOOTER
83
+
84
+ def footer
85
+ FOOTER
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,25 @@
1
+ module PdfForms
2
+ class Pdf
3
+ attr_reader :path
4
+
5
+ def initialize(path, pdftk)
6
+ @path = path
7
+ @pdftk = pdftk
8
+ end
9
+
10
+ def fields
11
+ @fields ||= read_fields
12
+ end
13
+
14
+ protected
15
+
16
+ def read_fields
17
+ field_output = @pdftk.call_pdftk "'#{path}'", 'dump_data_fields'
18
+ @fields = field_output.split(/^---\n/).map do |field_text|
19
+ if field_text =~ /^FieldName: (\w+)$/
20
+ $1
21
+ end
22
+ end.compact.uniq
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,47 @@
1
+ require 'tempfile'
2
+ module PdfForms
3
+ # Wraps calls to PdfTk
4
+ class PdftkWrapper
5
+
6
+ attr_reader :pdftk, :options
7
+
8
+ # PdftkWrapper.new('/usr/bin/pdftk', :encrypt => true, :encrypt_options => 'allow Printing')
9
+ def initialize(pdftk_path, options = {})
10
+ @pdftk = pdftk_path
11
+ @options = options
12
+ end
13
+
14
+ # pdftk.fill_form '/path/to/form.pdf', '/path/to/destination.pdf', :field1 => 'value 1'
15
+ def fill_form(template, destination, data = {})
16
+ fdf = Fdf.new(data)
17
+ tmp = Tempfile.new('pdf_forms-fdf')
18
+ tmp.close
19
+ fdf.save_to tmp.path
20
+ call_pdftk "'#{template}'", 'fill_form', tmp.path, 'output', destination, 'flatten', encrypt_options(tmp.path)
21
+ tmp.unlink
22
+ end
23
+
24
+ # pdftk.read '/path/to/form.pdf'
25
+ # returns an instance of PdfForms::Pdf representing the given template
26
+ def read(path)
27
+ Pdf.new path, self
28
+ end
29
+
30
+ def get_field_names(template)
31
+ read(template).fields
32
+ end
33
+
34
+ def call_pdftk(*args)
35
+ %x{#{pdftk} #{args.flatten.compact.join ' '}}
36
+ end
37
+
38
+ protected
39
+
40
+ def encrypt_options(pwd)
41
+ if options[:encrypt]
42
+ ['encrypt_128bit', 'owner_pw', pwd, options[:encrypt_options]]
43
+ end
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,3 @@
1
+ module PdfForms
2
+ VERSION = '0.3.0'
3
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pdf-forms
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.3.0
6
+ platform: ruby
7
+ authors:
8
+ - "Jens Kr\xC3\xA4mer"
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-05-10 00:00:00 +02:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: Fill out PDF forms with pdftk (http://www.accesspdf.com/pdftk/).
18
+ email:
19
+ - jk@jkraemer.net
20
+ executables: []
21
+
22
+ extensions: []
23
+
24
+ extra_rdoc_files: []
25
+
26
+ files:
27
+ - lib/pdf_forms/fdf.rb
28
+ - lib/pdf_forms/pdf.rb
29
+ - lib/pdf_forms/pdftk_wrapper.rb
30
+ - lib/pdf_forms/version.rb
31
+ - lib/pdf_forms.rb
32
+ - README.rdoc
33
+ has_rdoc: true
34
+ homepage: http://github.com/jkraemer/pdf-forms
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options: []
39
+
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.3.6
54
+ requirements: []
55
+
56
+ rubyforge_project: pdf-forms
57
+ rubygems_version: 1.6.2
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: Fill out PDF forms with pdftk (http://www.accesspdf.com/pdftk/).
61
+ test_files: []
62
+