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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
local path = require 'pandoc.path'
local utils = require 'pandoc.utils'
local common = require 'scripts.lib.common'
local sort = require 'scripts.lib.sort'
function slug(str)
return str:lower():gsub("[^ a-z]", ""):gsub("[ ]+", "-")
end
function format_date(date)
if not date then return date end
date = pandoc.utils.normalize_date(utils.stringify(date))
local year, month, day = date:match("(%d%d%d%d)-(%d%d)-(%d%d)")
if not year then return nil end
local time = os.time({ year = tonumber(year), month = tonumber(month), day = tonumber(day) })
return {
yyyy_mm_dd = os.date("%F", time),
yyyy = os.date("%Y", time),
mm = os.date("%m", time),
dd = os.date("%d", time),
rfc3339 = os.date("%FT%T+00:00", time),
long = os.date("%B %d, %Y", time),
short = os.date("%b %d, %Y", time),
}
end
function make_absolute(rel, base)
return path.is_absolute(rel) and rel or path.join({ path.directory(base), rel })
end
function resolve_layout(depth)
local layout = "categorized_list"
if depth == 0 then
layout = "page"
elseif depth == 1 then
layout = "list"
end
return layout
end
function prep_namespace(namespace)
namespace = utils.stringify(namespace)
local root = "index"
if namespace ~= "" then root = namespace:gsub("^/([^/]*).*$", "%1") end
return { root = { id = root, ["is_" .. root] = true }, full = namespace }
end
function prep_menu(active_id, main_menu)
local active_item = nil
local items = pandoc.List()
for i = 1, #main_menu do
local item = main_menu[i]
local active = utils.stringify(item.id) == active_id
item.active = active
if active then active_item = item end
if not item.hidden or item.active then items:insert(item) end
end
return { items = items, active = active_item }
end
function process_pages(meta)
local pages_all = pandoc.List()
local pages_date_desc = pandoc.List()
for id, p in pairs(meta.pages) do
if not p.unlisted then
pages_all:insert(id)
if p.last_update then pages_date_desc:insert(id) end
end
end
pages_all:sort(sort.page_sort(meta.list_order, meta.pages))
pages_date_desc:sort(sort.page_sort("date_desc", meta.pages))
meta.pages = {
all = pages_all,
date_desc = pages_date_desc,
by_id = meta.pages
}
end
function find_depth(meta)
if meta.depth then
meta.depth = tonumber(meta.depth)
end
local depth = 0
for _, p in pairs(meta.pages) do
find_depth(p)
if not p.unlisted then
local d = p.depth + 1
if d > depth then depth = d end
end
end
meta.depth = depth
end
function resolve_dates(meta)
if meta.last_update then
meta.last_update = format_date(meta.last_update)
elseif #meta.pages.date_desc ~= 0 then
meta.last_update = meta.pages.by_id[meta.pages.date_desc[1]].last_update
elseif meta.date then
meta.last_update = format_date(meta.date)
end
if meta.date then
meta.date = format_date(meta.date)
elseif meta.last_update then
meta.date = meta.last_update
end
meta.was_updated = meta.date and meta.last_update and meta.date.yyyy_mm_dd ~= meta.last_update.yyyy_mm_dd
end
function process_base(build, meta)
meta.namespace = prep_namespace(meta.namespace)
meta.id = meta.namespace.full:gsub("^.*/(.-)$", "%1")
meta.file_out = utils.stringify(meta.file_out)
meta.unlisted = meta.unlisted or (meta.draft and build.mode ~= "dev")
meta.redirect = meta.url and true
meta.url = meta.url or meta.file_out
meta.title = meta.title and utils.stringify(meta.title) or ""
meta.slug = slug(meta.title)
meta.schema_type = meta.schema_type or "CreativeWork"
meta.list_layout = common.prep_layout(meta.list_layout or "list")
meta.list_order = meta.list_order and utils.stringify(meta.list_order)
meta.position = meta.position and tonumber(utils.stringify(meta.position))
meta.thumbnail = meta.thumbnail and make_absolute("thumbnail." .. utils.stringify(meta.thumbnail), meta.file_out)
meta.layout = common.prep_layout(meta.layout or (meta.redirect and "redirect") or resolve_layout(meta.depth))
meta.show_date = meta.parent and meta.parent.list_order == "date_desc"
meta.category = meta.parent and meta.parent.title
meta.icon = meta.icon or (meta.parent and meta.parent.icon)
meta.post_icon = meta.post_icon or (meta.parent and meta.parent.list_post_icon) or
(meta.parent and meta.parent.parent and meta.parent.parent.list_post_icon)
meta.indicator = meta.parent and meta.parent.list_read_indicators
meta.content = meta.content:filter(function (el)
return el.tag ~= "LineBreak"
end)
end
function process(global, build, meta)
process_base(build, meta)
for _, p in pairs(meta.pages) do
p.parent = meta
process(global, build, p)
p.parent = nil
end
process_pages(meta)
resolve_dates(meta)
end
function find_pos(meta)
for _, p in pairs(meta.pages.by_id) do
p.parent = meta
find_pos(p)
p.parent = nil
end
if not meta.parent then return end
local pages = meta.parent.list_order == "date_desc" and meta.parent.pages.date_desc or meta.parent.pages.all
local _, index = pages:find(meta.id)
if index == nil then return end
meta.prev = index <= #pages - 1 and pages[index + 1] or nil
meta.next = index >= 2 and pages[index - 1] or nil
end
function Meta(meta)
local build = {}
for key, value in pairs(meta) do
local suffix = key:match('^build.(.*)$')
if suffix then
build[suffix] = value
meta[key] = nil
end
end
meta.site.url = utils.stringify(meta.site.url):gsub("/$", "")
find_depth(meta)
process(meta, build, meta)
find_pos(meta)
return meta
end
|