-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.rb
89 lines (66 loc) · 2.38 KB
/
build.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
require "bundler/inline"
gemfile do
source "https://rubygems.org"
gem "redcarpet", "~> 3.6"
gem "rouge", "~> 4.1"
end
require "erb"
class Template
def initialize(file_path)
@template = ::ERB.new(::File.read(file_path))
end
def render(locals, save_to:)
binding = ::Object.new.send(:binding).tap do |binding|
locals.each { |key, value| binding.local_variable_set(key, value) }
end
::File.write(save_to, @template.result(binding))
end
end
module Post
Data = ::Struct.new(
:id,
:metadata,
:html_body,
keyword_init: true
)
class Metadata
Parse = ->(lines) { ::Hash[lines.map { |line| line[2..].split(":").map(&:strip) }] }
def initialize(attributes)
@attributes = attributes
end
def title = @attributes["title"]
def publication_date = @attributes["publication_date"]
def summary = @attributes["summary"]
def published? = !!publication_date
end
ParsePost = ->(markdown_renderer, file_path) do
id = ::File.basename(file_path).gsub(".md", "")
lines = ::File.read(file_path).split("\n")
metadata_lines = lines.take_while { |line| line.start_with?("--") }
markdown_content_lines = lines.drop(metadata_lines.size + 1)
metadata = Metadata.new(Metadata::Parse[metadata_lines])
markdown_body = markdown_content_lines.join("\n")
html_body = markdown_renderer.render(markdown_body)
Data.new(id:, metadata:, html_body:)
end
MARKDOWN_RENDERER = ::Redcarpet::Markdown.new(Redcarpet::Render::HTML, fenced_code_blocks: true, tables: true)
RECORDS = ::Dir.glob("posts/*.md").map(&ParsePost.curry[MARKDOWN_RENDERER])
.filter { |post| post.metadata.published? }
.sort_by { |post| post.metadata.publication_date }
.reverse
JOURNAL = ::Dir.glob("posts/journal/*.md").map(&ParsePost.curry[MARKDOWN_RENDERER])
end
# ======== main ========
puts "#{Time.now}: Building..."
Template.new("pages/index.html.erb").tap do |index_template|
index_template.render({ posts: Post::RECORDS, journal: Post::JOURNAL }, save_to: "_dist/index.html")
end
Template.new("pages/post.html.erb").tap do |post_template|
Post::RECORDS.each do |post|
post_template.render({ post: }, save_to: "_dist/#{post.id}.html")
end
Post::JOURNAL.each do |journal_post|
post_template.render({ post: journal_post }, save_to: "_dist/#{journal_post.id}.html")
end
end
puts "#{Time.now}: Built!"