hexapdf 0.41.0 → 0.43.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +55 -0
  3. data/Rakefile +1 -1
  4. data/examples/031-acro_form_java_script.rb +36 -24
  5. data/lib/hexapdf/cli/command.rb +14 -11
  6. data/lib/hexapdf/cli/files.rb +31 -7
  7. data/lib/hexapdf/cli/form.rb +10 -31
  8. data/lib/hexapdf/cli/inspect.rb +1 -1
  9. data/lib/hexapdf/cli/usage.rb +215 -0
  10. data/lib/hexapdf/cli.rb +2 -0
  11. data/lib/hexapdf/configuration.rb +1 -1
  12. data/lib/hexapdf/dictionary.rb +3 -3
  13. data/lib/hexapdf/document.rb +14 -1
  14. data/lib/hexapdf/encryption.rb +17 -0
  15. data/lib/hexapdf/layout/box.rb +1 -0
  16. data/lib/hexapdf/layout/box_fitter.rb +3 -3
  17. data/lib/hexapdf/layout/column_box.rb +2 -2
  18. data/lib/hexapdf/layout/container_box.rb +1 -1
  19. data/lib/hexapdf/layout/line.rb +4 -0
  20. data/lib/hexapdf/layout/list_box.rb +2 -2
  21. data/lib/hexapdf/layout/table_box.rb +1 -1
  22. data/lib/hexapdf/layout/text_box.rb +16 -2
  23. data/lib/hexapdf/parser.rb +20 -17
  24. data/lib/hexapdf/type/acro_form/button_field.rb +7 -5
  25. data/lib/hexapdf/type/acro_form/form.rb +123 -27
  26. data/lib/hexapdf/type/acro_form/java_script_actions.rb +165 -14
  27. data/lib/hexapdf/type/acro_form/text_field.rb +13 -1
  28. data/lib/hexapdf/type/resources.rb +2 -1
  29. data/lib/hexapdf/utils.rb +19 -0
  30. data/lib/hexapdf/version.rb +1 -1
  31. data/test/hexapdf/layout/test_box_fitter.rb +3 -3
  32. data/test/hexapdf/layout/test_text_box.rb +27 -1
  33. data/test/hexapdf/test_dictionary.rb +6 -4
  34. data/test/hexapdf/test_parser.rb +12 -0
  35. data/test/hexapdf/test_utils.rb +16 -0
  36. data/test/hexapdf/type/acro_form/test_button_field.rb +5 -0
  37. data/test/hexapdf/type/acro_form/test_form.rb +110 -2
  38. data/test/hexapdf/type/acro_form/test_java_script_actions.rb +102 -1
  39. data/test/hexapdf/type/acro_form/test_text_field.rb +22 -4
  40. data/test/hexapdf/type/test_resources.rb +5 -0
  41. metadata +3 -2
@@ -31,6 +31,11 @@ describe HexaPDF::Type::AcroForm::JavaScriptActions do
31
31
  prepend_currency: false))
32
32
  end
33
33
 
34
+ it "raise an error for invalid arguments" do
35
+ assert_raises(ArgumentError) { @klass.af_number_format_action(separator_style: :unknown) }
36
+ assert_raises(ArgumentError) { @klass.af_number_format_action(negative_style: :unknown) }
37
+ end
38
+
34
39
  def assert_format(arg_string, result_value, result_color)
35
40
  @action[:JS] = "AFNumber_Format(#{arg_string});"
36
41
  value, text_color = @klass.apply_format(@value, @action)
@@ -77,10 +82,106 @@ describe HexaPDF::Type::AcroForm::JavaScriptActions do
77
82
  assert_equal('1.234,57', value)
78
83
  end
79
84
 
80
- it "does nothing to the value if the JavasSript method could not be determined " do
85
+ it "does nothing to the value if the JavaScript method could not be determined " do
81
86
  assert_format('2, 3, 0, 0, " E", false, a', "1234567.898765", nil)
82
87
  end
83
88
  end
89
+
90
+ describe "AFPercent_Format" do
91
+ before do
92
+ @value = '123.456789'
93
+ @action[:JS] = ''
94
+ end
95
+
96
+ it "returns a correct JavaScript string" do
97
+ assert_equal('AFPercent_Format(2, 0);',
98
+ @klass.af_percent_format_action)
99
+ assert_equal('AFPercent_Format(1, 1);',
100
+ @klass.af_percent_format_action(decimals: 1, separator_style: :point_no_thousands))
101
+ end
102
+
103
+ it "raise an error for invalid arguments" do
104
+ assert_raises(ArgumentError) { @klass.af_percent_format_action(separator_style: :unknown) }
105
+ end
106
+
107
+ def assert_format(arg_string, result_value)
108
+ @action[:JS] = "AFPercent_Format(#{arg_string});"
109
+ value, text_color = @klass.apply_format(@value, @action)
110
+ assert_equal(result_value, value)
111
+ assert_nil(text_color)
112
+ end
113
+
114
+ it "works with both commas and points as decimal separator" do
115
+ @value = '123.456789'
116
+ assert_format('2, 2', "12.345,68%")
117
+ @value = '123,456789'
118
+ assert_format('2, 2', "12.345,68%")
119
+ @value = '123,4567,89'
120
+ assert_format('2, 2', "12.345,67%")
121
+ end
122
+
123
+ it "respects the set number of decimals" do
124
+ assert_format('0, 2', "12.346%")
125
+ assert_format('2, 2', "12.345,68%")
126
+ end
127
+
128
+ it "respects the digit separator style" do
129
+ ["12,345.68%", "12345.68%", "12.345,68%", "12345,68%"].each_with_index do |result, style|
130
+ assert_format("2, #{style}", result)
131
+ end
132
+ end
133
+
134
+ it "allows omitting the trailing semicolon" do
135
+ @action[:JS] = "AFPercent_Format(2,2 )"
136
+ value, = @klass.apply_format('1.234', @action)
137
+ assert_equal('123,40%', value)
138
+ end
139
+
140
+ it "does nothing to the value if the JavaScript method could not be determined " do
141
+ assert_format('2, "df"', "123.456789")
142
+ end
143
+ end
144
+
145
+ describe "AFTime_Format" do
146
+ before do
147
+ @value = '15:25:37'
148
+ @action[:JS] = ''
149
+ end
150
+
151
+ it "returns a correct JavaScript string" do
152
+ assert_equal('AFTime_Format(0);',
153
+ @klass.af_time_format_action)
154
+ assert_equal('AFTime_Format(1);',
155
+ @klass.af_time_format_action(format: :hh12_mm))
156
+ end
157
+
158
+ it "raise an error for invalid arguments" do
159
+ assert_raises(ArgumentError) { @klass.af_time_format_action(format: :unknown) }
160
+ end
161
+
162
+ def assert_format(arg_string, result_value)
163
+ @action[:JS] = "AFTime_Format(#{arg_string});"
164
+ value, text_color = @klass.apply_format(@value, @action)
165
+ assert_equal(result_value, value)
166
+ assert_nil(text_color)
167
+ end
168
+
169
+ it "respects the time format" do
170
+ ["15:25", "3:25 PM", "15:25:37", "3:25:37 PM"].each_with_index do |result, style|
171
+ assert_format(style, result)
172
+ end
173
+ end
174
+
175
+ it "allows omitting the trailing semicolon" do
176
+ @action[:JS] = "AFTime_Format(2 )"
177
+ value, = @klass.apply_format('15:34', @action)
178
+ assert_equal('15:34:00', value)
179
+ end
180
+
181
+ it "does nothing to the value if the JavaScript method could not be determined " do
182
+ assert_format('1, "df"', "15:25:37")
183
+ end
184
+ end
84
185
  end
85
186
 
86
187
  describe "calculate" do
@@ -114,6 +114,12 @@ describe HexaPDF::Type::AcroForm::TextField do
114
114
  assert(widget[:AP][:N])
115
115
  end
116
116
 
117
+ it "calls acro_form.on_invalid_value if the provided value is not a string" do
118
+ @doc.config['acro_form.on_invalid_value'] = proc {|_field, value| value.to_s }
119
+ @field.field_value = 10
120
+ assert_equal("10", @field.field_value)
121
+ end
122
+
117
123
  it "fails if the :password flag is set" do
118
124
  @field.flag(:password)
119
125
  assert_raises(HexaPDF::Error) { @field.field_value = 'test' }
@@ -124,10 +130,6 @@ describe HexaPDF::Type::AcroForm::TextField do
124
130
  assert_raises(HexaPDF::Error) { @field.field_value = 'test' }
125
131
  end
126
132
 
127
- it "fails if the provided value is not a string" do
128
- assert_raises(HexaPDF::Error) { @field.field_value = 10 }
129
- end
130
-
131
133
  it "fails if the value exceeds the length set by /MaxLen" do
132
134
  @field[:MaxLen] = 5
133
135
  assert_raises(HexaPDF::Error) { @field.field_value = 'testdf' }
@@ -210,6 +212,22 @@ describe HexaPDF::Type::AcroForm::TextField do
210
212
  assert_equal('AFNumber_Format(0, 0, 0, 0, "", true);', @field[:AA][:F][:JS])
211
213
  end
212
214
 
215
+ it "applies the percent format" do
216
+ @doc.acro_form(create: true)
217
+ @field.set_format_action(:percent, decimals: 0)
218
+ assert(@field.key?(:AA))
219
+ assert(@field[:AA].key?(:F))
220
+ assert_equal('AFPercent_Format(0, 0);', @field[:AA][:F][:JS])
221
+ end
222
+
223
+ it "applies the time format" do
224
+ @doc.acro_form(create: true)
225
+ @field.set_format_action(:time, format: :hh_mm_ss)
226
+ assert(@field.key?(:AA))
227
+ assert(@field[:AA].key?(:F))
228
+ assert_equal('AFTime_Format(2);', @field[:AA][:F][:JS])
229
+ end
230
+
213
231
  it "fails if an unknown format action is specified" do
214
232
  assert_raises(ArgumentError) { @field.set_format_action(:unknown) }
215
233
  end
@@ -146,6 +146,11 @@ describe HexaPDF::Type::Resources do
146
146
  @res.font(:test)
147
147
  end
148
148
  end
149
+
150
+ it "wraps the resulting object in the appropriate font class" do
151
+ @res[:Font] = {test: {Type: :Font, Subtype: :Type1}}
152
+ assert_kind_of(HexaPDF::Type::FontType1, @res.font(:test))
153
+ end
149
154
  end
150
155
 
151
156
  describe "add_font" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hexapdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.41.0
4
+ version: 0.43.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Leitner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-05 00:00:00.000000000 Z
11
+ date: 2024-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cmdparse
@@ -325,6 +325,7 @@ files:
325
325
  - lib/hexapdf/cli/modify.rb
326
326
  - lib/hexapdf/cli/optimize.rb
327
327
  - lib/hexapdf/cli/split.rb
328
+ - lib/hexapdf/cli/usage.rb
328
329
  - lib/hexapdf/cli/watermark.rb
329
330
  - lib/hexapdf/composer.rb
330
331
  - lib/hexapdf/configuration.rb