petit-felix 0.1.5 → 0.1.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.
@@ -1,6 +1,7 @@
1
1
  require "prawn"
2
2
  require 'fileutils'
3
3
  require "prawndown-ext"
4
+ require "felix/file"
4
5
  require "worker/pdf_writer/column_box"
5
6
  require "worker/pdf_writer/bounding_box"
6
7
 
@@ -22,32 +23,43 @@ module PetitFelix
22
23
  def add_font (type,
23
24
  default_font: "default")
24
25
 
25
- if @options.key?(type + "_font_normal")
26
+ if @options.key? "#{type}_font_normal"
26
27
 
27
- font_normal = type + "_font_normal"
28
- font_italic = type + "_font_normal"
29
- font_bold = type + "_font_normal"
30
- font_bold_italic = type + "_font_normal"
28
+ font_normal = "#{type}_font_normal"
29
+ font_italic = "#{type}_font_normal"
30
+ font_bold = "#{type}_font_normal"
31
+ font_bold_italic = "#{type}_font_normal"
31
32
 
32
- if @options.key?(type + "_font_italic")
33
- font_italic = type + "_font_italic"
33
+ if @options.key? "#{type}_font_italic"
34
+
35
+ font_italic = "#{type}_font_italic"
36
+
34
37
  end
35
- if @options.key?(type + "_font_bold")
36
- font_bold = type + "_font_bold"
38
+
39
+ if @options.key? "#{type}_font_bold"
40
+
41
+ font_bold = "#{type}_font_bold"
42
+
37
43
  end
38
- if @options.key?(type + "_font_bold_italic")
39
- font_bold_italic = type + "_font_bold_italic"
44
+
45
+ if @options.key? "#{type}_font_bold_italic"
46
+
47
+ font_bold_italic = "#{type}_font_bold_italic"
48
+
40
49
  end
41
50
 
42
51
  font_families.update(type => {
52
+
43
53
  :normal => @options[font_normal],
44
54
  :italic => @options[font_italic],
45
55
  :bold => @options[font_bold],
46
56
  :bold_italic => @options[font_bold_italic]
57
+
47
58
  })
48
59
 
49
60
  else
50
61
  if font_families.key?(default_font)
62
+
51
63
  font_families.update(type => {
52
64
  :normal => font_families[default_font][:normal],
53
65
  :italic => font_families[default_font][:italic],
@@ -56,82 +68,37 @@ module PetitFelix
56
68
  })
57
69
 
58
70
  else
71
+
59
72
  font_families.update(type => {
60
73
  :normal => @options["font_normal"],
61
74
  :italic => @options["font_italic"],
62
75
  :bold => @options["font_bold"],
63
76
  :bold_italic => @options["font_bold_italic"]
64
77
  })
78
+
65
79
  end
66
80
 
67
81
  end
68
82
  end
69
83
 
70
84
  def set_options metaoptions
85
+
71
86
  @options = metaoptions
87
+
72
88
  end
73
89
 
74
90
  def output
75
- FileUtils.mkdir_p File.dirname(@options["output_dir"] + "/" + @options["output_file"])
76
- render_file(@options["output_dir"] + "/" + @options["output_file"])
77
- end
78
-
79
-
80
- def start_new_page(options = {})
81
- last_page = state.page
82
- if last_page
83
- last_page_size = last_page.size
84
- last_page_layout = last_page.layout
85
- last_page_margins = last_page.margins.dup
86
- end
87
-
88
- page_options = {
89
- size: options[:size] || last_page_size,
90
- layout: options[:layout] || last_page_layout,
91
- margins: last_page_margins,
92
- }
93
- if last_page
94
- if last_page.graphic_state
95
- new_graphic_state = last_page.graphic_state.dup
96
- end
97
-
98
- # erase the color space so that it gets reset on new page for fussy
99
- # pdf-readers
100
- new_graphic_state&.color_space = {}
101
-
102
- page_options[:graphic_state] = new_graphic_state
103
- end
91
+
92
+ fileedit = PetitFelix::FileManager.new
93
+
94
+ file_output = fileedit.file_array_from_string(@options["output_dir"]) + [@options["output_file"]]
104
95
 
