philomath 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.
- checksums.yaml +7 -0
- data/lib/philomath/rendering/render_callback.rb +21 -0
- data/lib/philomath/rendering/render_code_inline.rb +13 -0
- data/lib/philomath/rendering/render_styled_link.rb +23 -0
- data/lib/philomath/rendering/render_without_entities.rb +13 -0
- data/lib/philomath/version.rb +9 -0
- data/lib/philomath.rb +143 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bb70795a33712bfa57b1199014c8c8e47db6b01939a20b2076f8893f687cf126
|
4
|
+
data.tar.gz: 97dace31e67170cd2c76e5618be7263df4a57e9ff6c02bd8632cd99587164685
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a416eceddfbf958bc994dd221e9844bc4886f65bea2da18553a74d786c364b061860ad72fce0c345f78d85a6f15d2dd7327e678df50c3517806517837c19b048
|
7
|
+
data.tar.gz: afa5784f2b3c04aee3dd1f4cc4a0b1f2aec86a22ac6f73d18bdca7a4247fa6680a0145d40cd0d0b51210ec9c4f516e012f4fd45040968f6dc9af5d96d120ed24
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Philomath
|
2
|
+
module Rendering
|
3
|
+
class RenderCallback
|
4
|
+
CALLBACKS = [
|
5
|
+
Philomath::Rendering::RenderCodeInline,
|
6
|
+
Philomath::Rendering::RenderWithoutEntities,
|
7
|
+
Philomath::Rendering::RenderStyledLink
|
8
|
+
]
|
9
|
+
|
10
|
+
def call(value)
|
11
|
+
parsed_value = value
|
12
|
+
|
13
|
+
CALLBACKS.each do |callback|
|
14
|
+
parsed_value = callback.call(parsed_value)
|
15
|
+
end
|
16
|
+
|
17
|
+
parsed_value
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Philomath
|
2
|
+
module Rendering
|
3
|
+
class RenderCodeInline
|
4
|
+
def self.call(value)
|
5
|
+
if value.kind_of?(Array)
|
6
|
+
value.map { |v| v.gsub("<code>", "<color rgb='7d8182'>").gsub("</code>", "</color>") }
|
7
|
+
else
|
8
|
+
value.gsub("<code>", "<color rgb='7d8182'>").gsub("</code>", "</color>")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Philomath
|
2
|
+
module Rendering
|
3
|
+
class RenderStyledLink
|
4
|
+
class << self
|
5
|
+
def call(value)
|
6
|
+
if value.kind_of?(Array)
|
7
|
+
value.map { |v| replace_links(v) }
|
8
|
+
else
|
9
|
+
replace_links(value)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def replace_links(value)
|
16
|
+
fragment = Nokogiri::HTML.fragment(value)
|
17
|
+
fragment.css("a").wrap("<color rgb='0000FF'><u>")
|
18
|
+
fragment.to_html
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/philomath.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'markdownlyze'
|
2
|
+
require 'prawn'
|
3
|
+
require 'prawn_components'
|
4
|
+
require 'nokogiri'
|
5
|
+
|
6
|
+
require_relative 'philomath/rendering/render_code_inline'
|
7
|
+
require_relative 'philomath/rendering/render_styled_link'
|
8
|
+
require_relative 'philomath/rendering/render_without_entities'
|
9
|
+
require_relative 'philomath/rendering/render_callback'
|
10
|
+
|
11
|
+
module Philomath
|
12
|
+
class << self
|
13
|
+
def render(chapters:)
|
14
|
+
table_of_contents = {}
|
15
|
+
contents = {}
|
16
|
+
pdf_chapters = []
|
17
|
+
pdf = Prawn::Document.new
|
18
|
+
pdf.default_leading(10)
|
19
|
+
|
20
|
+
PrawnComponents.initialize_fonts(pdf: pdf)
|
21
|
+
pdf.font('Inter')
|
22
|
+
|
23
|
+
chapters.each do |chapter|
|
24
|
+
pdf_chapters << {
|
25
|
+
name: chapter[:name],
|
26
|
+
parsed_elements: Markdownlyze.parse(chapter[:content])
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
callback = Rendering::RenderCallback.new
|
31
|
+
|
32
|
+
toc_pages_count = get_toc_pages_count(chapters: pdf_chapters.map { |c| c[:parsed_elements] })
|
33
|
+
toc_pages_count.times { pdf.start_new_page }
|
34
|
+
|
35
|
+
pdf_chapters.each_with_index do |chapter_conf, chapter_conf_i|
|
36
|
+
chapter_elements = chapter_conf[:parsed_elements]
|
37
|
+
|
38
|
+
table_of_contents[chapter_conf[:name]] = {
|
39
|
+
page: pdf.page_number, headings: {}
|
40
|
+
}
|
41
|
+
|
42
|
+
chapter_elements.each do |node|
|
43
|
+
case node[:element]
|
44
|
+
when :h1
|
45
|
+
pdf.public_send("h1", node[:value], callback: callback)
|
46
|
+
when :h2
|
47
|
+
table_of_contents[chapter_conf[:name]][:headings][node[:value]] = pdf.page_number
|
48
|
+
pdf.public_send("h2", node[:value], callback: callback)
|
49
|
+
when :h3
|
50
|
+
pdf.public_send("h3", node[:value], callback: callback)
|
51
|
+
when :h4
|
52
|
+
pdf.public_send("h4", node[:value], callback: callback)
|
53
|
+
when :paragraph
|
54
|
+
pdf.public_send("paragraph", callback.call(node[:value]))
|
55
|
+
when :code_block
|
56
|
+
pdf.public_send("code_block", node[:value], node[:language])
|
57
|
+
when :blank_line
|
58
|
+
pdf.move_down(3)
|
59
|
+
when :ol
|
60
|
+
pdf.public_send("ol", node[:value], callback: callback)
|
61
|
+
when :ul
|
62
|
+
pdf.public_send("ul", node[:value], callback: callback)
|
63
|
+
when :image
|
64
|
+
pdf.move_down(6)
|
65
|
+
pdf.image(chapter.images[node[:value]], position: :center, width: pdf.bounds.width - 25)
|
66
|
+
pdf.move_down(6)
|
67
|
+
when :quote
|
68
|
+
pdf.public_send("quote", node[:value], callback: callback)
|
69
|
+
pdf.move_down(6)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
pdf.start_new_page unless chapter_conf_i == pdf_chapters.size - 1
|
74
|
+
end
|
75
|
+
|
76
|
+
toc_page = 1
|
77
|
+
|
78
|
+
pdf.go_to_page(toc_page)
|
79
|
+
|
80
|
+
pdf.public_send("h1", 'Table of contents')
|
81
|
+
pdf.move_down(50)
|
82
|
+
|
83
|
+
pdf.public_send("table_of_contents", table_of_contents)
|
84
|
+
|
85
|
+
# Generate clickable table of contents
|
86
|
+
pdf.outline.define do |outline|
|
87
|
+
table_of_contents.each do |chapter_data|
|
88
|
+
toc_chapter_title = chapter_data.first
|
89
|
+
toc_chapter_page = chapter_data.last[:page]
|
90
|
+
toc_chapter_headings = chapter_data.last[:headings]
|
91
|
+
|
92
|
+
outline.section(toc_chapter_title, destination: toc_chapter_page) do
|
93
|
+
toc_chapter_headings.each_pair do |heading_title, heading_page|
|
94
|
+
outline.page(title: heading_title, destination: heading_page)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
options = {
|
101
|
+
start_count_at: 3,
|
102
|
+
page_filter: lambda{ |pg| pg > 2 },
|
103
|
+
at: [0, 0],
|
104
|
+
align: :center,
|
105
|
+
size: 13
|
106
|
+
}
|
107
|
+
|
108
|
+
pdf.number_pages('<page>', options)
|
109
|
+
|
110
|
+
pdf.render
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def get_toc_pages_count(chapters:)
|
116
|
+
toc_list_item_type = :h2
|
117
|
+
subheading_height = 29
|
118
|
+
heading_height = 43
|
119
|
+
height_to_use_on_page = 592
|
120
|
+
|
121
|
+
toc_metrics = chapters.map do |c|
|
122
|
+
c.count { |m| m[:element] == toc_list_item_type }
|
123
|
+
end
|
124
|
+
|
125
|
+
sum = toc_metrics.map do |n|
|
126
|
+
heading_height + (subheading_height * n)
|
127
|
+
end
|
128
|
+
|
129
|
+
toc_page_length = 1
|
130
|
+
toc_page_pos = 0
|
131
|
+
sum.each do |chap_sum|
|
132
|
+
if (toc_page_pos + chap_sum) > height_to_use_on_page
|
133
|
+
toc_page_length += 1
|
134
|
+
toc_page_pos = 0
|
135
|
+
else
|
136
|
+
toc_page_pos += chap_sum
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
toc_page_length
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: philomath
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Paweł Dąbrowski
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-11-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pry
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: markdownlyze
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.0.2
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.0.2
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: prawn_components
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.0.1
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.0.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: prawn
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.2.2
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 2.2.2
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: nokogiri
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.16.7
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.16.7
|
83
|
+
description: Turn markdown files into PDF book
|
84
|
+
email: contact@paweldabrowski.com
|
85
|
+
executables: []
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- lib/philomath.rb
|
90
|
+
- lib/philomath/rendering/render_callback.rb
|
91
|
+
- lib/philomath/rendering/render_code_inline.rb
|
92
|
+
- lib/philomath/rendering/render_styled_link.rb
|
93
|
+
- lib/philomath/rendering/render_without_entities.rb
|
94
|
+
- lib/philomath/version.rb
|
95
|
+
homepage:
|
96
|
+
licenses: []
|
97
|
+
metadata: {}
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
requirements: []
|
113
|
+
rubygems_version: 3.4.10
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: Turn markdown files into PDF book
|
117
|
+
test_files: []
|