-
Notifications
You must be signed in to change notification settings - Fork 42
/
render.rb
executable file
·143 lines (124 loc) · 3.72 KB
/
render.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/usr/bin/env ruby
class Converter
require 'pandoc-ruby'
require 'nokogiri'
@@footer = <<-HTML
<div id="footer">
Notes by <a href="https://github.com/kevintpeng">Kevin Peng</a>, Google intern.<br>
Formerly Riot Games, Bloomberg, Apple & Shopify.<br>
Connect with me on <a href="https://www.linkedin.com/in/kevintpeng/">LinkedIn</a>.
</div>
HTML
def walk(path)
Dir.foreach(path) do |child|
next if child.start_with?("..")
full_path = File.join(path, child)
if File.directory?(full_path)
write_index_page(full_path)
walk(full_path) unless child.start_with?(".")
elsif File.extname(full_path) == ".md"
write_page(full_path)
end
end
end
def write_page(path)
output_path = File.join(File.dirname(path), File.basename(path, ".md")) + ".html"
contents = File.read(path)
page = Nokogiri::HTML(
PandocRuby
.new(contents, :standalone, from: "markdown_github+tex_math_dollars")
.to_html(
:no_wrap,
:table_of_contents,
:mathjax,
tab_stop: 2,
css: "/style.css"
)
)
process_page!(page, path)
File.write(output_path, page.to_html)
end
def process_page!(page, path)
body = page.css("body").first
head = page.css("head").first
return unless body
page.css("title").first&.unlink
title = page.css("h1").first
if title && head
head.add_child(Nokogiri::HTML.fragment(
<<-HTML
<title>#{title.text}</title>
HTML
))
end
toc = page.css("#TOC").first
if title && toc
# Remove heading 1 from ToC
list = page.css("#TOC > ul").first
sublist = page.css("#TOC > ul > li > ul").first
if list && sublist
list.unlink
toc.add_child(sublist)
end
# Move ToC to be after heading 1
toc.unlink
title.add_next_sibling(toc) if sublist
title.add_next_sibling(Nokogiri::HTML.fragment(
<<-HTML
<a href="index.html">Back to #{title_for_path(File.dirname(path))}</a>
HTML
))
end
body.add_child(Nokogiri::HTML.fragment(@@footer))
end
def write_index_page(path)
output_path = File.join(path, "index.html")
File.write(
output_path,
<<-HTML
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta name="generator" content="pandoc">
<title>#{title_for_path(path)} - Kevin Peng Learn Something Every Day</title>
<style type="text/css">code{white-space: pre;}</style>
<link rel="stylesheet" href="/style.css" type="text/css">
</head>
<body>
<h1>#{title_for_path(path)}</h1>
#{
unless path == "./."
"<p><a href='../index.html'>Back</a></p>"
else
""
end
}
<ul>
#{
Dir.entries(path).select{|f| File.directory?(File.join(path, f)) && !f.start_with?(".") && !f.include?("vendor")}.map{|f|
"<li><a href='#{f}/index.html'>#{f}</a></li>"
}.join("\n")
}
#{
Dir.entries(path).select{|f| f.end_with?(".md")}.map{|f|
"<li><a href='#{File.join(File.dirname(f), File.basename(f, ".md")) + ".html"}'>#{f}</a></li>"
}.join("\n")
}
</ul>
#{@@footer}
</body>
</html>
HTML
)
end
def title_for_path(path)
return "Learn Something Every Day" if path == "./."
match = /^(\.\/)?(.+?)(\/.)?$/.match(path)
return match[2]
end
def convert
walk(".")
end
end
Converter.new.convert