petit-felix 0.1.4 → 0.1.6
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.
- checksums.yaml +4 -4
- data/lib/felix/config.rb +34 -24
- data/lib/felix/error.rb +4 -2
- data/lib/felix/generator.rb +6 -3
- data/lib/felix/metadata.rb +33 -4
- data/lib/felix/task_manager.rb +17 -7
- data/lib/petit-felix.rb +3 -1
- data/lib/task/basic_pdf_classic_task.rb +182 -0
- data/lib/task/default_task.rb +54 -9
- data/lib/task/pdf_single_task.rb +74 -0
- data/lib/task/template_pdf_task.rb +51 -0
- data/lib/version.rb +3 -1
- data/lib/worker/{basic_pdf_writer.rb → basic_pdf_writer_classic.rb} +38 -66
- data/lib/worker/pdf_writer/bounding_box.rb +135 -0
- data/lib/worker/pdf_writer/column_box.rb +38 -0
- data/lib/worker/pdf_writer.rb +98 -0
- data/lib/worker/template_pdf_writer.rb +300 -0
- data/lib/worker/templater/error.rb +90 -0
- data/lib/worker/templater/font.rb +59 -0
- data/lib/worker/templater/methods.rb +1072 -0
- data/lib/worker/templater/validation.rb +213 -0
- data/templates/zine-single.json +774 -0
- metadata +29 -3
- data/lib/task/basic_pdf_task.rb +0 -133
@@ -0,0 +1,51 @@
|
|
1
|
+
require "task/default_task"
|
2
|
+
require "worker/template_pdf_writer"
|
3
|
+
|
4
|
+
module PetitFelix
|
5
|
+
|
6
|
+
module Task
|
7
|
+
|
8
|
+
class TemplatePDFTask < PetitFelix::Task::DefaultTask
|
9
|
+
|
10
|
+
def self.name
|
11
|
+
|
12
|
+
"template-pdf"
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
## Default options of the application
|
17
|
+
def self.default_options
|
18
|
+
|
19
|
+
return {
|
20
|
+
"template" => "./templates/test.json",
|
21
|
+
"output_file" => "./output/test.pdf"
|
22
|
+
}
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
def render_zine
|
27
|
+
|
28
|
+
# Only continue if metadata has a title
|
29
|
+
# Generates PDF
|
30
|
+
|
31
|
+
pdf = PetitFelix::Worker::TemplatePDFWriter.new(
|
32
|
+
page_layout: @metaoptions["page_layout"],
|
33
|
+
print_scaling: @metaoptions["print_scaling"])
|
34
|
+
|
35
|
+
pdf.set_options @metaoptions
|
36
|
+
|
37
|
+
pdf.init_values @metaoptions, pdf
|
38
|
+
|
39
|
+
pdf.read_template
|
40
|
+
|
41
|
+
# Outputs to file
|
42
|
+
pdf.output
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
data/lib/version.rb
CHANGED
@@ -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 <
|
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
|
-
|
57
|
-
|
58
|
-
|
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
|
@@ -113,7 +67,7 @@ module PetitFelix
|
|
113
67
|
|
114
68
|
font_size(@options["paginator_size"].to_i)
|
115
69
|
|
116
|
-
string = @options["title"]
|
70
|
+
string = "#{@options["title"]}: <page>"
|
117
71
|
|
118
72
|
page_start_count = @options["paginator_start_count"].to_i
|
119
73
|
page_start = @options["paginator_start"].to_i
|
@@ -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: [
|
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,
|
110
|
+
at: [0, -10],
|
157
111
|
width: bounds.width,
|
158
112
|
align: :right,
|
159
113
|
start_count_at: page_start_count,
|
@@ -309,7 +263,7 @@ module PetitFelix
|
|
309
263
|
bounding_box([50, cursor],
|
310
264
|
width: bounds.width - 100,
|
311
265
|
height: 30) do
|
312
|
-
text_box("Original Publication:
|
266
|
+
text_box("Original Publication: #{@options["date"]}",#.strftime('%e %B, %Y'),
|
313
267
|
align: :center)
|
314
268
|
#transparent(0.5) { stroke_bounds }
|
315
269
|
end
|
@@ -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([
|
362
|
-
width: bounds.width
|
363
|
-
height:
|
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([
|
343
|
+
column_box([0, cursor],
|
370
344
|
columns: columns,
|
371
|
-
width: bounds.width
|
372
|
-
height: [bounds.height
|
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,98 @@
|
|
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
|
+
|
34
|
+
font_italic = "#{type}_font_italic"
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
if @options.key? "#{type}_font_bold"
|
39
|
+
|
40
|
+
font_bold = "#{type}_font_bold"
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
if @options.key? "#{type}_font_bold_italic"
|
45
|
+
|
46
|
+
font_bold_italic = "#{type}_font_bold_italic"
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
font_families.update(type => {
|
51
|
+
|
52
|
+
:normal => @options[font_normal],
|
53
|
+
:italic => @options[font_italic],
|
54
|
+
:bold => @options[font_bold],
|
55
|
+
:bold_italic => @options[font_bold_italic]
|
56
|
+
|
57
|
+
})
|
58
|
+
|
59
|
+
else
|
60
|
+
if font_families.key?(default_font)
|
61
|
+
|
62
|
+
font_families.update(type => {
|
63
|
+
:normal => font_families[default_font][:normal],
|
64
|
+
:italic => font_families[default_font][:italic],
|
65
|
+
:bold => font_families[default_font][:bold],
|
66
|
+
:bold_italic => font_families[default_font][:bold_italic]
|
67
|
+
})
|
68
|
+
|
69
|
+
else
|
70
|
+
|
71
|
+
font_families.update(type => {
|
72
|
+
:normal => @options["font_normal"],
|
73
|
+
:italic => @options["font_italic"],
|
74
|
+
:bold => @options["font_bold"],
|
75
|
+
:bold_italic => @options["font_bold_italic"]
|
76
|
+
})
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def set_options metaoptions
|
84
|
+
|
85
|
+
@options = metaoptions
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
def output
|
90
|
+
|
91
|
+
FileUtils.mkdir_p File.dirname("#{@options["output_dir"]}/#{@options["output_file"]}")
|
92
|
+
render_file("#{@options["output_dir"]}/#{@options["output_file"]}")
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|