モジュール:an-headword
ナビゲーションに移動
検索に移動
このモジュールについての説明文ページを モジュール:an-headword/doc に作成できます
----adaptation of [[Module:es-headoword]]
local export = {}
local pos_functions = {}
local u = mw.ustring.char
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rsplit = mw.text.split
local m_links = require("モジュール:links")
local com = require("モジュール:es-common") --using the Spanish module
local lang = require("モジュール:languages").getByCode("an")
local langname = lang:getCanonicalName()
local PAGENAME = mw.title.getCurrentTitle().text
local V = com.V -- vowel regex class
local AV = com.AV -- accented vowel regex class
local C = com.C -- consonant regex class
local rsub = com.rsub
local suffix_categories = {
["形容詞"] = true,
["副詞"] = true,
["名詞"] = true,
["動詞"] = true,
}
local prepositions = {
"a ", "cara ", "con ", "contra ", "cuentra ", "de ", "dende ", "dica ", "en ", "enta ", "entre ", "pa ", "por ", "seguntes ", "sin ", "sobre ", "ta ",
}
-- Add links around words. If multiword_only, do it only in multiword forms.
local function add_links(form, multiword_only)
if form == "" or form == " " then
return form
end
if not form:find("%[%[") then
if rfind(form, "[%s%p]") then --optimization to avoid loading [[Module:headword]] on single-word forms
local m_headword = require("モジュール:headword")
if m_headword.head_is_multiword(form) then
form = m_headword.add_multiword_links(form)
end
end
if not multiword_only and not form:find("%[%[") then
form = "[[" .. form .. "]]"
end
end
return form
end
local function track(page)
require("モジュール:debug").track("es-headword/" .. page)
return true
end
local function glossary_link(entry, text)
text = text or entry
return "[[Appendix:Glossary#" .. entry .. "|" .. text .. "]]"
end
local function check_all_missing(forms, plpos, tracking_categories)
for _, form in ipairs(forms) do
if type(form) == "table" then
form = form.term
end
if form then
local title = mw.title.new(form)
if title and not title.exists then
table.insert(tracking_categories, langname .. " " .. plpos .. " 活用形に赤リンク有り")
end
end
end
end
-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
local tracking_categories = {}
local poscat = frame.args[1]
or error("Part of speech has not been specified. Please pass parameter 1 to the module invocation.")
local params = {
["head"] = {list = true},
["json"] = {type = "boolean"},
["id"] = {},
}
local parargs = frame:getParent().args
if poscat == "名詞" and (not parargs[2] or parargs[2] == "") and parargs.pl2 then
track("noun-pl2-without-pl")
end
if pos_functions[poscat] then
for key, val in pairs(pos_functions[poscat].params) do
params[key] = val
end
end
local args = require("モジュール:parameters").process(parargs, params)
local data = {
lang = lang,
pos_category = poscat,
categories = {},
heads = args["head"],
genders = {},
inflections = {},
id = args["id"],
}
local lemma = m_links.remove_links(data.heads[1] or PAGENAME)
if lemma:find("^%-") then -- suffix
if poscat:find(" forms?$") then
data.pos_category = "接尾辞 定形"
else
data.pos_category = "接尾辞"
end
if suffix_categories[poscat] then
local singular_poscat = poscat:gsub("s$", "")
table.insert(data.categories, langname .. " " .. singular_poscat .. "-forming suffixes")
end
end
if pos_functions[poscat] then
pos_functions[poscat].func(args, data, tracking_categories, frame)
end
if args["json"] then
return require("モジュール:JSON").toJSON(data)
end
return require("モジュール:headword").full_headword(data)
.. require("モジュール:utilities").format_categories(tracking_categories, lang)
end
local function make_plural(form, special)
local retval = require("モジュール:romance utilities").handle_multiword(form, special, make_plural, prepositions)
if retval then
return retval
end
-- ends in -ero -> -ers (the excepctions which have to be given manually)
if rfind(form, "ero$") then return {rsub(form, "ero", "ers")} end
--ends in -no/lo -> -ns/ls, -nos/los
if rfind(form, "no$") then return {rsub(form, "no", "nos"),rsub(form, "no", "ns")} end
if rfind(form, "lo$") and not rfind(form, "llo$") then return {rsub(form, "lo", "los"),rsub(form, "lo", "ls")} end
-- ends in vowel. Note that nouns with a final epenthetic -e like abete (alternative form of abet) form their plurals as if they ended in -t (for example abete->abets)
if rfind(form, "[áéíóúaeiou]$") then return {form .. "s"} end
--ends in -p/c/l/n/r/f/ll/ny/nt
if rfind(form, "[pclnrf]$") or rfind(form, "ll$") or rfind(form, "ny$") or rfind(form, "nt$") then return {form .. "s"} end
-- ends in -Vt/-rt. Some loanwords might have a plural in -s
if rfind(form, "[aeiou]t$") then return {form .. "z"} end
if rfind(form, "[aeiou]rt$") then return {form .. "z"} end
-- ends in s with more than 1 syllable, last syllable unstressed
local syllables = com.syllabify(form)
if syllables[2] and rfind(form, "s$") and not rfind(syllables[#syllables], AV) then
return {form}
end
-- ends in -ch/s/x/z -> -itudis
if rfind(form, "és$") then return {rsub(form, "és", "eses")} end
if rfind(form, "ch$") then return {form .. "es"} end
if rfind(form, "[sxz]$") then return {form .. "es"} end
return nil
end
local function make_feminine(form, special)
local retval = require("モジュール:romance utilities").handle_multiword(form, special, make_feminine, prepositions)
if retval then
if #retval ~= 1 then
error("Internal error: Should have one return value for make_feminine: " .. table.concat(retval, ","))
end
return retval[1]
end
if form:find("o$") then
local retval = form:gsub("o$", "a") -- discard second retval
return retval
end
if form:find("aire$") then
local retval = form:gsub("$", "")
return retval
end
if form:find("ce$") then
local retval = form:gsub("ce$", "za")
return retval
end
if form:find("e$") then
local retval = form:gsub("e$", "a")
return retval
end
if form:find("eu$") then --in Latinisms the ending is -ea
local retval = form:gsub("eu$", "eua")
return retval
end
if form:find("au$") then
local retval = form:gsub("au$", "ada")
return retval
end
if form:find("íu$") then
local retval = form:gsub("íu$", "ida")
return retval
end
return form
end
local function make_masculine(form, special)
local retval = require("モジュール:romance utilities").handle_multiword(form, special, make_masculine, prepositions)
if retval then
if #retval ~= 1 then
error("Internal error: Should have one return value for make_masculine: " .. table.concat(retval, ","))
end
return retval[1]
end
if form:find("ora$") then
local retval = form:gsub("ora$", "ol") -- discard second retval
return retval
end
if form:find("a$") then
local retval = form:gsub("a$", "u") -- discard second retval
return retval
end
if form:find("á$") then
local retval = form:gsub("á$", "au") -- discard second retval
return retval
end
return form
end
local function do_adjective(args, data, tracking_categories, is_superlative)
local feminines = {}
local plurals = {}
local masculine_plurals = {}
local feminine_plurals = {}
if args.sp and not require("モジュール:romance utilities").allowed_special_indicators[args.sp] then
local indicators = {}
for indic, _ in pairs(require("モジュール:romance utilities").allowed_special_indicators) do
table.insert(indicators, "'" .. indic .. "'")
end
table.sort(indicators)
error("Special inflection indicator beginning can only be " ..
require("モジュール:table").serialCommaJoin(indicators, {dontTag = true}) .. ": " .. args.sp)
end
local argsf = args.f or {}
local argspl = args.pl or {}
local argsmpl = args.mpl or {}
local argsfpl = args.fpl or {}
if args.inv then
-- invariable adjective
table.insert(data.inflections, {label = "不変化"})
table.insert(data.categories, langname .. " 形容詞 不変化")
if args.sp or #argsf > 0 or #argspl > 0 or #argsmpl > 0 or #argsfpl > 0 then
error("Can't specify inflections with an invariable adjective")
end
else
local lemma = m_links.remove_links(data.heads[1] or PAGENAME)
-- Gather feminines.
if #argsf == 0 then
argsf = {"+"}
end
for _, f in ipairs(argsf) do
if f == "+" then
-- Generate default feminine.
f = make_feminine(lemma, args.sp)
elseif f == "#" then
f = lemma
end
table.insert(feminines, f)
end
if #argspl > 0 and (#argsmpl > 0 or #argsfpl > 0) then
error("Can't specify both pl= and mpl=/fpl=")
end
if #feminines == 1 and feminines[1] == lemma then
-- Feminine like the masculine; just generate a plural
if #argspl == 0 then
argspl = {"+"}
end
elseif #argspl == 0 then
-- Distinct masculine and feminine plurals
if #argsmpl == 0 then
argsmpl = {"+"}
end
if #argsfpl == 0 then
argsfpl = {"+"}
end
end
for _, pl in ipairs(argspl) do
if pl == "+" then
-- Generate default plural.
local defpls = make_plural(lemma, args.sp)
if not defpls then
error("Unable to generate default plural of '" .. lemma .. "'")
end
for _, defpl in ipairs(defpls) do
table.insert(plurals, defpl)
end
elseif pl == "#" then
table.insert(plurals, lemma)
else
table.insert(plurals, pl)
end
end
for _, mpl in ipairs(argsmpl) do
if mpl == "+" then
-- Generate default masculine plural.
local defpls = make_plural(lemma, args.sp)
if not defpls then
error("Unable to generate default plural of '" .. lemma .. "'")
end
for _, defpl in ipairs(defpls) do
table.insert(masculine_plurals, defpl)
end
elseif mpl == "#" then
table.insert(masculine_plurals, lemma)
else
table.insert(masculine_plurals, mpl)
end
end
for _, fpl in ipairs(argsfpl) do
if fpl == "+" then
for _, f in ipairs(feminines) do
-- Generate default feminine plural.
local defpls = make_plural(f, args.sp)
if not defpls then
error("Unable to generate default plural of '" .. f .. "'")
end
for _, defpl in ipairs(defpls) do
table.insert(feminine_plurals, defpl)
end
end
elseif fpl == "#" then
table.insert(feminine_plurals, lemma)
else
table.insert(feminine_plurals, fpl)
end
end
if args.mapoc then
check_all_missing(args.mapoc, "形容詞", tracking_categories)
end
check_all_missing(feminines, "形容詞", tracking_categories)
check_all_missing(plurals, "形容詞", tracking_categories)
check_all_missing(masculine_plurals, "形容詞", tracking_categories)
check_all_missing(feminine_plurals, "形容詞", tracking_categories)
if args.mapoc and #args.mapoc > 0 then
args.mapoc.label = "masculine singular before a noun"
table.insert(data.inflections, args.mapoc)
end
-- Make sure there are feminines given and not same as lemma.
if #feminines > 0 and not (#feminines == 1 and feminines[1] == lemma) then
feminines.label = "女性"
feminines.accel = {form = "f|s"}
table.insert(data.inflections, feminines)
end
if #plurals > 0 then
plurals.label = "複数"
plurals.accel = {form = "p"}
table.insert(data.inflections, plurals)
end
if #masculine_plurals > 0 then
masculine_plurals.label = "男性複数"
masculine_plurals.accel = {form = "m|p"}
table.insert(data.inflections, masculine_plurals)
end
if #feminine_plurals > 0 then
feminine_plurals.label = "女性複数"
feminine_plurals.accel = {form = "f|p"}
table.insert(data.inflections, feminine_plurals)
end
end
if args.comp and #args.comp > 0 then
check_all_missing(args.comp, "形容詞", tracking_categories)
args.comp.label = "比較級"
table.insert(data.inflections, args.comp)
end
if args.sup and #args.sup > 0 then
check_all_missing(args.sup, "形容詞", tracking_categories)
args.sup.label = "最上級"
table.insert(data.inflections, args.sup)
end
if args.irreg and is_superlative then
table.insert(data.categories, langname .. " 形容詞 最上級 不規則変化")
end
end
pos_functions["形容詞"] = {
params = {
["inv"] = {type = "boolean"}, --invariable
["sp"] = {}, -- special indicator: "first", "first-last", etc.
["f"] = {list = true}, --feminine form(s)
["pl"] = {list = true}, --plural override(s)
["fpl"] = {list = true}, --feminine plural override(s)
["mpl"] = {list = true}, --masculine plural override(s)
["mapoc"] = {list = true}, --masculine apocopated (before a noun)
["comp"] = {list = true}, --comparative(s)
["sup"] = {list = true}, --superlative(s)
},
func = function(args, data, tracking_categories)
return do_adjective(args, data, tracking_categories, false)
end
}
pos_functions["形容詞 比較級"] = {
params = {
["inv"] = {type = "boolean"}, --invariable
["sp"] = {}, -- special indicator: "first", "first-last", etc.
["f"] = {list = true}, --feminine form(s)
["pl"] = {list = true}, --plural override(s)
["fpl"] = {list = true}, --feminine plural override(s)
["mpl"] = {list = true}, --masculine plural override(s)
},
func = function(args, data, tracking_categories)
return do_adjective(args, data, tracking_categories, false)
end
}
pos_functions["形容詞 最上級"] = {
params = {
["inv"] = {type = "boolean"}, --invariable
["sp"] = {}, -- special indicator: "first", "first-last", etc.
["f"] = {list = true}, --feminine form(s)
["pl"] = {list = true}, --plural override(s)
["fpl"] = {list = true}, --feminine plural override(s)
["mpl"] = {list = true}, --masculine plural override(s)
["irreg"] = {type = "boolean"},
},
func = function(args, data, tracking_categories)
return do_adjective(args, data, tracking_categories, true)
end
}
pos_functions["過去分詞"] = {
params = {
[1] = {}, --FIXME: ignore this until we've fixed the uses
["inv"] = {type = "boolean"}, --invariable
["sp"] = {}, -- special indicator: "first", "first-last", etc.
},
func = function(args, data, tracking_categories)
return do_adjective(args, data, tracking_categories, false)
end
}
pos_functions["副詞"] = {
params = {
["sup"] = {list = true}, --superlative(s)
},
func = function(args, data, tracking_categories, frame)
if #args.sup > 0 then
check_all_missing(args.sup, "副詞", tracking_categories)
args.sup.label = "最上級"
table.insert(data.inflections, args.sup)
end
end,
}
pos_functions["基数"] = {
params = {
["f"] = {list = true}, --feminine(s)
["mapoc"] = {list = true}, --masculine apocopated form(s)
},
func = function(args, data, tracking_categories, frame)
data.pos_category = "数詞"
table.insert(data.categories, 1, langname .. " 基数")
if #args.f > 0 then
table.insert(data.genders, "m")
check_all_missing(args.f, "数詞", tracking_categories)
args.f.label = "feminine"
table.insert(data.inflections, args.f)
end
if #args.mapoc > 0 then
check_all_missing(args.mapoc, "数詞", tracking_categories)
args.mapoc.label = "masculine before a noun"
table.insert(data.inflections, args.mapoc)
end
end,
}
-- Display information for a noun's gender
-- This is separate so that it can also be used for proper nouns
function noun_gender(args, data)
local gender = args[1]
table.insert(data.genders, gender)
if #data.genders == 0 then
table.insert(data.genders, "?")
end
end
pos_functions["固有名詞"] = {
params = {
[1] = {},
},
func = function(args, data)
noun_gender(args, data)
end
}
-- Display additional inflection information for a noun
pos_functions["nouns"] = {
params = {
[1] = {required = true, default = "m"}, --gender
["g2"] = {}, --second gender
["e"] = {type = "boolean"}, --epicene
[2] = {list = "pl"}, --plural override(s)
["f"] = {list = true}, --feminine form(s)
["m"] = {list = true}, --masculine form(s)
["fpl"] = {list = true}, --feminine plural override(s)
["mpl"] = {list = true}, --masculine plural override(s)
["dim"] = {list = true}, --diminutive(s)
["aug"] = {list = true}, --diminutive(s)
["pej"] = {list = true}, --pejorative(s)
},
func = function(args, data, tracking_categories)
local allowed_genders = {
["m"] = true,
["f"] = true,
["m-p"] = true,
["f-p"] = true,
["mf"] = true,
["mf-p"] = true,
["mfbysense"] = true,
["mfbysense-p"] = true,
}
local lemma = m_links.remove_links(
(#data.heads > 0 and data.heads[1]) or PAGENAME
)
if args[1] == "m-f" then
args[1] = "mf"
elseif args[1] == "mfp" or args[1] == "m-f-p" then
args[1] = "mf-p"
end
if not allowed_genders[args[1]] then error("Unrecognized gender: " .. args[1]) end
table.insert(data.genders, args[1])
if args.g2 then table.insert(data.genders, args.g2) end
if args["e"] then
table.insert(data.categories, langname .. " epicene nouns")
table.insert(data.inflections, {label = glossary_link("epicene")})
end
local plurals = {}
if args[1]:find("%-p$") then
table.insert(data.inflections, {label = glossary_link("plural only")})
if #args[2] > 0 then
error("Can't specify plurals of a plurale tantum noun")
end
else
-- Gather plurals, handling requests for default plurals
for _, pl in ipairs(args[2]) do
if pl == "+" then
local default_pls = make_plural(lemma)
for _, defp in ipairs(default_pls) do
table.insert(plurals, defp)
end
elseif pl == "#" then
table.insert(plurals, lemma)
elseif pl:find("^%+") then
pl = require("モジュール:romance utilities").get_special_indicator(pl)
local default_pls = make_plural(lemma, pl)
for _, defp in ipairs(default_pls) do
table.insert(plurals, defp)
end
else
table.insert(plurals, pl)
end
end
-- Check for special plural signals
local mode = nil
if #plurals > 0 and #plurals[1] == 1 then
if plurals[1] == "?" or plurals[1] == "!" or plurals[1] == "-" or plurals[1] == "~" then
mode = plurals[1]
table.remove(plurals, 1) -- Remove the mode parameter
else
error("Unexpected plural code")
end
end
if mode == "?" then
-- Plural is unknown
table.insert(data.categories, langname .. " nouns with unknown or uncertain plurals")
elseif mode == "!" then
-- Plural is not attested
table.insert(data.inflections, {label = "plural not attested"})
table.insert(data.categories, langname .. " nouns with unattested plurals")
return
elseif mode == "-" then
-- Uncountable noun; may occasionally have a plural
table.insert(data.categories, langname .. " 不可算名詞")
-- If plural forms were given explicitly, then show "usually"
if #plurals > 0 then
table.insert(data.inflections, {label = "通常 " .. glossary_link("uncountable")})
table.insert(data.categories, langname .. " 可算名詞")
else
table.insert(data.inflections, {label = glossary_link("uncountable")})
end
else
-- Countable or mixed countable/uncountable
if #plurals == 0 then
local pls = make_plural(lemma)
if pls then
for _, pl in ipairs(pls) do
table.insert(plurals, pl)
end
end
end
if mode == "~" then
-- Mixed countable/uncountable noun, always has a plural
table.insert(data.inflections, {label = glossary_link("countable") .. " and " .. glossary_link("uncountable")})
table.insert(data.categories, langname .. " 不可算名詞")
table.insert(data.categories, langname .. " 可算名詞")
else
-- Countable nouns
table.insert(data.categories, langname .. " 可算名詞")
end
end
end
-- Gather masculines/feminines. For each one, generate the corresponding plural(s).
local function handle_mf(mfs, inflect, default_plurals)
local retval = {}
for _, mf in ipairs(mfs) do
if mf == "1" then
track("noun-mf-1")
end
if mf == "1" or mf == "+" then
-- Generate default feminine.
mf = inflect(lemma)
elseif mf == "#" then
mf = lemma
end
local special = require("モジュール:romance utilities").get_special_indicator(mf)
if special then
mf = inflect(lemma, special)
end
table.insert(retval, mf)
local mfpls = make_plural(mf, special)
if mfpls then
for _, mfpl in ipairs(mfpls) do
-- Add an accelerator for each masculine/feminine plural whose lemma
-- is the corresponding singular, so that the accelerated entry
-- that is generated has a definition that looks like
-- # {{plural of|es|MFSING}}
table.insert(default_plurals, {term = mfpl, accel = {form = "p", lemma = mf}})
end
end
end
return retval
end
local feminine_plurals = {}
local feminines = handle_mf(args.f, make_feminine, feminine_plurals)
local masculine_plurals = {}
local masculines = handle_mf(args.m, make_masculine, masculine_plurals)
local function handle_mf_plural(mfpl, default_plurals, singulars)
local new_mfpls = {}
for i, mfpl in ipairs(mfpl) do
local accel
if #mfpl == #singulars then
-- If same number of overriding masculine/feminine plurals as singulars,
-- assume each plural goes with the corresponding singular
-- and use each corresponding singular as the lemma in the accelerator.
-- The generated entry will have # {{plural of|es|SINGULAR}} as the
-- definition.
accel = {form = "p", lemma = singulars[i]}
else
accel = nil
end
if mfpl == "+" then
for _, defpl in ipairs(default_plurals) do
-- defpl is already a table
table.insert(new_mfpls, defpl)
end
elseif mfpl == "#" then
table.insert(new_mfpls, {term = lemma, accel = accel})
elseif mfpl:find("^%+") then
mfpl = require("モジュール:romance utilities").get_special_indicator(mfpl)
for _, mf in ipairs(singulars) do
local default_mfpls = make_plural(mf, mfpl)
for _, defp in ipairs(default_mfpls) do
table.insert(new_mfpls, {term = defp, accel = accel})
end
end
else
table.insert(new_mfpls, {term = mfpl, accel = accel})
end
end
return new_mfpls
end
if #args.fpl > 0 then
-- Override any existing feminine plurals.
feminine_plurals = handle_mf_plural(args.fpl, feminine_plurals, feminines)
end
if #args.mpl > 0 then
-- Override any existing masculine plurals.
masculine_plurals = handle_mf_plural(args.mpl, masculine_plurals, masculines)
end
check_all_missing(plurals, "名詞", tracking_categories)
check_all_missing(feminines, "名詞", tracking_categories)
check_all_missing(feminine_plurals, "名詞", tracking_categories)
check_all_missing(masculines, "名詞", tracking_categories)
check_all_missing(masculine_plurals, "名詞", tracking_categories)
check_all_missing(args.dim, "名詞", tracking_categories)
check_all_missing(args.aug, "名詞", tracking_categories)
check_all_missing(args.pej, "名詞", tracking_categories)
local function redundant_plural(pl)
for _, p in ipairs(plurals) do
if p == pl then
return true
end
end
return false
end
for _, mpl in ipairs(masculine_plurals) do
if redundant_plural(mpl) then
track("noun-redundant-mpl")
end
end
for _, fpl in ipairs(feminine_plurals) do
if redundant_plural(fpl) then
track("noun-redundant-fpl")
end
end
if #plurals > 0 then
plurals.label = "複数"
plurals.accel = {form = "p"}
table.insert(data.inflections, plurals)
end
if #feminines > 0 then
feminines.label = "女性"
feminines.accel = {form = "f"}
table.insert(data.inflections, feminines)
end
if #feminine_plurals > 0 then
feminine_plurals.label = "女性複数"
table.insert(data.inflections, feminine_plurals)
end
if #masculines > 0 then
masculines.label = "男性"
table.insert(data.inflections, masculines)
end
if #masculine_plurals > 0 then
masculine_plurals.label = "男性複数"
table.insert(data.inflections, masculine_plurals)
end
if #args.dim > 0 then
args.dim.label = glossary_link("diminutive")
table.insert(data.inflections, args.dim)
end
if #args.aug > 0 then
args.aug.label = glossary_link("augmentative")
table.insert(data.inflections, args.aug)
end
if #args.pej > 0 then
args.pej.label = glossary_link("pejorative")
table.insert(data.inflections, args.pej)
end
end
}
return export