Module:letters

local export = {}

local m_parameters = require("Module:parameters") local m_languages = require("Module:languages") local m_links = require("Module:links") local m_scripts = require("Module:scripts") local m_script_utils = require("Module:script utilities") local data = mw.loadData("Module:letters/data")

-- Copied from Module:links/templates (function: export.l_term_t), and adapted. local function link(term, lang, sc, face) -- Forward the information to full_link return m_links.full_link( { term = term, lang = lang, sc = sc, tr = "" }, face) end

local function linkNoTag(term, lang) return m_links.language_link{ term = term, lang = lang } end

local function tag(term, lang, sc) return m_script_utils.tag_text(term, lang, sc) end

--The main function, that returns the formatted list of letters. function export.letters(frame) local args = frame:getParent.args local fullpagename = mw.title.getCurrentTitle.fullText if fullpagename:sub(1, 16) ~= "Appendix:Letters" then return export.letters2(frame) end

-- The variable "result" is going to contain the end text. local result = {}

-- l = the language code, such as "en" for English local l = args[1] local langObject = m_languages.getByCode(l) or m_languages.err(l, 1) local langName = langObject:getCanonicalName

-- sc = the script code, such as "Latn" for Latin local sc = args["sc"] or nil local scObject = nil local scName = nil

-- The first categories. table.insert(result, "") table.insert(result, "")

-- The beginning of the result text, a link to the script appendix between parentheses. if sc then scObject = m_scripts.getByCode(sc) scName = scObject:getCanonicalName

table.insert(result, "(" .. scName .. " script) ") table.insert(result, "") else table.insert(result, "(? script) ") end

-- colonArgs and numberedArgs are going to be filled below. local colonArgs = {} local numberedArgs = {}

-- k = key, it is the key to "v" -- v = value, each argument given in Template:letters for k, v in pairs(args) do

-- It does not contain "sc=", which is a named argument. -- The argument "1" is not added in numberedArgs. It is the language code. if mw.ustring.find(v, ":", 1, true) then table.insert(colonArgs, args[k]) elseif tonumber(k) ~= nil and k ~= 1 then table.insert(numberedArgs, args[k]) end end

-- kk = key, it is the key to "vv" -- vv = value, each numbered argument, like "Aa", "Bb", "Cc" for kk, vv in pairs(numberedArgs) do		if kk ~= 1 then table.insert(result, ", ") end

-- currentLetter = a single value like "Aa" local currentLetter = numberedArgs[kk]

-- About "letterCases": -- If currentLetter contains "[" (as in: Aa), letterCases is a table with only the currentLetter. -- Otherwise, letterCases is a table with each letter, unformatted. local letterCases = {} if mw.ustring.find(currentLetter, "[", 1, true) or mw.ustring.find(currentLetter, "<", 1, true) then letterCases[1] = currentLetter else for i=1, mw.ustring.len(currentLetter) do				letterCases[i] = mw.ustring.sub(currentLetter, i, i)			end end

-- kkk = key, it is the key to "vvv" -- vvv = value, each letter in letterCases for kkk, vvv in pairs(letterCases) do

-- Formats with "link" each letter in letterCases. -- The result is added in the "result" text. table.insert(result, link(letterCases[kkk], langObject, scObject))

end

-- Adds the letter category, like. table.insert(result, "") end

-- kkkk = key, it is the key to "vvvv" -- vvvv = value, it is the value, as in "Aa:⠁" for kkkk, vvvv in pairs(colonArgs) do

if kkkk ~= 1 then table.insert(result, ", ") end

local equalSignSplit = mw.text.split (vvvv, ": ", true) local partOne = equalSignSplit[1] local partTwo = equalSignSplit[2]

-- The result is added in the "result" text. table.insert(result, "" .. partOne .. "" .. ": " .. link(partTwo, langObject, scObject))

-- Adds the letter category, like. table.insert(result, "")

end

return table.concat(result) end

--Returns the list of letter names. function export.letterNames(frame) local namespace = mw.title.getCurrentTitle.nsText if namespace ~= "Appendix" then return export.letterNames2(frame) end local args = frame:getParent.args local colonArgs = {}

-- The variable "result" is going to contain the end text. local result = {}

-- sc = the script code, such as "Latn" for Latin local sc = args["sc"] or nil

-- l = the language code, such as "en" for English local l = args[1] local langObject = m_languages.getByCode(l) or m_languages.err(l, 1)

for k, v in pairs(args) do		if mw.ustring.find(v, ":", 1, true) then table.insert(colonArgs, args[k]) end end

-- k = key, it is the key to "v" -- v = value, it is the value, as in "Bb: bee" for k, v in pairs(colonArgs) do

if k ~= 1 then table.insert(result, ", ") end

local equalSignSplit = mw.text.split (v, ": ", true) local partOne = equalSignSplit[1] local partTwo = equalSignSplit[2]

-- The result is added in the "result" text. table.insert(result, "" .. partOne .. "" .. ": " .. link(partTwo, langObject, scObject))

end

return table.concat(result) end

local function qualifier(content) if content then return ' ( '		.. ' '		.. content .. ' '		.. ' ) ' end end

function export.letters2(frame) local output, list, categories = {}, {}, {} local namespace = mw.title.getCurrentTitle.nsText local params = { [1] = { list = true }, ["native name"] = {}, ["lang"] = { required = true }, ["sc"] = {}, ["qual"] = {}, }	local args = m_parameters.process(frame:getParent.args, params) local lang = m_languages.getByCode(args.lang) or m_languages.err(args.lang, "lang") local langName = lang:getCanonicalName local sc = m_scripts.getByCode(args.sc) or lang:findBestScript(text) or error("Script could not be identified.") local scName = sc:getCanonicalName local scCode = sc:getCode local data = data.list[args.lang] and data.list[args.lang][args.sc] and data.list[args.lang][args.sc] or data local qualifierContent = args.qual or '' .. scName .. '-script letters' table.insert(		output,		qualifier(qualifierContent)		) local native_name = data.native_name or args["native name"] if native_name then native_name = link(native_name, lang, sc, "bold") table.insert(output, native_name .. "; ") end if data.letters then for i,v in ipairs(data.letters) do table.insert(list, link(v[1], lang, sc) .. " " .. link(v[2], lang, sc)) end else for i, letterParameter in ipairs(args[1]) do			if scCode == "Latn" then --	If script is Latin, no transliteration is needed, so language span						is applied to whole list, and individual list items are linked and not language-tagged. local open_par, uppercase, lowercase, close_par if mw.ustring.find(letterParameter, "/") then open_par, uppercase, lowercase, close_par = mw.ustring.match(letterParameter, "(%(?)([^/]+)/([^%)]+)(%)?)")				elseif mw.ustring.find(letterParameter, "%u.*%l") then					open_par, uppercase, lowercase, close_par = mw.ustring.match(letterParameter, "^(%(?)(%u)(%l)(%)?)$")				else					open_par, letters, close_par = mw.ustring.match(letterParameter, "^(%(?)([^%(%)]+)(%)?)$")				end				if open_par and close_par then					if uppercase and lowercase then							uppercase, lowercase = linkNoTag(uppercase, lang, sc), linkNoTag(lowercase, lang, sc)						table.insert(list, open_par .. uppercase .. " " .. lowercase .. close_par)					elseif letters then						letters = linkNoTag(letters, lang, sc)						table.insert(list, open_par .. letters .. close_par)					end				else					letterParameter = linkNoTag(letterParameter, lang, sc)					table.insert(list, letterParameter)				end			else				--	If script is non-Latin, add transliteration to						and tag each item on the list individually.						local letters = {}				local uppercase, lowercase				local open_par, letterParameter, close_par = mw.ustring.match(letterParameter, "(%(?%s*)([^%)]+)(%s*%)?)") if mw.ustring.find(letterParameter, "/") then uppercase, lowercase = mw.ustring.match(letterParameter, "([^/]+)/(.+)") uppercase = "" .. uppercase .. "" lowercase = "" .. lowercase .. "" elseif mw.ustring.find(letterParameter, "^%*.") then letters = { "" .. mw.ustring.gsub(letterParameter, "^*", "") .. "" } else for letter in mw.ustring.gmatch(letterParameter, ".") do table.insert(letters, "" .. letter .. "") end end if uppercase and lowercase then letters = open_par .. link(uppercase .. " " .. lowercase, lang, sc) .. close_par elseif letters then letters = table.concat(letters, " ") letters = open_par .. link(letters, lang, sc) .. close_par end table.insert(list, letters) end end end if namespace == "Template" then table.insert(categories, "") table.insert(categories, "") end

