Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
-- elisp2.lua - Support for elisp hyperlinks for Blogme4 (rewritten).
-- The function `trisect_and_split' below identifies, extracts and
-- splits the last sexp in a line - the one that M-e would execute as
-- a sexp hyperlink in Emacs, as in:
--   (find-TH "eev-article" "hyperlinks")
--   (find-TH "eev-article" "forward-and-back")
--
-- The algorithm
-- =============
-- The algorithm - in the function `trisect' - works by determining
-- the "skeleton" of a line, in four steps:
--
--   1) simplify all the backslash-char pairs, replacing each by `__';
--   2) simplify all the strings, replacing each by `"____"';
--   3) extract the last sexp, using a balanced parentheses count;
--   4) simplify its subsexps, replacing each by `(___)'.
--
-- Some of these operations are performed on reversed strings, to let
-- a simple "%b" pattern match the last sexp very quickly. The
-- resulting skeleton has whitespace exactly in the places that
-- separate each element from the next in the top list of the sexp;
-- `trisect_and_split' uses these whitespaces as cues to split the
-- original line at the right places.


--                   
--   ___  ___   ___  
--  / _ \/ _ \ / _ \ 
-- |  __/ (_) | (_) |
--  \___|\___/ \___/ 
--                   
-- require "eoo"  -- (find-blogme4 "eoo.lua")
-- require "eoo"  -- (find-dn5 "eoo.lua")
Class = {
    type   = "Class",
    __call = function (class, o) return setmetatable(o, class) end,
  }
setmetatable(Class, Class)



--  ____                  
-- / ___|  _____  ___ __  
-- \___ \ / _ \ \/ / '_ \ 
--  ___) |  __/>  <| |_) |
-- |____/ \___/_/\_\ .__/ 
--                 |_|    
--
-- The "Sexp" class:
-- Low-level class function and object methods