105
- state.page = PDF::Core::Page.new(self, page_options)
96
+ file = File.join(file_output)
106
97
 
107
- apply_margin_options(options)
108
- generate_margin_box
109
-
110
- # Reset the bounding box if the new page has different size or layout
111
- if last_page && (last_page.size != state.page.size ||
112
- last_page.layout != state.page.layout)
113
- @bounding_box = @margin_box
114
- end
115
-
116
- use_graphic_settings
117
-
118
- unless options[:orphan]
119
- state.insert_page(state.page, @page_number)
120
- @page_number += 1
121
-
122
- if @background
123
- canvas do
124
- image(@background, scale: @background_scale, at: bounds.top_left)
125
- end
126
- end
127
- @y = @bounding_box.absolute_top
128
-
129
- float do
130
- state.on_page_create_action(self)
131
- end
132
- end
133
-
134
- end
98
+ FileUtils.mkdir_p File.dirname(file)
99
+ render_file(file)
100
+
101
+ end
135
102
 
136
103
  end
137
104
  end
@@ -4,7 +4,10 @@ require "prawndown-ext"
4
4
  require "felix/metadata"
5
5
  require "felix/error"
6
6
  require "worker/pdf_writer"
7
- require "worker/template_pdf_calls"
7
+ require "worker/templater/methods"
8
+ require "worker/templater/error"
9
+ require "worker/templater/validation"
10
+ require "worker/templater/font"
8
11
  require "eqn"
9
12
 
10
13
  ## Prawn PDF writer that inputs template files
@@ -14,49 +17,13 @@ module PetitFelix
14
17
 
15
18
  class TemplatePDFWriter < PetitFelix::Worker::DefaultPDFWriter
16
19
 
17
- # error count: 16
18
-
19
- ERROR_CODES = [
20
- "OK",
21
- "Malformed command list.",
22
- "No command defined. Use \"com\" or \"command\" to define commands.",
23
- "Command not found.",
24
- "Stack overflow.",
25
- "Template ID \"{{arg}}\" not found.",
26
- "Template method \"{{arg}}\" not found.",
27
- "\"{{arg}}\" argument not defined.",
28
- "Expression \"{{arg}}\" does not result in boolean result.",
29
- "Expression \"{{arg}}\" cannot be evaluated.",
30
- "File \"{{arg}}\" not found.",
31
- "Not a valid position.",
32
- "\"at\" (Array) argument not defined.",
33
- "\"{{arg}}\" is not an array.",
34
- "Image \"{{arg}}\" not found.",
35
- "Template file \"{{arg}}\" not found.",
36
- "\"template\" option not defined. No template file can be loaded."
37
- ]
38
-
39
- SYMBOLIZE = [
40
- :align,
41
- :odd_align,
42
- :even_align,
43
- :valign,
44
- :odd_valign,
45
- :even_valign,
46
- :direction,
47
- :mode,
48
- :style,
49
- :overflow,
50
- :rotate_around
51
- ]
52
-
53
-
54
20
  # Highest a stack is allowed to be
55
21
  MAX_STACK = 1024
56
22
 
57
23
  ## Functions
58
24
 
59
25
  def init_values options, pdf
26
+
60
27
  @variables = {}
61
28
 
62
29
  @options = Marshal.load(Marshal.dump(options))
@@ -89,51 +56,22 @@ module PetitFelix
89
56
  set_variables
90
57
  end
91
58
 