list = table.concat(list, ", ") list = mw.ustring.gsub(list, "%), %(", ", ") list = mw.ustring.gsub(list, ", %(", " (") --	Add language tagging to whole list for Latin script,			because individual letters were not tagged. if scCode == "Latn" then list = tag(list, lang, sc) end table.insert(output, list) return table.concat(output) .. table.concat(categories) end

function export.letterNames2(frame) local output, list = {}, {} local namespace = mw.title.getCurrentTitle.nsText local params = { [1] = { list = true, required = true }, ["native name"] = {}, ["lang"] = { required = true }, ["sc"] = {}, ["qual"] = {}, }	local output = {} local args = m_parameters.process(frame:getParent.args, params) local lang = m_languages.getByCode(args.lang) or m_languages.err(args.lang, "lang") local sc = args.sc or "Latn" sc = m_scripts.getByCode(sc) local qualifierContent = args.qual or sc:getCanonicalName .. "-script letter names" table.insert(		output,		qualifier(qualifierContent)		) local native_name = args["native name"] if native_name then native_name = link(native_name, lang, sc, "bold") table.insert(output, native_name .. "; ") end if sc:getCode == "Latn" then local alternative_names for i, letter_name in ipairs(args[1]) do			alternative_names = mw.text.split(letter_name, "%s*/%s*") local letterNames = {} for i, letter_name in ipairs(alternative_names) do				table.insert(letterNames, linkNoTag(letter_name, lang, sc) ) if alternative_names[i + 1] then table.insert(letterNames, " / ") end end table.insert(list, table.concat(letterNames)) end end list = table.concat(list, ", ") table.insert(output, list) return table.concat(output) end

function export.definition(frame) local parameters = { [1] = { list = true }, ["alphabet name"] = {}, ["name"] = {}, ["trans"] = {}, [""] = {},	}	local args = m_parameters.process(frame:getParent.args, parameters) local types = { letter = { text = table.concat { ' ',				'The letter of the  alphabet, ', 'called ', 'and written in the .' },			},		name = { text = table.concat { ' ',				'The name of the letter ', '. ',				},			},		diacritic = {}, ordinal = {}, syllable = {}, }	local lang = m_languages.getByCode(args[1][1]) or m_languages.err(args[1][1], 1) local type = args[1][2] local alphabet_name = args["alphabet name"] if alphabet_name then alphabet_name = " (" .. alphabet_name .. ")" else alphabet_name = "" end local data if type then if types[type] then data = types[type] else error('The type of definition "' .. tostring(type) .. '" is not recognized.') end else error("Select a type of definition using parameter 2: letter, letter name, diacritic, ordinal, or syllable.") end local text = {data.text} if #text > 0 then text.add = function(self, code, item) if self and self[1] then self[1] = mw.ustring.gsub(self[1], "", item) end end text:add("canonical name", lang:getCanonicalName ) text:add("Latin-script", "Latin-script") text:add("alphabet name", alphabet_name) else error('The type "' .. type .. '" does not have text defined.') end return text[1] end

return export