petit-felix 0.1.4 → 0.1.5

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.
@@ -2,18 +2,16 @@ require "prawn"
2
2
  require 'fileutils'
3
3
  require "prawndown-ext"
4
4
  require "felix/metadata"
5
+ require "worker/pdf_writer"
5
6
 
6
7
  module PetitFelix
7
8
  module Worker
8
9
 
9
- class BasicPDFWriter < Prawn::Document
10
-
11
- def set_options metaoptions
12
- @options = metaoptions
13
- end
10
+ class BasicPDFWriter < PetitFelix::Worker::DefaultPDFWriter
14
11
 
15
12
  # Initializes fonts
16
13
  def initialize_font
14
+
17
15
  # Fonts that must always be defined
18
16
  fonts = [
19
17
  "quote",
@@ -53,53 +51,9 @@ module PetitFelix
53
51
 
54
52
  end
55
53
 
56
- # Adds a font to the pdf document
57
- def add_font (type,
58
- default_font: "default")
59
-
60
- if @options.key?(type + "_font_normal")
61
-
62
- font_normal = type + "_font_normal"
63
- font_italic = type + "_font_normal"
64
- font_bold = type + "_font_normal"
65
- font_bold_italic = type + "_font_normal"
66
-
67
- if @options.key?(type + "_font_italic")
68
- font_italic = type + "_font_italic"
69
- end
70
- if @options.key?(type + "_font_bold")
71
- font_bold = type + "_font_bold"
72
- end
73
- if @options.key?(type + "_font_bold_italic")
74
- font_bold_italic = type + "_font_bold_italic"
75
- end
76
-
77
- font_families.update(type => {
78
- :normal => @options[font_normal],
79
- :italic => @options[font_italic],
80
- :bold => @options[font_bold],
81
- :bold_italic => @options[font_bold_italic]
82
- })
83
-
84
- else
85
- if font_families.key?(default_font)
86
- font_families.update(type => {
87
- :normal => font_families[default_font][:normal],
88
- :italic => font_families[default_font][:italic],
89
- :bold => font_families[default_font][:bold],
90
- :bold_italic => font_families[default_font][:bold_italic]
91
- })
92
-
93
- else
94
- font_families.update(type => {
95
- :normal => @options["font_normal"],
96
- :italic => @options["font_italic"],
97
- :bold => @options["font_bold"],
98
- :bold_italic => @options["font_bold_italic"]
99
- })
100
- end
101
-
102
- end
54
+ def output
55
+ FileUtils.mkdir_p @options["output_dir"]
56
+ render_file(@options["output_dir"] + "/" + @options["title"].gsub(/[^\w\s]/, '').tr(" ", "_") + '.pdf')
103
57
  end
104
58
 
105
59
  # Draws page numbering
@@ -139,7 +93,7 @@ module PetitFelix
139
93
  odd_options[:page_filter] = ->(pg) { pg > page_start && pg % 2 == 1 }
140
94
 
141
95
  even_options = {
142
- at: [0, bounds.left],
96
+ at: [bounds.left, 0],
143
97
  width: bounds.width,
144
98
  align: align_even,
145
99
  start_count_at: page_start_count + 1,
@@ -153,7 +107,7 @@ module PetitFelix
153
107
  else
154
108
 
155
109
  options = {
156
- at: [0, 0],
110
+ at: [0, -10],
157
111
  width: bounds.width,
158
112
  align: :right,
159
113
  start_count_at: page_start_count,
@@ -356,31 +310,49 @@ module PetitFelix
356
310
  # content generation
357
311
  font_size(@options["default_font_size"].to_i)
358
312
 
313
+ base_margin = [{
314
+ :left => 10,
315
+ :right => 10,
316
+ :top => 10,
317
+ :bottom => 30
318
+ }]
319
+
320
+ begin
321
+ obj = PetitFelix::Metadata.new.parse_property @options["markdown_margin_array"], "{\"margin\" : ${x}}"
322
+
323
+ base_margin = obj[:margin]
324
+
325
+ rescue
326
+ if @options.key?("markdown_margin_array")
327
+ print "\n"
328
+ print "Note: unable to parse argument " + @options["markdown_margin_array"]
329
+ end
330
+ end
331
+
359
332
  if columns == 1
360
333
 
361
- bounding_box([half_margin, cursor - half_margin],
362
- width: bounds.width-margin,
363
- height: [bounds.height - 20 - margin, bounds.height - margin].min) do
334
+ bounding_box([0, cursor],
335
+ width: bounds.width,
336
+ height: bounds.height,
337
+ base_margins: base_margin) do
364
338
  markdown(content, options: @options)
365
339
  end
366
340
 
367
341
  else
368
342
 
369
- column_box([half_margin, cursor - half_margin],
343
+ column_box([0, cursor],
370
344
  columns: columns,
371
- width: bounds.width-margin,
372
- height: [bounds.height - 20 - margin, bounds.height - margin].min) do
345
+ width: bounds.width,
346
+ height: [bounds.height, bounds.height].min,
347
+ base_margins: base_margin) do
373
348
 
374
349
  markdown(content, options: @options)
375
350
 
376
351
  end
377
352
  end
353
+
378
354
  end
379
355
 
380
- def output
381
- FileUtils.mkdir_p @options["output_dir"]
382
- render_file(@options["output_dir"] + "/" + @options["title"].gsub(/[^\w\s]/, '').tr(" ", "_") + '.pdf')
383
- end
384
356
 
385
357
  end
386
358
 
@@ -0,0 +1,135 @@
1
+ require "prawn"
2
+
3
+ ## Custom column box that calculates bounding box
4
+
5
+ module Prawn
6
+ class Document
7
+ class BoundingBox
8
+
9
+ def initialize(document, parent, point, options = {})
10
+ unless options[:width]
11
+ raise ArgumentError, 'BoundingBox needs the :width option to be set'
12
+ end
13
+
14
+ @document = document
15
+ @parent = parent
16
+ @x, @y = point
17
+ @base_x, @base_y = point
18
+ @width = options[:width]
19
+ @base_width = options[:width]
20
+ @height = options[:height]
21
+ @base_height = options[:height]
22
+ @total_left_padding = 0
23
+ @total_right_padding = 0
24
+ @stretched_height = nil
25
+ @margins = {}
26
+ @base_margins = []
27
+ if options.key?(:base_margins) && !options[:base_margins].nil?
28
+ @base_margins = options[:base_margins]
29
+ end
30
+
31
+ end
32
+
33
+ def update_margins
34
+
35
+ @margins = {}
36
+
37
+ if @base_margins.count > 0
38
+ @margins = @base_margins[@document.page_count % @base_margins.count]
39
+ end
40
+ end
41
+
42
+ def absolute_left
43
+ update_margins
44
+
45
+ margin = 0
46
+
47
+ if !@margins.empty?
48
+ margin = @margins[:left]
49
+ end
50
+
51
+ @base_x + margin
52
+ end
53
+
54
+ def absolute_top
55
+ update_margins
56
+
57
+ margin = 0
58
+
59
+ if !@margins.empty?
60
+ margin = @margins[:top]
61
+ end
62
+
63
+ @base_y - margin
64
+ end
65
+
66
+ def top
67
+ update_margins
68
+
69
+ margin = 0
70
+
71
+ if !@margins.empty?
72
+ margin = @margins[:top]
73
+ end
74
+
75
+ height - margin
76
+ end
77
+
78
+ def width
79
+ update_margins
80
+
81
+ margin_left = 0
82
+ margin_right = 0
83
+
84
+ if !@margins.empty?
85
+ margin_left = @margins[:left]
86
+ margin_right = @margins[:right]
87
+ end
88
+
89
+
90
+ @base_width - (margin_left + margin_right)
91
+ end
92
+
93
+ def height
94
+ update_margins
95
+
96
+ margin_top = 0
97
+ margin_bottom = 0
98
+
99
+ if !@margins.empty?
100
+ margin_top = @margins[:top]
101
+ margin_bottom = @margins[:bottom]
102
+ end
103
+
104
+ @base_height - (margin_top + margin_bottom)
105
+ end
106
+
107
+ # Increase the left padding of the bounding box.
108
+ def add_left_padding(left_padding)
109
+ @total_left_padding += left_padding
110
+ @base_x += left_padding
111
+ @base_width -= left_padding
112
+ end
113
+
114
+ # Decrease the left padding of the bounding box.
115
+ def subtract_left_padding(left_padding)
116
+ @total_left_padding -= left_padding
117
+ @base_x -= left_padding
118
+ @base_width += left_padding
119
+ end
120
+
121
+ # Increase the right padding of the bounding box.
122
+ def add_right_padding(right_padding)
123
+ @total_right_padding += right_padding
124
+ @base_width -= right_padding
125
+ end
126
+
127
+ # Decrease the right padding of the bounding box.
128
+ def subtract_right_padding(right_padding)
129
+ @total_right_padding -= right_padding
130
+ @base_width += right_padding
131
+ end
132
+
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,38 @@
1
+ require "worker/pdf_writer/bounding_box"
2
+
3
+ module Prawn
4
+ class Document
5
+ class ColumnBox < BoundingBox
6
+
7
+ def bare_column_width
8
+ update_margins
9
+
10
+ margin_left = 0
11
+ margin_right = 0
12
+
13
+ if !@margins.empty?
14
+ margin_left = @margins[:left]
15
+ margin_right = @margins[:right]
16
+ end
17
+
18
+ ((@width - (margin_left + margin_right)) - (@spacer * (@columns - 1))) / @columns
19
+ end
20
+
21
+ # Moves to the next column or starts a new page if currently positioned at
22
+ # the rightmost column.
23
+ #
24
+ # @return [void]
25
+ def move_past_bottom
26
+ @current_column = (@current_column + 1) % @columns
27
+ @document.y = absolute_top
28
+ if @current_column.zero?
29
+ if @reflow_margins
30
+ @y = @parent.absolute_top
31
+ end
32
+ @document.start_new_page
33
+ end
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,138 @@
1
+ require "prawn"
2
+ require 'fileutils'
3
+ require "prawndown-ext"
4
+ require "worker/pdf_writer/column_box"
5
+ require "worker/pdf_writer/bounding_box"
6
+
7
+ ## Prawn PDF writer that outputs template files
8
+
9
+ module PetitFelix
10
+ module Worker
11
+
12
+ class DefaultPDFWriter < Prawn::Document
13
+
14
+ # Initializes fonts
15
+ def initialize_font
16
+
17
+ add_font "default"
18
+
19
+ end
20
+
21
+ # Adds a font to the pdf document
22
+ def add_font (type,
23
+ default_font: "default")
24
+
25
+ if @options.key?(type + "_font_normal")
26
+
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"
31
+
32
+ if @options.key?(type + "_font_italic")
33
+ font_italic = type + "_font_italic"
34
+ end
35
+ if @options.key?(type + "_font_bold")
36
+ font_bold = type + "_font_bold"
37
+ end
38
+ if @options.key?(type + "_font_bold_italic")
39
+ font_bold_italic = type + "_font_bold_italic"
40
+ end
41
+
42
+ font_families.update(type => {
43
+ :normal => @options[font_normal],
44
+ :italic => @options[font_italic],
45
+ :bold => @options[font_bold],
46
+ :bold_italic => @options[font_bold_italic]
47
+ })
48
+
49
+ else
50
+ if font_families.key?(default_font)
51
+ font_families.update(type => {
52
+ :normal => font_families[default_font][:normal],
53
+ :italic => font_families[default_font][:italic],
54
+ :bold => font_families[default_font][:bold],
55
+ :bold_italic => font_families[default_font][:bold_italic]
56
+ })
57
+
58
+ else
59
+ font_families.update(type => {
60
+ :normal => @options["font_normal"],
61
+ :italic => @options["font_italic"],
62
+ :bold => @options["font_bold"],
63
+ :bold_italic => @options["font_bold_italic"]
64
+ })
65
+ end
66
+
67
+ end
68
+ end
69
+
70
+ def set_options metaoptions
71
+ @options = metaoptions
72
+ end
73
+
74
+ 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
104
+
105
+ state.page = PDF::Core::Page.new(self, page_options)
106
+
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
135
+
136
+ end
137
+ end
138
+ end