Module:Names

local m_languages = require("Module:languages") local m_links = require("Module:links") local m_utilities = require("Module:utilities") local m_table = require("Module:table")

local export = {}

local rfind = mw.ustring.find local rmatch = mw.ustring.match local rsubn = mw.ustring.gsub

-- version of rsubn that discards all but the first return value local function rsub(term, foo, bar) local retval = rsubn(term, foo, bar) return retval end

-- Used in category code export.personal_name_types = { "surnames", "given names", "male given names", "female given names", "unisex given names", "diminutives of male given names", "diminutives of female given names", "diminutives of unisex given names", "augmentatives of male given names", "augmentatives of female given names", "augmentatives of unisex given names" }

local function join_terms(terms, include_langname, do_language_link) local links = {} local langnametext for _, term in ipairs(terms) do		if include_langname and not langnametext then langnametext = term.lang:getCanonicalName .. " "		end term.lang = m_languages.getNonEtymological(term.lang) if do_language_link and term.lang:getCode == "en" then link = m_links.language_link(term, nil, true) else link = m_links.full_link(term, nil, true) end table.insert(links, link) end return (langnametext or "") .. m_table.serialCommaJoin(links, {conj = "or"}) end

local function join_names(lang, terms, alts, trs, ts, scs) local term_objs = {} local i = 1 local do_language_link = false if not lang then lang = m_languages.getByCode("en") do_language_link = true end while terms[i] do		table.insert(term_objs, {			lang = lang, term = terms[i], alt = alts[i], tr = trs[i], gloss = ts[i],			sc = scs[i] and require("Module:scripts").getByCode(scs[i], "error if invalid"),		}) i = i + 1 end return join_terms(term_objs, nil, do_language_link), #term_objs end

local function get_eqtext(args) local eqsegs = {} local i = 1 local lastlang = nil local last_eqseg = {} while args.eq[i] do		local eqlang, eqterm = rmatch(args.eq[i], "^(.-):(.*)$") if not eqlang then eqlang = "en" eqterm = args.eq[i] end if lastlang and lastlang ~= eqlang then if #last_eqseg > 0 then table.insert(eqsegs, last_eqseg) end last_eqseg = {} end lastlang = eqlang table.insert(last_eqseg, {			lang = m_languages.getByCode(eqlang, "eq" .. (i == 1 and "" or i), "allow etym lang"),			term = eqterm,			alt = args.eqalt[i],			tr = args.eqtr[i],			gloss = args.eqt[i],			sc = args.eqsc[i] and require("Module:scripts").getByCode(args.eqsc[i], "error if invalid"),		}) i = i + 1 end if #last_eqseg > 0 then table.insert(eqsegs, last_eqseg) end local eqtextsegs = {} for _, eqseg in ipairs(eqsegs) do		table.insert(eqtextsegs, join_terms(eqseg, "include langname")) end return m_table.serialCommaJoin(eqtextsegs) end

local function get_fromtext(args) local fromsegs = {} local i = 1 local last_fromseg = nil while args.from[i] do		local from = args.from[i] local prefix, suffix if from == "surnames" then prefix = "transferred from the " suffix = "surname" elseif from == "place names" then prefix = "transferred from the " suffix = "place name" elseif from == "coinages" then prefix = "originating as " suffix = "a coinage" else prefix = "from " local fromlang, fromterm = rmatch(from, "^(.-):(.*)$") if fromlang then fromlang = m_languages.getByCode(fromlang, "from" .. (i == 1 and "" or i), "allow etym lang") suffix = fromlang:getCanonicalName .. " " .. m_links.full_link({					lang = m_languages.getNonEtymological(fromlang),					term = fromterm,					alt = args.fromalt[i],					tr = args.fromtr[i],					gloss = args.fromt[i],					pos = args.frompos[i],					lit = args.fromlit[i],					id = args.fromid[i],					sc = args.fromsc[i] and require("Module:scripts").getByCode(args.fromsc[i], "error if invalid"),				}, nil, true) elseif rfind(from, " languages$") then suffix = "the " .. from else suffix = from end end if last_fromseg and last_fromseg.prefix ~= prefix then table.insert(fromsegs, last_fromseg) last_fromseg = nil end if not last_fromseg then last_fromseg = {prefix = prefix, suffixes = {}} end table.insert(last_fromseg.suffixes, suffix) i = i + 1 end table.insert(fromsegs, last_fromseg) local fromtextsegs = {} for _, fromseg in ipairs(fromsegs) do table.insert(fromtextsegs, fromseg.prefix ..			m_table.serialCommaJoin(fromseg.suffixes, {conj = "or"})) end return m_table.serialCommaJoin(fromtextsegs, {conj = "or"}) end

