origami-docspring 2.2.0 → 2.3.0

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.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/examples/attachments/attachment.rb +7 -8
  4. data/examples/attachments/nested_document.rb +6 -5
  5. data/examples/encryption/encryption.rb +5 -4
  6. data/examples/events/events.rb +7 -6
  7. data/examples/flash/flash.rb +10 -9
  8. data/examples/forms/javascript.rb +14 -13
  9. data/examples/forms/xfa.rb +67 -66
  10. data/examples/javascript/hello_world.rb +6 -5
  11. data/examples/javascript/js_emulation.rb +26 -26
  12. data/examples/loop/goto.rb +12 -11
  13. data/examples/loop/named.rb +17 -16
  14. data/examples/signature/signature.rb +11 -11
  15. data/examples/uri/javascript.rb +25 -24
  16. data/examples/uri/open-uri.rb +5 -4
  17. data/examples/uri/submitform.rb +11 -10
  18. data/lib/origami/3d.rb +330 -334
  19. data/lib/origami/acroform.rb +267 -268
  20. data/lib/origami/actions.rb +266 -278
  21. data/lib/origami/annotations.rb +659 -670
  22. data/lib/origami/array.rb +192 -196
  23. data/lib/origami/boolean.rb +66 -70
  24. data/lib/origami/catalog.rb +360 -363
  25. data/lib/origami/collections.rb +132 -133
  26. data/lib/origami/compound.rb +125 -129
  27. data/lib/origami/destinations.rb +226 -237
  28. data/lib/origami/dictionary.rb +155 -154
  29. data/lib/origami/encryption.rb +967 -923
  30. data/lib/origami/extensions/fdf.rb +270 -275
  31. data/lib/origami/extensions/ppklite.rb +323 -328
  32. data/lib/origami/filespec.rb +170 -173
  33. data/lib/origami/filters/ascii.rb +162 -167
  34. data/lib/origami/filters/ccitt/tables.rb +248 -252
  35. data/lib/origami/filters/ccitt.rb +309 -312
  36. data/lib/origami/filters/crypt.rb +31 -34
  37. data/lib/origami/filters/dct.rb +47 -50
  38. data/lib/origami/filters/flate.rb +57 -60
  39. data/lib/origami/filters/jbig2.rb +50 -53
  40. data/lib/origami/filters/jpx.rb +40 -43
  41. data/lib/origami/filters/lzw.rb +151 -155
  42. data/lib/origami/filters/predictors.rb +250 -255
  43. data/lib/origami/filters/runlength.rb +111 -115
  44. data/lib/origami/filters.rb +319 -325
  45. data/lib/origami/font.rb +173 -177
  46. data/lib/origami/functions.rb +62 -66
  47. data/lib/origami/graphics/colors.rb +203 -208
  48. data/lib/origami/graphics/instruction.rb +79 -81
  49. data/lib/origami/graphics/path.rb +141 -144
  50. data/lib/origami/graphics/patterns.rb +156 -160
  51. data/lib/origami/graphics/render.rb +51 -47
  52. data/lib/origami/graphics/state.rb +144 -142
  53. data/lib/origami/graphics/text.rb +185 -188
  54. data/lib/origami/graphics/xobject.rb +818 -804
  55. data/lib/origami/graphics.rb +25 -26
  56. data/lib/origami/header.rb +63 -65
  57. data/lib/origami/javascript.rb +718 -651
  58. data/lib/origami/linearization.rb +284 -285
  59. data/lib/origami/metadata.rb +156 -135
  60. data/lib/origami/name.rb +98 -100
  61. data/lib/origami/null.rb +49 -51
  62. data/lib/origami/numeric.rb +133 -135
  63. data/lib/origami/obfuscation.rb +180 -182
  64. data/lib/origami/object.rb +634 -631
  65. data/lib/origami/optionalcontent.rb +147 -149
  66. data/lib/origami/outline.rb +46 -48
  67. data/lib/origami/outputintents.rb +76 -77
  68. data/lib/origami/page.rb +637 -596
  69. data/lib/origami/parser.rb +214 -221
  70. data/lib/origami/parsers/fdf.rb +44 -45
  71. data/lib/origami/parsers/pdf/lazy.rb +147 -154
  72. data/lib/origami/parsers/pdf/linear.rb +104 -109
  73. data/lib/origami/parsers/pdf.rb +109 -107
  74. data/lib/origami/parsers/ppklite.rb +44 -46
  75. data/lib/origami/pdf.rb +886 -896
  76. data/lib/origami/reference.rb +116 -120
  77. data/lib/origami/signature.rb +617 -625
  78. data/lib/origami/stream.rb +560 -558
  79. data/lib/origami/string.rb +366 -368
  80. data/lib/origami/template/patterns.rb +50 -52
  81. data/lib/origami/template/widgets.rb +111 -114
  82. data/lib/origami/trailer.rb +153 -157
  83. data/lib/origami/tree.rb +55 -57
  84. data/lib/origami/version.rb +19 -19
  85. data/lib/origami/webcapture.rb +87 -90
  86. data/lib/origami/xfa/config.rb +409 -414
  87. data/lib/origami/xfa/connectionset.rb +113 -117
  88. data/lib/origami/xfa/datasets.rb +38 -42
  89. data/lib/origami/xfa/localeset.rb +33 -37
  90. data/lib/origami/xfa/package.rb +49 -52
  91. data/lib/origami/xfa/pdf.rb +54 -59
  92. data/lib/origami/xfa/signature.rb +33 -37
  93. data/lib/origami/xfa/sourceset.rb +34 -38
  94. data/lib/origami/xfa/stylesheet.rb +35 -39
  95. data/lib/origami/xfa/template.rb +1630 -1634
  96. data/lib/origami/xfa/xdc.rb +33 -37
  97. data/lib/origami/xfa/xfa.rb +132 -123
  98. data/lib/origami/xfa/xfdf.rb +34 -38
  99. data/lib/origami/xfa/xmpmeta.rb +34 -38
  100. data/lib/origami/xfa.rb +50 -53
  101. data/lib/origami/xreftable.rb +462 -462
  102. data/lib/origami.rb +37 -38
  103. data/test/test_actions.rb +22 -20
  104. data/test/test_annotations.rb +54 -52
  105. data/test/test_forms.rb +23 -21
  106. data/test/test_native_types.rb +82 -78
  107. data/test/test_object_tree.rb +25 -24
  108. data/test/test_pages.rb +43 -41
  109. data/test/test_pdf.rb +2 -0
  110. data/test/test_pdf_attachment.rb +23 -21
  111. data/test/test_pdf_create.rb +16 -15
  112. data/test/test_pdf_encrypt.rb +69 -66
  113. data/test/test_pdf_parse.rb +131 -129
  114. data/test/test_pdf_parse_lazy.rb +53 -53
  115. data/test/test_pdf_sign.rb +67 -67
  116. data/test/test_streams.rb +145 -143
  117. data/test/test_xrefs.rb +46 -45
  118. metadata +64 -8
