forked from jekyll/jekyll
/
convertible.rb
107 lines (95 loc) · 3.17 KB
/
convertible.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
module Jekyll
module Convertible
# Return the contents as a string
def to_s
if self.is_a? Jekyll::Post
(self.content || '') + (self.extended || '')
else
self.content || ''
end
end
# Read the YAML frontmatter
# +base+ is the String path to the dir containing the file
# +name+ is the String filename of the file
#
# Returns nothing
def read_yaml(base, name)
self.content = File.read(File.join(base, name))
if self.content =~ /^(---.*?\n.*?)\n---.*?\n(.*)/m
self.data = YAML.load($1)
self.content = $2
# if we have an extended section, separate that from content
if self.is_a? Jekyll::Post
if self.data.key? 'extended'
marker = self.data['extended']
self.content, self.extended = self.content.split(marker + "\n", 2)
end
end
end
end
# Transform the contents based on the file extension.
#
# Returns nothing
def transform
case self.ext
when ".textile":
self.ext = ".html"
self.content = RedCloth.new(self.content).to_html
if self.is_a? Jekyll::Post and self.extended
self.extended = RedCloth.new(self.extended).to_html
end
when ".markdown":
self.ext = ".html"
self.content = Jekyll.markdown_proc.call(self.content)
if self.is_a? Jekyll::Post and self.extended
self.extended = Jekyll.markdown_proc.call(self.extended)
end
end
end
# Add any necessary layouts to this convertible document
# +layouts+ is a Hash of {"name" => "layout"}
# +site_payload+ is the site payload hash
#
# Returns nothing
def do_layout(payload, layouts, site_payload)
# construct payload
payload = payload.merge(site_payload)
# render content
unless self.is_a? Jekyll::Post
self.content = Liquid::Template.parse(self.content).render(payload, [Jekyll::Filters])
end
self.transform
# output keeps track of what will finally be written
if self.is_a? Jekyll::Post and self.extended
self.output = self.content + self.extended
else
self.output = self.content
end
# recursively render layouts
layout = layouts[self.data["layout"]]
while layout
payload = payload.merge({"content" => self.output, "page" => self.data})
# process any scripts
if layout.data["scripts"]
payload = payload.merge(self.do_scripts(layout.data["scripts"]))
end
self.output = Liquid::Template.parse(layout.content).render(payload, [Jekyll::Filters])
layout = layouts[layout.data["layout"]]
end
end
# Process scripts for the layout
# +scripts+ is a Array of [{"name" => "foo", "command": "foo.py"}]
#
# Returns a Hash of {"foo" => "... script output ..."}
def do_scripts(scripts)
result = {}
scripts.each do |script|
p = IO.popen(File.join(@base, '_scripts', script["command"]) +
' ' + @base)
result[script["name"]] = p.read || ""
p.close
end
result
end
end
end