Sexp = Class {
  type    = "Sexp",
  q    = function (str) return str end,
  href = function (u, t) return u and "(HREF "..u.." "..t..")" or t end,
  simp_backslashes = function (s) return s:gsub("\\.", "__") end,
  simp_quote    = function (s) return '"'..string.rep("_", #s)..'"' end,
  simp_quotes   = function (s) return s:gsub('"([^"]-)"', Sexp.simp_quote) end,
  simp_subsexp  = function (subsexp)
      return "("..string.rep("_", #subsexp-2)..")"
    end,
  simp_subsexps = function (sexpskelin)
      return sexpskelin:gsub("%b()", Sexp.simp_subsexp)
    end,
  trisect = function (line)
      local revskel = Sexp.simp_quotes(Sexp.simp_backslashes(line):reverse())
      local secaps, lekspxes, erp = revskel:match("^([ \t]*)(%b)()(.*)")
      if not secaps then return end
      local pre      = line:sub(1, #erp)
      local sexpskel = lekspxes:reverse()
      local sexp     = line:sub(1+#pre, #pre+#sexpskel)
      local spaces   = secaps:reverse()
      --
      local sexp_in         = sexp:sub(2, -2)
      local sexpskel_in     = sexpskel:sub(2, -2)
      local sexpskelsimp_in = Sexp.simp_subsexps(sexpskel_in)
      local sexpskelsimp    = "("..sexpskelsimp_in..")"
      local subsexps       = {}
      for b,e in sexpskelsimp_in:gmatch("()[^ \t]+()[ \t]*") do
        table.insert(subsexps, sexp_in:sub(b, e-1))
      end
      return Sexp {line=line,
          l=pre, sexp=sexp, r=spaces,
          skel=sexpskel, unpack(subsexps)}
    end,
  __index = {
    strarg = function (sexp, n)
        if sexp[n] then return (sexp[n]:match("^\"(.*)\"$")) end
      end,
    abcd = function (sexp)
        sexp.a, sexp.b, sexp.c, sexp.d =
	  sexp.sexp:match("^(%()([A-Za-z0-9_%-]+)(.-)(\"?%))$")
	return sexp
      end,
  },
}


-- High-level methods and class functions
--
Sexp.__index.sexpurls = function (sexp)
    local head   = sexp[1]
    local stem   = sexp:strarg(2)
    local anchor = sexp:strarg(3)
    local defun  = defuns[head]
    -- PP(91, defun)
    if defun then
      sexp.help   = defun.help   and defun:help()          -- a URL
      sexp.target = defun.target and defun:f(stem, anchor) -- another URL
      -- no overrides yet
    end
    return sexp
  end
Sexp.__index.sexphtml_ = function (sexp, href, q)
    href = href or Sexp.href
    q    = q    or Sexp.q
    sexp:sexpurls()
    if sexp.help or sexp.target then
      sexp:abcd()
      sexp.sexphtml = sexp.a ..
                      href(sexp.help, sexp.b) ..
                      q(sexp.c) ..
                      href(sexp.target, sexp.d)
    end
    return sexp
  end
Sexp.sexphtml = function (line)
      local sexp = Sexp.trisect(line)
      return (sexp and sexp:sexphtml_()) or Sexp {line=line}
    end

Sexp.__index.linehtml = function (sexp, href, q)
    -- PP(117, sexp)
    -- PP(118, sexp.sexphtml)
    href = href or Sexp.href
    q    = q    or Sexp.q
    if sexp.sexphtml then
      sexp.linehtml = q(sexp.l)..sexp.sexphtml..q(sexp.r)
    else
      sexp.linehtml = q(sexp.line)
    end
    return sexp
  end
Sexp.linehtml = function (line)
    local sexp = Sexp.sexphtml(line)
    -- PP(129, sexp)
    return sexp:linehtml().linehtml
  end


--   ___  
--  / _ \ 
-- | | | |
-- | |_| |
--  \__\_\
--        
-- (find-blogme4 "anggdefs.lua" "Q")
Q_re            = "([\001-\008\011-\031&<>\127-\255])"
Q_table         = { ["&"]="&amp;", ["<"]="&lt;", [">"]="&gt;" }
Q_table["\15"]  = "<font color=\"red\"><strong>*</strong></font>"
Q_table["\171"] = "<font color=\"green\"><i>&laquo;</i></font>"
Q_table["\187"] = "<font color=\"green\"><i>&raquo;</i></font>"
Sexp.q    = function (str) return str:gsub(Q_re, Q_table) end
Sexp.href = function (url, text)
    if url
    then return "<a href=\""..url.."\">"..Sexp.q(text).."</a>"
    else return Sexp.q(text)
    end
  end


--  _                    _             
-- | |_ __ _  __ _  __ _(_)_ __   __ _ 
-- | __/ _` |/ _` |/ _` | | '_ \ / _` |
-- | || (_| | (_| | (_| | | | | | (_| |
--  \__\__,_|\__, |\__, |_|_| |_|\__, |
--           |___/ |___/         |___/ 

nsexps = 0
sexp_to_tag = {}
tag_to_sexp = {}
tag_to_html = {}

Sexp.__index.taggedline_ = function (s)
    if s.sexphtml then
      local sexp     = s.sexp
      local sexphtml = s.sexphtml
      local tag      = sexp_to_tag[sexp]
      if tag then
        s.tag = tag   -- recycle tag
      else
	repeat
          nsexps = nsexps + 1
          tag = "sexp"..nsexps.."_"
        until (tag_to_html[tag] == nil)
        s.tag = tag
        sexp_to_tag[sexp] = tag
        tag_to_html[tag]  = sexphtml
      end
      s.taggedline = s.l .. tag .. s.r    
    else
      s.taggedline = s.line
    end
    return s
  end
Sexp.taggedline = function (line)
    return Sexp.sexphtml(line):taggedline_().taggedline
  end

tag_all_lines = function (bigstr)
    return (bigstr:gsub("([^\n]+)", Sexp.taggedline))
  end



--  _     _       _     _ _       _     _   
-- | |__ (_) __ _| |__ | (_) __ _| |__ | |_ 
-- | '_ \| |/ _` | '_ \| | |/ _` | '_ \| __|
-- | | | | | (_| | | | | | | (_| | | | | |_ 
-- |_| |_|_|\__, |_| |_|_|_|\__, |_| |_|\__|
--          |___/           |___/           


tmpdir = "/tmp/highlight/"
highlight = function (fname, lang, out)
    local bigstr, bigstr2, bigstr3, title, qtitle
    local fname_tagged, fname_taggedhtml, fname_html
    local cmd
    qtitle           = "'"..fname.." (htmlized)'"
    fname_tagged     = tmpdir.."1"
    fname_taggedhtml = tmpdir.."1.html"
    fname_html       = out or tmpdir.."2.html"
    bigstr           = readfile(fname)
    bigstr2          = tag_all_lines(bigstr)
    writefile(fname_tagged, bigstr2)
    cmd = "highlight -I -S "..lang..
          " -T "..qtitle..
          " -o "..fname_taggedhtml..
             " "..fname_tagged
    print(cmd)
    print(getoutput(cmd))
    bigstr3 = readfile(fname_taggedhtml)
    bigstr4 = bigstr3:gsub("(sexp[0-9]+_)", tag_to_html)
    writefile(fname_html, bigstr4)
  end



ta = function (line) PP(Sexp.sexphtml(line):linehtml()) end
ta = function (line) print(Sexp.linehtml(line)) end

-- inputfname = "lua50init.lua"


--[==[

* (message (find-sh0 "rm -Rv /tmp/highlight/; mkdir /tmp/highlight/"))
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "elisp2.lua"
highlight("../LUA/lua50init.lua", "lua")
# (find-fline "/tmp/highlight/")

* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
* (message (find-sh0 "cp -v ~/LUA/lua50init.lua /tmp"))
dofile "elisp2.lua"
bigstr  = readfile "/tmp/lua50init.lua"
bigstr2 = tag_all_lines(bigstr)
PP(sexp_to_tag)
PP(tag_to_html)
writefile("/tmp/lua50init_.lua", bigstr2)
-- (find-tkdiff "/tmp/lua50init.lua" "/tmp/lua50init_.lua")
* (message (find-sh0 "highlight -I -o /tmp/lua50init_.lua.html /tmp/lua50init_.lua"))
bigstr3 = readfile "/tmp/lua50init_.lua.html"
bigstr4 = bigstr3:gsub("(sexp[0-9]+_)", tag_to_html)
writefile("/tmp/lua50init.lua.html", bigstr4)


* (message (find-sh0 "rm -Rv /tmp/highlight/; mkdir /tmp/highlight/"))
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "elisp2.lua"
userocks()
chdir "~/eev-current/"
-- PP(getoutput("ls"))
-- PP(getoutput("ls *.el"))
for _,fname in ipairs(split(getoutput("ls *.el"))) do
  print(fname)
  highlight(fname, "el", "/tmp/highlight/"..fname..".html")
end

-- (find-sh "cd ~/eev-current/; ls *.el")
-- (find-angg "LUA/lua50init.lua" "getoutput")
-- (find-fline "/tmp/")
-- (find-fline "/tmp/highlight/")


# (find-man "1 highlight")
# (find-man "1 highlight" "-T, --doc-title")
# (find-man "1 highlight" "-S, --syntax=<type>")
# (find-man "1 highlight" "-p, --list-langs")
# (find-sh "highlight -p")
# (find-sh "highlight -p" " el ")

ta 'foo (find-dn4 "ab" "cd")'
-- (find-es "highlight" "debian-package")
-- (find-fline "~/LUA/lua50init.lua")

PP(defuns)
PP(defuns["find-dn4"])
PP(defuns["find-dn4"]:f("a", "b"))
PP(sorted(keys(defuns)))

tah "foo"
tah 'foo (find-es "ab" "cd")'
ta2 'foo (find-es "ab" "cd")'
ta2 'foo (find-ep "ab" "cd")'
ta2 'foo (find-angg "ab" "cd")'

--]==]


q     = function (str) return str end
qhref = function (u, t) return u and "(HREF "..u.." "..t..")" or t end



--  _        _               _   
-- | |_ _ __(_)___  ___  ___| |_ 
-- | __| '__| / __|/ _ \/ __| __|
-- | |_| |  | \__ \  __/ (__| |_ 
--  \__|_|  |_|___/\___|\___|\__|
--                               

simplify_backslashes = function (s) return s:gsub("\\.", "__") end
simplify_quote_ = function (s) return '"'..string.rep("_", #s)..'"' end
simplify_quotes = function (s) return s:gsub('"([^"]-)"', simplify_quote_) end
simplify_subsexp = function (subsexp)
    return "("..string.rep("_", #subsexp-2)..")"
  end
simplify_subsexps = function (sexpskelin)
    return sexpskelin:gsub("%b()", simplify_subsexp)
  end
trisect = function (line)
    local revskel = simplify_quotes(simplify_backslashes(line):reverse())
    local secaps, lekspxes, erp = revskel:match("^([ \t]*)(%b)()(.*)")
    if not secaps then return end
    local pre      = line:sub(1, #erp)
    local sexpskel = lekspxes:reverse()
    local sexp     = line:sub(1+#pre, #pre+#sexpskel)
    local spaces   = secaps:reverse()
    return pre, sexp, spaces, sexpskel
  end
trisect_and_split = function (line)
    local pre, sexp, spaces, sexpskel = trisect(line)
    if sexp then
      local sexp_in         = sexp:sub(2, -2)
      local sexpskel_in     = sexpskel:sub(2, -2)
      local sexpskelsimp_in = simplify_subsexps(sexpskel_in)
      local sexpskelsimp    = "("..sexpskelsimp_in..")"
      local subsexps       = {}
      local capture = function (b, e)
          subsexps[#subsexps + 1] = sexp_in:sub(b, e-1)
        end
      sexpskelsimp_in:gsub("()[^ \t]+()[ \t]*", capture)
      -- local ret = {l=pre, s=sexp, r=spaces, unpack(subsexps)}
      return pre, sexp, spaces, subsexps, sexpskelsimp
    end
  end
trisect_and_htmlize_ = function (line)
    local pre, sexp, spaces, subsexps, sexpskel = trisect_and_split(line)
    local head     = pre   and subsexps[1]
    local defun    = head  and defuns[head]
    local sexphtml = defun and defun:htmlize(sexp, subsexps, sexpskel)
    return sexphtml        and q(pre)..sexphtml..q(spaces)
  end
trisect_and_htmlize  = function (line)
    return trisect_and_htmlize_(line) or q(line)
  end


--  ____        __             
-- |  _ \  ___ / _|_   _ _ __  
-- | | | |/ _ \ |_| | | | '_ \ 
-- | |_| |  __/  _| |_| | | | |
-- |____/ \___|_|  \__,_|_| |_|
--                             

isdir = function (fname) return fname:sub(-1) == "/" or fname == "" end

defuns = {}

Defun = Class {
  type    = "Defun",
  __index = {
    target_url = function () end,
    help_url   = function () end,
    f          = function (defun, stem, anchor)
        return defun:target_url(stem, anchor)
      end,
    help       = function (defun) return defun:help_url() end,
    target     = function (defun, a, b) return defun:target_url(a, b) end,
    htmlize    = function (defun, sexp, subsexps, sexpskel)
        local a, b, c, d = sexp:match("^(%()([A-Za-z0-9_%-]+)(.-)(\"?%))$")
        if not a then return end
        local help   = defun.help_url
        local stem   = subsexps[2] and subsexps[2]:match("^\"(.*)\"$")
        local anchor = subsexps[3] and subsexps[3]:match("^\"(.*)\"$")
        local target = defun:target_url(stem, anchor)
        local result = a..qhref(help, b)..q(c)..qhref(target, d)
        return result
      end,
  },
}

help_url_   = function (url) return function () return url end end
target_url_ = function (base, _html)
    _html = _html or ".html"
    return function (defun, stem, anchor)
        if     not stem    then return nil
        elseif isdir(stem) then return base..stem
        elseif not anchor  then return base..stem.._html
        else                    return base..stem.._html.."#"..anchor
        end
      end
  end


--                _                          _ 
--   ___ ___   __| | ___        ___       __| |
--  / __/ _ \ / _` |/ _ \_____ / __|____ / _` |
-- | (_| (_) | (_| |  __/_____| (_|_____| (_| |
--  \___\___/ \__,_|\___|      \___|     \__,_|
--                                             

eevarticle = "eev-article.html"
pathto = function (d) return d end

code_c_d_angg = function (c, d)
    defuns["find-"..c.."file"] = Defun {
        help_url   = help_url_(eevarticle.."#shorter-hyperlinks"),
        target_url = target_url_(pathto(d), ""),   --> change to no anchor
      }
    defuns["find-"..c] = Defun {
        help_url = help_url_(eevarticle.."#shorter-hyperlinks"),
        target_url = target_url_(pathto(d), ".html"),
      }
    defuns["find-"..c.."w3m"] = Defun {
        help = eevarticle.."#shorter-hyperlinks",
        target_url = target_url_(pathto(d), ""),   --> change to no anchor
      }
  end

-- (find-blogme3 "angglisp.lua")
-- (find-blogme4 "angglisp.lua")

code_c_d_angg("angg",    "")                  -- (find-angg "blogme4/")
code_c_d_angg("es",      "e/")                -- (find-es "lua5")
code_c_d_angg("dednat4", "dednat4/")          -- (find-dednat4 "")
code_c_d_angg("dn4",     "dednat4/")
code_c_d_angg("dn4ex",   "dednat4/examples/")
code_c_d_angg("dn5",     "dednat5/")
code_c_d_angg("blogme",  "blogme/")
code_c_d_angg("blogme3", "blogme3/")
code_c_d_angg("blogme4", "blogme4/")
code_c_d_angg("eev",     "eev-current/")
code_c_d_angg("flua",    "flua/")
code_c_d_angg("rubyforth", "rubyforth/")
code_c_d_angg("vtutil",  "vtutil/")
code_c_d_angg("vtutil4", "vtutil4/")
code_c_d_angg("RETRO",   "RETRO/")

defuns["find-es"].target_url = target_url_(pathto("e/"), ".e.html")



--  _            _       
-- | |_ ___  ___| |_ ___ 
-- | __/ _ \/ __| __/ __|
-- | ||  __/\__ \ |_\__ \
--  \__\___||___/\__|___/
--                       
trisect_test = function (li)
    local ang = function (s) return "<"..s..">" end
    local pre, sexp, spaces, subsexps, sexpskel = trisect_and_split(li)
    if sexp then
      print(sexp)
      print(sexpskel)
      print("  "..mapconcat(ang, subsexps, " "))
    end
  end
trisect_test_file = function (fname)
    for li in io.lines(fname) do trisect_test(li) end
  end

tah = function (li) print("__", trisect_and_htmlize(li)) end
ta2 = function (li)
    local ht = trisect_and_htmlize_(li)
    if ht then print(li); print(ht) end
  end



--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "elisp2.lua"
tah "foo"
tah 'foo (find-es "ab" "cd")'
ta2 'foo (find-es "ab" "cd")'
ta2 'foo (find-ep "ab" "cd")'
ta2 'foo (find-angg "ab" "cd")'

= string.sub("abcd", -1)
= string.sub("", -1)


defuns["find-es"] = Defun {
  target_url = function (defun, stem, anchor)
      PP("find-es", stem, anchor)
      if stem
      then if anchor
           then return "http://angg.twu.net/e/"..stem..".e.html#"..anchor
           else return "http://angg.twu.net/e/"..stem..".e.html"
           end
      end
    end,
}

defuns["find-angg"] = Defun {
  help_url   = help_url_   "help_angg",
  target_url = target_url_ "http://angg.twu.net/",
}

--]]

--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "elisp2.lua"
trisect_test_file("/home/edrx/ORG/index.org")
test = trisect_test
test [=[ abcd (foo '(bar plic "foo") "bar") ]=]
test [=[ abcd (foo   '(bar plic "foo")   "bar") ]=]
          --> (foo   '(bar plic "foo")   "bar")   <- sexp
          --> (foo   '(______________)   "___")   <- sexp skeleton, simplified
          --> <foo> <'(bar plic "foo")> <"bar">   <- its 3 subsexps

--]]







-- Local Variables:
-- coding:             raw-text-unix
-- ee-anchor-format:   "«%s»"
-- End: