summaryrefslogtreecommitdiffstats
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
parentCode reorganization (diff)
downloadvolpeon.ink-347d7c0da13079fefce6d8741a5604adb89eb97c.tar.gz
volpeon.ink-347d7c0da13079fefce6d8741a5604adb89eb97c.tar.bz2
volpeon.ink-347d7c0da13079fefce6d8741a5604adb89eb97c.zip
Overhauled metadata handling
-rw-r--r--Makefile43
-rw-r--r--filters/emojis.lua14
-rw-r--r--filters/vars.lua12
-rw-r--r--scripts/content.lua (renamed from scripts/pages_content.lua)2
-rw-r--r--scripts/lib/common.lua10
-rw-r--r--scripts/lib/sort.lua36
-rw-r--r--scripts/metadata.lua211
-rw-r--r--scripts/page.lua222
8 files changed, 337 insertions, 213 deletions
diff --git a/Makefile b/Makefile
index 52a90f9..aaf589d 100644
--- a/Makefile
+++ b/Makefile
@@ -50,7 +50,7 @@ subpages = $(patsubst content/%.md,.cache/meta/%.json, \
50 $(shell test -d $(patsubst .cache/meta%,content%,$(1)) && find $(patsubst .cache/meta%,content%,$(1)) -maxdepth 1 -type f -name "*.md" ! -name "index.md") \ 50 $(shell test -d $(patsubst .cache/meta%,content%,$(1)) && find $(patsubst .cache/meta%,content%,$(1)) -maxdepth 1 -type f -name "*.md" ! -name "index.md") \
51 $(shell test -d $(patsubst .cache/meta%,content%,$(1)) && find $(patsubst .cache/meta%,content%,$(1)) -mindepth 2 -maxdepth 2 -type f -name "index.md")) 51 $(shell test -d $(patsubst .cache/meta%,content%,$(1)) && find $(patsubst .cache/meta%,content%,$(1)) -mindepth 2 -maxdepth 2 -type f -name "index.md"))
52 52
53.cache/meta/%.json: content/%.md $$(call subpages,$$(call namespace,$$@,)) filters/*.lua scripts/pages_content.lua scripts/subpages.jq scripts/metadata.json | .cache/meta 53.cache/meta/%.json: content/%.md $$(call subpages,$$(call namespace,$$@,)) filters/*.lua scripts/content.lua scripts/subpages.jq scripts/metadata.json | .cache/meta
54 $(info [META] $< -> $@) 54 $(info [META] $< -> $@)
55 55
56 mkdir -p $(@D) 56 mkdir -p $(@D)
@@ -73,57 +73,70 @@ subpages = $(patsubst content/%.md,.cache/meta/%.json, \
73 -f markdown-citations-implicit_figures \ 73 -f markdown-citations-implicit_figures \
74 -t html5 \ 74 -t html5 \
75 --wrap preserve \ 75 --wrap preserve \
76 --lua-filter scripts/metadata.lua \ 76 --lua-filter scripts/content.lua \
77 --lua-filter scripts/pages_content.lua \
78 $(GLOBAL_METADATA) \ 77 $(GLOBAL_METADATA) \
79 --metadata-file "$@.meta" \ 78 --metadata-file "$@.meta" \
80 --metadata build.mode="$(MODE)" \
81 --metadata build.file_out="$(patsubst .cache/meta/%.json,/%.html,$@)" \
82 $(PANDOC_FILTERS) \ 79 $(PANDOC_FILTERS) \
83 -o "$@.content" "$<" 80 -o "$@.content" "$<"
84 jq '. + { content: $$content }' --rawfile content "$@.content" "$@.meta" > "$@" 81 jq '. + { content: $$content }' --rawfile content "$@.content" "$@.meta" > "$@"
85 rm "$@.meta" 82 rm "$@.meta"
86 rm "$@.content" 83 rm "$@.content"
87 84
85.cache/meta.json: .cache/meta/index.json scripts/metadata.lua | .cache
86 $(info [META] $@)
87
88 mkdir -p $(@D)
89 pandoc \
90 -f markdown-citations-implicit_figures \
91 -t html5 \
92 --wrap preserve \
93 --no-highlight \
94 --lua-filter scripts/metadata.lua \
95 $(GLOBAL_METADATA) \
96 --metadata-file "$<" \
97 --metadata build.mode="$(MODE)" \
98 --template scripts/metadata.json \
99 -o "$@" "$<"
100
88.cache/assets.json: $(ASSET_FILES) | .cache 101.cache/assets.json: $(ASSET_FILES) | .cache
102 $(info [ASET] $@)
103
89 sha256sum $^ | sed -r 's/([0-9a-f]+) +out\/(.*)/{ "\2": "\/\2?\1" }/' | jq '{ assets: [inputs] | add | with_entries( .key |= gsub( "\\."; "_") ) }' > "$@" 104 sha256sum $^ | sed -r 's/([0-9a-f]+) +out\/(.*)/{ "\2": "\/\2?\1" }/' | jq '{ assets: [inputs] | add | with_entries( .key |= gsub( "\\."; "_") ) }' > "$@"
90 105
91out/%.html: content/%.md .cache/meta/%.json .cache/assets.json $(CONTENT_TEMPLATES_SRC) metadata/*.yaml filters/*.lua scripts/metadata.lua | out 106out/%.html: content/%.md .cache/meta.json .cache/assets.json $(CONTENT_TEMPLATES_SRC) metadata/*.yaml filters/*.lua scripts/page.lua | out
92 $(info [MARK] $< -> $@) 107 $(info [MARK] $< -> $@)
93 108
94 mkdir -p $(@D) 109 mkdir -p $(@D)
95 $(eval NAMESPACE = $(call namespace,$@,.cache/meta)) 110 $(eval NAMESPACE = $(call namespace,$@,out))
96 pandoc \ 111 pandoc \
97 -f markdown-citations-implicit_figures \ 112 -f markdown-citations-implicit_figures \
98 -t html5 \ 113 -t html5 \
99 --wrap preserve \ 114 --wrap preserve \
100 --no-highlight \ 115 --no-highlight \
101 --template templates/base.html \ 116 --template templates/base.html \
102 --lua-filter scripts/metadata.lua \ 117 --lua-filter scripts/page.lua \
103 $(GLOBAL_METADATA) \ 118 $(GLOBAL_METADATA) \
104 --metadata-file .cache/assets.json \ 119 --metadata-file .cache/assets.json \
105 --metadata-file "$(filter .cache/meta/%.json,$^)" \ 120 --metadata-file .cache/meta.json \
106 --metadata build.mode="$(MODE)" \
107 --metadata build.namespace="$(NAMESPACE)" \ 121 --metadata build.namespace="$(NAMESPACE)" \
108 --metadata build.file_out="$(patsubst out/%,/%,$@)" \ 122 --metadata build.file_out="$(patsubst out/%,/%,$@)" \
109 $(PANDOC_FILTERS) \ 123 $(PANDOC_FILTERS) \
110 -o "$@" "$<" 124 -o "$@" "$<"
111 125
112out/%.xml: content/%.md .cache/meta/%.json $(FEED_TEMPLATES_SRC) metadata/*.yaml filters/*.lua scripts/metadata.lua | out 126out/%.xml: content/%.md .cache/meta.json $(FEED_TEMPLATES_SRC) metadata/*.yaml filters/*.lua scripts/page.lua | out
113 $(info [FEED] $< -> $@) 127 $(info [FEED] $< -> $@)
114 128
115 mkdir -p $(@D) 129 mkdir -p $(@D)
116 $(eval NAMESPACE = $(call namespace,$@,.cache/meta)) 130 $(eval NAMESPACE = $(call namespace,$@,out))
117 pandoc \ 131 pandoc \
118 -f markdown-citations-implicit_figures \ 132 -f markdown-citations-implicit_figures \
119 -t html5 \ 133 -t html5 \
120 --wrap preserve \ 134 --wrap preserve \
121 --no-highlight \ 135 --no-highlight \
122 --template templates/feed.xml \ 136 --template templates/feed.xml \
123 --lua-filter scripts/metadata.lua \ 137 --lua-filter scripts/page.lua \
124 $(GLOBAL_METADATA) \ 138 $(GLOBAL_METADATA) \
125 --metadata-file "$(filter .cache/meta/%.json,$^)" \ 139 --metadata-file .cache/meta.json \
126 --metadata build.mode="$(MODE)" \
127 --metadata build.namespace="$(NAMESPACE)" \ 140 --metadata build.namespace="$(NAMESPACE)" \
128 --metadata build.file_out="$(patsubst out/%,/%,$@)" \ 141 --metadata build.file_out="$(patsubst out/%,/%,$@)" \
129 $(PANDOC_FILTERS) \ 142 $(PANDOC_FILTERS) \
diff --git a/filters/emojis.lua b/filters/emojis.lua
index 427d04b..24a9fc3 100644
--- a/filters/emojis.lua
+++ b/filters/emojis.lua
@@ -1,4 +1,14 @@
1function Str(el) 1local common = require 'scripts.lib.common'
2
3local vars = {}
4
5function meta(meta) vars = meta end
6
7function str(el)
8 if vars.build and vars.build.file_out:match(".xml$") then
9 return el
10 end
11
2 local prefix, emojiref, suffix = el.text:match('^(.*):([^ ]+):(.*)$') 12 local prefix, emojiref, suffix = el.text:match('^(.*):([^ ]+):(.*)$')
3 13
4 if emojiref then 14 if emojiref then
@@ -13,3 +23,5 @@ function Str(el)
13 23
14 return el 24 return el
15end 25end
26
27return { { Meta = meta }, { Str = str } }
diff --git a/filters/vars.lua b/filters/vars.lua
index 99cedc4..61803cb 100644
--- a/filters/vars.lua
+++ b/filters/vars.lua
@@ -1,3 +1,4 @@
1local utils = require 'pandoc.utils'
1local common = require 'scripts.lib.common' 2local common = require 'scripts.lib.common'
2 3
3local vars = {} 4local vars = {}
@@ -12,15 +13,14 @@ function str(el)
12 local var = vars 13 local var = vars
13 14
14 for i = 1, #parts do 15 for i = 1, #parts do
15 local part = parts[i] 16 var = var[parts[i]]
16 local v = var[part]
17 17
18 if not v then return el end 18 if not var then
19 19 return el
20 var = v 20 end
21 end 21 end
22 22
23 if var then return pandoc.Str(prefix .. var .. suffix) end 23 return pandoc.Str(prefix .. utils.stringify(var) .. suffix)
24 end 24 end
25 25
26 return el 26 return el
diff --git a/scripts/pages_content.lua b/scripts/content.lua
index b753b1e..d77759d 100644
--- a/scripts/pages_content.lua
+++ b/scripts/content.lua
@@ -4,7 +4,7 @@ local namespace = ''
4local siteUrl = '' 4local siteUrl = ''
5 5
6function meta(meta) 6function meta(meta)
7 namespace = pandoc.utils.stringify(meta.namespace.full) 7 namespace = pandoc.utils.stringify(meta.namespace)
8 siteUrl = pandoc.utils.stringify(meta.site.url):gsub("/$", "") 8 siteUrl = pandoc.utils.stringify(meta.site.url):gsub("/$", "")
9end 9end
10 10
diff --git a/scripts/lib/common.lua b/scripts/lib/common.lua
index 80b81ba..5ed3e31 100644
--- a/scripts/lib/common.lua
+++ b/scripts/lib/common.lua
@@ -49,6 +49,16 @@ function pandoc.List:take(n)
49 return result 49 return result
50end 50end
51 51
52function pandoc.List:skip(n)
53 local result = pandoc.List()
54
55 if n >= #self then return result end
56
57 for i = n + 1, #self do result:insert(self[i]) end
58
59 return result
60end
61
52return { 62return {
53 dump = dump 63 dump = dump
54} 64}
diff --git a/scripts/lib/sort.lua b/scripts/lib/sort.lua
new file mode 100644
index 0000000..393e5d5
--- /dev/null
+++ b/scripts/lib/sort.lua
@@ -0,0 +1,36 @@
1local utils = require 'pandoc.utils'
2
3function page_sort(order, pages)
4 order = order and utils.stringify(order)
5
6 return function(ref1, ref2)
7 local p1 = pages and pages[utils.stringify(ref1)] or ref1
8 local p2 = pages and pages[utils.stringify(ref2)] or ref2
9
10 if p1.position then
11 if p2.position then
12 return tonumber(utils.stringify(p1.position)) < tonumber(utils.stringify(p2.position))
13 else
14 return true
15 end
16 elseif p2.position then
17 return false
18 elseif order == "date_desc" then
19 if p1.last_update then
20 if p2.last_update then
21 return utils.stringify(p1.last_update.yyyy_mm_dd) > utils.stringify(p2.last_update.yyyy_mm_dd)
22 else
23 return true
24 end
25 else
26 return false
27 end
28 else
29 return utils.stringify(p1.title):upper() < utils.stringify(p2.title):upper()
30 end
31 end
32end
33
34return {
35 page_sort = page_sort
36}
diff --git a/scripts/metadata.lua b/scripts/metadata.lua
index 6aa679a..5157677 100644
--- a/scripts/metadata.lua
+++ b/scripts/metadata.lua
@@ -1,31 +1,7 @@
1local path = require 'pandoc.path' 1local path = require 'pandoc.path'
2local utils = require 'pandoc.utils'
2local common = require 'scripts.lib.common' 3local common = require 'scripts.lib.common'
3 4local sort = require 'scripts.lib.sort'
4function page_sort(order)
5 return function(p1, p2)
6 if p1.position then
7 if p2.position then
8 return p1.position < p2.position
9 else
10 return true
11 end
12 elseif p2.position then
13 return false
14 elseif order == "date_desc" then
15 if p1.last_update then
16 if p2.last_update then
17 return p1.last_update.yyyy_mm_dd > p2.last_update.yyyy_mm_dd
18 else
19 return true
20 end
21 else
22 return false
23 end
24 else
25 return p1.title:upper() < p2.title:upper()
26 end
27 end
28end
29 5
30function slug(str) 6function slug(str)
31 return str:lower():gsub("[^ a-z]", ""):gsub("[ ]+", "-") 7 return str:lower():gsub("[^ a-z]", ""):gsub("[ ]+", "-")
@@ -34,7 +10,7 @@ end
34function format_date(date) 10function format_date(date)
35 if not date then return date end 11 if not date then return date end
36 12
37 date = pandoc.utils.normalize_date(pandoc.utils.stringify(date)) 13 date = pandoc.utils.normalize_date(utils.stringify(date))
38 local year, month, day = date:match("(%d%d%d%d)-(%d%d)-(%d%d)") 14 local year, month, day = date:match("(%d%d%d%d)-(%d%d)-(%d%d)")
39 if not year then return nil end 15 if not year then return nil end
40 16
@@ -54,17 +30,6 @@ function make_absolute(rel, base)
54 return path.is_absolute(rel) and rel or path.join({ path.directory(base), rel }) 30 return path.is_absolute(rel) and rel or path.join({ path.directory(base), rel })
55end 31end
56 32
57function resolve_url(site_url, ref_file, target_file)
58 target_file = target_file:gsub("/index%.html$", "/")
59
60 local ref_base_dir = path.directory(ref_file)
61 local abs = target_file
62 local rel = path.make_relative(abs, ref_base_dir, true)
63 local full = (abs:sub(1, 1) == "/" and (site_url .. abs)) or abs
64
65 return { abs = abs, rel = rel, full = full }
66end
67
68function resolve_layout(depth) 33function resolve_layout(depth)
69 local layout = "categorized_list" 34 local layout = "categorized_list"
70 35
@@ -78,12 +43,12 @@ function resolve_layout(depth)
78end 43end
79 44
80function prep_layout(layout) 45function prep_layout(layout)
81 layout = pandoc.utils.stringify(layout) 46 layout = utils.stringify(layout)
82 return { id = layout, ["is_" .. layout] = true } 47 return { id = layout, ["is_" .. layout] = true }
83end 48end
84 49
85function resolve_namespace(namespace) 50function prep_namespace(namespace)
86 namespace = pandoc.utils.stringify(namespace) 51 namespace = utils.stringify(namespace)
87 52
88 local root = "index" 53 local root = "index"
89 if namespace ~= "" then root = namespace:gsub("^/([^/]*).*$", "%1") end 54 if namespace ~= "" then root = namespace:gsub("^/([^/]*).*$", "%1") end
@@ -97,7 +62,7 @@ function prep_menu(active_id, main_menu)
97 62
98 for i = 1, #main_menu do 63 for i = 1, #main_menu do
99 local item = main_menu[i] 64 local item = main_menu[i]
100 local active = pandoc.utils.stringify(item.id) == active_id 65 local active = utils.stringify(item.id) == active_id
101 item.active = active 66 item.active = active
102 if active then active_item = item end 67 if active then active_item = item end
103 if not item.hidden or item.active then items:insert(item) end 68 if not item.hidden or item.active then items:insert(item) end
@@ -107,22 +72,20 @@ function prep_menu(active_id, main_menu)
107end 72end
108 73
109function process_pages(global, build, meta) 74function process_pages(global, build, meta)
110 local order = meta.list_order
111
112 local pages_all = pandoc.List() 75 local pages_all = pandoc.List()
113 local pages_date_desc = pandoc.List() 76 local pages_date_desc = pandoc.List()
114 77
115 for _, p in pairs(meta.pages) do 78 for id, p in pairs(meta.pages) do
116 process(global, build, p) 79 process(global, build, p)
117 80
118 if not p.unlisted then 81 if not p.unlisted then
119 pages_all:insert(p) 82 pages_all:insert(id)
120 if p.last_update then pages_date_desc:insert(p) end 83 if p.last_update then pages_date_desc:insert(id) end
121 end 84 end
122 end 85 end
123 86
124 pages_all:sort(page_sort(order)) 87 pages_all:sort(sort.page_sort(meta.list_order, meta.pages))
125 pages_date_desc:sort(page_sort("date_desc")) 88 pages_date_desc:sort(sort.page_sort("date_desc", meta.pages))
126 89
127 meta.pages = { all = pages_all, date_desc = pages_date_desc, by_id = meta.pages } 90 meta.pages = { all = pages_all, date_desc = pages_date_desc, by_id = meta.pages }
128end 91end
@@ -145,35 +108,11 @@ function find_depth(meta)
145 meta.depth = depth 108 meta.depth = depth
146end 109end
147 110
148function resolve_urls(global, build, meta)
149 meta.url = resolve_url(global.site.url, build.file_out, meta.url)
150
151 if meta.feed then
152 if meta.file_out:match(".html$") then
153 meta.feed = {
154 url = resolve_url(global.site.url, build.file_out, meta.file_out:gsub(".html$", ".xml")),
155 }
156 else
157 meta.page = {
158 url = resolve_url(global.site.url, build.file_out, meta.file_out:gsub(".xml$", ".html")),
159 }
160 end
161 end
162
163 if meta.thumbnail then
164 meta.thumbnail = resolve_url(global.site.url, build.file_out, meta.thumbnail)
165 end
166
167 -- for _, p in pairs(meta.pages.by_id) do
168 -- resolve_urls(global, build, p)
169 -- end
170end
171
172function resolve_dates(meta) 111function resolve_dates(meta)
173 if meta.last_update then 112 if meta.last_update then
174 meta.last_update = format_date(meta.last_update) 113 meta.last_update = format_date(meta.last_update)
175 elseif #meta.pages.date_desc ~= 0 then 114 elseif #meta.pages.date_desc ~= 0 then
176 meta.last_update = meta.pages.date_desc[1].last_update 115 meta.last_update = meta.pages.by_id[meta.pages.date_desc[1]].last_update
177 elseif meta.date then 116 elseif meta.date then
178 meta.last_update = format_date(meta.date) 117 meta.last_update = format_date(meta.date)
179 end 118 end
@@ -187,125 +126,23 @@ function resolve_dates(meta)
187 meta.was_updated = meta.date and meta.last_update and meta.date.yyyy_mm_dd ~= meta.last_update.yyyy_mm_dd 126 meta.was_updated = meta.date and meta.last_update and meta.date.yyyy_mm_dd ~= meta.last_update.yyyy_mm_dd
188end 127end
189 128
190function d1_page_to_list_item(meta, p)
191 return {
192 title = p.title,
193 subtitle = p.subtitle,
194 date = p.date,
195 last_update = p.last_update,
196 show_date = meta.list_order == "date_desc",
197 schema_type = p.schema_type,
198 draft = p.draft,
199 position = p.position,
200 url = p.url,
201 rel = p.rel,
202 slug = p.slug,
203 thumbnail = p.thumbnail,
204 icon = p.icon or meta.icon,
205 post_icon = p.post_icon or meta.list_post_icon,
206 indicator = meta.list_read_indicators,
207 }
208end
209
210function d2_page_to_list_item(meta, cat, p, set_cat_title)
211 return {
212 title = p.title,
213 subtitle = p.subtitle,
214 category = set_cat_title and cat.title,
215 date = p.date,
216 last_update = p.last_update,
217 show_date = cat.list_order == "date_desc",
218 schema_type = p.schema_type,
219 draft = p.draft,
220 position = p.position,
221 url = p.url,
222 rel = p.rel,
223 slug = p.slug,
224 thumbnail = p.thumbnail,
225 icon = p.icon or cat.icon,
226 post_icon = p.post_icon or cat.list_post_icon or meta.list_post_icon,
227 indicator = cat.list_read_indicators,
228 }
229end
230
231function cat_to_list_cat(cat, allItems)
232 local limit = cat.list_limit or 9999
233 local items = allItems:take(limit)
234 local omitted = #allItems - #items
235
236 return {
237 title = cat.title,
238 description = (cat.description and pandoc.MetaBlocks(pandoc.Para(cat.description))) or
239 (not cat.no_description and cat.content),
240 last_update = cat.last_update,
241 schema_type = cat.schema_type,
242 url = cat.url,
243 slug = cat.slug,
244 layout = cat.list_layout,
245 items = items,
246 total = tostring(#allItems),
247 omitted = omitted ~= 0 and tostring(omitted),
248 }
249end
250
251function generate_list(meta)
252 if meta.depth < 1 then return pandoc.List() end
253
254 if meta.depth == 1 then
255 return meta.pages.all:map(function(p) return d1_page_to_list_item(meta, p) end)
256 end
257
258 if meta.depth == 2 then
259 return meta.pages.all
260 :map(function(cat)
261 local allItems = cat.pages.all:map(function(p) return d2_page_to_list_item(meta, cat, p, false) end)
262
263 return cat_to_list_cat(cat, allItems)
264 end)
265 :filter(function(cat) return #cat.items ~= 0 end)
266 end
267
268 if meta.depth == 3 then
269 local list = meta.pages.all
270 :map(function(cat)
271 local allItems = cat.pages.all:flatMap(function(c)
272 if cat.list_flatten and c.depth ~= 0 then
273 return c.pages.all:map(function(p) return d2_page_to_list_item(cat, c, p, true) end)
274 else
275 return pandoc.List({ d1_page_to_list_item(cat, c) })
276 end
277 end)
278
279 allItems:sort(page_sort(cat.list_order))
280
281 return cat_to_list_cat(cat, allItems)
282 end)
283 :filter(function(cat) return #cat.items ~= 0 end)
284
285 return list
286 end
287end
288
289function process_base(build, meta) 129function process_base(build, meta)
290 meta.namespace = resolve_namespace(meta.namespace) 130 meta.namespace = prep_namespace(meta.namespace)
291 meta.file_out = pandoc.utils.stringify(meta.file_out) 131 meta.file_out = utils.stringify(meta.file_out)
292 meta.unlisted = meta.unlisted or (meta.draft and build.mode ~= "dev") 132 meta.unlisted = meta.unlisted or (meta.draft and build.mode ~= "dev")
293 meta.redirect = meta.url and true 133 meta.redirect = meta.url and true
294 meta.url = meta.url and pandoc.utils.stringify(meta.url) or meta.file_out 134 meta.url = meta.url or meta.file_out
295 meta.title = meta.title and pandoc.utils.stringify(meta.title) or "" 135 meta.title = meta.title and utils.stringify(meta.title) or ""
296 meta.slug = slug(meta.title) 136 meta.slug = slug(meta.title)
297 meta.schema_type = meta.schema_type and pandoc.utils.stringify(meta.schema_type) or "CreativeWork" 137 meta.schema_type = meta.schema_type or "CreativeWork"
298 meta.list_order = meta.list_order and pandoc.utils.stringify(meta.list_order)
299 meta.list_layout = prep_layout(meta.list_layout or "list") 138 meta.list_layout = prep_layout(meta.list_layout or "list")
300 meta.list_limit = meta.list_limit and tonumber(pandoc.utils.stringify(meta.list_limit)) 139 meta.position = meta.position and tonumber(utils.stringify(meta.position))
301 meta.position = meta.position and tonumber(pandoc.utils.stringify(meta.position)) 140 meta.thumbnail = meta.thumbnail and make_absolute("thumbnail." .. utils.stringify(meta.thumbnail), meta.file_out)
302 meta.thumbnail = meta.thumbnail and make_absolute("thumbnail." .. pandoc.utils.stringify(meta.thumbnail), meta.file_out)
303 meta.layout = prep_layout(meta.layout or (meta.redirect and "redirect") or resolve_layout(meta.depth)) 141 meta.layout = prep_layout(meta.layout or (meta.redirect and "redirect") or resolve_layout(meta.depth))
304end 142end
305 143
306function process(global, build, meta) 144function process(global, build, meta)
307 process_base(build, meta) 145 process_base(build, meta)
308 resolve_urls(global, build, meta)
309 process_pages(global, build, meta) 146 process_pages(global, build, meta)
310 resolve_dates(meta) 147 resolve_dates(meta)
311end 148end
@@ -322,16 +159,10 @@ function Meta(meta)
322 end 159 end
323 end 160 end
324 161
325 meta.site.url = pandoc.utils.stringify(meta.site.url):gsub("/$", "") 162 meta.site.url = utils.stringify(meta.site.url):gsub("/$", "")
326 163
327 find_depth(meta) 164 find_depth(meta)
328 process(meta, build, meta) 165 process(meta, build, meta)
329 166
330 meta.list = generate_list(meta)
331
332 if meta.menus and meta.menus.main then
333 meta.menus.main = prep_menu(meta.namespace.root.id, meta.menus.main)
334 end
335
336 return meta 167 return meta
337end 168end
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