92
- # Adds a font to the pdf document
93
- def add_font font, font_name
94
-
95
- if font.key?(:normal)
96
-
97
- if font.key?(:italic)
98
- font[:italic] = font[:normal]
99
- end
100
- if font.key?(:bold)
101
- font[:bold] = font[:normal]
102
- end
103
- if font.key?(:bold_italic)
104
- font[:bold_italic] = font[:normal]
105
- end
106
-
107
- font.keys.each do |key|
108
- font[key] = replace_variable font[key]
109
- end
110
-
111
- font_families.update(font_name => font)
112
-
113
- end
114
-
115
- end
116
-
117
- def add_fonts
118
- font_families.clear
119
-
120
- fonts = Marshal.load(Marshal.dump(@fonts))
121
-
122
- fonts.keys.each do |font|
123
- add_font fonts[font], font.to_s
124
- end
125
-
126
- end
127
-
128
59
  def set_variables
60
+
129
61
  @metaoptions.keys.each do |key|
62
+
130
63
  @variables[key] = @metaoptions[key]
64
+
131
65
  end
132
66
 
133
67
  if @variables.key? :markdown_metadata
68
+
134
69
  @variables[:markdown_metadata].keys.each do |meta|
70
+
135
71
  @variables[meta] = @variables[:markdown_metadata][meta]
72
+
136
73
  end
74
+
137
75
  end
138
76
 
139
77
  ## add additional functional stuff
@@ -150,17 +88,22 @@ module PetitFelix
150
88
  def replace_variables args
151
89
 
152
90
  args.keys.each do |arg|
91
+
153
92
  if args[arg].instance_of? String
93
+
154
94
  args[arg] = replace_variable args[arg]
95
+
155
96
  end
156
97
  end
157
98
 
158
99
  args
100
+
159
101
  end
160
102
 
161
103
  def replace_variable string
104
+
162
105
  @variables.keys.each do |key|
163
- string = string.gsub("${" + key.to_s + "}", @variables[key].to_s)
106
+ string = string.gsub("${#{key}}", @variables[key].to_s)
164
107
  end
165
108
 
166
109
  string
@@ -172,8 +115,11 @@ module PetitFelix
172
115
  # Format: Array of objects where
173
116
  # each object has command and set of args
174
117
  def read_template
175
- if @options.key?("template")
176
- if File.file?(@options["template"])
118
+
119
+ if @options.key? "template"
120
+
121
+ if File.file? @options["template"]
122
+
177
123
  obj = JSON.parse(File.read(@options["template"]), symbolize_names: true)
178
124
 
179
125
  default_options = obj[:default_variables].transform_keys!(&:to_s)
@@ -184,12 +130,14 @@ module PetitFelix
184
130
 
185
131
  @fonts = {}
186
132
 
187
- @metaoptions = default_options.merge(@options)
133
+ @metaoptions = default_options.merge @options
188
134
 
189
135
  set_variables
190
136
 
191
- if obj.key?(:fonts)
137
+ if obj.key? :fonts
138
+
192
139
  @fonts = obj[:fonts]
140
+
193
141
  end
194
142
 
195
143
  add_fonts
@@ -199,17 +147,21 @@ module PetitFelix
199
147
  }
200
148
 
201
149
  # Runs the main function as entry point of the template
202
- @template_stack.push("main")
150
+ @template_stack.push "main"
203
151
  result = execute_function "main", "main", self
204
152
 
205
153
  if result[0] != 0
154
+
206
155
  print_error result[0], result[1]
207
156
  end
157
+
208
158
  else
159
+
209
160
  @error_param["arg"] = @options["template"].to_s
210
161
  print_error 15, -1
211
162
 
212
163
  end
164
+
213
165
  else
214
166
 
215
167
  print_error 16, -1
@@ -221,18 +173,24 @@ module PetitFelix
221
173
 
222
174
  definition = nil
223
175
 
224
- if !@template.key?(template_id)
176
+ if !@template.key? template_id
177
+
225
178
  @error_param["arg"] = template_id.to_s
226
179
  # Fails because template ID not found.
227
180
  return [5, -1]
181
+
228
182
  else
229
183
 
