summaryrefslogtreecommitdiff
path: root/prose.lua
diff options
context:
space:
mode:
Diffstat (limited to 'prose.lua')
-rw-r--r--prose.lua90
1 files changed, 90 insertions, 0 deletions
diff --git a/prose.lua b/prose.lua
new file mode 100644
index 0000000..ceadec0
--- /dev/null
+++ b/prose.lua
@@ -0,0 +1,90 @@
+local html = require'html'
+
+local extensions = {}
+
+local function prose(S, text)
+ -- this may be a hack
+ local replacements = {}
+ local SO, SI = "\x0e", "\x0f"
+ -- if debugview then SO,SI = "\x1b[7m", "\x1b[0m" end
+ local function emplace(s)
+ table.insert(replacements, s)
+ return SO .. #replacements .. SI
+ end
+
+ -- no way to match 'after ws or at start of string'
+ -- so, just add ws to start and end of string
+ -- this may also be a hack
+ text = ' ' .. text .. ' '
+
+ local function simple_sub(delim, tagname)
+ return {
+ "(%s)"..delim..'(.-)'..delim..'(%W)', -- wo wimple
+ function(a,x,b) return a..emplace(html.T[tagname](x))..b end
+ }
+ end
+
+ local function extension(str)
+ local verb, rest = str:match("^{(%w+);%s*(.*)}$")
+ if verb then
+ return emplace(extensions[verb](S, rest))
+ end
+ local verbonly = str:match("^{(%w+)}$")
+ if verbonly then
+ return emplace(extensions[verbonly](S))
+ end
+ error("invalid extension syntax: "..str)
+ end
+
+ local subs = {
+ { "%b{}", extension },
+ simple_sub('%*', 'strong'),
+ simple_sub('_', 'em'),
+ simple_sub('`', 'code'),
+ }
+
+ for i, row in ipairs(subs) do
+ local pattern,replacement = row[1], row[2]
+ text = text:gsub(pattern,replacement)
+ end
+
+ text = text:gsub("^%s*",""):gsub("%s*$","")
+ -- print(text)
+ local insects = {""}
+ local n = 1
+ while n <= #text do
+ local _, nn, id = text:find('^'..SO:gsub("%[","%%[").."(%d+)"..SI:gsub("%[","%%["), n)
+ if nn then
+ table.insert(insects, replacements[tonumber(id)])
+ table.insert(insects, "")
+ n = nn + 1
+ else
+ local c = text:sub(n,n)
+ -- print("'"..c.."'")
+ insects[#insects] = insects[#insects] .. c
+ n = n + 1
+ end
+ end
+
+ -- for i,n in ipairs(insects) do print(i,type(n),n) end
+
+ return insects
+end
+
+extensions.fn = function(S,text)
+ S.footnotes = S.footnotes or {}
+ local n = #S.footnotes + 1
+ local link_id = "fnref_"..n
+ local note_id = "fn_"..n
+ S.footnotes[n] = html.T.li({id=note_id}, {
+ prose(S,text), html.safe"&nbsp;",
+ html.T.a({href="#"..link_id, role="doc-backlink"}, html.safe"&#x21a9;&#xfe0e;")})
+ return html.T.sup({id=link_id}, html.T.a({href="#"..note_id, role='doc-noteref'}, '('..n..')'))
+end
+
+extensions.fns = function(S)
+ if not S.footnotes then return "" end
+ return {html.T.hr{}, html.T.ol(S.footnotes)}
+end
+
+return prose