From 5f6712cfc4fd9e63bff6c935665b8426ef2ba2a4 Mon Sep 17 00:00:00 2001 From: Volpeon Date: Sun, 12 Jun 2022 10:20:41 +0200 Subject: Optimized list generation --- scripts/metadata_filter.lua | 217 +++++++++++++++++--------------------------- 1 file changed, 84 insertions(+), 133 deletions(-) (limited to 'scripts') diff --git a/scripts/metadata_filter.lua b/scripts/metadata_filter.lua index fcceffa..314f2b0 100644 --- a/scripts/metadata_filter.lua +++ b/scripts/metadata_filter.lua @@ -57,15 +57,6 @@ function slug(str) return str:lower():gsub("[^ a-z]", ""):gsub("[ ]+", "-") end -function file_exists(name) - local f = io.open(name, "r") - if f ~= nil then - io.close(f) - return true - end - return false -end - function format_date(date) if not date then return date end @@ -85,20 +76,6 @@ function format_date(date) } end -function table_to_list(t, kv, cmp) - local l = pandoc.List() - - if kv then - for key, value in pairs(t) do l:insert({ key = key, value = value }) end - else - for _, value in pairs(t) do l:insert(value) end - end - - l:sort(cmp or function(i1, i2) return i1.key < i2.key end) - - return l -end - function make_absolute(rel, base) return path.is_absolute(rel) and rel or path.join({ path.directory(base), rel }) end @@ -117,9 +94,9 @@ end function resolve_layout(depth) local layout = "categorized_list" - if depth == "0" then + if depth == 0 then layout = "page" - elseif depth == "1" then + elseif depth == 1 then layout = "list" end @@ -180,124 +157,98 @@ end function find_depth(pages) local depth = 0 - for i = 1, #pages do - local p = pages[i] - local d = tonumber(p.depth) - if d > depth then depth = d end + if pages then + for i = 1, #pages.all do + local p = pages.all[i] + local d = tonumber(p.depth) + if d > depth then depth = d end + end + + depth = depth + 1 end - depth = depth + 1 + return depth +end - return tostring(depth) +function d1_page_to_list_item(meta, p) + return { + title = p.title, + subtitle = p.subtitle, + date = p.date, + position = p.position, + url = p.url, + slug = p.slug, + thumbnail = p.thumbnail, + icon = p.icon or meta.icon, + post_icon = p.post_icon or meta.list_post_icon, + indicator = meta.list_read_indicators, + } +end + +function d2_page_to_list_item(meta, cat, p) + return { + title = p.title, + subtitle = p.subtitle, + date = p.date, + position = p.position, + url = p.url, + slug = p.slug, + thumbnail = p.thumbnail, + icon = p.icon or cat.icon, + post_icon = p.post_icon or cat.list_post_icon or meta.list_post_icon, + indicator = cat.list_read_indicators, + } +end + +function cat_to_list_cat(cat, allItems) + local limit = cat.list_limit or 9999 + local items = allItems:take(limit) + local omitted = #allItems - #items + + return { + title = cat.title, + description = (cat.description and pandoc.MetaBlocks(pandoc.Para(cat.description))) or + (not cat.no_description and cat.content), + url = cat.url, + slug = cat.slug, + layout = cat.list_layout, + items = items, + total = tostring(#allItems), + omitted = omitted ~= 0 and tostring(omitted), + } end function generate_list(meta) - if not meta.pages then return nil end - - if meta.depth == "1" then - return meta.pages.all:map(function(p) - return { - title = p.title, - subtitle = p.subtitle, - date = p.date, - position = p.position, - url = p.url, - slug = p.slug, - thumbnail = p.thumbnail, - icon = p.icon or meta.icon, - post_icon = p.post_icon or meta.list_post_icon, - indicator = meta.list_read_indicators, - } - end) - elseif meta.depth == "2" then + if meta.depth < 1 then return nil end + + if meta.depth == 1 then + return meta.pages.all:map(function(p) return d1_page_to_list_item(meta, p) end) + end + + if meta.depth == 2 then return meta.pages.all :map(function(cat) - local limit = (cat.list_limit and tonumber(pandoc.utils.stringify(cat.list_limit))) or - 9999 - local allItems = ((cat.pages and cat.pages.all) or pandoc.List()):map(function(p) - return { - title = p.title, - subtitle = p.subtitle, - date = p.date, - position = p.position, - url = p.url, - slug = p.slug, - thumbnail = p.thumbnail, - icon = p.icon or cat.icon, - post_icon = p.post_icon or cat.list_post_icon or meta.list_post_icon, - indicator = cat.list_read_indicators, - } - end) - local items = allItems:take(limit) - local omitted = #allItems - #items - - return { - title = cat.title, - description = (cat.description and pandoc.MetaBlocks(pandoc.Para(cat.description))) or - (not cat.no_description and cat.content), - url = cat.url, - slug = cat.slug, - layout = cat.list_layout, - items = items, - total = tostring(#allItems), - omitted = omitted ~= 0 and tostring(omitted), - } + local allItems = ((cat.pages and cat.pages.all) or pandoc.List()) + :map(function(p) return d2_page_to_list_item(meta, cat, p) end) + + return cat_to_list_cat(cat, allItems) end) :filter(function(cat) return #cat.items ~= 0 end) - elseif meta.depth == "3" then + end + + if meta.depth == 3 then return meta.pages.all :map(function(cat) - local limit = (cat.list_limit and tonumber(pandoc.utils.stringify(cat.list_limit))) or - 9999 - local allItems = (cat.pages and cat.pages.all or pandoc.List()) - :flatMap(function(c) - if c.pages then - return c.pages.all:map(function(p) - return { - title = p.title, - subtitle = p.subtitle, - date = p.date, - position = p.position, - category = c.title, - url = p.url, - slug = p.slug, - thumbnail = p.thumbnail, - icon = p.icon or c.icon, - post_icon = p.post_icon or c.list_post_icon or cat.list_post_icon, - indicator = c.list_read_indicators, - } - end) - else - local l = pandoc.List() - l:insert({ - title = c.title, - subtitle = c.subtitle, - date = c.date, - position = c.position, - url = c.url, - slug = c.slug, - icon = c.icon or cat.icon, - post_icon = c.post_icon or cat.list_post_icon, - indicator = cat.list_read_indicators, - }) - return l - end - end) + local allItems = (cat.pages and cat.pages.all or pandoc.List()):flatMap(function(c) + if c.pages then + return c.pages.all:map(function(p) return d2_page_to_list_item(cat, c, p) end) + else + return pandoc.List({ d1_page_to_list_item(cat, c) }) + end + end) allItems:sort(page_sort(cat.list_order)) - local items = allItems:take(limit) - local omitted = #allItems - #items - - return { - title = cat.title, - description = (cat.description and pandoc.MetaBlocks(pandoc.Para(cat.description))) or - (not cat.no_description and cat.content), - url = cat.url, - slug = cat.slug, - layout = cat.list_layout, - items = items, - total = tostring(#allItems), - omitted = omitted ~= 0 and tostring(omitted), - } + + return cat_to_list_cat(cat, allItems) end) :filter(function(cat) return #cat.items ~= 0 end) end @@ -313,6 +264,7 @@ function process(global, meta) meta.slug = slug(meta.title) if meta.list_order then meta.list_order = pandoc.utils.stringify(meta.list_order) end meta.list_layout = meta.list_layout and prep_layout(meta.list_layout) + if meta.list_limit then meta.list_limit = tonumber(pandoc.utils.stringify(meta.list_limit)) end if meta.position then meta.position = pandoc.utils.stringify(meta.position) end if meta.feed then @@ -340,9 +292,8 @@ function process(global, meta) end meta.pages = process_pages(global, meta.list_order, meta.pages) - meta.depth = (meta.pages and find_depth(meta.pages.all)) or "0" - meta.layout = prep_layout(meta.layout or (meta.redirect and "redirect") or - resolve_layout(meta.depth)) + meta.depth = find_depth(meta.pages) + meta.layout = prep_layout(meta.layout or (meta.redirect and "redirect") or resolve_layout(meta.depth)) if meta.date then meta.date = format_date(meta.date) -- cgit v1.2.3-70-g09d2