|
|
| (79 intermediate revisions by the same user not shown) |
| Line 5: |
Line 5: |
| local find = mw.ustring.find | | local find = mw.ustring.find |
| local match = mw.ustring.match | | local match = mw.ustring.match |
| | local gmatch = mw.ustring.gmatch |
| local gsub = mw.ustring.gsub | | local gsub = mw.ustring.gsub |
| local u = mw.ustring.char | | local u = mw.ustring.char |
| local split = mw.text.split | | local split = mw.text.split |
| local gsplit = mw.text.gsplit | | local gsplit = mw.text.gsplit |
| | |
| | local PAGENAME = mw.title.getCurrentTitle().text |
| | local NAMESPACE = mw.title.getCurrentTitle().nsText |
| | local SUBPAGENAME = mw.title.getCurrentTitle().subpageText |
|
| |
|
| local legal_gender = { | | local legal_gender = { |
| Line 14: |
Line 19: |
| ["lun"] = true, | | ["lun"] = true, |
| ["sol"] = true, | | ["sol"] = true, |
| ["ter"] = true, | | ["ter"] = true, |
| ["p"] = true, | | ["?"] = true, |
| } | | } |
|
| |
|
| Line 22: |
Line 27: |
| ["lun"] = "lunar", | | ["lun"] = "lunar", |
| ["sol"] = "solar", | | ["sol"] = "solar", |
| ["ter"] = "terrestrial" | | ["ter"] = "terrestrial", |
| | ["?"] = "unknown", |
| } | | } |
|
| |
|
| Line 37: |
Line 43: |
| local lang = require("Module:languages").getByCode("qhv") | | local lang = require("Module:languages").getByCode("qhv") |
| local m_data = require("Module:qhv-noun/data") | | local m_data = require("Module:qhv-noun/data") |
| | |
| | local function glossary_link(entry, text) |
| | text = text or entry |
| | return "[[wikt:Appendix:Glossary#" .. entry .. "|" .. text .. "]]" |
| | end |
|
| |
|
| local function detect_gender(word) | | local function detect_gender(word) |
| local ending = sub(word, -1) | | local ending = word:sub(-1) |
| if find(word, "[aeioy]$") then | | if word:find("illa$") then |
| | return "aq" |
| | elseif word:find("[aeioy]$") then |
| return "lun" | | return "lun" |
| elseif ending == "r" then | | elseif ending == "r" then |
| Line 51: |
Line 64: |
| end | | end |
|
| |
|
| local function generate_genitive(word, args, data, decl_type) | | local function generate_gen_sg(word, rc, rp) |
| return m_data[word] and m_data[word](args, data) or m_data[decl_type](args, data) | | local genitive = {} |
| | local r = rc and "gen_co" |
| | for alt in gmatch(require("Module:qhv-noun/head").pass_to_module((rc and "gen_co" or rp and "gen_pa" or "gen_sg"), word), "[^,]+") do |
| | table.insert(genitive, alt) |
| | end |
| | return genitive |
| | end |
| | |
| | local function generate_nom_pl(word) |
| | local plural = {} |
| | for alt in gmatch(require("Module:qhv-noun/head").pass_to_module("nom_pl", word), "[^,]+") do |
| | table.insert(plural, alt) |
| | end |
| | return plural |
| end | | end |
|
| |
|
| Line 58: |
Line 84: |
| -- This is the only function that can be invoked from a template. | | -- This is the only function that can be invoked from a template. |
| function export.show(frame) | | function export.show(frame) |
| local frame_args = frame.args | | if NAMESPACE == "Template" and SUBPAGENAME ~= "doc" then return end |
| local parent_args = frame:getParent().args | | local parent_args = frame:getParent().args |
| PAGENAME = mw.title.getCurrentTitle().text
| |
| | | |
| local head = parent_args["head"]; if head == "" then head = nil end | | local head = parent_args["head"] or PAGENAME:match("%s") and require("Module:linkeach").link_for_modules(PAGENAME) or nil |
| local pass = {forms = {}, categories = {}}
| |
| local poscat = frame_args[1] or error("Part of speech has not been specified. Please pass parameter 1 to the module invocation.")
| |
| local class = frame_args[2]; if class == "" then class = nil end
| |
| | | |
| local data = {lang = lang, pos_category = poscat, categories = {}, heads = {head}, genders = {}, inflections = {}} | | local poscat = frame.args[1] or error("Part of speech has not been specified. Please pass parameter 1 to the module invocation.") |
| | local class = frame.args[2]; if class == "" then class = nil end |
| | |
| | local data = { |
| | lang = lang, |
| | heads = {head}, |
| | inflections = {}, |
| | genders = {}, |
| | pos_category = poscat, |
| | categories = {"Contionary"}, |
| | } |
| | | |
| if pos_functions[poscat] then | | if pos_functions[poscat] then |
| Line 78: |
Line 110: |
| pos_functions.nouns = function(class, args, data) | | pos_functions.nouns = function(class, args, data) |
| local params = { | | local params = { |
| [1] = {list = "g", default = detect_gender(PAGENAME)}, | | [1] = {default = detect_gender(PAGENAME)}, |
| [2] = {list = "gen"}, | | [2] = {default = PAGENAME}, |
| [3] = {list = "pl"}, | | ["nopl"] = {}, |
| [4] = {list = "dim"}, | | ["noinf"] = {type = "boolean", default = false}, |
| ["number"] = {}, | | ["gen"] = {}, |
| ["class"] = {}, | | ["pl"] = {}, |
| ["head"] = {default = PAGENAME}, | | ["head"] = {}, |
| ["m"] = {list = true}, | | ["rc"] = {type = "boolean"}, |
| ["f"] = {list = true}, | | ["rp"] = {type = "boolean"}, |
| | ["og"] = {}, |
| } | | } |
| | | |
| local args = require("Module:parameters").process(args, params) | | local args = require("Module:parameters").process(args, params) |
| local decl_type = require("Module:qhv-noun").detect_decl(table.concat(data.heads), args["number"], args["class"]) | | --data.heads = {args["head"]} |
| local decl_args = require("Module:parameters").process(parent_args, m_data[decl_type].params, true) | | |
| data.heads = {args["head"]}
| | table.insert(data.genders, args[1]) |
| | table.insert(data.categories, "High Valyrian " .. (args[1] == "?" and "" or gender_names[args[1]]) .. " " .. data.pos_category) |
| | | |
| | if not args["noinf"] then |
| | args["gen"] = generate_gen_sg(args["og"] or args[2], args["rc"], args["rp"]) |
| | | |
| -- Gender
| | for i, form in ipairs(args["gen"]) do |
| for _, g in ipairs(args[1]) do
| | args["gen"][i] = {term = form} |
| if legal_gender[g] then
| |
| table.insert(data.genders, g)
| |
|
| |
| if g == "p" then
| |
| table.insert(data.categories, "High Valyrian pluralia tantum")
| |
| end
| |
| else
| |
| table.insert(data.genders, "?")
| |
| end | | end |
| | |
| | args["gen"].label = "genitive" |
| | table.insert(data.inflections, args["gen"]) |
| end | | end |
|
| |
| -- Genitive
| |
| if not args[2][1] then
| |
| table.insert(args[2], generate_genitive(data.heads, args, data))
| |
| end
| |
|
| |
| for i, form in ipairs(args[2]) do
| |
| args[2][i] = {term = form}
| |
| end
| |
|
| |
| args[2].accel = {form = "gen|s"}
| |
| args[2].label = "genitive"
| |
| table.insert(data.inflections, args[2])
| |
|
| |
| if args[1][1] ~= "p" then
| |
| -- Plural
| |
| if not args[3][1] and data.pos_category == "nouns" then
| |
| table.insert(args[3], PAGENAME .. "en")
| |
| end
| |
| | | |
| if args[3][1] == "-" then
| | if data.pos_category == "nouns" and not args["noinf"] then |
| table.insert(data.inflections, {label = "no plural"}) | | if not args["nopl"] then |
| table.insert(data.categories, "German uncountable nouns")
| | args["pl"] = generate_nom_pl(args["og"] or args[2]) |
| elseif #args[3] > 0 then
| | |
| for i, form in ipairs(args[3]) do | | for i, form in ipairs(args["pl"]) do |
| args[3][i] = {term = form} | | args["pl"][i] = {term = form} |
| end | | end |
| | | |
| args[3].accel = {form = "p"} | | args["pl"].label = "plural" |
| args[3].label = "plural"
| | table.insert(data.inflections, args["pl"]) |
| table.insert(data.inflections, args[3]) | |
| end | | end |
| end
| |
|
| |
| -- Diminutive
| |
| if #args[4] > 0 then
| |
| for i, form in ipairs(args[4]) do
| |
| args[4][i] = {term = form, genders = {"n"}}
| |
| end
| |
|
| |
| args[4].accel = {form = "diminutive", gender = "n"}
| |
| args[4].label = "diminutive"
| |
| table.insert(data.inflections, args[4])
| |
| end
| |
|
| |
| -- Other gender
| |
| if #args.f > 0 then
| |
| args.f.label = "female"
| |
| table.insert(data.inflections, args.f)
| |
| end
| |
|
| |
| if #args.m > 0 then
| |
| args.m.label = "male"
| |
| table.insert(data.inflections, args.m)
| |
| end | | end |
| end | | end |
| Line 166: |
Line 155: |
| pos_functions.adjectives = function(class, args, data) | | pos_functions.adjectives = function(class, args, data) |
| local params = { | | local params = { |
| [1] = {list = "comp"}, | | [1] = {list = "eq"}, |
| [2] = {list = "sup"}, | | [2] = {list = "comp"}, |
| | [3] = {list = "sup"}, |
| | ["unc"] = {type = "boolean"}, |
| | ["indecl"] = {type = "boolean"}, |
| ["head"] = {}, | | ["head"] = {}, |
| } | | } |
| | |
| local args = require("Module:parameters").process(args, params) | | local args = require("Module:parameters").process(args, params) |
| | local isdet = data.pos_category == "determiners" |
| data.heads = {args["head"]} | | data.heads = {args["head"]} |
| | | |
| if args[1][1] == "-" then | | table.insert(data.categories, "High Valyrian " .. data.pos_category) |
| table.insert(data.inflections, {label = "not comparable"}) | | if args["unc"] or isdet then |
| table.insert(data.categories, "German uncomparable adjectives") | | table.insert(data.inflections, {label = "not " .. glossary_link("comparable")}) |
| return
| | if not isdet then table.insert(data.categories, "High Valyrian uncomparable adjectives") end |
| end
| | elseif args["indecl"] then |
| | | table.insert(data.inflections, {label = glossary_link("indeclinable")}) |
| if #args[1] > 0 then
| | table.insert(data.categories, "High Valyrian indeclinable " .. data.pos_category) |
| for i, form in ipairs(args[1]) do | |
| args[1][i] = {term = (form == "er" and PAGENAME .. "er" or form),
| |
| accel = {form = "comparative"}}
| |
| end
| |
| else | | else |
| args[1] = {request = true} | | args[1] = require("Module:qhv-adj/head").fetch("eq") |
| table.insert(data.categories, "de-adj lacking comparative") | | args[2] = require("Module:qhv-adj/head").fetch("comp") |
| | args[3] = require("Module:qhv-adj/head").fetch("sup") |
| | |
| | |
| | args[1].label = glossary_link("equative") |
| | args[2].label = glossary_link("comparative") |
| | args[3].label = glossary_link("superlative") |
| | |
| | table.insert(data.inflections, args[1]) |
| | table.insert(data.inflections, args[2]) |
| | table.insert(data.inflections, args[3]) |
| end | | end |
| args[1].label = "[[Appendix:Glossary#comparative|comparative]]"
| |
| table.insert(data.inflections, args[1])
| |
|
| |
| if #args[2] > 0 then
| |
| for i, form in ipairs(args[2]) do
| |
| args[2][i] = {
| |
| term = "am [[" .. (form == "sten" and PAGENAME .. "sten" or form) .. "]]",
| |
| accel = {form = "superlative"}}
| |
| end
| |
| else
| |
| args[2] = {request = true}
| |
| table.insert(data.categories, "de-adj lacking superlative")
| |
| end
| |
| args[2].label = "[[Appendix:Glossary#superlative|superlative]]"
| |
| table.insert(data.inflections, args[2])
| |
| end | | end |
|
| |
|
| pos_functions["proper nouns"] = pos_functions.nouns | | pos_functions["proper nouns"] = pos_functions.nouns |
| | pos_functions["determiners"] = pos_functions.adjectives |
|
| |
|
| pos_functions.verbs = function(class, args, data) | | pos_functions.verbs = function(class, args, data) |
| if args[2] then -- old-style | | local params = { |
| local params = {
| | [1] = {list = "pres"}, |
| [1] = {list = "pres", required = true},
| | [2] = {list = "subj"}, |
| ["pres_qual"] = {list = "pres=_qual", allow_holes = true},
| | [3] = {list = "pp"}, |
| [2] = {list = "past", required = true},
| | ["head"] = {}, |
| ["past_qual"] = {list = "past=_qual", allow_holes = true},
| | } |
| [3] = {list = "pp", required = true},
| | |
| ["pp_qual"] = {list = "pp=_qual", allow_holes = true},
| | local args = require("Module:parameters").process(args, params) |
| [4] = {list = "pastsubj"},
| | data.heads = {args["head"]} |
| ["pastsubj_qual"] = {list = "pastsubj=_qual", allow_holes = true},
| | |
| ["aux"] = {list = true},
| | table.insert(data.categories, "High Valyrian " .. data.pos_category) |
| ["aux_qual"] = {list = "aux=_qual", allow_holes = true},
| | |
| ["head"] = {list = true},
| | args[1] = require("Module:qhv-verb/head").fetch("act_ind_prs_1sg") |
| ["class"] = {list = true},
| | args[2] = require("Module:qhv-verb/head").fetch("act_sub_prs_1sg") |
| }
| | args[3] = require("Module:qhv-verb/head").fetch("act_part_prf") |
| | | |
| local args = require("Module:parameters").process(args, params)
| | args[1].label = "first-person singular present indicative" |
| data.heads = args["head"]
| | args[2].label = "first-person singular present subjunctive" |
| | | args[3].label = "perfect participle" |
| local function collect_forms(label, accel_form, forms, qualifiers)
| | |
| if forms[1] == "-" then
| | table.insert(data.inflections, args[1]) |
| return {label = "no " .. label}
| | table.insert(data.inflections, args[2]) |
| else
| | table.insert(data.inflections, args[3]) |
| local into_table = accel_form and {label = label, accel = {form = accel_form}} or {label = label}
| |
| for i, form in ipairs(forms) do
| |
| table.insert(into_table, {term = form, qualifiers = qualifiers[i] and {qualifiers[i]} or nil})
| |
| end
| |
| return into_table
| |
| end
| |
| end
| |
| | |
| if #args.class > 0 then
| |
| local class_descs, cats = require("Module:de-verb").process_verb_classes(args.class)
| |
| for _, cats in ipairs(cats) do
| |
| table.insert(data.categories, cats)
| |
| end
| |
| table.insert(data.inflections, {label = require("Module:table").serialCommaJoin(class_descs, {conj = "or"})})
| |
| end
| |
| table.insert(data.inflections, collect_forms("third-person singular present", "3|s|pres", args[1], args.pres_qual))
| |
| table.insert(data.inflections, collect_forms("past tense", "1//3|s|pret", args[2], args.past_qual))
| |
| table.insert(data.inflections, collect_forms("past participle", "perf|part", args[3], args.pp_qual))
| |
| if #args[4] > 0 then
| |
| table.insert(data.inflections, collect_forms("past subjunctive", "1//3|s|sub|II", args[4], args.pastsubj_qual))
| |
| end
| |
| if #args.aux > 0 then
| |
| table.insert(data.inflections, collect_forms("auxiliary", nil, args.aux, args.aux_qual))
| |
| end
| |
| return
| |
| end | |
| | |
| local function get_headword_inflection(forms, label, accel_form)
| |
| if forms then
| |
| local inflection = accel_form and {label = label, accel = {form = accel_form}} or {label = label}
| |
| for _, form in ipairs(forms) do
| |
| local qualifiers
| |
| if form.footnotes then
| |
| qualifiers = {}
| |
| for _, footnote in ipairs(form.footnotes) do
| |
| footnote = footnote:gsub("^%[(.*)%]$", "%1")
| |
| table.insert(qualifiers, footnote)
| |
| end
| |
| end
| |
| table.insert(inflection, {term = form.form, qualifiers = qualifiers})
| |
| end
| |
| return inflection
| |
| elseif label then
| |
| return {label = "no " .. label}
| |
| else
| |
| return {}
| |
| end
| |
| end
| |
| | |
| local alternant_multiword_spec = require("Module:de-verb").do_generate_forms(args, "from headword")
| |
| for _, cat in ipairs(alternant_multiword_spec.categories) do
| |
| table.insert(data.categories, cat) | |
| end | |
| table.insert(data.inflections, {label = table.concat(alternant_multiword_spec.verb_types, " or ")})
| |
| | |
| if #data.heads == 0 then | |
| for _, head in ipairs(alternant_multiword_spec.forms.infinitive_linked) do
| |
| table.insert(data.heads, head.form)
| |
| end
| |
| end
| |
| table.insert(data.inflections, get_headword_inflection(alternant_multiword_spec.forms.pres_3s,
| |
| "third-person singular present", "3|s|pres"))
| |
| local pret_3s = alternant_multiword_spec.forms.pret_3s | |
| table.insert(data.inflections, get_headword_inflection(pret_3s, "past tense", "1//3|s|pret"))
| |
| table.insert(data.inflections, get_headword_inflection(alternant_multiword_spec.forms.perf_part,
| |
| "past participle", "perf|part"))
| |
| -- See if we need the past subjunctive, i.e. there exist past subjunctive forms whose stem is not the
| |
| -- same as some past tense form. To facilitate comparison, we truncate final -e in both preterite 3s
| |
| -- and past subjunctive 3s, to handle cases like subjunctive 'ginge aus' vs. preterite 'ging aus'.
| |
| -- We need to compare 3s forms (and not e.g. 3p forms, where the issue with truncating -e doesn't
| |
| -- occur) so we work correctly with impersonal verbs. | |
| local need_past_subj
| |
| local truncated_pret_3s_forms = {}
| |
| if pret_3s then
| |
| for _, form in ipairs(pret_3s) do
| |
| local truncated_form = form.form:gsub("e$", ""):gsub("e ", " ") -- discard 2nd retval
| |
| table.insert(truncated_pret_3s_forms, truncated_form)
| |
| end
| |
| end
| |
| local subii_3s = alternant_multiword_spec.forms.subii_3s
| |
| local truncated_subii_3s_forms = {}
| |
| if subii_3s then
| |
| for _, form in ipairs(subii_3s) do
| |
| local truncated_form = form.form:gsub("e$", ""):gsub("e ", " ") -- discard 2nd retval
| |
| table.insert(truncated_subii_3s_forms, truncated_form)
| |
| end
| |
| end
| |
| for _, past_subj_form in ipairs(truncated_subii_3s_forms) do | |
| local saw_same = false
| |
| for _, pret_3s_form in ipairs(truncated_pret_3s_forms) do
| |
| if past_subj_form == pret_3s_form then
| |
| saw_same = true
| |
| break
| |
| end
| |
| end
| |
| if not saw_same then
| |
| need_past_subj = true
| |
| break
| |
| end
| |
| end
| |
| if need_past_subj then
| |
| table.insert(data.inflections, get_headword_inflection(subii_3s, "past subjunctive", "1//3|s|sub|II"))
| |
| end
| |
| | |
| local auxes = alternant_multiword_spec.forms.aux
| |
| table.insert(data.inflections, get_headword_inflection(auxes, "auxiliary")) | |
| end | | end |
|
| |
|
| return export | | return export |