Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
-- prefixes.lua: handle expansions, abbrev tables and tables of prefixes.
-- This file:
--   http://angg.twu.net/dednat5/prefixes.lua.html
--   http://angg.twu.net/dednat5/prefixes.lua
--                    (find-dn5 "prefixes.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
-- Version: 2011apr10
-- License: GPL3

-- «.unabbrev»	(to "unabbrev")

-- (find-dn4 "dednat5.lua" "prefixes-and-ptables")
-- (find-dn4 "dednat5.lua" "heads")
-- (find-dn4 "dednat5.lua" "abbrevs")

-- We have two standard "prefix tables" in dednat5: abbrevs and heads.
-- The way to search for a "longest prefix" is the same in both...
-- Here is an example, to explain both the data structure and the
-- basic algorithm. If we only have two abbreviations, "a"->"<a>" and
-- "abc"->"<abc>", then the table "abbrevs" will be like this:
--   abbrevs = { ["a"]="<a>",
--               ["ab"]=0,
--               ["abc"]="<abc>" }
-- and then:
--   unabbrev("ababc")
-- returns:
--   "<a>b<abc>"
-- To calculate the "unabbreviated form" of the string "ababc" we
-- start at the left, and try to find the longest substring of
-- "ababc", starting at 1, which has an expansion... "a" has an
-- expansion, and "ab" has not; but the table abbrevs has an entry
-- ["ab"]=0, that means "keep trying" - because even though "ab" does
-- not have an expansion, some strings starting with "ab" may have.

abbrevs = {}
longestprefix = function (str, j, pt)
    j  = j  or 1          -- starting position
    pt = pt or abbrevs    -- prefix table
    local longest = nil   -- longest prefix having an expansion
    for k=j,#str do
      local candidate = str:sub(j, k)
      local e = pt[candidate]
      if e == nil then break end   -- if e==nil we can stop
      if e ~= 0 then               -- if e==0 we keep trying
        longest = candidate        -- if e~=nil and e~=0 we record the match
    return longest, pt[longest]    -- return the best match and its "expansion"
findfirstexpansion = function (str, i, pt)
    for j=i,#str do
      local longest, expansion = longestprefix(str, j, pt)
      if longest then return j, longest, expansion end
-- «unabbrev»  (to ".unabbrev")
unabbrev = function (str, i, pt)
    i = i or 1
    local j, longest, expansion = findfirstexpansion(str, i, pt)
    if j then
      return str:sub(i, j-1) ..               -- the unexpandable part, then
             expansion ..                     -- the expansion, then...
             unabbrev(str, j+#longest, pt)    -- recurse!
    return str:sub(i)                         -- or all the rest of the string.

-- (find-dn4 "dednat4.lua" "abbrevs")
addabbrev = function (abbrev, expansion, pt)
    pt = pt or abbrevs
    for i=1,#abbrev-1 do
      local prefix = abbrev:sub(1, i)
      pt[prefix] = pt[prefix] or 0
    pt[abbrev] = expansion
addabbrevs = function (...)
    local arg = {...}
    for i=1,#arg,2 do
      addabbrev(arg[i], arg[i+1])
delabbrev = function (abbrev, pt)
    (pt or abbrevs)[abbrev] = 0    -- yep!

-- dump-to: tests
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "common.lua"
dofile "prefixes.lua"
abbrevs = {}
addabbrevs("a", "<a>", "abc", "<abc>")


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