-- The main entry point. function export.given_name(frame) local parent_args = frame:getParent.args local compat = parent_args.lang local offset = compat and 0 or 1

local function track(page) require("Module:debug").track("given name/" .. page) end

local params = { [compat and "lang" or 1] = { required = true }, ["gender"] = { default = "unknown-gender" }, [1 + offset] = { alias_of = "gender", default = "unknown-gender" }, -- second gender ["or"] = {}, ["from"] = { list = true }, [2 + offset] = { alias_of = from, list = true }, ["fromt"] = { list = "from=t", allow_holes = true }, ["fromalt"] = { list = "from=alt", allow_holes = true }, ["fromtr"] = { list = "from=tr", allow_holes = true }, ["frompos"] = { list = "from=pos", allow_holes = true }, ["fromlit"] = { list = "from=lit", allow_holes = true }, ["fromid"] = { list = "from=id", allow_holes = true }, ["fromsc"] = { list = "from=sc", allow_holes = true }, ["usage"] = {}, ["meaning"] = { list = true }, ["dim"] = { list = true }, ["dimalt"] = { list = "dim=alt", allow_holes = true }, ["dimtr"] = { list = "dim=tr", allow_holes = true }, ["dimt"] = { list = "dim=t", allow_holes = true }, ["dimsc"] = { list = "dim=sc", allow_holes = true }, ["diminutive"] = { list = true, alias_of = "dim" }, ["diminutivealt"] = { list = "diminutive=alt", alias_of = "dimalt", allow_holes = true }, ["diminutivetr"] = { list = "diminutive=tr", alias_of = "dimtr", allow_holes = true }, ["diminutivet"] = { list = "diminutive=t", alias_of = "dimt", allow_holes = true }, ["diminutivesc"] = { list = "diminutive=sc", alias_of = "dimsc", allow_holes = true }, ["eq"] = { list = true }, ["eqalt"] = { list = "eq=alt", allow_holes = true }, ["eqtr"] = { list = "eq=tr", allow_holes = true }, ["eqt"] = { list = "eq=t", allow_holes = true }, ["eqsc"] = { list = "eq=sc", allow_holes = true }, ["xlit"] = { list = true }, ["xlitalt"] = { list = "xlit=alt", allow_holes = true }, ["var"] = { list = true }, ["varalt"] = { list = "var=alt", allow_holes = true }, ["vartr"] = { list = "var=tr", allow_holes = true }, ["vart"] = { list = "var=t", allow_holes = true }, ["varsc"] = { list = "var=sc", allow_holes = true }, ["m"] = { list = true }, ["malt"] = { list = "m=alt", allow_holes = true }, ["mtr"] = { list = "m=tr", allow_holes = true }, ["mt"] = { list = "m=t", allow_holes = true }, ["msc"] = { list = "m=sc", allow_holes = true }, ["f"] = { list = true }, ["falt"] = { list = "f=alt", allow_holes = true }, ["ftr"] = { list = "f=tr", allow_holes = true }, ["ft"] = { list = "f=t", allow_holes = true }, ["fsc"] = { list = "f=sc", allow_holes = true }, -- initial article: A or An		["A"] = {}, ["sort"] = {}, ["dimtype"] = {}, }	local args = require("Module:parameters").process(parent_args, params) local textsegs = {} local lang = args[compat and "lang" or 1] if not lang and mw.title.getCurrentTitle.nsText == "Template" then lang = "und" end lang = lang and m_languages.getByCode(lang, compat and "lang" or 1)

