diff options
| author | Volpeon <git@volpeon.ink> | 2022-08-04 10:26:57 +0200 |
|---|---|---|
| committer | Volpeon <git@volpeon.ink> | 2022-08-04 10:26:57 +0200 |
| commit | 347d7c0da13079fefce6d8741a5604adb89eb97c (patch) | |
| tree | 43b568e5ae48692425a9ddeeddc4001b1e940336 /scripts/page.lua | |
| parent | Code reorganization (diff) | |
| download | volpeon.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.lua | 222 |
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 @@ | |||
| 1 | local path = require 'pandoc.path' | ||
| 2 | local utils = require 'pandoc.utils' | ||
| 3 | local common = require 'scripts.lib.common' | ||
| 4 | local sort = require 'scripts.lib.sort' | ||
| 5 | |||
| 6 | function 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 } | ||
| 17 | end | ||
| 18 | |||
| 19 | function 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 } | ||
| 34 | end | ||
| 35 | |||
| 36 | function 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 | } | ||
| 46 | end | ||
| 47 | |||
| 48 | function 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 | ||
| 66 | end | ||
| 67 | |||
| 68 | function 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 | } | ||
| 86 | end | ||
| 87 | |||
| 88 | function 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 | } | ||
| 107 | end | ||
| 108 | |||
| 109 | function 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 | } | ||
| 127 | end | ||
| 128 | |||
| 129 | function 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 | ||
| 165 | end | ||
| 166 | |||
| 167 | function 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) | ||
| 176 | end | ||
| 177 | |||
| 178 | function process(global, build, meta) | ||
| 179 | process_base(meta) | ||
| 180 | resolve_urls(global, build, meta) | ||
| 181 | process_pages(global, build, meta) | ||
| 182 | end | ||
| 183 | |||
| 184 | function 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 | ||
| 222 | end | ||
