clockworkcomicpdf 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 983d2f02eac2ae6b01baf045ccae832effa3ae3a
4
+ data.tar.gz: 565431e7815bcfd34301b89b45b3b6873cb8a0a6
5
+ SHA512:
6
+ metadata.gz: 034150b51ff58647e31ba36f77a0916bd3290984e153fffcaca1b8c3acac180a4f2b4f57d3abc29d961efd9dd356d77220b3cd2e877d8cf42a3971a4a9e1502a
7
+ data.tar.gz: 0a6aefc0b8080189f0b6a9e57c12b5a3126d1c398531e1805856717f2a0589821760d613a95553b4e795a5005d047caf58e8ccd4fb40c062ebbe3a232e2aab22
@@ -0,0 +1,102 @@
1
+ require_relative 'to_points'
2
+ require_relative 'page_header'
3
+ require_relative 'errors'
4
+ require_relative 'cover'
5
+ require_relative 'version'
6
+ require_relative 'option_validation'
7
+ require_relative 'book_validation'
8
+ require_relative 'book_init'
9
+
10
+ module ClockworkComicPDF
11
+ # variable storage for the book class
12
+ class Book
13
+ include OptionValidation, BookValidation, BookInit
14
+ def font
15
+ @font ||= 'Helvetica'
16
+ end
17
+ attr_writer :font
18
+
19
+ def font_size
20
+ @font_size ||= 12
21
+ end
22
+
23
+ def font_size=(font_size)
24
+ @font_size = font_size.to_points unless font_size.nil?
25
+ end
26
+
27
+ attr_accessor :base_file_name
28
+
29
+ def info
30
+ @info ||= {}
31
+ end
32
+
33
+ def info=(info)
34
+ if info.is_a? Hash
35
+ info[:CreationDate] = Time.now
36
+ info[:Creator] = 'Clockwork Comic PDF Engine'
37
+ info[:Producer] = 'Prawn'
38
+ else
39
+ fail InvalidValueError, 'Information must be set as a Hash value'
40
+ end
41
+ @info = info
42
+ end
43
+
44
+ def page_size
45
+ @page_size ||= [{ val: 8.5, type: :in },
46
+ { val: 11, type: :in }]
47
+ end
48
+
49
+ def page_size=(page_size)
50
+ page_size = page_size.to_a
51
+ page_size.each do |dim|
52
+ page_size[page_size.find_index dim] = dim.to_points
53
+ end
54
+ @page_size = page_size
55
+ end
56
+
57
+ def margin
58
+ @margin ||= { val: 0.25, type: :in }
59
+ end
60
+
61
+ def margin=(margin)
62
+ @margin = []
63
+ margin = [margin] unless margin.is_a? Array
64
+ unless margin.count == 4 || margin.count == 1
65
+ fail InvalidValueError 'Margin must contain 1 or 4 values'
66
+ end
67
+ margin.each_index do |i|
68
+ @margin[i] = margin[i].to_points
69
+ end
70
+ @margin
71
+ end
72
+
73
+ def offset_from_spine
74
+ @offset_from_spine ||= 0
75
+ end
76
+
77
+ def offset_from_spine=(offset_from_spine)
78
+ @offset_from_spine = offset_from_spine.to_points
79
+ end
80
+
81
+ def print_toc
82
+ @print_toc = true if @print_toc.nil?
83
+ @print_toc
84
+ end
85
+ attr_writer :print_toc
86
+
87
+ def print_pagenum
88
+ @print_pagenum = true if @print_toc.nil?
89
+ @print_pagenum
90
+ end
91
+ attr_writer :print_pagenum
92
+ attr_accessor :page_header
93
+ attr_accessor :cover
94
+
95
+ def versions
96
+ @versions ||= []
97
+ end
98
+ attr_writer :versions
99
+
100
+ attr_accessor :sections
101
+ end
102
+ end
@@ -0,0 +1,37 @@
1
+ module ClockworkComicPDF
2
+ # initalization blocks for the book class
3
+ module BookInit
4
+ def valid_options
5
+ [:font, :info, :base_file_name, :page_size, :margin,
6
+ :offset_from_spine, :print_toc, :print_pagenum, :page_header,
7
+ :versions, :sections, :font_size, :cover]
8
+ end
9
+
10
+ def initialize(options = {})
11
+ check_options(options.keys, valid_options)
12
+ initialize_options(options)
13
+ initialize_content(options)
14
+ end
15
+
16
+ private
17
+
18
+ def initialize_options(options = {})
19
+ self.font = options[:font]
20
+ self.base_file_name = options[:base_file_name]
21
+ self.info = options[:info]
22
+ self.page_size = options[:page_size]
23
+ self.margin = options[:margin]
24
+ self.offset_from_spine = options[:offset_from_spine]
25
+ self.print_toc = options[:print_toc]
26
+ self.print_pagenum = options[:print_pagenum]
27
+ end
28
+
29
+ def initialize_content(options = {})
30
+ self.page_header = PageHeader.new(options[:page_header])
31
+ self.cover = Cover.new(options[:cover])
32
+ self.versions = Versions.new(options[:versions])
33
+ self.sections = Sections.new(options[:sections])
34
+ self.font_size = options[:font_size]
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,79 @@
1
+ module ClockworkComicPDF
2
+ # Validation Module for Book Class
3
+ module BookValidation
4
+ def validate
5
+ fail MissingValueError, 'base_file_name required' unless @base_file_name
6
+ cover.validate if cover
7
+ sections.validate
8
+ versions.validate
9
+ miss = image_mismatch
10
+ if miss.count > 0
11
+ fail_s = "Image directories do no match: #{miss.join(', ')}"
12
+ fail MissingValueError, fail_s
13
+ end
14
+ end
15
+
16
+ def image_mismatch
17
+ mismatch = []
18
+ files = version_files
19
+ files.each_pair do |key_v, sec|
20
+ mismatch.concat(scan_version(key_v, sec, files))
21
+ end
22
+ mismatch.flatten
23
+ end
24
+
25
+ def scan_version(key_v, sec, files)
26
+ mismatch = []
27
+ files.each_pair do |c_ver, c_sec|
28
+ unless key_v == c_ver
29
+ mismatch << scan_section(key_v.name, sec, c_ver.name, c_sec)
30
+ end
31
+ end
32
+ mismatch
33
+ end
34
+
35
+ def scan_section(v_name, sec_v, c_name, sec_c)
36
+ mismatch = []
37
+ sec_v.each_pair do |ss_key, ss_v|
38
+ ss_v.each do |f|
39
+ unless sec_c[ss_key].include? f
40
+ mismatch << "#{f} in section #{ss_key.name} exists " <<
41
+ "in #{v_name} but not #{c_name}"
42
+ end
43
+ end
44
+ end
45
+ mismatch
46
+ end
47
+
48
+ def version_files
49
+ files = {}
50
+ versions.each do |version|
51
+ files[version] = section_files(version)
52
+ end
53
+ files
54
+ end
55
+
56
+ def section_files(check_ver)
57
+ s_files = {}
58
+ [sections.front_matter, sections.body,
59
+ sections.end_matter].flatten.each do |sub|
60
+ if sub.is_a? SectionComicPages
61
+ s_files[sub] = get_comic_files(check_ver, sub)
62
+ end
63
+ end
64
+ s_files
65
+ end
66
+
67
+ def get_comic_files(check_ver, sub)
68
+ current_dir = "./#{check_ver.name}/#{sub.directory}/"
69
+ unless File.exist?(current_dir)
70
+ fail InvalidValueError, "#{File.path(current_dir)} does not exist"
71
+ end
72
+ c_files = []
73
+ Dir["#{current_dir}*.*"].each do |file|
74
+ c_files << File.basename(file, '.*')
75
+ end
76
+ c_files
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,42 @@
1
+ require_relative 'to_points'
2
+ require_relative 'errors'
3
+ require_relative 'option_validation'
4
+
5
+ module ClockworkComicPDF
6
+ # this contains the size, file path, and size of the cover
7
+ class Cover
8
+ include OptionValidation
9
+ attr_reader :size
10
+ def size=(size)
11
+ unless size.is_a?(Array) && size.count == 2
12
+ throw InvalidValueError.new 'Cover size must contain exactly 2 values'
13
+ end
14
+ size[0] = size[0].to_points
15
+ size[1] = size[1].to_points
16
+ @size = size
17
+ end
18
+
19
+ attr_reader :path
20
+ def path=(path)
21
+ @path = path.to_s
22
+ end
23
+
24
+ attr_reader :file
25
+ def file=(file)
26
+ @file = file.to_s
27
+ end
28
+
29
+ def validate
30
+ fail InvalidValueError, 'Cover Must specify a file' unless file
31
+ fail InvalidValueError, 'Cover must specify a size' unless size
32
+ fail InvalidValueError, 'Cover must specify a path' unless path
33
+ end
34
+
35
+ def initialize(options = {})
36
+ check_options(options.keys, [:size, :path, :file])
37
+ self.path = options[:path]
38
+ self.size = options[:size]
39
+ self.file = options[:file]
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,13 @@
1
+ module ClockworkComicPDF
2
+ class MissingValueError < StandardError
3
+ end
4
+
5
+ class InvalidValueError < ArgumentError
6
+ end
7
+
8
+ class UndefinedKeyError < ArgumentError
9
+ end
10
+
11
+ class ArgumentError < ArgumentError
12
+ end
13
+ end
@@ -0,0 +1,83 @@
1
+ module ClockworkComicPDF
2
+ # stores the option parsing logic for PDFMaker
3
+ module MeasurementParser
4
+ def parse_options(pdf, opt_in)
5
+ out = {}
6
+ opt_in.each_pair do |key, val|
7
+ case key
8
+ when :height_ratio then out[:height] = pdf.bounds.height * val.to_r
9
+ when :width_ratio then out[:width] = pdf.bounds.width * val.to_r
10
+ else out[key] = convert_val(pdf, val, opt_in)
11
+ end
12
+ end
13
+ out
14
+ end
15
+
16
+ def convert_val(pdf, val, opt_in)
17
+ if val.is_a? Array
18
+ val = Array.new(val)
19
+ val.each_index do |i|
20
+ val[i] = convert_val(pdf, val[i], opt_in)
21
+ end
22
+ else
23
+ val = convert_position(pdf, val)
24
+ val = convert_size(pdf, val, opt_in)
25
+ end
26
+ val
27
+ end
28
+
29
+ def convert_position(pdf, val)
30
+ val = convert_complex_position(pdf, val)
31
+ val = convert_simple_position(pdf, val)
32
+ val
33
+ end
34
+
35
+ def convert_complex_position(pdf, val)
36
+ case val
37
+ when :bounds_top_left then return pdf.bounds.top_left
38
+ when :bounds_top_right then return pdf.bounds.top_right
39
+ when :bounds_bottom_left then return pdf.bounds.bottom_left
40
+ when :bounds_bottom_right then return pdf.bounds.bottom_right
41
+ else return val
42
+ end
43
+ end
44
+
45
+ def convert_simple_position(pdf, val)
46
+ case val
47
+ when :bounds_top then return pdf.bounds.top
48
+ when :bounds_bottom then return pdf.bounds.bottom
49
+ when :bounds_left then return pdf.bounds.left
50
+ when :bounds_right then return pdf.bounds.right
51
+ else return val
52
+ end
53
+ end
54
+
55
+ def convert_size(pdf, val, opt_in)
56
+ case val
57
+ when :bounds_width then return pdf.bounds.width
58
+ when :bounds_height then return pdf.bounds.height
59
+ when :bounds_center_width then return get_h_center(pdf, opt_in)
60
+ when :bounds_center_height then return get_v_center(pdf, opt_in)
61
+ else return val
62
+ end
63
+ end
64
+
65
+ def get_h_center(pdf, opt_in)
66
+ if !opt_in[:width_ratio].nil?
67
+ box_width = opt_in[:width_ratio].to_r * pdf.bounds.width
68
+ else
69
+ box_width = opt_in[:width]
70
+ end
71
+ pdf.bounds.width / 2 - box_width / 2
72
+ end
73
+
74
+ def get_v_center(pdf, options)
75
+ if !opt_in[:height_ratio].nil?
76
+ box_height = opt_in[:height_ratio].to_r * pdf.bounds.height
77
+ else
78
+ box_height = opt_in[:height]
79
+ end
80
+ pdf.bounds.height / 2 - box_height / 2
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'errors'
2
+
3
+ # Module-level parameter checker
4
+ module ClockworkComicPDF
5
+ # provides option validation and requirements vaildaiton
6
+ module OptionValidation
7
+ def check_options(options, valid_options)
8
+ options.each do |key|
9
+ unless valid_options.include? key
10
+ fail UndefinedKeyError, "Unsupported key '#{key}' " <<
11
+ "for '#{self.class}'"
12
+ end
13
+ end
14
+ end
15
+
16
+ def check_required(options = {})
17
+ options.each_pair do |key, val|
18
+ fail UndefinedKeyError, "'#{self.class}' requires " <<
19
+ "key '#{key}'" if val.nil?
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,59 @@
1
+ require_relative 'errors'
2
+ require_relative 'option_validation'
3
+
4
+ module ClockworkComicPDF
5
+ # storage class for the page header
6
+ # includes alignment, left and right side text, and size
7
+ class PageHeader
8
+ include OptionValidation
9
+ def align
10
+ @align = :center unless @align
11
+ @align
12
+ end
13
+ attr_writer :align
14
+
15
+ def text=(text)
16
+ self.left_text = text
17
+ self.right_text = text
18
+ end
19
+
20
+ def text
21
+ { left: left_text, right: right_text }
22
+ end
23
+
24
+ def left_text
25
+ @left_text ||= ''
26
+ end
27
+
28
+ def left_text=(left_text)
29
+ @left_text = left_text.to_s
30
+ end
31
+
32
+ def right_text
33
+ @right_text ||= ''
34
+ end
35
+
36
+ def right_text=(right_text)
37
+ @right_text = right_text.to_s
38
+ end
39
+
40
+ def size
41
+ @size = 8 unless @size
42
+ @size
43
+ end
44
+
45
+ def size=(size)
46
+ @size = size.to_points
47
+ end
48
+
49
+ def initialize(options = {})
50
+ valid_options = [:size, :text, :left_text, :right_text, :align]
51
+ check_options(options.keys, valid_options)
52
+ self.size = options[:size]
53
+ self.text = options[:text]
54
+ self.left_text = options[:left_text]
55
+ self.right_text = options[:right_text]
56
+ self.align = options[:align]
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,116 @@
1
+ require_relative 'book'
2
+ require_relative 'version'
3
+ require_relative 'measurement_parser'
4
+ require_relative 'pdf_section_maker'
5
+ require_relative 'pdf_toc_maker'
6
+ require 'prawn'
7
+
8
+ module ClockworkComicPDF
9
+ # this parses the sections of a book into a pdf file
10
+ class PDFMaker
11
+ include MeasurementParser, PDFSectionMaker, PDFTocMaker
12
+ attr_accessor :book, :content_start, :debug, :printing_body, :current_page,
13
+ :trim_offset
14
+
15
+ attr_writer :page_index
16
+ def page_index
17
+ @page_index ||= []
18
+ end
19
+
20
+ def initialize(book)
21
+ self.book = book
22
+ end
23
+
24
+ def print
25
+ book.validate
26
+ book.versions.each do |version|
27
+ self.content_start = nil
28
+ self.printing_body = false
29
+ self.current_page = nil
30
+ self.page_index = nil
31
+ self.debug = false
32
+ print_version(version)
33
+ end
34
+ end
35
+
36
+ def print_version(version)
37
+ self.trim_offset = version.trim_offset
38
+ pdf = Prawn::Document.new(info: book.info, font_size: book.font_size,
39
+ skip_page_creation: true)
40
+ print_sections(pdf, version)
41
+ print_cover(pdf, version) if version.print_cover
42
+ pdf.render_file "#{book.base_file_name} - #{version.name}.pdf"
43
+ end
44
+
45
+ def print_cover(pdf, version)
46
+ pdf.go_to_page 0
47
+ return if book.cover.nil?
48
+ cover = book.cover
49
+ pdf.start_new_page(size: cover.size, margin: 0)
50
+ pdf.image("#{cover.path}/#{version.name}/#{cover.file}",
51
+ at: pdf.bounds.top_left, scale: 72.0 / version.dpi.to_f)
52
+ end
53
+
54
+ def new_page(pdf)
55
+ if trim_offset then make_trim_page(pdf)
56
+ else make_offset_page(pdf)
57
+ end
58
+ pdf.font(book.font)
59
+ print_body_page(pdf) if printing_body
60
+ debug_stroke(pdf) if debug
61
+ end
62
+
63
+ def make_offset_page(pdf)
64
+ margin = Array.new(book.margin)
65
+ if pdf.page_number.odd? then margin[1] += book.offset_from_spine
66
+ else margin[3] += book.offset_from_spine
67
+ end
68
+ pdf.start_new_page(size: book.page_size, margin: margin)
69
+ end
70
+
71
+ def make_trim_page(pdf)
72
+ margin = Array.new(book.margin)
73
+ pdf.start_new_page(size: [book.page_size[0] - book.offset_from_spine,
74
+ book.page_size[1]],
75
+ margin: margin)
76
+ end
77
+
78
+ def print_body_page(pdf)
79
+ self.current_page += 1
80
+ print_header(pdf) unless book.page_header.nil?
81
+ print_page_num(pdf) if book.print_pagenum
82
+ end
83
+
84
+ def print_header(pdf)
85
+ head = book.page_header
86
+ options = { size: head.size, align: head.align, width: pdf.bounds.width }
87
+ text = pdf.page_number.even? ? head.left_text : head.right_text
88
+ options[:at] = [pdf.bounds.left, pdf.bounds.top + 0.25.in]
89
+ options[:valign] = :center
90
+ options[:height] = 0.25.in
91
+ if options[:align] == :alternating
92
+ options[:align] = even_page ? :left : :right
93
+ end
94
+ pdf.text_box(text, options)
95
+ end
96
+
97
+ def print_page_num(pdf)
98
+ options = { at: pdf.bounds.bottom_left,
99
+ width: pdf.bounds.width,
100
+ align: :center,
101
+ size: 8 }
102
+ options[:height] = 0.25.in
103
+ pdf.text_box("#{self.current_page}", options)
104
+ end
105
+
106
+ def debug_stroke(pdf)
107
+ pdf.stroke_bounds
108
+ pdf.stroke do
109
+ pdf.line [0, 0], [pdf.bounds.width, pdf.bounds.height]
110
+ pdf.line [pdf.bounds.width, 0], [0, pdf.bounds.height]
111
+ pdf.line [pdf.bounds.width / 2,
112
+ pdf.bounds.height], [pdf.bounds.width / 2, 0]
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,82 @@
1
+ module ClockworkComicPDF
2
+ # this parses the sections of a book into a pdf file
3
+ module PDFSectionMaker
4
+ def print_sections(pdf, version)
5
+ print_section(pdf, version, book.sections.front_matter)
6
+ self.printing_body = true
7
+ self.current_page = 0
8
+ self.content_start = pdf.page_number + 1
9
+ print_section(pdf, version, book.sections.body)
10
+ self.printing_body = false
11
+ print_section(pdf, version, book.sections.end_matter)
12
+ new_page(pdf) if pdf.page_number.odd?
13
+ print_toc(pdf) if book.print_toc
14
+ end
15
+
16
+ def print_section(pdf, version, section)
17
+ section.each do |item|
18
+ case item.type
19
+ when :text_box
20
+ print_text_box(pdf, version, item)
21
+ when :formatted_text_box
22
+ print_formatted_text_box(pdf, version, item)
23
+ when :comic_pages
24
+ print_comic_pages(pdf, version, item)
25
+ end
26
+ end
27
+ end
28
+
29
+ def print_comic_pages(pdf, version, comic_pages)
30
+ puts comic_pages.name
31
+ if comic_pages.print_section_intro
32
+ print_section_break(pdf, comic_pages.name)
33
+ end
34
+ section_dir = "./#{version.name}/#{comic_pages.directory}/"
35
+ Dir["#{section_dir}*.*"].each do |image|
36
+ print_comic_image(pdf, version, image)
37
+ end
38
+ end
39
+
40
+ def print_section_break(pdf, text)
41
+ new_page(pdf)
42
+ pdf.move_cursor_to pdf.bounds.top
43
+ options = { valign: :center, align: :center, width: pdf.bounds.width,
44
+ height: pdf.bounds.height, size: 18,
45
+ at: pdf.bounds.top_left }
46
+ page_index << { page: current_page, name: text } if printing_body
47
+ pdf.text_box(text, options)
48
+ end
49
+
50
+ def print_comic_image(pdf, version, image)
51
+ new_page(pdf)
52
+ name = make_name(image)
53
+ page_index << { page: current_page, name: "#{name}" } if printing_body
54
+ content = [[name], [{ image: image, scale: 72.0 / version.dpi }]]
55
+ table = Prawn::Table.new(content, pdf, cell_style: { borders: [] },
56
+ position: :center)
57
+ pdf.move_down((pdf.bounds.height - table.height) / 2.0)
58
+ table.draw
59
+ end
60
+
61
+ def make_name(file_path)
62
+ File.basename(file_path, '.*').split(' ').slice(1..-1).join(' ')
63
+ end
64
+
65
+ def print_text_box(pdf, version, content)
66
+ text = File.new(content.file).read
67
+ make_text_box(pdf, [{ text: text }], content)
68
+ end
69
+
70
+ def print_formatted_text_box(pdf, version, content)
71
+ text = YAML.load_file(content.file)
72
+ make_text_box(pdf, text, content)
73
+ end
74
+
75
+ def make_text_box(pdf, text, content)
76
+ new_page(pdf)
77
+ page_index << { page: current_page, name: content.name } if printing_body
78
+ options = parse_options(pdf, content.options)
79
+ pdf.formatted_text_box(text, options)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,27 @@
1
+ module ClockworkComicPDF
2
+ # stores the PDF printing methods for making the table of contents
3
+ module PDFTocMaker
4
+ def print_toc(pdf)
5
+ pdf.go_to_page(content_start - 1)
6
+ toc_start = pdf.page_number
7
+ new_page(pdf)
8
+ pdf.text 'Table of Contents', size: 18, align: :left
9
+ pdf.move_down(25)
10
+ page_index.each { |toc_item| make_toc_item(pdf, toc_item) }
11
+ new_page(pdf) unless (toc_start - pdf.page_number).even?
12
+ self.content_start += (toc_start - pdf.page_number)
13
+ end
14
+
15
+ def make_toc_item(pdf, toc_item)
16
+ content = [["#{toc_item[:name]}", "#{toc_item[:page]}"]]
17
+ options = { width: pdf.bounds.width / 2, position: :center,
18
+ cell_style: { borders: [], size: 8,
19
+ padding: 1 } }
20
+ table = Prawn::Table.new(content, pdf, options) do
21
+ cells.style { |c| c.align = c.column.zero? ? :left : :right }
22
+ end
23
+ new_page(pdf) if table.height >= pdf.cursor
24
+ table.draw
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,144 @@
1
+ require_relative 'option_validation'
2
+
3
+ module ClockworkComicPDF
4
+ # this stores the data for each section of the book
5
+ class Sections
6
+ include OptionValidation
7
+ def front_matter
8
+ @front_matter ||= []
9
+ end
10
+ attr_writer :front_matter
11
+
12
+ def body
13
+ @body ||= []
14
+ @body
15
+ end
16
+ attr_writer :body
17
+
18
+ def end_matter
19
+ @end_matter ||= []
20
+ @end_matter
21
+ end
22
+ attr_writer :end_matter
23
+
24
+ def parse_sections(sections)
25
+ parsed_sections = []
26
+ sections.each do |section|
27
+ parsed_sections << section_by_type(section)
28
+ end
29
+ parsed_sections
30
+ end
31
+
32
+ def section_by_type(section)
33
+ case section[:type]
34
+ when :comic_pages
35
+ return SectionComicPages.new(section)
36
+ when :text_box
37
+ return SectionTextBox.new(section)
38
+ when :formatted_text_box
39
+ return SectionFormattedTextBox.new(section)
40
+ else
41
+ fail InvalidKeyError, "#{section[:type]} is not a valid section type"
42
+ end
43
+ end
44
+
45
+ def validate
46
+ [front_matter, body, end_matter].each do |chunk|
47
+ chunk.each { |sec| sec.validate }
48
+ end
49
+ end
50
+
51
+ def print_pdf(options = {})
52
+ [front_matter, body, end_matter].each do |chunk|
53
+ chunk.each { |sec| sec.print_pdf(options) }
54
+ end
55
+ end
56
+
57
+ def initialize(options = {})
58
+ check_options(options.keys, [:front_matter, :body, :end_matter])
59
+ self.front_matter = parse_sections(options[:front_matter])
60
+ self.body = parse_sections(options[:body])
61
+ self.end_matter = parse_sections(options[:end_matter])
62
+ end
63
+ end
64
+
65
+ # this is the base class for sections data that stores common section info
66
+ class Section
67
+ include OptionValidation
68
+ attr_writer :print_section_intro
69
+ def print_section_intro
70
+ @print_section_intro = false if @print_section_intro.nil?
71
+ @print_section_intro
72
+ end
73
+
74
+ attr_accessor :type
75
+ attr_accessor :name
76
+
77
+ def valid_options
78
+ @valid_options = [:print_section_intro, :type, :name]
79
+ end
80
+
81
+ def req_keys
82
+ @required_keys = { name: @name }
83
+ end
84
+
85
+ def validate
86
+ check_required(req_keys)
87
+ end
88
+
89
+ def initialize(options = {})
90
+ self.name = options[:name]
91
+ self.type = options[:type]
92
+ self.print_section_intro = options[:print_section_intro]
93
+ end
94
+ end
95
+
96
+ # Comic Pages section
97
+ class SectionComicPages < Section
98
+ def valid_options
99
+ super
100
+ @valid_options << :directory
101
+ end
102
+
103
+ def req_keys
104
+ super
105
+ @required_keys[:directory] = @directory
106
+ @required_keys
107
+ end
108
+
109
+ attr_accessor :directory
110
+
111
+ def initialize(options = {})
112
+ super
113
+ self.directory = options[:directory]
114
+ end
115
+ end
116
+
117
+ # text box method
118
+ class SectionTextBox < Section
119
+ attr_accessor :file, :options
120
+
121
+ def valid_options
122
+ super
123
+ @valid_options << :file
124
+ @valid_options << :options
125
+ end
126
+
127
+ def req_keys
128
+ super
129
+ @required_keys[:file] = @file
130
+ @required_keys[:options] = @options
131
+ @required_keys
132
+ end
133
+
134
+ def initialize(options = {})
135
+ super
136
+ self.options = options[:options]
137
+ self.file = options[:file]
138
+ end
139
+ end
140
+
141
+ # formatted text box method
142
+ class SectionFormattedTextBox < SectionTextBox
143
+ end
144
+ end
@@ -0,0 +1,27 @@
1
+ require 'prawn/measurement_extensions'
2
+
3
+ # adds point conversion function for hash values
4
+ class Hash
5
+ def to_points
6
+ if size == 2 && self[:val] && self[:type]
7
+ return self[:val].to_f.send(self[:type])
8
+ end
9
+ puts self
10
+ fail ClockworkComicPDF::UndefinedKeyError,
11
+ 'measurement must contain only :val and :type'
12
+ end
13
+ end
14
+
15
+ # returns itself as is for fixnum
16
+ class Fixnum
17
+ def to_points
18
+ self
19
+ end
20
+ end
21
+
22
+ # returns itself as is for Float
23
+ class Float
24
+ def to_points
25
+ self
26
+ end
27
+ end
@@ -0,0 +1,59 @@
1
+ require_relative 'option_validation'
2
+
3
+ module ClockworkComicPDF
4
+ # convienience class for parsing and holding version objects
5
+ class Versions < Array
6
+ def initialize(options)
7
+ options.each do |param|
8
+ self << Version.new(param)
9
+ end
10
+ end
11
+
12
+ def validate
13
+ each { |version| version.validate }
14
+ end
15
+ end
16
+
17
+ # stores version information for PDF generation
18
+ # includes name, length, dpi and a toggle for printing the cover
19
+ class Version
20
+ include OptionValidation
21
+ attr_reader :name
22
+ def name=(name)
23
+ @name = name.to_s
24
+ end
25
+
26
+ attr_reader :dpi
27
+ def dpi=(dpi)
28
+ @dpi = dpi.to_i
29
+ end
30
+
31
+ def print_cover
32
+ @print_cover = false if @print_cover.nil?
33
+ @print_cover
34
+ end
35
+ attr_writer :print_cover
36
+
37
+ def trim_offset
38
+ @trim_offset = false if @trim_offset.nil?
39
+ @trim_offset
40
+ end
41
+ attr_writer :trim_offset
42
+
43
+ def validate
44
+ fail InvalidValueError, 'Each version must contain a name' unless name
45
+ fail InvalidValueError,
46
+ 'Each version must contain a name' if name.length == 0
47
+ fail InvalidValueError,
48
+ 'each version must specify a dpi value' unless dpi
49
+ end
50
+
51
+ def initialize(options = {})
52
+ check_options(options.keys, [:name, :dpi, :print_cover, :trim_offset])
53
+ self.name = options[:name]
54
+ self.dpi = options[:dpi]
55
+ self.trim_offset = options[:trim_offset]
56
+ self.print_cover = options[:print_cover]
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,21 @@
1
+ require 'prawn'
2
+ require 'yaml'
3
+
4
+ require_relative 'clockwork_comic_pdf/book'
5
+ require_relative 'clockwork_comic_pdf/errors'
6
+ require_relative 'clockwork_comic_pdf/page_header'
7
+ require_relative 'clockwork_comic_pdf/cover'
8
+ require_relative 'clockwork_comic_pdf/version'
9
+ require_relative 'clockwork_comic_pdf/section'
10
+ require_relative 'clockwork_comic_pdf/option_validation'
11
+ require_relative 'clockwork_comic_pdf/pdf_maker'
12
+
13
+ # the base module for ClockworkComicPDF
14
+ module ClockworkComicPDF
15
+ # VERSION "0.1.0"
16
+ def book_from_yaml(book)
17
+ parsed_book = Book.new(YAML.load_file(book))
18
+ PDFMaker.new(parsed_book).print
19
+ end
20
+ module_function :book_from_yaml
21
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: clockworkcomicpdf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Skiba
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: prawn
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.15.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 0.15.0
27
+ description: A Simple(ish) Ruby System for creating print and web ready PDF files.
28
+ email: mike.skiba@atelierclockwork.net
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/clockwork_comic_pdf/book.rb
34
+ - lib/clockwork_comic_pdf/book_init.rb
35
+ - lib/clockwork_comic_pdf/book_validation.rb
36
+ - lib/clockwork_comic_pdf/cover.rb
37
+ - lib/clockwork_comic_pdf/errors.rb
38
+ - lib/clockwork_comic_pdf/measurement_parser.rb
39
+ - lib/clockwork_comic_pdf/option_validation.rb
40
+ - lib/clockwork_comic_pdf/page_header.rb
41
+ - lib/clockwork_comic_pdf/pdf_maker.rb
42
+ - lib/clockwork_comic_pdf/pdf_section_maker.rb
43
+ - lib/clockwork_comic_pdf/pdf_toc_maker.rb
44
+ - lib/clockwork_comic_pdf/section.rb
45
+ - lib/clockwork_comic_pdf/to_points.rb
46
+ - lib/clockwork_comic_pdf/version.rb
47
+ - lib/clockworkcomicpdf.rb
48
+ homepage: http://www.atelierclockwork.net/ccpdf/
49
+ licenses:
50
+ - MIT
51
+ metadata: {}
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - '>='
59
+ - !ruby/object:Gem::Version
60
+ version: 1.9.3
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - '>='
64
+ - !ruby/object:Gem::Version
65
+ version: 1.3.6
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 2.0.3
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: Clockwork Comic PDF
72
+ test_files: []