local dimtext, numdims = join_names(lang, args.dim, args.dimalt, args.dimtr, args.dimt, args.dimsc) local xlittext = join_names(nil, args.xlit, args.xlitalt, {}, {}, {}) local vartext = join_names(lang, args.var, args.varalt, args.vartr, args.vart, args.varsc) local mtext = join_names(lang, args.m, args.malt, args.mtr, args.mt, args.msc) local ftext = join_names(lang, args.f, args.falt, args.ftr, args.ft, args.fsc) local meaningsegs = {} for _, meaning in ipairs(args.meaning) do table.insert(meaningsegs, '"' .. meaning .. '"') end local meaningtext = m_table.serialCommaJoin(meaningsegs, {conj = "or"})

local eqtext = get_eqtext(args)

table.insert(textsegs, " ") local dimtype = args.dimtype local article = args.A or		dimtype and rfind(dimtype, "^[aeiouAEIOU]") and "An" or		args.gender == "unknown-gender" and "An" or		"A"

table.insert(textsegs, article .. " ") if numdims > 0 then table.insert(textsegs,			(dimtype and dimtype .. " " or "") ..			"diminutive" ..			(xlittext ~= "" and ", " .. xlittext .. "," or "") ..			" of the ") end local genders = {} table.insert(genders, args.gender) table.insert(genders, args["or"]) table.insert(textsegs, table.concat(genders, " or ") .. " ") table.insert(textsegs, numdims > 1 and "given names" or		"given name") local need_comma = false if numdims > 0 then table.insert(textsegs, " " .. dimtext) need_comma = true elseif xlittext ~= "" then table.insert(textsegs, ", " .. xlittext) need_comma = true end if #args.from > 0 then if need_comma then table.insert(textsegs, ",") end need_comma = true table.insert(textsegs, " ") table.insert(textsegs, get_fromtext(args)) end if meaningtext ~= "" then if need_comma then table.insert(textsegs, ",") end need_comma = true table.insert(textsegs, " meaning " .. meaningtext) end if args.usage then if need_comma then table.insert(textsegs, ",") end need_comma = true table.insert(textsegs, " of " .. args.usage .. " usage") end if vartext ~= "" then table.insert(textsegs, ", variant of " .. vartext) end if mtext ~= "" then table.insert(textsegs, ", masculine equivalent " .. mtext) end if ftext ~= "" then table.insert(textsegs, ", feminine equivalent " .. ftext) end if eqtext ~= "" then table.insert(textsegs, ", equivalent to " .. eqtext) end table.insert(textsegs, " ")

local categories = {} local langname = lang:getCanonicalName .. " "	local function insert_cats(isdim) if isdim == "" then -- No category such as "English diminutives of given names" table.insert(categories, langname .. isdim .. "given names") end local function insert_cats_gender(g) if g == "unknown-gender" then track("unknown gender") return end if g ~= "male" and g ~= "female" and g ~= "unisex" then error("Unrecognized gender: " .. g)			end if g == "unisex" then insert_cats_gender("male") insert_cats_gender("female") end table.insert(categories, langname .. isdim .. g .. " given names") for i, from in ipairs(args.from) do				local fromcatform local fromlang, fromterm = rmatch(from, "^(.-):(.*)$") if fromlang then fromcatform = m_languages.getByCode(fromlang, "from" .. (i == 1 and "" or i), "allow etym lang"):getCanonicalName elseif from == "surnames" or from == "place names" or from == "coinages" then fromcatform = from else local family = rmatch(from, "^(.*) languages$") if family then if require("Module:families").getByCanonicalName(family) then fromcatform = from end elseif m_languages.getByCanonicalName(from, nil, "allow etym") then fromcatform = from end end if fromcatform then table.insert(categories, langname .. isdim .. g .. " given names from " .. fromcatform) else track("unrecognized from") track("unrecognized from/" .. from) end end end insert_cats_gender(args.gender) if args["or"] then insert_cats_gender(args["or"]) end end insert_cats("") if numdims > 0 then insert_cats("diminutives of ") end

return table.concat(textsegs, "") .. m_utilities.format_categories(categories, lang, args.sort) end

return export