Module:Sandbox/Cousteau/strsubst

local p = {}

-- Usage: --  string: string to parse --  c1, c2...: single characters --  replacement1, replacement2...: what those characters are replaced by --   separator: separator between replacements -- Unknown characters are ignored and may be used for spacing. -- Example: --> dit-daah-daah-dit function p.char(frame) -- Extract separator local sep = '' if frame.args.sep ~= nil then sep = frame.args.sep end -- Extract key-value pairs local tokenlist = {} local i = 2 -- NB: #frame.args doesn't work; iterating the old way while frame.args[i] ~= nil do       if frame.args[i] == '' then -- assume empty = space (but be careful with those) tokenlist[' '] = frame.args[i+1] else tokenlist[frame.args[i] ] = frame.args[i+1] end i = i+2 end --TODO-- check no repeated keys, odd number of args... -- Parse string: replace each matching token by closest match local str = frame.args[1] local res = '' local isfirst = true for i = 1,#str do       local c = str:sub(i,i) -- get i-th character if tokenlist[c] ~= nil then -- if c is a recognized character if isfirst then isfirst = false else res = res .. sep -- add separator (except for the first time) end res = res .. tokenlist[c] end end return res end

-- Usage: --  string: string to parse --  key1, key2...: substrings to replace (one or more characters) --  replacement1, replacement2...: what those substrings are replaced by --   separator: separator between replacements -- If more than one substring matches, the longest one is used. -- If no substring matches, one character is chomped; therefore unknown characters may be used for spacing. -- This function might be more expensive than the .char version. -- Example: --> ./-/-/. function p.str(frame) -- Extract separator local sep = '' if frame.args.sep ~= nil then sep = frame.args.sep end -- Extract key-value pairs local tokenlist = {} local i = 2 -- NB: #frame.args doesn't work; iterating the old way while frame.args[i] ~= nil do       if frame.args[i] == '' then -- assume empty = space (but be careful with those) table.insert(tokenlist, {k=' ', v=frame.args[i+1]}) else table.insert(tokenlist, {k=frame.args[i], v=frame.args[i+1]}) end i = i+2 end --TODO-- check no repeated keys, odd number of args... -- Sort by key length so that longest strings are tried first table.sort(tokenlist, function(a,b) return #a.k > #b.k end) -- Parse string: replace each matching token by closest match local str = frame.args[1] local res = '' local isfirst = true while str ~= '' do       local found = false for _,token in ipairs(tokenlist) do           if str:sub(1, #token.k) == token.k then -- if str begins with substring if isfirst then isfirst = false else res = res .. sep -- add separator (except for the first time) end res = res .. token.v -- append replacement to res str = str:sub(#token.k+1) -- discard that substring found = true break end end if not found then str = str:sub(2) -- discard one character and try again end end return res end

-- [TEST] Print the arguments passed function p.test(frame) local res = '' for k,v in pairs(frame.args) do       res = res .. ' [' .. k .. ']="' .. v .. '"\n' end return res end

return p