prawn-forms 0.1
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/README.markdown +67 -0
- data/lib/prawn/forms.rb +100 -0
- metadata +50 -0
data/README.markdown
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# prawn-forms
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
This is the beginnings of a prawn extension for adding interactive forms to
|
6
|
+
PDFs.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
gem install prawn-forms
|
11
|
+
|
12
|
+
## Usage
|
13
|
+
|
14
|
+
Prawn-Forms depends on the core prawn library, and simply adds a few additional
|
15
|
+
methods to the standard Prawn::Document object that allow you to add form elements
|
16
|
+
to your output.
|
17
|
+
|
18
|
+
Start by requiring the prawn library, then the prawn-forms library. Build your PDF as usual,
|
19
|
+
and use methods like text_field() to add a free text input box.
|
20
|
+
|
21
|
+
require 'prawn'
|
22
|
+
require 'prawn/forms'
|
23
|
+
|
24
|
+
Prawn::Document.generate "form.pdf" do |pdf|
|
25
|
+
pdf.text_field("fname", 100, 560, 200, 16)
|
26
|
+
end
|
27
|
+
|
28
|
+
For further examples and documentation, check out the examples/ directory of this project
|
29
|
+
and the code docs for the Prawn::Forms module.
|
30
|
+
|
31
|
+
## Technical Discussion
|
32
|
+
|
33
|
+
Interactive forms are primarily defined by section 8.6 the PDF spec. The visual
|
34
|
+
appearance of fields is controlled using widget annotations, defined in section
|
35
|
+
8.4.5.
|
36
|
+
|
37
|
+
A PDF can contain *one* form.
|
38
|
+
|
39
|
+
The form is defined by a dict linked via the AcroForm entry in the root
|
40
|
+
catalog. Amongst other entries, the form dict has a Fields entry that holds an
|
41
|
+
array of all the form fields. The array should be indirect references to a
|
42
|
+
dicts, generally one per field.
|
43
|
+
|
44
|
+
Each field dict can link to one or more widget annotations that define the visual
|
45
|
+
appearance in various states. It seems most fields have a single widget
|
46
|
+
annotation, in which case it is permitted to merge the field and annotation
|
47
|
+
dicts into a single dict. Annotation and field dicts have no common keys, so
|
48
|
+
there is no conflict.
|
49
|
+
|
50
|
+
For the fields to appear on the page, the widget annotation (or merged
|
51
|
+
field/widget dict) must appear in the page Annots entry.
|
52
|
+
|
53
|
+
## Disclaimer
|
54
|
+
|
55
|
+
This code is still very much experimental and is not recommended for use in
|
56
|
+
production systems.
|
57
|
+
|
58
|
+
## Licensing
|
59
|
+
|
60
|
+
This library is distributed under the terms of the MIT License. See the included file for
|
61
|
+
more detail.
|
62
|
+
|
63
|
+
## Further Reading
|
64
|
+
|
65
|
+
- The source: [http://github.com/yob/prawn-js/tree/master](http://github.com/yob/prawn-forms/tree/master)
|
66
|
+
- Prawn source: [http://github.com/sandal/prawn/tree/master](http://github.com/sandal/prawn/tree/master)
|
67
|
+
- Rubyforge: [http://rubyforge.org/projects/prawn](http://rubyforge.org/projects/prawn)
|
data/lib/prawn/forms.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# forms.rb : Interactive form support for prawn
|
4
|
+
#
|
5
|
+
# Copyright August 2009, James Healy. All Rights Reserved.
|
6
|
+
#
|
7
|
+
# This is free software. Please see the LICENSE file for details.
|
8
|
+
|
9
|
+
module Prawn
|
10
|
+
module Forms
|
11
|
+
|
12
|
+
def button(text)
|
13
|
+
add_interactive_field(:Btn, :T => Prawn::Core::LiteralString.new(text),
|
14
|
+
:DA => Prawn::Core::LiteralString.new("/Helv 0 Tf 0 g"),
|
15
|
+
:F => 4,
|
16
|
+
:Ff => 65536,
|
17
|
+
:MK => {:CA => Prawn::Core::LiteralString.new(text), :BG => [0.75294, 0.75294, 0.75294], :BC => [0.75294, 0.75294, 0.75294]},
|
18
|
+
:Rect => [304.5, 537.39, 429, 552.39])
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
def text_field(name, x, y, w, h, opts = {})
|
23
|
+
x, y = map_to_absolute(x, y)
|
24
|
+
|
25
|
+
field_dict = {:T => Prawn::Core::LiteralString.new(name),
|
26
|
+
:DA => Prawn::Core::LiteralString.new("/Helv 0 Tf 0 g"),
|
27
|
+
:F => 4,
|
28
|
+
:Ff => flags_from_options(opts),
|
29
|
+
:BS => {:Type => :Border, :W => 1, :S => :S},
|
30
|
+
:MK => {:BC => [0, 0, 0]},
|
31
|
+
:Rect => [x, y, x + w, y - h]}
|
32
|
+
|
33
|
+
if opts[:default]
|
34
|
+
field_dict[:V] = Prawn::Core::LiteralString.new(opts[:default])
|
35
|
+
end
|
36
|
+
|
37
|
+
add_interactive_field(:Tx, field_dict)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def add_interactive_field(type, opts = {})
|
43
|
+
defaults = {:FT => type, :Type => :Annot, :Subtype => :Widget}
|
44
|
+
annotation = ref!(opts.merge(defaults))
|
45
|
+
acroform.data[:Fields] << annotation
|
46
|
+
state.page.dictionary.data[:Annots] ||= []
|
47
|
+
state.page.dictionary.data[:Annots] << annotation
|
48
|
+
end
|
49
|
+
|
50
|
+
# The AcroForm dictionary (PDF spec 8.6) for this document. It is
|
51
|
+
# lazily initialized, so that documents that do not use interactive
|
52
|
+
# forms do not incur the additional overhead.
|
53
|
+
def acroform
|
54
|
+
state.store.root.data[:AcroForm] ||=
|
55
|
+
ref!({:DR => acroform_resources,
|
56
|
+
:DA => Prawn::Core::LiteralString.new("/Helv 0 Tf 0 g"),
|
57
|
+
:Fields => []})
|
58
|
+
end
|
59
|
+
|
60
|
+
# a resource dictionary for interactive forms. At a minimum,
|
61
|
+
# must contain the font we want to use
|
62
|
+
def acroform_resources
|
63
|
+
helv = ref!(:Type => :Font,
|
64
|
+
:Subtype => :Type1,
|
65
|
+
:BaseFont => :Helvetica,
|
66
|
+
:Encoding => :WinAnsiEncoding)
|
67
|
+
ref!(:Font => {:Helv => helv})
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns the integer value for the /Ff (flags) entry in the field
|
71
|
+
# dictionary, based on the options provided.
|
72
|
+
#
|
73
|
+
def flags_from_options(opts)
|
74
|
+
flags = 0
|
75
|
+
|
76
|
+
flags |= 1<<12 if opts[:multiline]
|
77
|
+
flags |= 1<<13 if opts[:password]
|
78
|
+
|
79
|
+
if opts[:file_select]
|
80
|
+
min_version 1.4
|
81
|
+
flags |= 1<<20
|
82
|
+
end
|
83
|
+
|
84
|
+
if opts[:do_not_spell_check]
|
85
|
+
min_version 1.4
|
86
|
+
flags |= 1<<22
|
87
|
+
end
|
88
|
+
|
89
|
+
if opts[:do_not_scroll]
|
90
|
+
min_version 1.4
|
91
|
+
flags |= 1<<23
|
92
|
+
end
|
93
|
+
|
94
|
+
flags
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
require 'prawn/document'
|
100
|
+
Prawn::Document.send(:include, Prawn::Forms)
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: prawn-forms
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brad Ediger
|
9
|
+
- James Healy
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2014-06-16 00:00:00.000000000 Z
|
14
|
+
dependencies: []
|
15
|
+
description: This is the beginnings of a prawn extension for adding interactive forms
|
16
|
+
to PDFs.
|
17
|
+
email: ''
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- lib/prawn/forms.rb
|
23
|
+
- README.markdown
|
24
|
+
homepage: https://github.com/yob/prawn-forms
|
25
|
+
licenses: []
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ! '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubyforge_project:
|
44
|
+
rubygems_version: 1.8.29
|
45
|
+
signing_key:
|
46
|
+
specification_version: 3
|
47
|
+
summary: This is the beginnings of a prawn extension for adding interactive forms
|
48
|
+
to PDFs.
|
49
|
+
test_files: []
|
50
|
+
has_rdoc:
|