public inbox archive for pandoc-discuss@googlegroups.com
 help / color / mirror / Atom feed
From: Albert Krewinkel <albert+pandoc-9EawChwDxG8hFhg+JK9F0w@public.gmane.org>
To: pandoc-discuss <pandoc-discuss-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org>
Subject: Yet more fun with pandoc lua
Date: Wed, 25 Jan 2023 22:18:10 +0100	[thread overview]
Message-ID: <87tu0ejo7e.fsf@zeitkraut.de> (raw)

#!/usr/bin/env -S pandoc lua
-- This Lua script can be used as a very simple task manager. It allows
-- to manage tasks in a plain Markdown file `panjour.md`. E.g., if this
-- script is saved as file `panjour` and given executable permissions,
-- then the following works:
--
--     # Add two tasks to the file.
--     ./panjour add Dabble with Lua
--     ./panjour add Use some '*Markdown*'
--
--     # List all tasks
--     ./panjour list
--
--     # Mark a task as DONE
--     ./panjour done Dabble with Lua
--
-- The code here is unpolished; the main goal was to try and write a
-- full Lua program built on top of pandoc.

local panjour_file = (os.getenv 'PANJOUR_FILE') or 'panjour.md'
local format = 'markdown'
warn '@on'

local TaskManager = {
  done_marker = pandoc.Inlines{pandoc.Str '☒', pandoc.Space()},
  todo_marker = pandoc.Inlines{pandoc.Str '☐', pandoc.Space()},
}

function TaskManager:new(filename)
  local fh = io.open(filename, 'r+')
  if not doc then
    doc = pandoc.read(fh:read 'a', format)
  end
  local mgr = {
    document = doc,
    file_handle = fh,
  }
  setmetatable(mgr, self)
  self.__index = self
  return mgr
end

function TaskManager:add_task (task)
  local item = {pandoc.Plain(self.todo_marker .. task)}
  for i, blk in ipairs(self.document.blocks) do
    if blk.t == 'BulletList' then
      blk.content:insert(item)
      goto done
    end
  end
  self.document.blocks:insert(
    pandoc.BulletList{item}
  )
  ::done::
  return self
end

function TaskManager:mark_task_as_done (task)
  local todo_item = pandoc.Blocks{pandoc.Plain(self.todo_marker..task)}
  local done_item = pandoc.Blocks{pandoc.Plain(self.done_marker..task)}
  local found = false
  self.document = self.document:walk {
    BulletList = function (ul)
      if not found then
        local li, idx = ul.content:find(todo_item)
        if idx then
          found = true
          ul.content[idx] = {pandoc.Plain(self.done_marker .. task)}
        elseif ul.content:find(done_item) then
          found = true
          warn('Item already marked as done!')
        end
        return ul
      end
    end
  }
  if not found then
    local msg = 'task not found: "%s"'
    error(msg:format(pandoc.utils.stringify(task)))
  end
  return self
end

function TaskManager:list ()
  self:write_doc(io.stdout)
end

function TaskManager:write_doc (fh)
  local out = pandoc.write(self.document, format)
  fh = fh or self.file_handle
  fh:seek('set')
  fh:write(out)
end

function TaskManager:__gc()
  self.file_handle:close()
end

local action = arg[1]
local task_args = pandoc.List{}
for i=2, #arg do
  task_args:insert(arg[i])
end
local task = pandoc.utils.blocks_to_inlines(
  pandoc.read(table.concat(task_args, ' '), format).blocks
)

local task_manager = TaskManager:new(panjour_file)

if action == 'add' then
  task_manager:add_task(task)
  task_manager:write_doc()
elseif action == 'done' then
  task_manager:mark_task_as_done(task)
  task_manager:write_doc()
elseif action == 'list' then
  task_manager:list()
else
  local msg = 'Unknown or missing action. Bailing out.\n'
  io.stderr:write(msg)
  os.exit(1)
end


-- 
Albert Krewinkel
GPG: 8eed e3e2 e8c5 6f18 81fe  e836 388d c0b2 1f63 1124

-- 
You received this message because you are subscribed to the Google Groups "pandoc-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pandoc-discuss+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To view this discussion on the web visit https://groups.google.com/d/msgid/pandoc-discuss/87tu0ejo7e.fsf%40zeitkraut.de.


                 reply	other threads:[~2023-01-25 21:18 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87tu0ejo7e.fsf@zeitkraut.de \
    --to=albert+pandoc-9eawchwdxg8hfhg+jk9f0w@public.gmane.org \
    --cc=pandoc-discuss-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).