Module:D'ni Tools
From Guild of Archivists
Documentation for this module may be created at Module:D'ni Tools/doc
--
-- This implements several useful functions for dealing with D'ni text in the Wiki.
--
-- parsed_dni() returns a string in which every component is linked to its appropriate Dictionary namespace entry.
-- dnifont2ots() converts a Dnifont string to an ots one
-- dnifont2nts() converts a Dnifont string to an nts one
local p = {}
local args = {}
local origArgs
local root
local output = ''
-- Local Functions
local function num2dnum(str,sep)
str = str or ''
str = mw.text.trim(str)
if (sep == nil or sep == '') then
sep = "|"
end
local output = "nil"
local num = tonumber(str)
if (num ~= nil and num >= 0) then
output = num % 25
while (num >= 25) do
num = math.floor(num / 25)
output = tostring(num % 25)..sep..output
end
end
return output
end
local function dnum2num(str,sep)
str = str or ''
sep = sep or ''
local output = mw.text.trim(str)
output = mw.ustring.gsub(output,"%d%d", {["24"] = "O",
["23"] = "N",
["22"] = "M",
["21"] = "L",
["20"] = "K",
["19"] = "J",
["18"] = "I",
["17"] = "H",
["16"] = "G",
["15"] = "F",
["14"] = "E",
["13"] = "D",
["12"] = "C",
["11"] = "B",
["10"] = "A"
})
output = mw.ustring.gsub(output,sep,"")
output = tonumber(output,25)
return output
end
local function dnum2dnifont(str,min,use25,useWrap)
str = str or ""
min = min or 0
use25 = use25 or false
useWarp = useWrap or false
local output = mw.text.trim(str)
if str == "25" and use25 then output = "|"
elseif str == "0" and useWrap then output = "="
else
output = mw.ustring.gsub(output,"%d%d", {["24"] = "}",
["23"] = "{",
["22"] = "\\",
["21"] = "]",
["20"] = "[",
["19"] = "(",
["18"] = "*",
["17"] = "&",
["16"] = "^",
["15"] = "%",
["14"] = "$",
["13"] = "#",
["12"] = "@",
["11"] = "!",
["10"] = ")"
})
output = mw.ustring.gsub(output,"%|","")
if #output < min then output = string.rep("0", (min - #output))..output end
end
return output
end
local function dnifont2dnum(str,sep)
str = mw.text.trim(str)
local chars = mw.text.split(str,'')
local output = table.concat(chars,sep)
output = mw.ustring.gsub(output,"%S", {["}"] = "24" ,
["{"] = "23",
["\\"] = "22",
["]"] = "21",
["["] = "20",
["("] = "19",
["*"] = "18",
["&"] = "17",
["^"] = "16",
["%"] = "15",
["$"] = "14",
["#"] = "13",
["@"] = "12",
["!"] = "11",
[")"] = "10"
})
return output
end
local function dnifont2ots(str)
local output = mw.text.trim(str)
output = mw.ustring.gsub(str,"%S", {["S"] = "sh",
["T"] = "th",
["O"] = "oy",
["c"] = "ch",
["a"] = "ah",
["E"] = "ee",
["A"] = "ay",
["u"] = "uh",
["U"] = "oo",
["x"] = "ts",
["d"] = "dh",
["D"] = "d",
["k"] = "kh",
["K"] = "k",
["I"] = "ai",
["å"] = "a",
})
return output
end
local function dnifont2nts(str)
local output = mw.text.trim(str)
output = mw.ustring.gsub(str,"%S", {["S"] = "š",
["T"] = "þ",
["O"] = "ó",
["c"] = "ç",
["E"] = "í",
["A"] = "é",
["U"] = "ú",
["x"] = "c",
["d"] = "ð",
["D"] = "d",
["k"] = "x",
["K"] = "k",
["I"] = "á",
["å"] = "æ",
})
return output
end
local function parseDniWord(input)
local output
local word = mw.text.trim(input)
local first = mw.ustring.sub(word,1,1)
local last = mw.ustring.sub(word,-1,-1)
local prefix = ''
local suffix = ''
if (word == mw.ustring.lower(mw.title.getCurrentTitle().rootText)) then
prefix = '\'\'\''
suffix = prefix
end
if (word == '') then
output = ' '
elseif (word == ' ') then
output = ' '
elseif (word == '.' or word == '?' or word == '!' or word == ',') then
output = first
elseif (first == '-') then
output = prefix..'[[ContainsTerm::Dictionary:'..word..'|'..mw.ustring.sub(word,2,-1)..']]'..suffix
elseif (last == '-') then
output = prefix..'[[ContainsTerm::Dictionary:'..word..'|'..mw.ustring.sub(word,1,-2)..']]'..suffix
elseif (first == '.' or first == '!' or first == '?' or first == ',') then
output = first..prefix..'[[ContainsTerm::Dictionary:'..mw.ustring.sub(word,2,-1)..'|'..mw.ustring.sub(word,2,-1)..']]'..suffix
elseif (last == ',') then
output = prefix..'[[ContainsTerm::Dictionary:'..mw.ustring.sub(word,1,-2)..'|'..mw.ustring.sub(word,1,-2)..']]'..suffix..last
else
output = prefix..'[[ContainsTerm::Dictionary:'..word..'|'..word..']]'..suffix
end
return output
end
local function preprocessSingleArg(argName)
-- If the argument exists and isn't blank, add it to the argument table.
-- Blank arguments are treated as nil to match the behaviour of ParserFunctions.
if origArgs[argName] and origArgs[argName] ~= '' then
args[argName] = origArgs[argName]
end
end
function p.parsed_dni(frame)
-- If called via #invoke, use the args passed into the invoking template.
-- Otherwise, for testing purposes, assume args are being passed directly in.
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
else
origArgs = frame.args
end
for word in ipairs(origArgs) do
output = output..parseDniWord(origArgs[word])
end
output = output..'{{#set:\n ContainsQuote='..output..'}}'
return output
end
-- For call by other Modules
function p._num2dnum(str,sep)
return num2dnum(str,sep)
end
function p._dnum2num(str,sep)
return dnum2num(str,sep)
end
function p._dnum2dnifont(str,min,use25,useWrap)
return dnum2dnifont(str,min,use25,useWrap)
end
function p._dnifont2dnum(str,sep)
return dnifont2dnum(str,sep)
end
function p._num2dnifont(str,min,use25,useWrap)
return dnum2dnifont(num2dnum(str),min,use25,useWrap)
end
function p.dnifont2ots(frame)
return dnifont2ots(frame.args[1])
end
function p.dnifont2nts(frame)
return dnifont2nts(frame.args[1])
end
function p.num2dnum(frame)
-- If called via #invoke, use the args passed into the invoking template.
-- Otherwise, for testing purposes, assume args are being passed directly in.
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
else
origArgs = frame.args
end
preprocessSingleArg(1)
preprocessSingleArg('val')
preprocessSingleArg('format')
preprocessSingleArg('sep')
local output
local val = args['val'] or args[1]
if (args['format'] == 'dnifont') then
output = dnum2dnifont(num2dnum(val))
else
output = num2dnum(val,args['sep'])
end
return output
end
function p.dnifont2dnum(frame)
-- If called via #invoke, use the args passed into the invoking template.
-- Otherwise, for testing purposes, assume args are being passed directly in.
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
else
origArgs = frame.args
end
preprocessSingleArg(1)
preprocessSingleArg('sep')
return dnifont2dnum(args[1],args['sep'])
end
function p.dnum2num(frame)
-- If called via #invoke, use the args passed into the invoking template.
-- Otherwise, for testing purposes, assume args are being passed directly in.
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
else
origArgs = frame.args
end
preprocessSingleArg(1)
preprocessSingleArg('sep')
return dnum2num(args[1],args['sep'])
end
return p