@@ -1,190 +1,186 @@
1
- =begin
2
-
3
- This file is part of Origami, PDF manipulation framework for Ruby
4
- Copyright (C) 2016 Guillaume Delugré.
5
-
6
- Origami is free software: you can redistribute it and/or modify
7
- it under the terms of the GNU Lesser General Public License as published by
8
- the Free Software Foundation, either version 3 of the License, or
9
- (at your option) any later version.
10
-
11
- Origami is distributed in the hope that it will be useful,
12
- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- GNU Lesser General Public License for more details.
15
-
16
- You should have received a copy of the GNU Lesser General Public License
17
- along with Origami. If not, see <http://www.gnu.org/licenses/>.
18
-
19
- =end
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # This file is part of Origami, PDF manipulation framework for Ruby
5
+ # Copyright (C) 2016 Guillaume Delugré.
6
+ #
7
+ # Origami is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # Origami is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with Origami. If not, see <http://www.gnu.org/licenses/>.
19
+ #
20
20
 
21
21
  module Origami
22
+ class PDF
23
+ #
24
+ # Returns the current trailer.
25
+ # This might be either a Trailer or XRefStream.
26
+ #
27
+ def trailer
28
+ #
29
+ # First look for a standard trailer dictionary
30
+ #
31
+ trl = if @revisions.last.trailer.dictionary?
32
+ @revisions.last.trailer
33
+
34
+ #
35
+ # Otherwise look for a xref stream.
36
+ #
37
+ else
38
+ @revisions.last.xrefstm
39
+ end
40
+
41
+ raise InvalidPDFError, "No trailer found" if trl.nil?
42
+
43
+ trl
44
+ end
22
45
 
