So you have a super-long, nifty speedwalk that you included comments in. You want to be able to get at your comments in your Lua script.
GetMapperItem can retrieve your comments for you, but there's no SetMappingString. So you can't load your saved speedwalk into the Mapper.
EvaluateSpeedwalk strips the comments out.
What can ya do?
function SplitSpeedwalk(speedwalk)
lpeg.locale(lpeg)
local P, C, Cs, V, Ct, Cg, S, Cc = lpeg.P, lpeg.C, lpeg.Cs, lpeg.V, lpeg.Ct, lpeg.Cg, lpeg.S, lpeg.Cc
local digit, space = lpeg.digit, lpeg.space
local function ExpandCounter (repeated, cmd)
local tmp = {}
repeated = math.max(1,tonumber(repeated))
for i = 1,repeated do
tmp[#tmp+1] = cmd
end
return unpack(tmp)
end
local function er (c, i, lvl)
error(string.format("Bad Speedwalk character near '%s' at position %d", c:sub(i, i), i) , 4 )
end
local SWdirs = {n = "north", s = "south", e = "east", w = "west",
u = "up", d = "down", f= GetInfo(19), }
local Macros = {L = "lock ", O = "open ", C = "close ", K = "unlock ",}
local tmp = {}
for k,_ in pairs(SWdirs) do
SWdirs[k:upper()] = SWdirs[k]
tmp[#tmp+1] = k
tmp[#tmp+1] = k:upper()
end
local DirChars = table.concat(tmp)
tmp = nil
local function SWmacros (x,y)
return Macros[x] .. y
end
local
SpeedWalk = P{"grammar",
grammar = Ct( ( V"comment" + -- Capture to a table: {a comment} or
V"action" + -- an action like LW or
V"repeatable" + -- a dir that might have a #: 2w 3(jump) e or
space^1 )^0) -- ignore white space, 0 or more captures.
* (-1 + P(er)), -- match to end of string or error.
comment = C(P"{" * (1-P"}")^1 * P"}"), -- PCRE: (\{[^\}]+\})
counter = C(digit^1) + Cc(1) , -- match a number or default to 1
special = P"(" * C( (1- P")" )^1) * P")", -- PCRE: \(([^\)]+)\)
action = Cg( C(S"LOCK") * V"dir")/SWmacros, -- string.gsub(s, "([LOCK])([nsewudfNSEWUDF])", SWMacros) -- kinda
dir = Cs(S(DirChars) / SWdirs), -- string.gsub(s, "([nsewudfNSEWUDF])", SWdirs)
repeatable = Cg( V"counter" * space^0 * -- similar to string.gsub(s, "(%d+)%s*([nse...])", ExpandCounter)
( V"special" + V"dir" )) / ExpandCounter, -- but V"counter" is a lot more complex than (%d) :)
}
return SpeedWalk:match(speedwalk)
end
This returns a table of the evaluated speedwalk, with comments still included. It is meant to replicate the behavior of GetMappingItem, not Evaluate Speedwalk. Speedwalks with special directions (forward/backward) will be parsed as "forward/backward", not just "forward".
**This has been modified after Erendir's post. I don't see a reason to save bad code for posterity. :) |