199 lines
5.6 KiB
Lua
199 lines
5.6 KiB
Lua
-- Tweaks our manual pages during conversion to html by pandoc.
|
|
--
|
|
-- See https://pandoc.org/lua-filters.html#debugging-lua-filters on
|
|
-- how to debug and develop these filters.
|
|
|
|
-- Overwrites the title.
|
|
--
|
|
-- It just says 'sq` which looks odd.
|
|
function Meta(m)
|
|
m.title = "Sequoia PGP Manual Pages"
|
|
return m
|
|
end
|
|
|
|
-- Turns subcommand headers into links.
|
|
function Header (h)
|
|
-- Given a sequence of subcommands, return the appropriate file
|
|
-- name.
|
|
local function subcommand_to_link (s)
|
|
t = ""
|
|
for i = 1, #s do
|
|
if s[i].t == 'Space' then
|
|
t = t .. '-'
|
|
else
|
|
t = t .. s[i].text
|
|
end
|
|
end
|
|
return t .. ".1.html"
|
|
end
|
|
|
|
if h.c[1].t == 'Str' and h.c[1].text == 'sq' then
|
|
h.c = pandoc.Link(h.c, subcommand_to_link(h.c))
|
|
return h
|
|
end
|
|
end
|
|
|
|
-- Transform the entries in the "SYNOPSIS" section into links.
|
|
local function rewrite_synopsis (inlines)
|
|
-- Returns true if we're looking at a synopsis entry.
|
|
--
|
|
-- Matches on the following sequence:
|
|
--
|
|
-- [1] LineBreak {}
|
|
-- [2] Strong {
|
|
-- content: Inlines[7] {
|
|
-- [1] Str "sq"
|
|
-- [2] Space
|
|
-- [3] Str "key"
|
|
-- [4] Space
|
|
-- [5] Str "userid"
|
|
-- [6] Space
|
|
-- [7] Str "add"
|
|
-- }
|
|
-- }
|
|
-- [3] Space
|
|
-- [4] Str "["
|
|
local function synopsis_p (s)
|
|
return s[1] and s[1].t == 'LineBreak'
|
|
and s[2] and s[2].t == 'Strong'
|
|
and s[2].c[1].text == 'sq' and s[2].c[2].t == 'Space'
|
|
and s[3] and s[3].t == 'Space'
|
|
and s[4] and s[4].t == 'Str' and s[4].text == '['
|
|
end
|
|
|
|
-- Given a sequence of subcommands, return the appropriate file
|
|
-- name.
|
|
local function subcommand_to_link (s)
|
|
t = ""
|
|
for i = 1, #s do
|
|
if s[i].t == 'Space' then
|
|
t = t .. '-'
|
|
else
|
|
t = t .. s[i].text
|
|
end
|
|
end
|
|
return t .. ".1.html"
|
|
end
|
|
|
|
for i = 1, #inlines-4 do
|
|
if synopsis_p(table.pack(table.unpack(inlines, i, i + 3))) then
|
|
inlines[i+1] = pandoc.Link(inlines[i+1], subcommand_to_link(inlines[i+1].c))
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Transforms the entries in the "SEE ALSO" section into links.
|
|
local function rewrite_see_also (inlines)
|
|
-- Returns true if we're looking at a see-also entry.
|
|
--
|
|
-- Matches on the following sequence:
|
|
--
|
|
-- [43] Strong {
|
|
-- content: Inlines[1] {
|
|
-- [1] Str "sq-wkd"
|
|
-- }
|
|
-- }
|
|
-- [44] Str "(1),"
|
|
local function see_also_p (a, b)
|
|
return a and a.t == 'Strong'
|
|
and b and b.t == 'Str' and string.sub(b.text, 1, 3) == '(1)'
|
|
end
|
|
|
|
for i = 1, #inlines-1 do
|
|
if see_also_p(inlines[i], inlines[i+1]) then
|
|
inlines[i] = pandoc.Link(inlines[i], inlines[i].c[1].text .. ".1.html")
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Transforms text enclosed in backticks into inline code or links.
|
|
local function rewrite_inline_code (inlines)
|
|
-- Returns the length of the token stream containing quoted text
|
|
-- starting from the first token, or nil if no quoted text is
|
|
-- found.
|
|
local function inline_quoted (s)
|
|
if s[1] and s[1].t == 'Str' and string.sub(s[1].text, 1, 1) == "`" then
|
|
-- Find the end, i.e. the first token containing the closing
|
|
-- tick (which may be the first token).
|
|
for i = 1, #s do
|
|
if s[i] and s[i].t == 'Str' and string.find(s[i].text, "`", 2) then
|
|
return i
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Given a sequence of tokens, returns the text representation.
|
|
local function tokens_to_text (s)
|
|
t = ""
|
|
for i = 1, #s do
|
|
if s[i].t == 'Space' then
|
|
t = t .. ' '
|
|
else
|
|
t = t .. s[i].text
|
|
end
|
|
end
|
|
return t
|
|
end
|
|
|
|
-- Given a string subcommand, return the appropriate file
|
|
-- name.
|
|
local function subcommand_to_link (s)
|
|
return string.gsub(s, " ", "-") .. ".1.html"
|
|
end
|
|
|
|
for i = 1, #inlines do
|
|
local len = inline_quoted(table.pack(table.unpack(inlines, i)))
|
|
if len then
|
|
-- First, flatten the matched tokens to a text.
|
|
local text = tokens_to_text(table.pack(table.unpack(inlines, i, i+len)))
|
|
|
|
-- Then, remove the tokens from the AST.
|
|
for j = math.min(i+len, #inlines), i, -1 do
|
|
inlines:remove(j)
|
|
end
|
|
|
|
-- We need to create a replacement node.
|
|
local replacement
|
|
|
|
-- See if the quoted text is a reference to a (sub)command.
|
|
local s, e = string.find(text, "`sq[^`]*`")
|
|
if s then
|
|
-- If so, we turn it into a link.
|
|
local sub = string.sub(text, s+1, e-1)
|
|
replacement = pandoc.Link(sub, subcommand_to_link(sub))
|
|
else
|
|
s, e = string.find(text, "`[^`]*`")
|
|
replacement = pandoc.Code(string.sub(text, s+1, e-1))
|
|
end
|
|
|
|
-- Finally, insert prefix, replacement, and suffix into the
|
|
-- AST.
|
|
inlines:insert(i+0, pandoc.Str(string.sub(text, 1, s-1)))
|
|
inlines:insert(i+1, replacement)
|
|
inlines:insert(i+2, pandoc.Str(string.sub(text, e+1)))
|
|
end
|
|
end
|
|
end
|
|
|
|
function Inlines (inlines)
|
|
rewrite_synopsis(inlines)
|
|
rewrite_see_also(inlines)
|
|
rewrite_inline_code(inlines)
|
|
return inlines
|
|
end
|
|
|
|
-- Turns implicit links into actual links.
|
|
function Str (s)
|
|
s = s.text
|
|
a, b = string.find(s, "<https://[^>]+>")
|
|
if a and b then
|
|
target = string.sub(s, a+1, b-1)
|
|
return pandoc.Inlines {
|
|
pandoc.Str(string.sub(s, 0, a)),
|
|
pandoc.Link(target, target),
|
|
pandoc.Str(string.sub(s, b)),
|
|
}
|
|
end
|
|
end
|