23
- class PDF
24
-
25
- #
26
- # Returns the current trailer.
27
- # This might be either a Trailer or XRefStream.
28
- #
29
- def trailer
30
- #
31
- # First look for a standard trailer dictionary
32
- #
33
- if @revisions.last.trailer.dictionary?
34
- trl = @revisions.last.trailer
35
-
36
- #
37
- # Otherwise look for a xref stream.
38
- #
39
- else
40
- trl = @revisions.last.xrefstm
41
- end
42
-
43
- raise InvalidPDFError, "No trailer found" if trl.nil?
44
-
45
- trl
46
- end
47
-
48
- private
46
+ private
49
47
 
50
- def trailer_key?(attr) #:nodoc:
51
- !!trailer_key(attr)
52
- end
48
+ def trailer_key?(attr) # :nodoc:
49
+ !!trailer_key(attr)
50
+ end
53
51
 
54
- def trailer_key(attr) #:nodoc:
55
- @revisions.reverse_each do |rev|
56
- if rev.trailer.dictionary? and rev.trailer.key?(attr)
57
- return rev.trailer[attr].solve
58
- elsif rev.xrefstm?
59
- xrefstm = rev.xrefstm
60
- if xrefstm.is_a?(XRefStream) and xrefstm.key?(attr)
61
- return xrefstm[attr].solve
62
- end
63
- end
64
- end
65
-
66
- nil
52
+ def trailer_key(attr) # :nodoc:
53
+ @revisions.reverse_each do |rev|
54
+ if rev.trailer.dictionary? && rev.trailer.key?(attr)
55
+ return rev.trailer[attr].solve
56
+ elsif rev.xrefstm?
57
+ xrefstm = rev.xrefstm
58
+ if xrefstm.is_a?(XRefStream) && xrefstm.key?(attr)
59
+ return xrefstm[attr].solve
60
+ end
67
61
  end
62
+ end
68
63
 
69
- def generate_id
70
- id = HexaString.new Random.new.bytes 16
71
- self.trailer.ID = [ id, id ]
72
- end
64
+ nil
73
65
  end
74
66
 
75
- class InvalidTrailerError < Error #:nodoc:
67
+ def generate_id
68
+ id = HexaString.new Random.new.bytes 16
69
+ trailer.ID = [id, id]
76
70
  end
71
+ end
77
72
 
78
- # Forward declarations.
79
- class Catalog < Dictionary; end
80
- class Metadata < Dictionary; end
81
-
82
- #
83
- # Class representing a PDF file Trailer.
84
- #
85
- class Trailer
86
- include StandardObject
73
+ class InvalidTrailerError < Error # :nodoc:
74
+ end
87
75
 
88
- TOKENS = %w{ trailer %%EOF } #:nodoc:
89
- XREF_TOKEN = "startxref" #:nodoc:
76
+ # Forward declarations.
77
+ class Catalog < Dictionary; end
90
78
 
91
- @@regexp_open = Regexp.new(WHITESPACES + TOKENS.first + WHITESPACES)
92
- @@regexp_xref = Regexp.new(WHITESPACES + XREF_TOKEN + WHITESPACES + "(?<startxref>\\d+)")
93
- @@regexp_close = Regexp.new(WHITESPACES + TOKENS.last + WHITESPACES)
79
+ class Metadata < Dictionary; end
94
80
 
95
- attr_accessor :document
96
- attr_accessor :startxref
97
- attr_reader :dictionary
81
+ #
82
+ # Class representing a PDF file Trailer.
83
+ #
84
+ class Trailer
85
+ include StandardObject
98
86
 
99
- field :Size, :Type => Integer, :Required => true
100
- field :Prev, :Type => Integer
101
- field :Root, :Type => Catalog, :Required => true
102
- field :Encrypt, :Type => Encryption::Standard::Dictionary
103
- field :Info, :Type => Metadata
104
- field :ID, :Type => Array.of(String, length: 2)
105
- field :XRefStm, :Type => Integer
87
+ TOKENS = %w[trailer %%EOF] # :nodoc:
88
+ XREF_TOKEN = "startxref" # :nodoc:
106
89
 
107
- #
108
- # Creates a new Trailer.
109
- # _startxref_:: The file _offset_ to the XRef::Section.
110
- # _dictionary_:: A hash of attributes to set in the Trailer Dictionary.
111
- #
112
- def initialize(startxref = 0, dictionary = {})
113
- @startxref, self.dictionary = startxref, dictionary && Dictionary.new(dictionary)
114
- end
90
+ @@regexp_open = Regexp.new(WHITESPACES + TOKENS.first + WHITESPACES)
91
+ @@regexp_xref = Regexp.new(WHITESPACES + XREF_TOKEN + WHITESPACES + "(?<startxref>\\d+)")
92
+ @@regexp_close = Regexp.new(WHITESPACES + TOKENS.last + WHITESPACES)
115
93
 
116
- def self.parse(stream, parser = nil) #:nodoc:
117
- scanner = Parser.init_scanner(stream)
94
+ attr_accessor :document
95
+ attr_accessor :startxref
96
+ attr_reader :dictionary
118
97
 
119
- if scanner.skip(@@regexp_open)
120
- dictionary = Dictionary.parse(scanner, parser)
121
- else
122
- dictionary = nil
123
- end
98
+ field :Size, Type: Integer, Required: true
99
+ field :Prev, Type: Integer
100
+ field :Root, Type: Catalog, Required: true
101
+ field :Encrypt, Type: Encryption::Standard::Dictionary
102
+ field :Info, Type: Metadata
103
+ field :ID, Type: Array.of(String, length: 2)
104
+ field :XRefStm, Type: Integer
124
105
 
125
- if not scanner.scan(@@regexp_xref)
126
- raise InvalidTrailerError, "Cannot get startxref value"
127
- end
106
+ #
107
+ # Creates a new Trailer.
108
+ # _startxref_:: The file _offset_ to the XRef::Section.
109
+ # _dictionary_:: A hash of attributes to set in the Trailer Dictionary.
110
+ #
111
+ def initialize(startxref = 0, dictionary = {})
112
+ @startxref, self.dictionary = startxref, dictionary && Dictionary.new(dictionary)
113
+ end
128
114
 
129
- startxref = scanner['startxref'].to_i
115
+ def self.parse(stream, parser = nil) # :nodoc:
116
+ scanner = Parser.init_scanner(stream)
130
117
 
131
- if not scanner.scan(@@regexp_close)
132
- parser.warn("No %%EOF token found") if parser
133
- end
118
+ dictionary = if scanner.skip(@@regexp_open)
119
+ Dictionary.parse(scanner, parser)
120
+ end
134
121
 
135
- Trailer.new(startxref, dictionary)
136
- end
122
+ if !scanner.scan(@@regexp_xref)
123
+ raise InvalidTrailerError, "Cannot get startxref value"
124
+ end
137
125
 
138
- #
139
- # Returns true if the specified key is present in the Trailer dictionary.
140
- #
141
- def key?(key)
142
- self.dictionary? and @dictionary.key?(key)
143
- end
126
+ startxref = scanner['startxref'].to_i
144
127
 
145
- #
146
- # Access a key in the trailer dictionary if present.
147
- #
148
- def [](key)
149
- @dictionary[key] if dictionary?
150
- end
128
+ if !scanner.scan(@@regexp_close)
129
+ parser&.warn("No %%EOF token found")
130
+ end
151
131
 
152
- #
153
- # Sets a value in the trailer dictionary.
154
- #
155
- def []=(key, value)
156
- self.dictionary = Dictionary.new unless dictionary?
157
- @dictionary[key] = value
158
- end
132
+ Trailer.new(startxref, dictionary)
133
+ end
159
134
 
160
- #
161
- # Sets the trailer dictionary.
162
- #
163
- def dictionary=(dict)
164
- dict.parent = self if dict
165
- @dictionary = dict
166
- end
135
+ #
136
+ # Returns true if the specified key is present in the Trailer dictionary.
137
+ #
138
+ def key?(key)
139
+ dictionary? and @dictionary.key?(key)
140
+ end
167
141
 
168
- #
169
- # Returns true if the Trailer contains a Dictionary.
170
- #
171
- def dictionary?
172
- not @dictionary.nil?
173
- end
142
+ #
143
+ # Access a key in the trailer dictionary if present.
144
+ #
145
+ def [](key)
146
+ @dictionary[key] if dictionary?
147
+ end
174
148
 
175
- #
176
- # Outputs self into PDF code.
177
- #
178
- def to_s(indent: 1, eol: $/)
179
- content = ""
180
- if self.dictionary?
181
- content << TOKENS.first << eol << @dictionary.to_s(indent: indent, eol: eol) << eol
182
- end
149
+ #
150
+ # Sets a value in the trailer dictionary.
151
+ #
152
+ def []=(key, value)
153
+ self.dictionary = Dictionary.new unless dictionary?
154
+ @dictionary[key] = value
155
+ end
183
156
 
184
- content << XREF_TOKEN << eol << @startxref.to_s << eol << TOKENS.last << eol
157
+ #
158
+ # Sets the trailer dictionary.
159
+ #
160
+ def dictionary=(dict)
161
+ dict.parent = self if dict
162
+ @dictionary = dict
163
+ end
185
164
 
186
- content
187
- end
165
+ #
166
+ # Returns true if the Trailer contains a Dictionary.
167
+ #
168
+ def dictionary?
169
+ !@dictionary.nil?
188
170
  end
189
171
 
172
+ #
173
+ # Outputs self into PDF code.
174
+ #
175
+ def to_s(indent: 1, eol: $/)
176
+ content = +""
177
+ if dictionary?
178
+ content << TOKENS.first << eol << @dictionary.to_s(indent: indent, eol: eol) << eol
179
+ end
180
+
181
+ content << XREF_TOKEN << eol << @startxref.to_s << eol << TOKENS.last << eol
182
+
183
+ content
184
+ end
185
+ end
190
186
  end
data/lib/origami/tree.rb CHANGED
@@ -1,62 +1,60 @@
1
- =begin
2
-
3
- This file is part of Origami, PDF manipulation framework for Ruby
4
- Copyright (C) 2016 Guillaume Delugré.
5
-
6
- Origami is free software: you can redistribute it and/or modify
7
- it under the terms of the GNU Lesser General Public License as published by
8
- the Free Software Foundation, either version 3 of the License, or
9
- (at your option) any later version.
10
-
11
- Origami is distributed in the hope that it will be useful,
12
- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- GNU Lesser General Public License for more details.
15
-
16
- You should have received a copy of the GNU Lesser General Public License
17
- along with Origami. If not, see <http://www.gnu.org/licenses/>.
18
-
19
- =end
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # This file is part of Origami, PDF manipulation framework for Ruby
5
+ # Copyright (C) 2016 Guillaume Delugré.
6
+ #
7
+ # Origami is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # Origami is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with Origami. If not, see <http://www.gnu.org/licenses/>.
19
+ #
20
20
 
