|
Warning: this is an htmlized version!
The original is here, 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
end
end
return longest, pt[longest] -- return the best match and its "expansion"
end
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
end
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!
end
return str:sub(i) -- or all the rest of the string.
end
-- (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
end
pt[abbrev] = expansion
end
addabbrevs = function (...)
local arg = {...}
for i=1,#arg,2 do
addabbrev(arg[i], arg[i+1])
end
end
delabbrev = function (abbrev, pt)
(pt or abbrevs)[abbrev] = 0 -- yep!
end
-- dump-to: tests
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "common.lua"
dofile "prefixes.lua"
abbrevs = {}
addabbrevs("a", "<a>", "abc", "<abc>")
PP(abbrevs)
print(unabbrev("ababc"))
--]==]
-- Local Variables:
-- coding: raw-text-unix
-- ee-anchor-format: "«%s»"
-- End: