Module:Escape

local escape = { char = function(self, chr, args) args = args or {} local safe = args.safeChr or string.char(13) chr = tostring(chr or '\\') self[1] = ('%s0%%s%s'):format(			('%x%s%s'):format(chr:byte, safe, safe),			('%s%x'):format(safe, chr:byte)		) if not self[self[1]] then self[self[1]] = { char = chr, text = ('%s(.)'):format(chr), undo = self[1]:format'(%d+)' }		end return args.text and self:text(args.text) or args.undo and self:undo(args.undo, chr) or args.kill and self:kill(args.kill) or self end, exec = function(self, text, mode, newEscape) local target = self[self[1] or self:char and self[1]] for v in text:gfind(target[mode]) do			text = text:gsub(				mode == 'text' and					('%s%s'):format(target.char, v:gsub('%W', '%%%1'))					or self[1]:format(v),				mode == 'text' and					self[1]:format(v:byte)					or (newEscape or '') .. v:char			) end return text end, text = function(self, text) return self:exec(type(text) == 'table' and text[1] or text, 'text') end, undo = function(self, text, newEscape) if type(text) == 'table' then text, newEscape = unpack(text) end return self:exec(text, 'undo', newEscape) end, kill = function(self, text, chars, newEscape) if type(text) == 'table' then text, chars, newEscape = unpack(text) end return self:undo(self:text(text):gsub(chars or , ), newEscape) end }

function escape.main(frame) local args, family = {}, {frame:getParent, frame} for f = 1, 2 do		for k, v in pairs(family[f] and family[f].args or {}) do			args[k] = args[k] or v:match('^%s*(.-)%s*$') end end if args.mode == 'char' then return escape:char(args.char or args[2], args) end return escape[args.mode](escape:char(args.char), args) end

return escape