21
21
  module Origami
22
-
23
- class InvalidNameTreeError < Error #:nodoc:
22
+ class InvalidNameTreeError < Error # :nodoc:
23
+ end
24
+
25
+ #
26
+ # Class representing a node in a Name tree.
27
+ #
28
+ class NameTreeNode < Dictionary
29
+ include StandardObject
30
+
31
+ field :Kids, Type: Array.of(self)
32
+ field :Names, Type: Array.of(String, Object)
33
+ field :Limits, Type: Array.of(String, length: 2)
34
+
35
+ def self.of(klass)
36
+ Class.new(self) do
37
+ field :Kids, Type: Array.of(self)
38
+ field :Names, Type: Array.of(String, klass)
39
+ end
24
40
  end
25
-
26
- #
27
- # Class representing a node in a Name tree.
28
- #
29
- class NameTreeNode < Dictionary
30
- include StandardObject
31
-
32
- field :Kids, :Type => Array.of(self)
33
- field :Names, :Type => Array.of(String, Object)
34
- field :Limits, :Type => Array.of(String, length: 2)
35
-
36
- def self.of(klass)
37
- return Class.new(self) do
38
- field :Kids, :Type => Array.of(self)
39
- field :Names, :Type => Array.of(String, klass)
40
- end
41
- end
41
+ end
42
+
43
+ #
44
+ # Class representing a node in a Number tree.
45
+ #
46
+ class NumberTreeNode < Dictionary
47
+ include StandardObject
48
+
49
+ field :Kids, Type: Array.of(self)
50
+ field :Nums, Type: Array.of(Number, Object)
51
+ field :Limits, Type: Array.of(Number, length: 2)
52
+
53
+ def self.of(klass)
54
+ Class.new(self) do
55
+ field :Kids, Type: Array.of(self)
56
+ field :Nums, Type: Array.of(Number, klass)
57
+ end
42
58
  end
43
-
44
- #
45
- # Class representing a node in a Number tree.
46
- #
47
- class NumberTreeNode < Dictionary
48
- include StandardObject
49
-
50
- field :Kids, :Type => Array.of(self)
51
- field :Nums, :Type => Array.of(Number, Object)
52
- field :Limits, :Type => Array.of(Number, length: 2)
53
-
54
- def self.of(klass)
55
- return Class.new(self) do
56
- field :Kids, :Type => Array.of(self)
57
- field :Nums, :Type => Array.of(Number, klass)
58
- end
59
- end
60
- end
61
-
59
+ end
62
60
  end
@@ -1,23 +1,23 @@
1
- =begin
1
+ # frozen_string_literal: true
2
2
 
3
- This file is part of Origami, PDF manipulation framework for Ruby
4
- Copyright (C) 2016 Guillaume Delugré.
5
-
6
- Origami is free software: you can redistribute it and/or modify
7
- it under the terms of the GNU Lesser General Public License as published by
8
- the Free Software Foundation, either version 3 of the License, or
9
- (at your option) any later version.
10
-
11
- Origami is distributed in the hope that it will be useful,
12
- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- GNU Lesser General Public License for more details.
15
-
16
- You should have received a copy of the GNU Lesser General Public License
17
- along with Origami. If not, see <http://www.gnu.org/licenses/>.
18
-
19
- =end
3
+ #
4
+ # This file is part of Origami, PDF manipulation framework for Ruby
5
+ # Copyright (C) 2016 Guillaume Delugré.
6
+ #
7
+ # Origami is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Lesser General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # Origami is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Lesser General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Lesser General Public License
18
+ # along with Origami. If not, see <http://www.gnu.org/licenses/>.
19
+ #
20
20
 
21
21
  module Origami
22
- VERSION = "2.2.0"
22
+ VERSION = "2.3.0"
23
23
  end