230
- if !@template[template_id].key?(function_id.to_sym )
184
+ if !@template[template_id].key? function_id.to_sym
185
+
231
186
  @error_param["arg"] = function_id.to_s
232
187
  # Fails because template function ID not found.
233
188
  return [6, -1]
189
+
234
190
  else
191
+
235
192
  definition = Marshal.load(Marshal.dump(@template[template_id][function_id.to_sym]))
193
+
236
194
  end
237
195
 
238
196
  end
@@ -241,7 +199,7 @@ module PetitFelix
241
199
 
242
200
  counter = 0
243
201
 
244
- @counter_stack.push(counter)
202
+ @counter_stack.push counter
245
203
 
246
204
  for index in counter ... definition.size
247
205
 
@@ -252,50 +210,63 @@ module PetitFelix
252
210
 
253
211
  command = ""
254
212
 
255
- if line.key?(:cmd)
213
+ if line.key? :cmd
214
+
256
215
  command = line[:cmd].to_sym
216
+
257
217
  end
258
218
 
259
- if line.key?(:command)
219
+ if line.key? :command
220
+
260
221
  command = line[:command].to_sym
222
+
261
223
  end
262
224
 
263
225
  args = {
264
226
  "LINE_NUMBER" => counter
265
227
  }
266
228
 
267
- if line.key?(:args)
229
+ if line.key? :args
230
+
268
231
  args = line[:args]
232
+
269
233
  end
270
234
 
271
235
  begin
236
+
272
237
  args = replace_variables(args)
273
238
 
274
239
  rescue => error
240
+
275
241
  print "\n"
276
242
  print error
277
243
  print "\n"
278
244
  print "Error rendering variables!\n"
245
+
279
246
  end
280
247
 
281
248
  if !command.empty?
282
249
 
283
- if COMMAND.keys.include?(command)
250
+ if COMMAND.keys.include? command
251
+
284
252
  @command_stack.push definition
285
253
 
286
254
  if @command_stack.count > 1024
287
255
  # Failed because of stack overflow
288
256
  return [4, counter]
257
+
289
258
  end
290
259
 
291
- comm = COMMAND[command].call(obj, args)
260
+ comm = COMMAND[command].call obj, args
292
261
 
293
262
  @counter_stack[-1] = counter
294
263
  counter += 1
295
264
 
296
265
  # something about command execution failed
297
266
  if comm != 0
267
+
298
268
  return [comm, counter]
269
+
299
270
  end
300
271
 
301
272
  @command_stack.pop
@@ -310,7 +281,6 @@ module PetitFelix
310
281
  return [2, -1]
311
282
 
312
283
  end
313
-
314
284
  end
315
285
 
316
286
  @counter_stack.pop()
@@ -322,178 +292,6 @@ module PetitFelix
322
292
 
323
293
  # Failed because malformed command list
324
294
  return [1, -1]
325
- end
326
-
327
- ## Error display
328
-
329
- def error_replace_string error
330
-
331
- @error_param.keys.each do |key|
332
- error = error.gsub("{{"+ key +"}}", @error_param[key])
333
- end
334
-
335
- error
336
- end
337
-
338
- def print_error error_code, line
339
-
340
- if error_code > -1 && error_code < ERROR_CODES.count
341
- @error_printer.print_err "Error reading template. " + error_replace_string(ERROR_CODES[error_code])
342
- else
343
- @error_printer.print_err "Error reading template. General template processing error occured."
344
- end
345
-
346
- print "Error code: " + error_code.to_s
347
-
348
- print "\n\n"
349
- print "Processing markdown file: " + @metaoptions["filename"]
350
- print "\n\n"
351
-
352
- stack_rv = @command_stack.reverse
353
-
354
- if line >= 0 && !stack_rv.empty?
355
-
356
- print "\n\nCurrent line:\n"
357
- print stack_rv[0][line]
358
-
359
- print "\n\nCurrent Stack:"
360
- test_arr = *(0..[19,@command_stack.count-1].min)
361
- test_arr.each do | i |
362
- command_obj = stack_rv[i]
363
-
364
- line_edit = command_obj[0..@counter_stack[i]+1]
365
-
366
- print "\n"
367
- print "Line: (" + line_edit.count.to_s + "): "
368
- print line_edit[-1]
369
- end
370
- end
371
-
372
- print "\n"
373
-
374
- return error_code
375
- end
376
-
377
- ## These methods validate parameters
378
-
379
- def args_has_string arg_name, args
380
- if !args.key?(arg_name)
381
- # text not defined
382
- @error_param["arg"] = arg_name.to_s
383
- return 7
384
- end
385
-
386
- args[arg_name] = replace_variable args[arg_name].to_s
387
-
388
- return 0
389
- end
390
-
391
- def args_has_int arg_name, args
392
- if !args.key?(arg_name)
393
- # text not defined
394
- @error_param["arg"] = arg_name.to_s
395
- return 7
396
- end
397
-
398
- if args[arg_name].instance_of? String
399
- args[arg_name] = Eqn::Calculator.calc(replace_variable args[arg_name]).to_i
400
- end
401
- return 0
402
- end
403
-
404
- def args_has_float arg_name, args
405
-
406
- if !args.key?(arg_name)
407
- # text not defined
408
- @error_param["arg"] = arg_name.to_s
409
- return 7
410
- end
411
-
412
- args[arg_name] = Eqn::Calculator.calc(replace_variable args[arg_name]).to_f
413
-
414
- return 0
415
- end
416
-
417
- def args_has_arr (arg_name, args, type, options = {})
418
-
419
- if !args.key?(arg_name)
420
- # text not defined
421
- @error_param["arg"] = arg_name.to_s
422
- return 7
423
- end
424
-
425
- if args[arg_name].instance_of? String
426
- begin
427
- set_variables
428
-
429
- test = replace_variable args[arg_name]
430
-
431
- args[arg_name] = JSON.parse(test)
432
-
433
- rescue => error
434
- print "\nError parsing array: " + args[arg_name] + "\n"
435
- print error
436
-
437
- end
438
-
439
- end
440
-
441
- if args[arg_name].instance_of? Array
442
- if type == :float
443
- args[arg_name].map! {|item| Eqn::Calculator.calc(replace_variable item.to_s).to_f }
444
- elsif type == :int
445
- args[arg_name].map! {|item| Eqn::Calculator.calc(replace_variable item.to_s).to_i }
446
- elsif type == :hash
447
- args[arg_name].map! {|item| args_correct_hash item, options[:second_type] }
448
- else
449
- args[arg_name].map! {|item| replace_variable item.to_s }
450
- end
451
-
452
- end
453
-
454
- return 0
455
- end
456
-
457
- def args_correct_hash hash, type
458
- hash.transform_keys!(&:to_sym)
459
-
460
- hash.keys.each do |key|
461
-
462
- if type == :int
463
- hash[key] = Eqn::Calculator.calc(replace_variable hash[key].to_s).to_i
464
- elsif type == :float
465
- hash[key] = Eqn::Calculator.calc(replace_variable hash[key].to_s).to_f
466
- else
467
- hash[key] = replace_variable hash[key].to_s
468
- end
469
-
470
- end
471
-
472
- hash
473
-
474
- end
475
-
476
- def args_correct_values args
477
- args_has_int :width, args
478
- args_has_int :height, args
479
-
480
- SYMBOLIZE.each do |symbol|
481
- if args.key?(symbol)
482
- args[symbol] = args[symbol].to_sym
483
- end
484
- end
485
-
486
- if args.key?(:position)
487
-
488
- if ["left","center","right"].include? args[:position]
489
- args[:position] = args[:position].to_sym
490
- else
491
- args[:position] = args[:position].to_i
492
- end
493
-
494
- end
495
-
496
- args
497
295
 
498
296
  end
499
297