|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- -*- coding: raw-text-unix -*-
-- elisp.lua - convert elisp hyperlinks (in e-scripts) to html.
-- This is part of blogme3.
--
-- The ascii files at http://anggtwu.net/ are all e-scripts
-- (see <http://anggtwu.net/eev-article.html#e-scripts>); the code in
-- blogme3 that converts them to HTML is spread over three files:
-- (find-blogme3 "escripts.lua")
-- (find-blogme3 "elisp.lua")
-- (find-blogme3 "angglisp.lua")
-- and this one is the second of them. The files escripts.lua and
-- elisp.lua can be loaded independently of one another, and
-- escripts.lua needs lpeg; because of this I'm currently making
-- blogme3.lua always load elisp.lua, even though I'm not using its
-- functions elsewhere... At some point I will clean this.
--
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
-- Version: 2014jan24
-- <http://anggtwu.net/blogme3/elisp.lua>
-- <http://anggtwu.net/blogme3/elisp.lua.html>
-- License: GPL.
-- (find-es "lua5" "sheadsymbol-roberto")
-- (find-angg "LUA/lua50init.lua")
-- (find-angg "LUA/lua50init.lua" "loadlpeg")
-- (find-lpegw3m "doc.html" "function anywhere (p)")
-- (find-blogmefile "blogme2-outer.lua" "entities and quoting (Q)")
-- (find-anggfile "TH/Generate")
-- (find-anggfile "TH/Generate" "txt2html")
-- Quick index:
-- «.tools» (to "tools")
-- «.makesexphtml» (to "makesexphtml")
-- «.maketarget» (to "maketarget")
-- «.relative-links» (to "relative-links")
-- «._E» (to "_E")
-- «._E_intro» (to "_E_intro")
-- «.Tgt» (to "Tgt")
-- «.TGT» (to "TGT")
-- «.set_E4» (to "set_E4")
-- «.set_EHELP» (to "set_EHELP")
-- «.code_c_d_local» (to "code_c_d_local")
-- «.code_c_d_remote» (to "code_c_d_remote")
-- «._E4s_as_lua» (to "_E4s_as_lua")
--------[ Some tools ]--------
-- «tools» (to ".tools")
null = function (obj) return obj == nil or obj == "" end
isdir = function (str) return str == "" or string.sub(str, -1, -1) == "/" end
-- dequote = function (sstr) return sstr and string.sub(sstr, 2, -2) end
dequote = function (qstr) return qstr and qstr:match "^\"(.*)\"$" end
href = function (target, text)
if target then return format("<a href=\"%s\">%s</a>", target, text) end
return text -- if target is nil then return text unchanged, not an href
end
--------[ makesexphtml ]--------
-- «makesexphtml» (to ".makesexphtml")
-- Sexp hyperlinks are usually htmlized like this:
--
-- (find-eev "eev-mini.el")
-- \------/ \/
-- this points this points to
-- to help on the result of
-- "find-eev" evaluating the sexp
--
-- The html for them is produced by the function "makesexphtml".
-- It receives four arguments:
-- (name) (sample value or description)
-- all [[(find-eev "eev-mini.el")]]
-- funname "find-eev"
-- help URL of the help link, or nil
-- target URL of the "result" link, or nil
makesexphtml = function (all, funname, help, target)
if all == 1 then return help end -- hack, 2007apr20 (unused)
if all == 2 then return target end -- hack, 2007apr20 (for Tgt)
if help then help = pathto(help) end -- hack, 2019feb20
local raw0, raw1, raw2, raw3 = "(", funname
if string.sub(all, -2, -1) == "\")" then
raw2, raw3 = string.sub(all, 2 + #funname, -3), "\")"
else
raw2, raw3 = string.sub(all, 2 + #funname, -2), ")"
end
return raw0 .. href(help, raw1) .. Q(raw2) .. href(target, raw3)
end
--------[ maketarget, makelocaltarget ]--------
-- «maketarget» (to ".maketarget")
-- "maketarget" and "makelocaltarget" add a suffix (usually ".html")
-- when the base url that they receive is not a directory, and add a
-- "#tag" when their "tag" argument is not nil.
maketarget = function (baseurl, suffix, tag)
local url = baseurl
if suffix and not isdir(baseurl) then
url = url .. suffix
end
if not null(tag) then
url = url .. "#" .. tag
end
return url
end
makelocaltarget = function (base, fname, suffix, tag)
if fname then return maketarget(pathto(base..fname), suffix, tag) end
end
--------[ Relative links ]--------
-- «relative-links» (to ".relative-links")
-- A link from
-- "http://anggtwu.net/foo/bar/plic.html" to
-- "http://anggtwu.net/ploc/bletch.html" should be relative:
-- "../../ploc/bletch.html".
-- For simplicity, a link from
-- "http://anggtwu.net/foo/bar/plic.html" to
-- "http://anggtwu.net/foo/blop.html" is relativized as
-- "../../foo/blop.html", not as
-- "../blop.html".
-- My current convention is that I always run blogme3.lua from the
-- "root of the output tree"; to generate
-- http://anggtwu.net/foo/bar/plic.html
-- I run something like, say,
-- blogme3.lua -o foo/bar/plic.html -i ~/PAGESRC/foo/bar/plic.blogme
-- from the directory "~/PAGE" or "/var/www/"...
-- The function "getpathtoroot" can be used to set pathtoroot from the
-- argument to "-o" - see blogme3.lua.
pathtoroot = ""
pathto = function (path) return pathtoroot .. path end
getpathtoroot = function (path)
local _, nslashes = string.gsub(path, "/", "/")
return string.rep("../", nslashes)
end
--------[ _E_localanchor and friends ]--------
-- «_E» (to "._E")
-- The functions in the table "_E" have signatures like
-- "all,funname,qarg1,qarg2|->html"; here we define some of these
-- functions, using "makesexphtml" and "maketarget"/"makelocaltarget"
-- to do most of the work. We avoid using closures in _E because the
-- code with them would be a bit harder to debug (and to explain...) -
-- instead we use three extra tables, _EHELP, _EBASE, and _ESUFFIX.
-- The values in _EBASE are interpreted differently by different
-- "_E_kindoflink" functions.
--
-- An example: when I generate the pages at angg I have this:
-- _E ["find-eev"] = _E_localanchor
-- _EHELP ["find-eev"] = eevarticle.."#shorter-hyperlinks"
-- _EBASE ["find-eev"] = "eev-current/"
-- _ESUFFIX["find-eev"] = ".html"
-- and to produce the html for a link like
--
-- (find-eev "eev-mini.el" "ee-code-c-d")
--
-- the function "_E_localanchor" first "dequotes" its arguments qarg1
-- and qarg2 - that are [["eev-mini.el"]] and [["ee-code-c-d"]] - to
-- remove the outer double-quotes from them. The results of the
-- dequoting become the "fname" and the "tag" in the diagram below;
-- they would be nil if the function "dequote" had received arguments
-- that were not double-quoted strings. The values of "help", "base",
-- and "suffix" are obtained from the entries for the funname
-- ("find-eev", in this case) in the tables _EHELP, _EBASE, and
-- _ESUFFIX. The first "}->" with four inputs and one output is
-- "makelocaltarget", the second is "makesexphtml".
--
-- Diagram from "_E_localanchor":
-- all \
-- funname |---> sexphtml
-- funname --_HELP-------------------> help |
-- funname --_EBASE-----> base \---> target /
-- \ fname |
-- --_ESUFFIX---> suffix |
-- tag /
--
-- The other "_E_kindoflink" functions are similar, but simpler.
_E = _E or {}
_EBASE = _EBASE or {}
_ESUFFIX = _ESUFFIX or {}
_EHELP = _EHELP or {}
_Es = _Es or {}
-- eevarticle = pathto("eev-article.html")
_E_localanchor = function (all, funname, qfname, qtag)
local fname, tag = dequote(qfname), dequote(qtag)
return makesexphtml(all, funname, _EHELP[funname],
makelocaltarget(_EBASE[funname], fname, _ESUFFIX[funname], tag))
end
_E_localfile = function (all, funname, qfname)
local fname = dequote(qfname)
return makesexphtml(all, funname, _EHELP[funname],
makelocaltarget(_EBASE[funname], fname, _ESUFFIX[funname]))
end
_E_remoteanchor = function (all, funname, qfname, qtag)
local fname, tag = dequote(qfname), dequote(qtag)
if fname == nil then PP(all, funname, qfname, qtag) end
return makesexphtml(all, funname, _EHELP[funname],
maketarget(_EBASE[funname]..fname, _ESUFFIX[funname], tag))
end
_E_remotefile = function (all, funname, qfname)
local fname = dequote(qfname)
return makesexphtml(all, funname, _EHELP[funname],
maketarget(_EBASE[funname]..fname, _ESUFFIX[funname]))
end
_E_helponly = function (all, funname)
return makesexphtml(all, funname, _EHELP[funname], nil)
end
_E_info = function (all, funname) -- a stub: info links are not working
return makesexphtml(all, funname, _EHELP[funname], nil)
end
-- «_E_intro» (to "._E_intro")
-- Added in 2019feb28
_E_intro = function (all, funname, qarg1, qarg2)
local intro = "eev-intros/"..funname..".html"
local posspec = dequote(qarg1)
local sec = posspec and posspec:match "^(%d[%d%.]*)%. "
local introsec = sec and intro.."#"..sec or intro
return makesexphtml(all, funname, introsec, pathto(introsec))
end
--------[ Tgt ]--------
-- «Tgt» (to ".Tgt")
-- A hack. An example of usage: this block in blogme,
-- [Tgt find-angg ".zshrc" "an_anchor" etc etc]
-- evaluates to the target link of this sexp:
-- (find-angg ".zshrc" "an_anchor")
_A["Tgt"] = _AA["4"]
_G["Tgt"] = function (funname, qarg1, qarg2, rest)
if not _E[funname] then error(format("Tgt: not in _E: %q", funname)) end
return _E[funname](2, funname, qarg1, qarg2) or
error(format("Tgt: empty target for (%s %s %s)", funname,
qarg1 or "nil", qarg2 or "nil"))
end
-- «TGT» (to ".TGT")
-- 2007jul24: TGT is more natural to use than Tgt...
-- Example: [TGT (find-enode "M-x")]
def [[ ONESPACE 1 body string.gsub(body, "%s+", " ") ]]
-- def [[ TGT 1 sexp Tgt(string.match(ONESPACE(sexp), "^%(([^%s]+) (.*)%)$")) ]]
-- 2007sep29: (find-es "blogme" "_TARGETS" "SexpLink:match")
-- the definition of TGT above is a hack that will not work always...
-- When we need a "full TGT" we need to replace it like this:
require "escripts"
def [[ TGT 1 sexp Tgt(SexpLink:match(sexp)) ]]
--------[ code_c_d ]--------
-- «set_E4» (to ".set_E4")
-- «set_EHELP» (to ".set_EHELP")
-- Functions to set many entries in the _Exxx tables at once.
-- The top-level syntax - code_c_d_anchor(c, d) - is similar to the
-- one that I use to define many hyperlink functions at once in elisp.
-- Example:
-- code_c_d_anchor("eev", "eev-current/")
-- works as this:
-- _E ["find-eev"] = _E_localanchor
-- _EHELP ["find-eev"] = eevarticle.."#anchors"
-- _EBASE ["find-eev"] = "eev-current/"
-- _ESUFFIX["find-eev"] = ".html"
-- _E ["find-eevfile"] = _E_localfile
-- _EHELP ["find-eevfile"] = eevarticle.."#long"
-- _EBASE ["find-eevfile"] = "eev-current/"
-- _ESUFFIX["find-eevfile"] = ""
set_E4 = function (funname, _e, _ehelp, _ebase, _esuffix)
_E [funname] = _e
_EHELP [funname] = _ehelp
_EBASE [funname] = _ebase
_ESUFFIX[funname] = _esuffix
table.insert(_Es, funname)
end
set_EHELP = function (funname, help) -- set only _E and _EHELP
set_E4(funname, _E_helponly, help) -- base and suffix are nil
end
--------[ code_c_d_local and code_c_d_remote ]--------
-- «code_c_d_local» (to ".code_c_d_local")
-- «code_c_d_remote» (to ".code_c_d_remote")
-- (find-blogme3 "angglisp.lua" "code_c_d_angg")
-- (find-eev-quick-intro "9. Shorter hyperlinks")
code_c_d_local = function (c, d)
-- local h = eevarticle.."#shorter-hyperlinks"
-- local h = eevintro "code-c-d"
local h = "eev-intros/find-eev-quick-intro.html#9"
set_E4("find-"..c.."file", _E_localfile, h, d, "")
set_E4("find-"..c, _E_localanchor, h, d, ".html")
set_E4("find-"..c.."w3m", _E_localfile, h, d, "")
end
code_c_d_remote = function (c, d)
-- local h = eevarticle.."#shorter-hyperlinks"
-- local h = eevintro "code-c-d"
local h = "eev-intros/find-eev-quick-intro.html#9"
set_E4("find-"..c.."file", _E_remotefile, h, d, "")
set_E4("find-"..c, _E_remoteanchor, h, d, ".html")
set_E4("find-"..c.."w3m", _E_remotefile, h, d, "")
end
--------[ Dump the four _E tables ]--------
-- «_E4s_as_lua» (to "._E4s_as_lua")
-- (find-blogme3file "definers.lua" "def_as_lua =")
_E4_as_lua = function (funname)
if not f2n then f2n = preparef2n() end
local _e = _E [funname]
local _ehelp = _EHELP [funname]
local _ebase = _EBASE [funname]
local _esuffix = _ESUFFIX[funname]
local _ename = f2n and f2n[_e] or mytostring(_e)
return format([[
_E [%q] = %s
_EHELP [%q] = %q
_EBASE [%q] = %q
_ESUFFIX[%q] = %q
]], funname, _ename,
funname, _ehelp,
funname, _ebase,
funname, _esuffix)
end
_E4s_as_lua = function ()
return table.concat(map(_E4_as_lua, _Es), "\n")
end
--------[ Elisp hyperlinks that are not angg-specific ]--------
-- _EHELP["to"] = eevarticle.."#anchors"
-- _E ["to"] = function (all, funname, qtag)
-- local tag = dequote(qtag)
-- return makesexphtml(all, funname, eevarticle.."#anchors", tag and "#"..tag)
-- end