Module:names: Difference between revisions
No edit summary |
(this and last edit) support diminutives of classes of names (described using addl=) rather than specific names |
||
| Line 1: | Line 1: | ||
local export = {} | |||
local m_languages = require("Module:languages") | local m_languages = require("Module:languages") | ||
local m_links = require("Module:links") | local m_links = require("Module:links") | ||
local m_utilities = require("Module:utilities") | local m_utilities = require("Module:utilities") | ||
local m_str_utils = require("Module:string utilities") | |||
local m_table = require("Module:table") | local m_table = require("Module:table") | ||
local en_utilities_module = "Module:en-utilities" | |||
local parameter_utilities_module = "Module:parameter utilities" | |||
local parse_interface_module = "Module:parse interface" | |||
local parse_utilities_module = "Module:parse utilities" | |||
local pron_qualifier_module = "Module:pron qualifier" | |||
local | local enlang = m_languages.getByCode("en") | ||
local rsubn = m_str_utils.gsub | |||
local rsplit = m_str_utils.split | |||
local u = m_str_utils.char | |||
local | local function rsub(str, from, to) | ||
return (rsubn(str, from, to)) | |||
end | |||
local | local TEMP_LESS_THAN = u(0xFFF2) | ||
local force_cat = false -- for testing | local force_cat = false -- for testing | ||
-- | --[=[ | ||
FIXME: | |||
1. from=the Bible (DONE) | |||
2. origin=18th century [DONE] | |||
3. popular= (DONE) | |||
4. varoftype= (DONE) | |||
5. eqtype= [DONE] | |||
6. dimoftype= [DONE] | |||
7. from=de:Elisabeth (same language) (DONE) | |||
8. blendof=, blendof2= [DONE] | |||
9. varform, dimform [DONE] | |||
10. from=English < Latin [DONE] | |||
11. usage=rare -> categorize as rare? | |||
12. dimeq= (also vareq=?) [DONE] | |||
13. fromtype= [DONE] | |||
14. <tr:...> and similar params [DONE] | |||
]=] | |||
-- Used in category code | -- Used in category code; name types which are full-word end-matching substrings of longer name types (e.g. "surnames" | ||
-- of "male surnames", but not "male surnames" of "female surnames" because "male" only matches a part of the word | |||
-- "female") should follow the longer name. | |||
export.personal_name_types = { | export.personal_name_types = { | ||
"surnames | "male surnames", "female surnames", "common-gender surnames", "surnames", | ||
"patronymics", "matronymics", | |||
" | |||
} | } | ||
export.personal_name_type_set = m_table.listToSet(export.personal_name_types) | |||
export.given_name_genders = { | |||
male = {type = "human"}, | |||
female = {type = "human"}, | |||
unisex = {type = "human", cat = {"male given names", "female given names", "unisex given names"}, article = "a"}, | |||
["unknown-gender"] = {type = "human", cat = {}, track = true}, | |||
animal = {type = "animal", track = true}, | |||
cat = {type = "animal"}, | |||
cow = {type = "animal"}, | |||
dog = {type = "animal"}, | |||
horse = {type = "animal"}, | |||
pig = {type = "animal"}, | |||
} | |||
local function get_given_name_cats(gender, props) | |||
local cats = props.cat | |||
if not cats then | |||
if props.type == "animal" then | |||
cats = {gender .. " names"} | |||
else | |||
cats = {gender .. " given names"} | |||
end | |||
end | |||
return cats | |||
end | |||
do | |||
local function do_cat(cat) | |||
if not export.personal_name_type_set[cat] then | |||
export.personal_name_type_set[cat] = true | |||
table.insert(export.personal_name_types, cat) | |||
end | |||
end | |||
for gender, props in pairs(export.given_name_genders) do | |||
local cats = get_given_name_cats(gender, props) | |||
for _, cat in ipairs(cats) do | |||
do_cat("diminutives of " .. cat) | |||
do_cat("augmentatives of " .. cat) | |||
do_cat(cat) | |||
end | |||
end | |||
do_cat("given names") | |||
end | |||
local translit_name_type_list = { | local translit_name_type_list = { | ||
| Line 36: | Line 105: | ||
"patronymic" | "patronymic" | ||
} | } | ||
local | local function track(page) | ||
require("Module:debug").track("names/" .. page) | |||
end | |||
-- Get raw text, for use in computing the indefinite article. Use get_plaintext() in [[Module:utilities]] and also | |||
-- remove parens that may surround qualifier or label text preceding a term. | |||
local function get_rawtext(text) | |||
text = m_utilities.get_plaintext(text) | |||
text = text:gsub("[()%[%]]", "") | |||
return text | |||
end | |||
| Line 47: | Line 123: | ||
'Kunigunde<q:medieval, now rare>' or 'non:Óláfr' or 'ru:Фру́нзе<tr:Frúnzɛ><q:rare>' where the modifying properties | 'Kunigunde<q:medieval, now rare>' or 'non:Óláfr' or 'ru:Фру́нзе<tr:Frúnzɛ><q:rare>' where the modifying properties | ||
are contained in <...> specifications after the term. `term` is the full parameter value including any angle brackets | are contained in <...> specifications after the term. `term` is the full parameter value including any angle brackets | ||
and colons; ` | and colons; `paramname` is the name of the parameter that this value comes from, for error purposes; `deflang` is a | ||
language object used in the return value when the language isn't specified (e.g. in the examples 'Karlheinz' and | language object used in the return value when the language isn't specified (e.g. in the examples 'Karlheinz' and | ||
'Kunigunde<q:medieval, now rare>' above); `allow_explicit_lang` indicates whether the language can be explicitly given | 'Kunigunde<q:medieval, now rare>' above); `allow_explicit_lang` indicates whether the language can be explicitly given | ||
(e.g. in the examples 'non:Óláfr' or 'ru:Фру́нзе<tr:Frúnzɛ><q:rare>' above). | (e.g. in the examples 'non:Óláfr' or 'ru:Фру́нзе<tr:Frúnzɛ><q:rare>' above). | ||
Normally the return value is | Normally the return value is a terminfo object that can be passed to full_link() in [[Module:links]]), additionally | ||
[[Module:links]]) and | with optional fields `.q`, `.qq`, `.l`, `.ll`, `.refs` and `.eq` (a list of objects of the same form as the returned | ||
can be given in `term`, and the return value is a list of objects of the form described just above. | terminfo object. However, if `allow_multiple_terms` is given, multiple comma-separated names can be given in `term`, | ||
and the return value is a list of objects of the form described just above. | |||
]=] | ]=] | ||
local function parse_term_with_annotations(term, | local function parse_term_with_annotations(term, paramname, deflang, allow_explicit_lang, allow_multiple_terms) | ||
local | local param_mods = require(parameter_utilities_module).construct_param_mods { | ||
{group = {"link", "l", "q", "ref"}}, | |||
{param = "eq", convert = function(eqval, parse_err) | |||
return parse_term_with_annotations(eqval, paramname .. ".eq", enlang, false, "allow multiple terms") | |||
end}, | |||
} | |||
local function generate_obj(term, parse_err) | |||
local termlang | |||
if allow_explicit_lang then | |||
local actual_term | |||
actual_term, termlang = require(parse_interface_module).parse_term_with_lang { | |||
term = term, | |||
parse_err = parse_err, | |||
paramname = paramname, | |||
} | |||
term = actual_term or term | |||
end | end | ||
return { | |||
term = term, | |||
lang = termlang or deflang, | |||
} | |||
end | end | ||
return require(parse_interface_module).parse_inline_modifiers(term, { | |||
param_mods = param_mods, | |||
paramname = paramname, | |||
generate_obj = generate_obj, | |||
splitchar = allow_multiple_terms and "," or nil, | |||
}) | |||
end | end | ||
| Line 135: | Line 167: | ||
--[=[ | --[=[ | ||
Link a single term. If `do_language_link` is given and a given term's language is English, the link will be constructed | Link a single term. If `do_language_link` is given and a given term's language is English, the link will be constructed | ||
using language_link() in [[Module:links]]; otherwise, with full_link(). | using language_link() in [[Module:links]]; otherwise, with full_link(). `termobj` is an object as returned by | ||
parse_term_with_annotations(), i.e. it is suitable for passing to [[Module:links]] and additionally contains optional | |||
fields `.q`, `.qq`, `.l`, `.ll`, `.refs` and `.eq` (a list of objects of the same form as `termobj`). | |||
`termobj`). | |||
]=] | ]=] | ||
local function link_one_term(termobj, do_language_link) | local function link_one_term(termobj, do_language_link) | ||
local link | local link | ||
if do_language_link and termobj | if do_language_link and termobj.lang:getCode() == "en" then | ||
link = m_links.language_link(termobj | link = m_links.language_link(termobj) | ||
else | else | ||
link = m_links.full_link(termobj | link = m_links.full_link(termobj) | ||
end | end | ||
if termobj.q then | if termobj.q and termobj.q[1] or termobj.qq and termobj.qq[1] or | ||
link = require( | termobj.l and termobj.l[1] or termobj.ll and termobj.ll[1] or termobj.refs and termobj.refs[1] then | ||
link = require(pron_qualifier_module).format_qualifiers { | |||
lang = termobj.lang, | |||
text = link, | |||
q = termobj.q, | |||
qq = termobj.qq, | |||
l = termobj.l, | |||
ll = termobj.ll, | |||
refs = termobj.refs, | |||
} | |||
end | end | ||
if termobj.eq then | if termobj.eq then | ||
| Line 170: | Line 209: | ||
`do_language_link` is given and a given term's language is English, the link will be constructed using language_link() | `do_language_link` is given and a given term's language is English, the link will be constructed using language_link() | ||
in [[Module:links]]; otherwise, with full_link(). Each term in `terms` is an object as returned by | in [[Module:links]]; otherwise, with full_link(). Each term in `terms` is an object as returned by | ||
parse_term_with_annotations( | parse_term_with_annotations(). | ||
]=] | ]=] | ||
local function join_terms(terms, include_langname, do_language_link, conj) | local function join_terms(terms, include_langname, do_language_link, conj) | ||
| Line 178: | Line 216: | ||
for _, termobj in ipairs(terms) do | for _, termobj in ipairs(terms) do | ||
if include_langname and not langnametext then | if include_langname and not langnametext then | ||
langnametext = termobj | langnametext = termobj.lang:getCanonicalName() .. " " | ||
end | end | ||
table.insert(links, link_one_term(termobj, do_language_link)) | table.insert(links, link_one_term(termobj, do_language_link)) | ||
| Line 211: | Line 249: | ||
end | end | ||
for | local function process_one_term(term, i) | ||
for _, termobj in ipairs(parse_term_with_annotations(term, pname .. (i == 1 and "" or i), lang, | |||
allow_explicit_lang, "allow multiple terms")) do | |||
table.insert(termobjs, termobj) | |||
end | |||
end | |||
if not args[pname] then | |||
return "", 0 | |||
elseif type(args[pname]) == "table" then | |||
for i, term in ipairs(args[pname]) do | |||
process_one_term(term, i) | |||
end | |||
else | |||
process_one_term(args[pname], 1) | |||
end | end | ||
return join_terms(termobjs, nil, do_language_link, conj), #termobjs | return join_terms(termobjs, nil, do_language_link, conj), #termobjs | ||
| Line 222: | Line 273: | ||
local lastlang = nil | local lastlang = nil | ||
local last_eqseg = {} | local last_eqseg = {} | ||
for | local function process_one_term(term, i) | ||
for _, termobj in ipairs(parse_term_with_annotations(term, "eq" .. (i == 1 and "" or i), enlang, | |||
"allow explicit lang", "allow multiple terms")) do | |||
local termlang = termobj.lang:getCode() | |||
if lastlang and lastlang ~= termlang then | |||
if #last_eqseg > 0 then | |||
table.insert(eqsegs, last_eqseg) | |||
end | |||
last_eqseg = {} | |||
end | end | ||
last_eqseg = | lastlang = termlang | ||
table.insert(last_eqseg, termobj) | |||
end | |||
end | |||
if type(args.eq) == "table" then | |||
for i, term in ipairs(args.eq) do | |||
process_one_term(term, i) | |||
end | end | ||
elseif type(args.eq) == "string" then | |||
process_one_term(args.eq, 1) | |||
end | end | ||
if #last_eqseg > 0 then | if #last_eqseg > 0 then | ||
| Line 253: | Line 313: | ||
local unrecognized = false | local unrecognized = false | ||
local prefix, suffix | local prefix, suffix | ||
if from == "surnames" then | if from == "surnames" or from == "given names" or from == "nicknames" or from == "place names" or from == "common nouns" or from == "month names" then | ||
prefix = "transferred from the " | prefix = "transferred from the " | ||
suffix = " | suffix = from:gsub("s$", "") | ||
table.insert(catparts, from) | table.insert(catparts, from) | ||
elseif from == " | elseif from == "patronymics" or from == "matronymics" or from == "coinages" then | ||
prefix = " | prefix = "originating " | ||
suffix = " | suffix = "as a " .. from:gsub("s$", "") | ||
table.insert(catparts, from) | table.insert(catparts, from) | ||
elseif from == " | elseif from == "occupations" or from == "ethnonyms" then | ||
prefix = "originating " | prefix = "originating " | ||
suffix = "as | suffix = "as an " .. from:gsub("s$", "") | ||
table.insert(catparts, from) | table.insert(catparts, from) | ||
elseif from == "the Bible" then | elseif from == "the Bible" then | ||
| Line 272: | Line 332: | ||
prefix = "from " | prefix = "from " | ||
if from:find(":") then | if from:find(":") then | ||
local termobj = parse_term_with_annotations(from, "from" .. (i == 1 and "" or i), lang, "allow explicit lang") | local termobj = parse_term_with_annotations(from, "from" .. (i == 1 and "" or i), lang, | ||
"allow explicit lang") | |||
local fromlangname = "" | local fromlangname = "" | ||
if termobj | if termobj.lang:getCode() ~= lang:getCode() then | ||
-- If name is derived from another name in the same language, don't include lang name after text | -- If name is derived from another name in the same language, don't include lang name after text | ||
-- or create a category like "German male given names derived from German". | -- "from " or create a category like "German male given names derived from German". | ||
local canonical_name = termobj | local canonical_name = termobj.lang:getCanonicalName() | ||
fromlangname = canonical_name .. " " | fromlangname = canonical_name .. " " | ||
table.insert(catparts, canonical_name) | table.insert(catparts, canonical_name) | ||
end | end | ||
suffix = fromlangname .. link_one_term(termobj) | suffix = fromlangname .. link_one_term(termobj) | ||
else | else | ||
local family = from:match("^(.+) languages$") or | |||
table.insert(catparts, from) | from:match("^.+ Languages$") or | ||
from:match("^.+ [Ll]ects$") | |||
if family then | |||
if require("Module:families").getByCanonicalName(family) then | |||
table.insert(catparts, from) | |||
else | |||
unrecognized = true | |||
end | |||
suffix = "the " .. from | |||
else | else | ||
unrecognized = true | if m_languages.getByCanonicalName(from, nil, "allow etym") then | ||
table.insert(catparts, from) | |||
else | |||
unrecognized = true | |||
end | |||
suffix = from | |||
end | end | ||
end | end | ||
end | |||
if unrecognized then | |||
track("unrecognized from") | |||
track("unrecognized from/" .. from) | |||
end | end | ||
return prefix, suffix | return prefix, suffix | ||
| Line 304: | Line 372: | ||
local last_fromseg = nil | local last_fromseg = nil | ||
local put = require(parse_utilities_module) | |||
local from_args = args.from or {} | |||
local | if type(from_args) == "string" then | ||
if #froms == 1 then | from_args = {from_args} | ||
end | |||
while from_args[i] do | |||
-- We may have multiple comma-separated items, each of which may have multiple items separated by a | |||
-- space-delimited < sign, each of which may have inline modifiers with embedded commas in them. To handle | |||
-- this correctly, first replace space-delimited < signs with a special character, then split on balanced | |||
-- <...> and [...] signs, then split on comma, then rejoin the stuff between commas. We will then split on | |||
-- TEMP_LESS_THAN (the replacement for space-delimited < signs) and reparse. | |||
local rawfroms = rsub(from_args[i], "%s+<%s+", TEMP_LESS_THAN) | |||
local segments = put.parse_multi_delimiter_balanced_segment_run(rawfroms, {{"<", ">"}, {"[", "]"}}) | |||
local comma_separated_groups = put.split_alternating_runs_on_comma(segments) | |||
for j, comma_separated_group in ipairs(comma_separated_groups) do | |||
comma_separated_groups[j] = table.concat(comma_separated_group) | |||
end | |||
for _, rawfrom in ipairs(comma_separated_groups) do | |||
local froms = rsplit(rawfrom, TEMP_LESS_THAN) | |||
if #froms == 1 then | |||
local prefix, suffix = parse_from(froms[1]) | |||
if last_fromseg and (last_fromseg.has_multiple_froms or 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) | |||
else | |||
if last_fromseg then | |||
table.insert(fromsegs, last_fromseg) | |||
last_fromseg = nil | |||
end | |||
local first_suffixpart = "" | |||
local rest_suffixparts = {} | |||
for j, from in ipairs(froms) do | |||
local prefix, suffix = parse_from(from) | |||
if j == 1 then | |||
first_suffixpart = prefix .. suffix | |||
else | |||
table.insert(rest_suffixparts, prefix .. suffix) | |||
end | |||
end | end | ||
local full_suffix = first_suffixpart .. " [in turn " .. table.concat(rest_suffixparts, ", in turn ") .. "]" | |||
last_fromseg = {prefix = "", has_multiple_froms = true, suffixes = {full_suffix}} | |||
end | end | ||
end | end | ||
i = i + 1 | i = i + 1 | ||
| Line 340: | Line 425: | ||
local fromtextsegs = {} | local fromtextsegs = {} | ||
for _, fromseg in ipairs(fromsegs) do | for _, fromseg in ipairs(fromsegs) do | ||
table.insert(fromtextsegs, fromseg.prefix .. | table.insert(fromtextsegs, fromseg.prefix .. m_table.serialCommaJoin(fromseg.suffixes, {conj = "or"})) | ||
end | end | ||
return m_table.serialCommaJoin(fromtextsegs, {conj = "or"}), catparts | return m_table.serialCommaJoin(fromtextsegs, {conj = "or"}), catparts | ||
end | |||
local function parse_given_name_genders(genderspec) | |||
if export.given_name_genders[genderspec] then -- optimization | |||
return {{ | |||
type = genderspec, | |||
props = export.given_name_genders[genderspec], | |||
}}, export.given_name_genders[genderspec].type == "animal" | |||
end | |||
local genders = {} | |||
local is_animal = nil | |||
local param_mods = require(parameter_utilities_module).construct_param_mods { | |||
{group = {"l", "q", "ref"}}, | |||
{param = {"text", "article"}}, | |||
} | |||
local function generate_obj(term, parse_err) | |||
if not export.given_name_genders[term] then | |||
local valid_genders = {} | |||
for k, _ in pairs(export.given_name_genders) do | |||
table.insert(valid_genders, k) | |||
end | |||
table.sort(valid_genders) | |||
parse_err(("Unrecognized gender '%s': valid genders are %s"):format( | |||
term, table.concat(valid_genders, ", "))) | |||
end | |||
return { | |||
type = term, | |||
props = export.given_name_genders[term], | |||
} | |||
end | |||
local retval = require(parse_interface_module).parse_inline_modifiers(genderspec, { | |||
param_mods = param_mods, | |||
paramname = "2", | |||
generate_obj = generate_obj, | |||
splitchar = ",", | |||
}) | |||
for _, spec in ipairs(retval) do | |||
local this_is_animal = spec.props.type == "animal" | |||
if is_animal == nil then | |||
is_animal = this_is_animal | |||
elseif is_animal ~= this_is_animal then | |||
error("Can't mix animal and human genders") | |||
end | |||
end | |||
return retval, is_animal | |||
end | |||
local function generate_given_name_genders(lang, genders) | |||
local parts = {} | |||
for _, spec in ipairs(genders) do | |||
local text | |||
if spec.text then | |||
-- NOTE: This assumes no % sign in the gender type, which seems safe. | |||
text = spec.text:gsub("%+", spec.type) | |||
else | |||
if spec.props.type == "animal" then | |||
text = "[[" .. spec.type .. "]]" | |||
else | |||
text = spec.type | |||
end | |||
end | |||
if spec.q and spec.q[1] or spec.qq and spec.qq[1] or spec.l and spec.l[1] or spec.ll and spec.ll[1] or | |||
spec.refs and spec.refs[1] then | |||
text = require(pron_qualifier_module).format_qualifiers { | |||
lang = lang, | |||
text = text, | |||
q = spec.q, | |||
qq = spec.qq, | |||
l = spec.l, | |||
ll = spec.ll, | |||
refs = spec.refs, | |||
raw = true, | |||
} | |||
end | |||
table.insert(parts, text) | |||
end | |||
local retval = m_table.serialCommaJoin(parts, {conj = "or"}) | |||
local article = genders[1].article | |||
if not article and not genders[1].text and not genders[1].q and not genders[1].l then | |||
article = genders[1].props.article | |||
end | |||
if not article then | |||
article = require(en_utilities_module).get_indefinite_article(get_rawtext(retval)) | |||
end | |||
return retval, article | |||
end | end | ||
| Line 352: | Line 524: | ||
local offset = compat and 0 or 1 | local offset = compat and 0 or 1 | ||
local | local lang_index = compat and "lang" or 1 | ||
["gender"] = { default = "unknown-gender" }, | local list = {list = true} | ||
[1 + offset] = { alias_of = "gender" | local args = require("Module:parameters").process(parent_args, { | ||
[lang_index] = {required = true, type = "language", default = "und"}, | |||
["gender"] = {default = "unknown-gender"}, | |||
["usage"] = | [1 + offset] = {alias_of = "gender"}, | ||
["origin"] = | ["usage"] = true, | ||
["popular"] = | ["origin"] = true, | ||
["populartype"] = | ["popular"] = true, | ||
["meaning"] = | ["populartype"] = true, | ||
["meaningtype"] = | ["meaning"] = list, | ||
[" | ["meaningtype"] = true, | ||
["addl"] = true, | |||
-- initial article: A or An | -- initial article: A or An | ||
["A"] = | ["A"] = true, | ||
["sort"] = | ["sort"] = true, | ||
["from"] | ["from"] = true, | ||
[2 + offset] = { alias_of = "from" | [2 + offset] = {alias_of = "from"}, | ||
["fromtype"] = | ["fromtype"] = true, | ||
["xlit"] | ["xlit"] = true, | ||
["eq"] | ["eq"] = true, | ||
["eqtype"] = | ["eqtype"] = true, | ||
["varof"] | ["varof"] = true, | ||
["varoftype"] = | ["varoftype"] = true, | ||
["var"] = { alias_of = "varof" | ["var"] = {alias_of = "varof"}, | ||
["vartype"] = { alias_of = "varoftype" }, | ["vartype"] = {alias_of = "varoftype"}, | ||
["varform"] = | ["varform"] = true, | ||
["dimof"] | ["varformtype"] = true, | ||
["dimoftype"] = | ["dimof"] = true, | ||
["dim"] = { alias_of = "dimof" | ["dimoftype"] = true, | ||
["dimtype"] = { alias_of = "dimoftype" }, | ["dim"] = {alias_of = "dimof"}, | ||
[" | ["dimtype"] = {alias_of = "dimoftype"}, | ||
[" | ["dimform"] = true, | ||
[" | ["dimformtype"] = true, | ||
["blend"] | ["augof"] = true, | ||
["blendtype"] = | ["augoftype"] = true, | ||
["m"] | ["aug"] = {alias_of = "augof"}, | ||
["mtype"] = | ["augtype"] = {alias_of = "augoftype"}, | ||
["f"] | ["augform"] = true, | ||
["ftype"] = | ["augformtype"] = true, | ||
} | ["clipof"] = true, | ||
["clipoftype"] = true, | |||
["blend"] = true, | |||
["blendtype"] = true, | |||
["m"] = true, | |||
["mtype"] = true, | |||
["f"] = true, | |||
["ftype"] = true, | |||
}) | |||
local textsegs = {} | local textsegs = {} | ||
local lang = | local lang = args[lang_index] | ||
local langcode = lang:getCode() | |||
local function fetch_typetext(param) | local function fetch_typetext(param) | ||
| Line 403: | Line 583: | ||
end | end | ||
local dimoftext, | local genders, is_animal = parse_given_name_genders(args.gender) | ||
local dimoftext, numdimofs = join_names(lang, args, "dimof") | |||
local augoftext, numaugofs = join_names(lang, args, "augof") | |||
local xlittext = join_names(nil, args, "xlit") | local xlittext = join_names(nil, args, "xlit") | ||
local blendtext = join_names(lang, args, "blend", "and") | local blendtext = join_names(lang, args, "blend", "and") | ||
local varoftext = join_names(lang, args, "varof") | local varoftext = join_names(lang, args, "varof") | ||
local clipoftext = join_names(lang, args, "clipof") | |||
local mtext = join_names(lang, args, "m") | local mtext = join_names(lang, args, "m") | ||
local ftext = join_names(lang, args, "f") | local ftext = join_names(lang, args, "f") | ||
local varformtext, numvarforms = join_names(lang, args, "varform", ", ") | local varformtext, numvarforms = join_names(lang, args, "varform", ", ") | ||
local dimformtext, numdimforms = join_names(lang, args, "dimform", ", ") | local dimformtext, numdimforms = join_names(lang, args, "dimform", ", ") | ||
local augformtext, numaugforms = join_names(lang, args, "augform", ", ") | |||
local meaningsegs = {} | local meaningsegs = {} | ||
for _, meaning in ipairs(args.meaning) do | for _, meaning in ipairs(args.meaning) do | ||
table.insert(meaningsegs, ' | table.insert(meaningsegs, '“' .. meaning .. '”') | ||
end | end | ||
local meaningtext = m_table.serialCommaJoin(meaningsegs, {conj = "or"}) | local meaningtext = m_table.serialCommaJoin(meaningsegs, {conj = "or"}) | ||
local eqtext = get_eqtext(args) | local eqtext = get_eqtext(args) | ||
table.insert(textsegs, | local function ins(txt) | ||
local | table.insert(textsegs, txt) | ||
local | end | ||
local dimoftype = args.dimoftype | |||
args. | local augoftype = args.augoftype | ||
added_text = nil | |||
if numdimofs > 0 then | |||
added_text = (dimoftype and dimoftype .. " " or "") .. "[[diminutive]]" .. | |||
(xlittext ~= "" and ", " .. xlittext .. "," or "") .. " of " | |||
elseif numaugofs > 0 then | |||
added_text = (augoftype and augoftype .. " " or "") .. "[[augmentative]]" .. | |||
(xlittext ~= "" and ", " .. xlittext .. "," or "") .. " of " | |||
end | |||
force_plural = false | |||
if added_text ~= nil then | |||
if args.dimof == "-" then | |||
dimoftext = "" | |||
force_plural = true | |||
else | |||
added_text = added_text .. "the " | |||
end | |||
ins(added_text) | |||
end | |||
local article = args.A | |||
if not article and textsegs[1] then | |||
article = require(en_utilities_module).get_indefinite_article(textsegs[1]) | |||
end | |||
if not is_animal then | |||
local gendertext, gender_article = generate_given_name_genders(lang, genders) | |||
article = article or gender_article | |||
ins(gendertext) | |||
ins(" ") | |||
end | |||
ins((numdimofs > 1 or numaugofs > 1 or force_plural) and "[[given name|given names]]" or "[[given name]]") | |||
article = article or "a" -- if no article set yet, it's "a" based on "given name" | |||
if langcode == "en" then | |||
article = mw.getContentLanguage():ucfirst(article) | |||
end | |||
local need_comma = false | local need_comma = false | ||
if | if numdimofs > 0 then | ||
ins(" " .. dimoftext) | |||
need_comma = not is_animal | |||
elseif numaugofs > 0 then | |||
ins(" " .. augoftext) | |||
need_comma = not is_animal | |||
elseif xlittext ~= "" then | |||
ins(", " .. xlittext) | |||
need_comma = true | need_comma = true | ||
end | |||
if is_animal then | |||
if need_comma then | |||
ins(",") | |||
end | |||
need_comma = true | need_comma = true | ||
ins(" for ") | |||
local gendertext, gender_article = generate_given_name_genders(lang, genders) | |||
ins(gender_article) | |||
ins(" ") | |||
ins(gendertext) | |||
end | end | ||
local from_catparts = {} | local from_catparts = {} | ||
if | if args.from then | ||
if need_comma then | if need_comma then | ||
ins(",") | |||
end | end | ||
need_comma = true | need_comma = true | ||
ins(" " .. fetch_typetext("fromtype")) | |||
local textseg, this_catparts = get_fromtext(lang, args) | local textseg, this_catparts = get_fromtext(lang, args) | ||
for _, catpart in ipairs(this_catparts) do | for _, catpart in ipairs(this_catparts) do | ||
m_table.insertIfNot(from_catparts, catpart) | m_table.insertIfNot(from_catparts, catpart) | ||
end | end | ||
ins(textseg) | |||
end | end | ||
if meaningtext ~= "" then | if meaningtext ~= "" then | ||
if need_comma then | if need_comma then | ||
ins(",") | |||
end | end | ||
need_comma = true | need_comma = true | ||
ins(" " .. fetch_typetext("meaningtype") .. "meaning " .. meaningtext) | |||
end | end | ||
if args.origin then | if args.origin then | ||
if need_comma then | if need_comma then | ||
ins(",") | |||
end | end | ||
need_comma = true | need_comma = true | ||
ins(" of " .. args.origin .. " origin") | |||
end | end | ||
if args.usage then | if args.usage then | ||
if need_comma then | if need_comma then | ||
ins(",") | |||
end | end | ||
need_comma = true | need_comma = true | ||
ins(" of " .. args.usage .. " usage") | |||
end | end | ||
if varoftext ~= "" then | if varoftext ~= "" then | ||
ins(", " ..fetch_typetext("varoftype") .. "variant of " .. varoftext) | |||
end | |||
if clipoftext ~= "" then | |||
ins(", " .. fetch_typetext("clipoftype") .. "clipping of " .. clipoftext) | |||
end | end | ||
if blendtext ~= "" then | if blendtext ~= "" then | ||
ins(", " .. fetch_typetext("blendtype") .. "blend of " .. blendtext) | |||
end | end | ||
if args.popular then | if args.popular then | ||
ins(", " .. fetch_typetext("populartype") .. "popular " .. args.popular) | |||
end | end | ||
if mtext ~= "" then | if mtext ~= "" then | ||
ins(", " .. fetch_typetext("mtype") .. "masculine equivalent " .. mtext) | |||
end | end | ||
if ftext ~= "" then | if ftext ~= "" then | ||
ins(", " .. fetch_typetext("ftype") .. "feminine equivalent " .. ftext) | |||
end | end | ||
if eqtext ~= "" then | if eqtext ~= "" then | ||
ins(", " .. fetch_typetext("eqtype") .. "equivalent to " .. eqtext) | |||
end | end | ||
if args. | if args.addl then | ||
if args.addl:find("^;") then | |||
ins(args.addl) | |||
elseif args.addl:find("^_") then | |||
ins(" " .. args.addl:sub(2)) | |||
else | |||
ins(", " .. args.addl) | |||
end | |||
end | end | ||
if varformtext ~= "" then | if varformtext ~= "" then | ||
ins("; " .. fetch_typetext("varformtype") .. "variant form" .. (numvarforms > 1 and "s" or "") .. " " .. | |||
varformtext) | |||
end | end | ||
if dimformtext ~= "" then | if dimformtext ~= "" then | ||
ins("; " .. fetch_typetext("dimformtype") .. "diminutive form" .. (numdimforms > 1 and "s" or "") .. " " .. | |||
dimformtext) | |||
end | |||
if augformtext ~= "" then | |||
ins("; " .. fetch_typetext("augformtype") .. "augmentative form" .. (numaugforms > 1 and "s" or "") .. " " .. | |||
augformtext) | |||
end | end | ||
table. | textsegs = "<span class='use-with-mention'>" .. article .. " " .. table.concat(textsegs) .. "</span>" | ||
local categories = {} | local categories = {} | ||
local langname = lang:getCanonicalName() .. " " | local langname = lang:getCanonicalName() .. " " | ||
local function insert_cats( | local function insert_cats(dimaugof) | ||
if | if dimaugof == "" and genders[1].props.type == "human" then | ||
-- No category such as "English diminutives of given names" | -- No category such as "English diminutives of given names" | ||
table.insert(categories, langname | table.insert(categories, langname .. "given names") | ||
end | end | ||
local function | local function insert_cat(cat) | ||
table.insert(categories, langname .. dimaugof .. cat) | |||
for _, catpart in ipairs(from_catparts) do | |||
table.insert(categories, langname .. dimaugof .. cat .. " from " .. catpart) | |||
end | end | ||
if | end | ||
for _, spec in ipairs(genders) do | |||
local typ = spec.type | |||
if spec.props.track then | |||
track(typ) | |||
end | end | ||
local cats = get_given_name_cats(spec.type, spec.props) | |||
for _, cat in ipairs(cats) do | |||
insert_cat(cat) | |||
for _, | |||
end | end | ||
end | end | ||
end | end | ||
insert_cats("") | insert_cats("") | ||
if | if numdimofs > 0 then | ||
insert_cats("diminutives of ") | insert_cats("diminutives of ") | ||
elseif numaugofs > 0 then | |||
insert_cats("augmentatives of ") | |||
end | end | ||
return | return textsegs .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) | ||
end | end | ||
-- The entry point for {{ | -- The entry point for {{surname}}, {{patronymic}} and {{matronymic}}. | ||
function export. | function export.surname(frame) | ||
local iargs = require("Module:parameters").process(frame.args, { | |||
["type"] = {required = true, set = {"surname", "patronymic", "matronymic"}}, | |||
}) | |||
local parent_args = frame:getParent().args | local parent_args = frame:getParent().args | ||
local compat = parent_args.lang | |||
local offset = compat and 0 or 1 | |||
local | if parent_args.dot or parent_args.nodot then | ||
[ | error("dot= and nodot= are no longer supported in [[Template:" .. iargs.type .. "]] because a trailing " .. | ||
[ | "period is no longer added by default; if you want it, add it explicitly after the template") | ||
[ | end | ||
[" | |||
[" | local lang_index = compat and "lang" or 1 | ||
[" | |||
[" | local list = {list = true} | ||
[" | local gender_arg = iargs.type == "surname" and "g" or 1 + offset | ||
[" | local adj_arg = iargs.type == "surname" and 1 + offset or 2 + offset | ||
[" | local args = require("Module:parameters").process(parent_args, { | ||
[" | [lang_index] = {required = true, type = "language", template_default = "und"}, | ||
[" | [gender_arg] = iargs.type == "surname" and true or {required = true, template_default = "unknown"}, -- gender(s) | ||
[" | [adj_arg] = true, -- adjective/qualifier | ||
[" | ["usage"] = true, | ||
[" | ["origin"] = true, | ||
[" | ["popular"] = true, | ||
[" | ["populartype"] = true, | ||
[" | ["meaning"] = list, | ||
[" | ["meaningtype"] = true, | ||
} | ["parent"] = true, | ||
["addl"] = true, | |||
-- initial article: by default A or An (English), a or an (otherwise) | |||
["A"] = true, | |||
["sort"] = true, | |||
["from"] = true, | |||
["fromtype"] = true, | |||
["xlit"] = true, | |||
["eq"] = true, | |||
["eqtype"] = true, | |||
["varof"] = true, | |||
["varoftype"] = true, | |||
["var"] = {alias_of = "varof"}, | |||
["vartype"] = {alias_of = "varoftype"}, | |||
["varform"] = true, | |||
["varformtype"] = true, | |||
["clipof"] = true, | |||
["clipoftype"] = true, | |||
["blend"] = true, | |||
["blendtype"] = true, | |||
["m"] = true, | |||
["mtype"] = true, | |||
["f"] = true, | |||
["ftype"] = true, | |||
["nocat"] = {type = "boolean"}, | |||
}) | |||
local | local textsegs = {} | ||
local lang = | local lang = args[lang_index] | ||
local | local langcode = lang:getCode() | ||
local | |||
local function fetch_typetext(param) | |||
return args[param] and args[param] .. " " or "" | |||
end | end | ||
local | local saw_male = false | ||
local saw_female = false | |||
for _, | local genders = {} | ||
if | if args[gender_arg] then | ||
for _, g in ipairs(require(parse_interface_module).split_on_comma(args[gender_arg])) do | |||
if g == "unknown" or g == "unknown gender" or g == "unknown-gender" or g == "?" then | |||
g = "unknown-gender" | |||
track("unknown gender") | |||
elseif g == "unisex" or g == "common gender" or g == "common-gender" or g == "c" then | |||
g = "common-gender" | |||
saw_male = true | |||
saw_female = true | |||
elseif g == "m" or g == "male" then | |||
g = "male" | |||
saw_male = true | |||
elseif g == "f" or g == "female" then | |||
g = "female" | |||
saw_female = true | |||
else | |||
error("Unrecognized gender: " .. g) | |||
end | end | ||
table.insert( | table.insert(genders, g) | ||
end | |||
end | |||
local adj = args[adj_arg] | |||
local xlittext = join_names(nil, args, "xlit") | |||
local blendtext = join_names(lang, args, "blend", "and") | |||
local varoftext = join_names(lang, args, "varof") | |||
local clipoftext = join_names(lang, args, "clipof") | |||
local mtext = join_names(lang, args, "m") | |||
local ftext = join_names(lang, args, "f") | |||
local parenttext = join_names(lang, args, "parent", nil, "allow explicit lang") | |||
local varformtext, numvarforms = join_names(lang, args, "varform", ", ") | |||
local meaningsegs = {} | |||
for _, meaning in ipairs(args.meaning) do | |||
table.insert(meaningsegs, '“' .. meaning .. '”') | |||
end | |||
if parenttext ~= "" then | |||
local child = saw_male and not saw_female and "son" or saw_female and not saw_male and "daughter" or | |||
"son/daughter" | |||
table.insert(meaningsegs, ("“%s of %s”"):format(child, parenttext)) | |||
end | |||
local meaningtext = m_table.serialCommaJoin(meaningsegs, {conj = "or"}) | |||
local eqtext = get_eqtext(args) | |||
local function ins(txt) | |||
table.insert(textsegs, txt) | |||
end | |||
ins("<span class='use-with-mention'>") | |||
-- If gender is supplied, it goes before the specified adjective in adj=. The only value of gender that uses "an" is | |||
-- "unknown-gender" (note that "unisex" wouldn't use it but in any case we map "unisex" to "common-gender"). If gender | |||
-- isn't supplied, look at the first letter of the value of adj= if supplied; otherwise, the article is always "a" | |||
-- because the word "surname", "patronymic" or "matronymic" follows. Capitalize "A"/"An" if English. | |||
local article | |||
if args.A then | |||
article = args.A | |||
else | |||
article = #genders > 0 and genders[1] == "unknown-gender" and "an" or | |||
#genders == 0 and adj and require(en_utilities_module).get_indefinite_article(adj) or | |||
"a" | |||
if langcode == "en" then | |||
article = mw.getContentLanguage():ucfirst(article) | |||
end | |||
end | |||
ins(article .. " ") | |||
if #genders > 0 then | |||
ins(table.concat(genders, " or ") .. " ") | |||
end | |||
if adj then | |||
ins(adj .. " ") | |||
end | |||
ins("[[" .. iargs.type .. "]]") | |||
local need_comma = false | |||
if xlittext ~= "" then | |||
ins(", " .. xlittext) | |||
need_comma = true | |||
end | |||
local from_catparts = {} | |||
if args.from then | |||
if need_comma then | |||
ins(",") | |||
end | |||
need_comma = true | |||
ins(" " .. fetch_typetext("fromtype")) | |||
local textseg, this_catparts = get_fromtext(lang, args) | |||
for _, catpart in ipairs(this_catparts) do | |||
m_table.insertIfNot(from_catparts, catpart) | |||
end | |||
ins(textseg) | |||
end | |||
if meaningtext ~= "" then | |||
if need_comma then | |||
ins(",") | |||
end | |||
need_comma = true | |||
ins(" " .. fetch_typetext("meaningtype") .. "meaning " .. meaningtext) | |||
end | |||
if args.origin then | |||
if need_comma then | |||
ins(",") | |||
end | |||
need_comma = true | |||
ins(" of " .. args.origin .. " origin") | |||
end | |||
if args.usage then | |||
if need_comma then | |||
ins(",") | |||
end | end | ||
need_comma = true | |||
ins(" of " .. args.usage .. " usage") | |||
end | |||
if varoftext ~= "" then | |||
ins(", " ..fetch_typetext("varoftype") .. "variant of " .. varoftext) | |||
end | |||
if clipoftext ~= "" then | |||
ins(", " .. fetch_typetext("clipoftype") .. "clipping of " .. clipoftext) | |||
end | |||
if blendtext ~= "" then | |||
ins(", " .. fetch_typetext("blendtype") .. "blend of " .. blendtext) | |||
end | |||
if args.popular then | |||
ins(", " .. fetch_typetext("populartype") .. "popular " .. args.popular) | |||
end | |||
if mtext ~= "" then | |||
ins(", " .. fetch_typetext("mtype") .. "masculine equivalent " .. mtext) | |||
end | |||
if ftext ~= "" then | |||
ins(", " .. fetch_typetext("ftype") .. "feminine equivalent " .. ftext) | |||
end | |||
if eqtext ~= "" then | |||
ins(", " .. fetch_typetext("eqtype") .. "equivalent to " .. eqtext) | |||
end | |||
if args.addl then | |||
if args.addl:find("^;") then | |||
ins(args.addl) | |||
elseif args.addl:find("^_") then | |||
ins(" " .. args.addl:sub(2)) | |||
else | |||
ins(", " .. args.addl) | |||
end | |||
end | |||
if varformtext ~= "" then | |||
ins("; " .. fetch_typetext("varformtype") .. "variant form" .. | |||
(numvarforms > 1 and "s" or "") .. " " .. varformtext) | |||
end | |||
ins("</span>") | |||
local text = table.concat(textsegs, "") | |||
if args.nocat then | |||
return text | |||
end | end | ||
local categories = {} | |||
local | local langname = lang:getCanonicalName() .. " " | ||
local function insert_cats(g) | |||
g = g and g .. " " or "" | |||
table.insert(categories, langname .. g .. iargs.type .. "s") | |||
for _, catpart in ipairs(from_catparts) do | |||
table.insert(categories, langname .. g .. iargs.type .. "s from " .. catpart) | |||
end | |||
end | |||
insert_cats(nil) | |||
local function insert_cats_gender(g) | |||
if g == "unknown-gender" then | |||
return | |||
end | |||
if g == "common-gender" then | |||
insert_cats_gender("male") | |||
insert_cats_gender("female") | |||
end | end | ||
insert_cats(g) | |||
end | |||
for _, g in ipairs(genders) do | |||
insert_cats_gender(g) | |||
end | end | ||
return text .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) | |||
end | |||
-- The entry point for {{name translit}}, {{name respelling}}, {{name obor}} and {{foreign name}}. | |||
function export.name_translit(frame) | |||
local boolean = {type = "boolean"} | |||
local iargs = require("Module:parameters").process(frame.args, { | |||
["desctext"] = {required = true}, | |||
["obor"] = boolean, | |||
["foreign_name"] = boolean, | |||
}) | |||
local parent_args = frame:getParent().args | |||
local params = { | |||
[1] = {required = true, type = "language", template_default = "en"}, | |||
[2] = {required = true, type = "language", sublist = true, template_default = "ru"}, | |||
[3] = {list = true, allow_holes = true}, | |||
["type"] = {required = true, set = translit_name_type_list, sublist = true, default = "patronymic"}, | |||
["dim"] = boolean, | |||
["aug"] = boolean, | |||
["nocap"] = boolean, | |||
["addl"] = true, | |||
["sort"] = true, | |||
["pagename"] = true, | |||
} | |||
local m_param_utils = require(parameter_utilities_module) | |||
local param_mods = m_param_utils.construct_param_mods { | |||
{group = {"link", "q", "l", "ref"}}, | |||
{param = {"xlit", "eq"}}, | |||
} | |||
local names, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params { | |||
params = params, | |||
param_mods = param_mods, | |||
raw_args = parent_args, | |||
termarg = 3, | |||
track_module = "names/name translit", | |||
disallow_custom_separators = true, | |||
-- Use the first source language as the language of the specified names. | |||
lang = function(args) return args[2][1] end, | |||
sc = "sc.default", | |||
} | |||
local lang = args[1] | |||
local langcode = lang:getCode() | |||
local sources = args[2] | |||
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename | |||
local textsegs = {} | local textsegs = {} | ||
table.insert(textsegs, "<span class='use-with-mention'>") | local function ins(txt) | ||
table.insert(textsegs, txt) | |||
end | |||
ins("<span class='use-with-mention'>") | |||
local desctext = iargs.desctext | local desctext = iargs.desctext | ||
if not args.nocap then | if langcode == "en" and not args.nocap then | ||
desctext = mw.getContentLanguage():ucfirst(desctext) | desctext = mw.getContentLanguage():ucfirst(desctext) | ||
end | end | ||
ins(desctext .. " ") | |||
if not iargs.foreign_name then | |||
ins("of ") | |||
end | |||
local langsegs = {} | local langsegs = {} | ||
for i, source in ipairs(sources) do | for i, source in ipairs(sources) do | ||
local sourcename = source:getCanonicalName() | local sourcename = source:getCanonicalName() | ||
local function get_source_link() | local function get_source_link() | ||
if | local term_to_link = names[1] and names[1].term or pagename | ||
return m_links.language_link { | -- We link the language name to either the first specified name or the pagename, in the following | ||
lang = | -- circumstances: | ||
-- (1) More than one language was given along with at least one name; or | |||
-- (2) We're handling {{foreign name}} or {{name obor}}, and no name was given. | |||
-- The reason for (1) is that if more than one language was given, we want a link to the name | |||
-- in each language, as the name that's displayed is linked only to the first specified language. | |||
-- However, if only one language was given, linking the language to the name is redundant. | |||
-- The reason for (2) is that {{foreign name}} is often used when the name in the destination language | |||
-- is spelled the same as the name in the source language (e.g. [[Clinton]] or [[Obama]] in Italian), | |||
-- and in that case no name will be explicitly specified but we still want a link to the name in the | |||
-- source language. The reason we restrict this to {{foreign name}} or {{name obor}}, not to | |||
-- {{name translit}} or {{name respelling}}, is that {{name translit}} and {{name respelling}} ought to be | |||
-- used for names spelled differently in the destination language (either transliterated or respelled), so | |||
-- assuming the pagename is the name in the source language is wrong. | |||
if names[1] and #sources > 1 or (iargs.foreign_name or iargs.obor) and not names[1] then | |||
return m_links.language_link{ | |||
lang = sources[i], term = term_to_link, alt = sourcename, tr = "-" | |||
} | } | ||
else | else | ||
| Line 633: | Line 1,118: | ||
end | end | ||
if i == 1 then | if i == 1 and not iargs.foreign_name then | ||
-- If at least one name is given, we say "A transliteration of the LANG surname FOO", linking LANG to FOO. | -- If at least one name is given, we say "A transliteration of the LANG surname FOO", linking LANG to FOO. | ||
-- Otherwise we say "A transliteration of a LANG surname". | -- Otherwise we say "A transliteration of a LANG surname". | ||
if | if names[1] then | ||
table.insert(langsegs, "the " .. get_source_link()) | table.insert(langsegs, "the " .. get_source_link()) | ||
else | else | ||
table.insert(langsegs, require( | table.insert(langsegs, require(en_utilities_module).add_indefinite_article(sourcename)) | ||
end | end | ||
else | else | ||
| Line 645: | Line 1,130: | ||
end | end | ||
end | end | ||
local langseg_text = m_table.serialCommaJoin(langsegs, {conj = "or"}) | |||
local augdim_text | |||
if args.dim then | if args.dim then | ||
augdim_text = " [[diminutive]]" | |||
elseif args.aug then | elseif args.aug then | ||
table.insert( | augdim_text = " [[augmentative]]" | ||
else | |||
augdim_text = "" | |||
end | |||
local nametype_linked = {} | |||
for _, nametype in ipairs(args["type"]) do | |||
if nametype == "surname" or nametype == "patronymic" then | |||
table.insert(nametype_linked, "[[" .. nametype .. "]]") | |||
elseif nametype == "male given name" then | |||
table.insert(nametype_linked, "male [[given name]]") | |||
elseif nametype == "female given name" then | |||
table.insert(nametype_linked, "female [[given name]]") | |||
elseif nametype == "unisex given name" then | |||
table.insert(nametype_linked, "unisex [[given name]]") | |||
else | |||
table.insert(nametype_linked, nametype) | |||
end | |||
end | |||
local nametype_text = m_table.serialCommaJoin(nametype_linked) .. augdim_text | |||
if not iargs.foreign_name then | |||
ins(langseg_text .. " ") | |||
ins(nametype_text) | |||
if names[1] then | |||
ins(" ") | |||
end | |||
else | |||
ins(nametype_text) | |||
ins(" in " .. langseg_text) | |||
if names[1] then | |||
ins(", ") | |||
end | |||
end | end | ||
local linked_names = {} | |||
local embedded_comma = false | local embedded_comma = false | ||
for | for _, name in ipairs(names) do | ||
local | local linked_name = m_links.full_link(name, "term") | ||
if name.q and name.q[1] or name.qq and name.qq[1] or name.l and name.l[1] or name.ll and name.ll[1] or | |||
name.refs and name.refs[1] then | |||
linked_name = require(pron_qualifier_module).format_qualifiers { | |||
lang = name.lang, | |||
text = linked_name, | |||
q = name.q, | |||
qq = name.qq, | |||
l = name.l, | |||
ll = name.ll, | |||
refs = name.refs, | |||
raw = true, | |||
} | |||
end | end | ||
if | if name.xlit then | ||
embedded_comma = true | embedded_comma = true | ||
linked_name = linked_name .. ", " .. m_links.language_link { lang = enlang, term = name.xlit } | |||
end | end | ||
if | if name.eq then | ||
embedded_comma = true | embedded_comma = true | ||
linked_name = linked_name .. ", equivalent to " .. m_links.language_link { lang = enlang, term = name.eq } | |||
end | end | ||
table.insert( | table.insert(linked_names, linked_name) | ||
end | end | ||
if embedded_comma then | if embedded_comma then | ||
ins(table.concat(linked_names, "; or of ")) | |||
else | else | ||
ins(m_table.serialCommaJoin(linked_names, {conj = "or"})) | |||
end | |||
if args.addl then | |||
if args.addl:find("^;") then | |||
ins(args.addl) | |||
elseif args.addl:find("^_") then | |||
ins(" " .. args.addl:sub(2)) | |||
else | |||
ins(", " .. args.addl) | |||
end | |||
end | end | ||
ins("</span>") | |||
local categories = {} | local categories = {} | ||
for _, nametype in ipairs( | local function inscat(cat) | ||
local function insert_cats( | table.insert(categories, lang:getFullName() .. " " .. cat) | ||
end | |||
for _, nametype in ipairs(args.type) do | |||
local function insert_cats(dimaugof) | |||
local function insert_cats_type(ty) | local function insert_cats_type(ty) | ||
if ty == "unisex given name" then | if ty == "unisex given name" then | ||
| Line 695: | Line 1,226: | ||
insert_cats_type("female given name") | insert_cats_type("female given name") | ||
end | end | ||
for | for _, source in ipairs(sources) do | ||
inscat("renderings of " .. source:getCanonicalName() .. " " .. dimaugof .. ty .. "s") | |||
inscat("terms derived from " .. source:getCanonicalName()) | |||
if source:getCode() ~= | inscat("terms borrowed from " .. source:getCanonicalName()) | ||
if iargs.obor then | |||
inscat("orthographic borrowings from " .. source:getCanonicalName()) | |||
end | |||
if source:getCode() ~= source:getFullCode() then | |||
-- etymology language | -- etymology language | ||
inscat("renderings of " .. source:getFullName() .. " " .. dimaugof .. ty .. "s") | |||
end | end | ||
end | end | ||
| Line 715: | Line 1,250: | ||
end | end | ||
return table.concat(textsegs, "") .. | return table.concat(textsegs, "") .. m_utilities.format_categories(categories, lang, args.sort, nil, force_cat) | ||
end | end | ||
return export | return export | ||