summaryrefslogtreecommitdiffstats
path: root/scripts/page.lua
diff options
context:
space:
mode:
authorVolpeon <git@volpeon.ink>2022-08-04 10:26:57 +0200
committerVolpeon <git@volpeon.ink>2022-08-04 10:26:57 +0200
commit347d7c0da13079fefce6d8741a5604adb89eb97c (patch)
tree43b568e5ae48692425a9ddeeddc4001b1e940336 /scripts/page.lua
parentCode reorganization (diff)
downloadvolpeon.ink-347d7c0da13079fefce6d8741a5604adb89eb97c.tar.gz
volpeon.ink-347d7c0da13079fefce6d8741a5604adb89eb97c.tar.bz2
volpeon.ink-347d7c0da13079fefce6d8741a5604adb89eb97c.zip
Overhauled metadata handling
Diffstat (limited to 'scripts/page.lua')
-rw-r--r--scripts/page.lua222
1 files changed, 222 insertions, 0 deletions
diff --git a/scripts/page.lua b/scripts/page.lua
new file mode 100644
index 0000000..e846dd5
--- /dev/null
+++ b/scripts/page.lua
@@ -0,0 +1,222 @@
1local path = require 'pandoc.path'
2local utils = require 'pandoc.utils'
3local common = require 'scripts.lib.common'
4local sort = require 'scripts.lib.sort'
5
6function resolve_url(site_url, ref_file, target_file)
7 site_url = utils.stringify(site_url)
8 ref_file = utils.stringify(ref_file)
9 target_file = utils.stringify(target_file):gsub("/index%.html$", "/")
10
11 local ref_base_dir = path.directory(ref_file)
12 local abs = target_file
13 local rel = path.make_relative(abs, ref_base_dir, true)
14 local full = (abs:sub(1, 1) == "/" and (site_url .. abs)) or abs
15
16 return { abs = abs, rel = rel, full = full }
17end
18
19function prep_menu(active_id, main_menu)
20 active_id = utils.stringify(active_id)
21
22 local active_item = nil
23 local items = pandoc.List()
24
25 for i = 1, #main_menu do
26 local item = main_menu[i]
27 local active = utils.stringify(item.id) == active_id
28 item.active = active
29 if active then active_item = item end
30 if not item.hidden or item.active then items:insert(item) end
31 end
32
33 return { items = items, active = active_item }
34end
35
36function process_pages(global, build, meta)
37 for _, p in pairs(meta.pages.by_id) do
38 process(global, build, p)
39 end
40
41 meta.pages = {
42 all = meta.pages.all:map(utils.stringify):map(function (ref) return meta.pages.by_id[ref] end),
43 date_desc = meta.pages.date_desc:map(utils.stringify):map(function (ref) return meta.pages.by_id[ref] end),
44 by_id = meta.pages.by_id
45 }
46end
47
48function resolve_urls(global, build, meta)
49 meta.url = resolve_url(global.site.url, build.file_out, meta.url)
50
51 if meta.feed then
52 if meta.file_out:match(".html$") then
53 meta.feed = {
54 url = resolve_url(global.site.url, build.file_out, meta.file_out:gsub(".html$", ".xml")),
55 }
56 else
57 meta.page = {
58 url = resolve_url(global.site.url, build.file_out, meta.file_out:gsub(".xml$", ".html")),
59 }
60 end
61 end
62
63 if meta.thumbnail then
64 meta.thumbnail = resolve_url(global.site.url, build.file_out, meta.thumbnail)
65 end
66end
67
68function d1_page_to_list_item(meta, p)
69 return {
70 title = p.title,
71 subtitle = p.subtitle,
72 date = p.date,
73 last_update = p.last_update,
74 show_date = meta.list_order == "date_desc",
75 schema_type = p.schema_type,
76 draft = p.draft,
77 position = p.position,
78 url = p.url,
79 rel = p.rel,
80 slug = p.slug,
81 thumbnail = p.thumbnail,
82 icon = p.icon or meta.icon,
83 post_icon = p.post_icon or meta.list_post_icon,
84 indicator = meta.list_read_indicators,
85 }
86end
87
88function d2_page_to_list_item(meta, cat, p, set_cat_title)
89 return {
90 title = p.title,
91 subtitle = p.subtitle,
92 category = set_cat_title and cat.title,
93 date = p.date,
94 last_update = p.last_update,
95 show_date = cat.list_order == "date_desc",
96 schema_type = p.schema_type,
97 draft = p.draft,
98 position = p.position,
99 url = p.url,
100 rel = p.rel,
101 slug = p.slug,
102 thumbnail = p.thumbnail,
103 icon = p.icon or cat.icon,
104 post_icon = p.post_icon or cat.list_post_icon or meta.list_post_icon,
105 indicator = cat.list_read_indicators,
106 }
107end
108
109function cat_to_list_cat(cat, allItems)
110 local limit = cat.list_limit or 9999
111 local items = allItems:take(limit)
112 local omitted = #allItems - #items
113
114 return {
115 title = cat.title,
116 description = (cat.description and pandoc.MetaBlocks(pandoc.Para(cat.description))) or
117 (not cat.no_description and cat.content),
118 last_update = cat.last_update,
119 schema_type = cat.schema_type,
120 url = cat.url,
121 slug = cat.slug,
122 layout = cat.list_layout,
123 items = items,
124 total = tostring(#allItems),
125 omitted = omitted ~= 0 and tostring(omitted),
126 }
127end
128
129function generate_list(meta)
130 if meta.depth < 1 then return pandoc.List() end
131
132 if meta.depth == 1 then
133 return meta.pages.all:map(function(p) return d1_page_to_list_item(meta, p) end)
134 end
135
136 if meta.depth == 2 then
137 return meta.pages.all
138 :map(function(cat)
139 local allItems = cat.pages.all:map(function(p) return d2_page_to_list_item(meta, cat, p, false) end)
140
141 return cat_to_list_cat(cat, allItems)
142 end)
143 :filter(function(cat) return #cat.items ~= 0 end)
144 end
145
146 if meta.depth == 3 then
147 local list = meta.pages.all
148 :map(function(cat)
149 local allItems = cat.pages.all:flatMap(function(c)
150 if cat.list_flatten and c.depth ~= 0 then
151 return c.pages.all:map(function(p) return d2_page_to_list_item(cat, c, p, true) end)
152 else
153 return pandoc.List({ d1_page_to_list_item(cat, c) })
154 end
155 end)
156
157 allItems:sort(sort.page_sort(cat.list_order))
158
159 return cat_to_list_cat(cat, allItems)
160 end)
161 :filter(function(cat) return #cat.items ~= 0 end)
162
163 return list
164 end
165end
166
167function process_base(meta)
168 meta.depth = tonumber(utils.stringify(meta.depth))
169 meta.file_out = utils.stringify(meta.file_out)
170 meta.url = utils.stringify(meta.url)
171 meta.title = utils.stringify(meta.title)
172 meta.list_limit = meta.list_limit and tonumber(utils.stringify(meta.list_limit))
173 meta.list_order = meta.list_order and utils.stringify(meta.list_order)
174 meta.position = meta.position and tonumber(utils.stringify(meta.position))
175 meta.thumbnail = meta.thumbnail and utils.stringify(meta.thumbnail)
176end
177
178function process(global, build, meta)
179 process_base(meta)
180 resolve_urls(global, build, meta)
181 process_pages(global, build, meta)
182end
183
184function Meta(meta)
185 local build = {}
186
187 for key, value in pairs(meta) do
188 local suffix = key:match('^build.(.*)$')
189
190 if suffix then
191 build[suffix] = value
192 meta[key] = nil
193 end
194 end
195
196 local global = {
197 assets = meta.assets,
198 site = meta.site,
199 menus = meta.menus
200 }
201
202 process(global, build, meta)
203
204 local parts = utils.stringify(build.namespace):split('/'):skip(1)
205 for i = 1, #parts do
206 meta = meta.pages.by_id[parts[i]]
207 end
208
209 meta.list = generate_list(meta)
210
211 if global.menus and global.menus.main then
212 global.menus.main = prep_menu(meta.namespace.root.id, global.menus.main)
213 end
214
215 for key, value in pairs(global) do
216 meta[key] = value
217 end
218
219 meta.build = build
220
221 return meta
222end