Made this space lua snippet recently to collect todo lists. It gets all the tasks in an index, finds what percent of them are complete in each note, sorts them by date modified, and writes the result as an array, which can be rendered as bullets through a ${} block.
Here’s a screenshot of what its output looks like:
raw markdown:
- [[Shopping List]] (100%)
- [[Summer TODO]] (82%)
- [[General tasks]] (1%)
Here’s the code for it:
-- generate a bulleted list of notes with tasks and what percent of them are complete in each note
local generate_bulleted_tasklist = function()
-- all tasks
local tasks_todo = query [[
from index.tag 'task'
]]
-- references to date modifed
local ref_datemodified = {}
for _, row in pairs(query [[ from index.tag 'page' ]]) do
ref_datemodified[row.ref] = row.lastModified
end
-- add "lastModified" to the tasks_todo table
for _, row in pairs(tasks_todo) do
row.lastModified = ref_datemodified[row.page]
end
-- count how many tasks each note has
local tasks_per_note = {}
for _, row in pairs(tasks_todo) do
local idx = row.page
local current = tasks_per_note[idx] or { complete = 0, total = 0 }
local complete = current.complete or 0
local total = current.total or 0
tasks_per_note[idx] = {
complete = complete + (row.done and 1 or 0),
total = total + 1,
}
end
-- mathematical round
local round = function(f)
local rem = f - math.floor(f)
f = rem >= 0.5 and math.ceil(f) or math.floor(f)
return f
end
-- format a list of strings based on tasks_per_note
local tasks_per_note_list = {}
for note, done in pairs(tasks_per_note) do
local done_percent = round((done.complete/done.total)*100)
tasks_per_note_list[#tasks_per_note_list + 1] = {
note = note,
lastModified = ref_datemodified[note],
done_percent = done_percent,
}
end
-- final query
return query [[
from tasks_per_note_list
order by lastModified desc
limit 15
select '[' .. '[' .. note .. ']' .. '] (' .. tostring(done_percent) .. '%)'
]]
end
It would be a bit simpler to write this kind of thing if there was a clean way to get the lastModified attribute along with the result of the index.tag('task') query, since most of the code here is dedicated to combining the appropriate data from the index.tag('task') list with the index.tag('page') list to get the lastModified and done attributes associated with each page. If there’s a way I can refactor this to not need to do that, I’d like to know!
