summaryrefslogtreecommitdiffstats
path: root/scripts/metadata_filter.lua
diff options
context:
space:
mode:
authorVolpeon <git@volpeon.ink>2021-01-05 10:58:04 +0100
committerVolpeon <git@volpeon.ink>2021-01-05 10:58:04 +0100
commit5db16a08a9726b67b5bb96fd17f813fa1b74f568 (patch)
tree8313cb28561f856da7782ff667ecabfdd1716222 /scripts/metadata_filter.lua
parentUse Pygments for syntax highlighting, design adjustments, preload fonts (diff)
downloadvolpeon.ink-5db16a08a9726b67b5bb96fd17f813fa1b74f568.tar.gz
volpeon.ink-5db16a08a9726b67b5bb96fd17f813fa1b74f568.tar.bz2
volpeon.ink-5db16a08a9726b67b5bb96fd17f813fa1b74f568.zip
Moved all metadata processing from the build script into a Pandoc Lua filter
Diffstat (limited to 'scripts/metadata_filter.lua')
-rw-r--r--scripts/metadata_filter.lua225
1 files changed, 225 insertions, 0 deletions
diff --git a/scripts/metadata_filter.lua b/scripts/metadata_filter.lua
new file mode 100644
index 0000000..f31bc1f
--- /dev/null
+++ b/scripts/metadata_filter.lua
@@ -0,0 +1,225 @@
1function format_date(date)
2 if date == nil then
3 return date
4 end
5
6 date = pandoc.utils.normalize_date(pandoc.utils.stringify(date))
7 local year, month, day = date:match("(%d%d%d%d)-(%d%d)-(%d%d)")
8 if year == nil then
9 return nil
10 end
11
12 local time = os.time({
13 year = tonumber(year),
14 month = tonumber(month),
15 day = tonumber(day)
16 })
17 return pandoc.MetaMap({
18 yyyy_mm_dd = pandoc.MetaString(os.date("%F", time)),
19 yyyy = pandoc.MetaString(os.date("%Y", time)),
20 mm_dd = pandoc.MetaString(os.date("%m-%d", time)),
21 rfc3339 = pandoc.MetaString(os.date("%FT%T+00:00", time))
22 })
23end
24
25function table_to_list(t, cmp)
26 local l = pandoc.MetaList({})
27
28 for key, value in pairs(t) do
29 l:insert(pandoc.MetaMap({
30 key = key,
31 value = value
32 }))
33 end
34
35 l:sort(cmp or function(i1, i2)
36 return i1.key < i2.key
37 end)
38
39 return l
40end
41
42function splitstr(input, sep)
43 sep = sep or "%s"
44 local t = {}
45 for str in input:gmatch("([^" .. sep .. "]+)") do
46 table.insert(t, str)
47 end
48 return t
49end
50
51function relative_to(dir, target)
52 dir = splitstr(dir, "/")
53 target = splitstr(target, "/")
54
55 local prefix = true
56 local path = ""
57
58 for i = 1, math.min(#dir, #target) do
59 local t = target[i]
60 if prefix then
61 if dir[i] ~= t then
62 prefix = false
63 path = "../" .. t
64 end
65 else
66 path = "../" .. path .. "/" .. t
67 end
68 end
69
70 if #dir < #target then
71 for i = #dir + 1, #target do
72 path = path .. (path == "" and "" or "/") .. target[i]
73 end
74 elseif #dir > #target then
75 for i = #target + 1, #dir do
76 path = "../" .. path
77 end
78 end
79
80 return path
81end
82
83function resolve_url(page_type, site_url, content_dir, base_dir, cur_file)
84 if page_type == "page" then
85 cur_file = cur_file:gsub("%.md$", ".html")
86 elseif page_type == "feed" then
87 cur_file = cur_file:gsub("%.md$", ".xml")
88 end
89
90 local abs = cur_file:gsub("^" .. content_dir, ""):gsub("/index.html$", "/")
91 local rel = relative_to(base_dir, cur_file):gsub("/index.html$", "/")
92
93 return pandoc.MetaMap({
94 abs = pandoc.MetaString(abs),
95 rel = pandoc.MetaString(rel),
96 full = pandoc.MetaString(site_url .. abs)
97 })
98end
99
100function resolve_section(abs_url)
101 local section = abs_url:match("^/(.-)[/.]") or "index"
102 return pandoc.MetaMap({
103 id = pandoc.MetaString(section),
104 ["is_" .. section] = pandoc.MetaBool(true)
105 })
106end
107
108function organize_subpages(site_url, content_dir, base_dir, pages, categories)
109 local categories_data = pandoc.MetaList({})
110
111 pages:sort(function(p1, p2)
112 if p1.date and p2.date then
113 return pandoc.utils.stringify(p1.date.yyyy_mm_dd) > pandoc.utils.stringify(p2.date.yyyy_mm_dd)
114 elseif p2.date then
115 return true
116 elseif p1.date then
117 return false
118 else
119 return pandoc.utils.stringify(p1.title) < pandoc.utils.stringify(p2.title)
120 end
121 end)
122
123 local pages_data = pandoc.MetaMap({
124 all = pages,
125 by_year = pandoc.MetaList({}),
126 last_update = nil
127 })
128
129 if pages then
130 local pages_by_year_map = {}
131 local categories_map = {}
132
133 for i = 1, #pages do
134 local page = pages[i]
135
136 if page.date then
137 local yyyy = pandoc.utils.stringify(page.date.yyyy)
138 local pages_by_yyyy = pages_by_year_map[yyyy]
139
140 if not pages_by_yyyy then
141 pages_by_yyyy = pandoc.MetaList(pandoc.List())
142 pages_by_year_map[yyyy] = pages_by_yyyy
143 end
144
145 pages_by_yyyy:insert(page)
146 end
147
148 if page.category and categories then
149 local category = pandoc.utils.stringify(page.category)
150
151 if categories[category] then
152 local current_category = categories_map[category]
153
154 if not current_category then
155 current_category = pandoc.MetaMap({
156 name = pandoc.MetaString(categories[category]),
157 count = 0
158 })
159 categories_map[category] = current_category
160 end
161
162 current_category.count = current_category.count + 1
163 end
164 end
165 end
166
167 pages_data.by_year = table_to_list(pages_by_year_map, function(i1, i2)
168 return i1.key > i2.key
169 end)
170
171 categories_data = table_to_list(categories_map)
172
173 for _, item in ipairs(categories_data) do
174 item.value.count = pandoc.MetaString(("%d"):format(item.value.count))
175 end
176
177 if #pages_data.by_year ~= 0 then
178 pages_data.last_update = pages_data.by_year[1].value[1].last_update
179 end
180 end
181
182 return pages_data, categories_data
183end
184
185function Meta(meta)
186 meta.content_dir = meta.content_dir:gsub("/$", "")
187 meta.site.url = pandoc.utils.stringify(meta.site.url):gsub("/$", "")
188 meta.base_dir = meta.base_file:gsub("^(.*)/.-$", "%1")
189 meta.type = meta.type or "page"
190
191 meta.date = format_date(meta.date)
192 if meta.last_update ~= nil then
193 meta.last_update = format_date(meta.last_update)
194 else
195 meta.last_update = meta.date
196 end
197
198 if meta.type == "feed" then
199 meta.page = pandoc.MetaMap({
200 url = resolve_url("page", meta.site.url, meta.content_dir, meta.base_dir, meta.file)
201 })
202 end
203
204 meta.url = resolve_url(meta.type, meta.site.url, meta.content_dir, meta.base_dir, meta.file)
205 meta.section = resolve_section(meta.url.abs)
206 meta.categories = meta.categories[meta.section.id]
207
208 if meta.menus and meta.menus.main then
209 for i = 1, #meta.menus.main do
210 local item = meta.menus.main[i]
211 item.active = pandoc.MetaBool(pandoc.utils.stringify(item.id) == meta.section.id)
212 end
213 end
214
215 if meta.pages then
216 local pages, categories = organize_subpages(meta.site.url, meta.content_dir, meta.base_dir, meta.pages,
217 meta.categories)
218 meta.pages = pages
219 meta.categories = categories
220 else
221 meta.categories = nil
222 end
223
224 return meta
225end