This module contains functions for creating inflection tables for Dutch verbs.
local m_utilities = require("Module:utilities")
local m_links = require("Module:links")
local m_table = require("Module:table")
local lang = require("Module:languages").getByCode("nl")
local export = {}
-- Functions that do the actual inflecting by creating the forms of a basic term.
local inflections = {}
local irregular = {}
-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
local infl_type = frame.args or error("Inflection type has not been specified. Please pass parameter 1 to the module invocation.")
if not inflections then
error("Unknown inflection type '" .. infl_type .. "'")
end
local params = {
= {},
= {},
= {type = "boolean"},
= {},
= {},
= {},
= {},
= {},
= {},
= {},
}
for key, val in pairs(inflections.params) do
params = val
end
local args = require("Module:parameters").process(frame:getParent().args, params)
local data = {forms = {}, title = nil, categories = {}}
inflections.func(args, data)
postprocess(args, data)
if (args or "") ~= "" then
return make_bot_list(data, args)
else
return make_table(data, args) .. m_utilities.format_categories(data.categories, lang)
end
end
function postprocess(args, data)
-- Verbal noun
local vnoun = args
local vnoun2 = args
if vnoun then
data.forms = {vnoun, vnoun2}
end
-- Prefixed and separable
local pref = args
local sep = args
if pref then
table.insert(data.categories, "Dutch prefixed verbs")
table.insert(data.categories, "Dutch prefixed verbs with " .. pref .. "-")
data.title = data.title .. ", prefixed"
end
if sep then
table.insert(data.categories, "Dutch separable verbs")
table.insert(data.categories, "Dutch separable verbs with " .. sep)
data.title = data.title .. ", separable"
end
if not pref and not sep then
table.insert(data.categories, "Dutch basic verbs")
end
local abbr = args
add_pref(data, pref, abbr)
add_sep(data, sep, pref, abbr)
data.aux = args or "hebben"
if args then
if args == "zijn" then
require("Module:debug").track("nl-verb/zijn")
else
require("Module:debug").track("nl-verb/aux")
end
end
if args then
require("Module:debug").track("nl-verb/aux2")
end
data.trans = args
if data.trans then
if data.trans == "acc" then
table.insert(data.categories, "Dutch accusative verbs")
elseif data.trans == "erg" then
table.insert(data.categories, "Dutch ergative verbs")
elseif data.trans == "unerg" then
table.insert(data.categories, "Dutch unergative verbs")
elseif data.trans == "unacc" then
table.insert(data.categories, "Dutch unaccusative verbs")
else
error("The \"trans=\" parameter has an invalid value. Valid are: acc, erg, unerg, unacc.")
end
end
data.trans2 = args
if data.trans2 then
if data.trans2 == "acc" then
table.insert(data.categories, "Dutch accusative verbs")
elseif data.trans2 == "erg" then
table.insert(data.categories, "Dutch ergative verbs")
elseif data.trans2 == "unerg" then
table.insert(data.categories, "Dutch unergative verbs")
elseif data.trans2 == "unacc" then
table.insert(data.categories, "Dutch unaccusative verbs")
else
error("The \"trans2=\" parameter has an invalid value. Valid are: acc, erg, unerg, unacc.")
end
end
if not args then
require("Module:debug").track("nl-verb/no trans")
end
end
-- Add the unstressed prefix to all the verb forms, or
-- if there is no prefix, add ge- to the past participle
function add_pref(data, pref, abbr)
if pref then
-- Add prefix before every form
for key, form in pairs(data.forms) do
for i, subform in ipairs(form) do
-- Add hyphen if abbr=1
data.forms = not abbr and pref .. subform or pref .. "-" .. subform
end
end
else
-- Add ge- prefix before past participle
if data.forms then
for i, subform in ipairs(data.forms) do
if not abbr then
-- Place a diaeresis on the initial vowel of the stem if necessary
if mw.ustring.find(subform, "^") and not mw.ustring.find(subform, "^ij") then
subform = subform:gsub("^e", "ë"):gsub("^i", "ï"):gsub("^u", "ü")
end
end
-- Add hyphen if abbr=1
data.forms = not abbr and "ge" .. subform or "ge-" .. subform
end
end
end
end
-- Add the separable part to all the verb forms
function add_sep(data, sep, pref, abbr)
if not sep then
return
end
-- Add main clause forms
local mainforms = {}
for key, form in pairs(data.forms) do
if (key:find("^pres_") or key:find("^past_")) and not key:find("_ptc$") then
mainforms = mw.clone(form)
end
end
for key, form in pairs(mainforms) do
data.forms = form
end
-- Add separable part to forms
for key, form in pairs(data.forms) do
if key:find("_main$") or key:find("^impr_") then
-- For main-clause finite forms, add the separable part after the form, separated by a space
for i, subform in ipairs(data.forms) do
data.forms = data.forms .. " " .. sep
end
else
-- For all other forms, add the separable part before the form, with no space
for i, subform in ipairs(data.forms) do
-- Add a hyphen after the separable part if it ends with the same vowel
-- that the main/prefixed verb begins with, for verbs like na-apen,
-- also if abbr=1 but not for the past participle
if (mw.ustring.find("aeiou", sep:sub(-1)) and sep:sub(-1) == subform:sub(1, 1)) or (abbr and key ~= "past_ptc" and not pref) then
subform = sep .. "-" .. subform
else
subform = sep .. subform
end
data.forms = subform
end
end
end
end
--[=[
*** REGULAR VERBS (mostly) ***
]=]--
local function addform(data, key, form, index)
if data.forms then
if index then
table.insert(data.forms, index, form)
else
table.insert(data.forms, form)
end
else
data.forms = {form}
end
end
-- Conjugate a weak verb
inflections = {
params = {
= {required = true},
= {},
= {},
= {},
= {type = "boolean"},
},
func = function(args, data)
table.insert(data.categories, "Dutch weak verbs")
data.title = "weak"
local stems = {}
local abbr = args
stems = args or "{{{1}}}"
if not abbr then
stems = args
present(data, stems)
local dt = args or (stems:find("e$") and "t" or "d")
stems = stems:gsub("()i$", "%1ie") .. dt .. "e"
past(data, stems)
stems = args or make_long(stems) .. (stems:find("$") and "" or dt)
data.forms = {stems}
if stems:find("n$") then
table.insert(data.categories, "Dutch weak verbs with strong past participles")
data.title = data.title .. " with strong past participle"
end
-- "zeggen" has an irregular past tense alongside the regular one
if stems == "zeg" then
past(data, { = "zei", = "zeide", = "zeidt"}, 1)
table.insert(data.categories, "Dutch irregular weak verbs")
data.title = data.title .. ", irregular"
end
else
stems = stems .. "'e"
stems = stems .. "'t"
present(data, stems)
local dt = args or (stems:find("$") and "t" or "d")
stems = stems .. "'" .. dt .. "e"
past(data, stems)
stems = stems .. "'" .. dt
data.forms = {stems}
end
end
}
-- Conjugate a weak verb with a past tense in -cht
inflections = {
params = {
= {required = true},
= {},
= {required = true},
},
func = function(args, data)
table.insert(data.categories, "Dutch weak verbs (-cht)")
data.title = "weak with past in ''-cht''"
local stems = {}
stems = args or "{{{1}}}"
stems = args
present(data, stems)
stems = (args or "{{{3}}}") .. "cht"
past(data, stems)
stems = stems
data.forms = {stems}
end
}
local syncopic_verbs = m_table.listToSet {
"houd", "glijd", "rijd", "snijd"
}
-- Conjugate a strong verb
inflections = {
params = {
= {required = true},
= {required = true},
= {required = true},
= {},
= {},
= {},
= {},
},
func = function(args, data)
local class = args
table.insert(data.categories, "Dutch" .. (class and " class " .. class or "") .. " strong verbs")
data.title = "strong" .. (class and " class " .. class or "")
local stems = {}
stems = args or "{{{1}}}"
stems = args
present(data, stems)
stems = args or "{{{2}}}"
stems = args
stems = args
past(data, stems)
stems = args or "{{{3}}}"
data.forms = {stems}
-- If the final consonant of the past participle is not n, then it is a weak past participle.
if not stems:find("n$") then
table.insert(data.categories, "Dutch strong verbs with weak past participles")
data.title = data.title .. " with weak past participle"
end
-- some verbs have alternative forms without the final -d
if syncopic_verbs] then
local syncopic_form = stems:sub(1,-2)
addform(data, "pres_indc_1sg", syncopic_form, 1)
addform(data, "pres_indc_jij_inversion", syncopic_form, 1)
addform(data, "impr_sg", syncopic_form, 1)
table.insert(data.categories, "Dutch irregular strong verbs")
data.title = data.title .. ", slightly irregular"
elseif stems == "scheid" and args == "uit" then
addform(data, "pres_indc_1sg", "schei", 1)
addform(data, "pres_indc_jij_inversion", "schei", 1)
addform(data, "impr_sg", "schei", 1)
addform(data, "past_indc_sg", "schee", 1)
addform(data, "past_indc_pl", "scheeën", 1)
addform(data, "past_ptc", "scheeën", 1)
table.insert(data.categories, "Dutch irregular strong verbs")
data.title = data.title .. ", slightly irregular"
-- If the initial or final consonants of the present stem don't match, then this verb is irregular.
elseif stems:match("^(*)") ~= stems:match("^(*)") or stems:match("(*)$") ~= stems:match("(*)$") then
table.insert(data.categories, "Dutch irregular strong verbs")
data.title = data.title .. ", irregular"
end
end
}
-- Conjugate an irregular verb
inflections = {
params = {
= {required = true},
},
func = function(args, data)
local base = args or "zijn"
if irregular then
irregular(data)
else
error("Unknown irregular verb '" .. base .. "'.")
end
end
}
--[=[
*** IRREGULAR VERB TYPES ***
]=]--
irregular = function(data)
table.insert(data.categories, "Dutch irregular verbs")
data.title = "irregular"
present(data, { = "doe", = "doe"})
past(data, { = "deed", = "dede"})
data.forms = {"daan"}
data.forms = {"doet"}
data.forms = {"doet"}
end
irregular = function(data)
table.insert(data.categories, "Dutch irregular weak verbs")
data.title = "weak, irregular"
present(data, { = "heb", = "hebbe"})
past(data, { = "had", = "hadde"})
data.forms = {"had"}
data.forms = {"hebt", "heeft"}
data.forms = {"heeft"}
end
irregular = function(data)
table.insert(data.categories, "Dutch preterite-present verbs")
data.title = "preterite-present"
present(data, { = "durf", = "durve", = "durft"})
past(data, { = "dorst"})
data.forms = {"durfd"}
end
irregular = function(data)
table.insert(data.categories, "Dutch preterite-present verbs")
data.title = "preterite-present"
present(data, { = "kan", = "kunne", = "kunt"})
past(data, { = "kon", = "konde", = "kondt"})
addform(data, "pres_indc_jij", "kan")
addform(data, "pres_indc_u", "kan")
data.forms = {"kun"}
data.forms = {"kan"}
data.forms = {"kund"}
end
irregular = function(data)
table.insert(data.categories, "Dutch preterite-present verbs")
data.title = "preterite-present"
present(data, { = "moet"})
past(data, { = "moest"})
data.forms = {"moeten"}
end
irregular = function(data)
table.insert(data.categories, "Dutch preterite-present verbs")
data.title = "preterite-present"
present(data, { = "mag", = "moge", = "moogt"})
past(data, { = "mocht"})
data.forms = {"mag"}
data.forms = {"mag"}
data.forms = {"mag"}
data.forms = {"mogen"}
end
irregular = function(data)
table.insert(data.categories, "Dutch preterite-present verbs")
data.title = "preterite-present"
present(data, { = "weet", = "wete"})
past(data, { = "wist"})
data.forms = {"weten"}
end
irregular = function(data)
table.insert(data.categories, "Dutch irregular verbs")
data.title = "irregular"
present(data, { = "wil", = "wille"})
past(data, { = "wilde"})
past(data, { = "wou", = "woude", = "woudt"})
data.forms = {"wild"}
addform(data, "pres_indc_jij", "wil")
addform(data, "pres_indc_u", "wil")
data.forms = {"wil"}
end
irregular = function(data)
table.insert(data.categories, "Dutch irregular verbs")
table.insert(data.categories, "Dutch suppletive verbs")
data.title = "irregular, suppletive"
present(data, { = "ben", = "zij", = "zijt"})
past(data, { = "was", = "ware", = "waart"})
data.forms = {"weest"}
data.forms = {"bent"}
data.forms = {"bent", "is"}
data.forms = {"is"}
addform(data, "impr_sg", "wees", 1)
addform(data, "impr_pl", "weest", 1)
end
irregular = function(data)
table.insert(data.categories, "Dutch preterite-present verbs")
data.title = "preterite-present"
present(data, { = "zal", = "zulle", = "zult"})
past(data, { = "zou", = "zoude", = "zoudt"})
data.forms = {"zult", "zal"}
data.forms = {"zul"}
data.forms = {"zult", "zal"}
data.forms = {"zal"}
end
irregular = function(data)
table.insert(data.categories, "Dutch irregular verbs")
data.title = "irregular"
present(data, { = "wees", = "weze", = "weest"})
past(data, { = "was", = "ware", = "waart"})
data.forms = {"weest"}
data.forms = {"weest"}
data.forms = {"weest"}
data.forms = {"weest"}
end
--[=[
*** HELPER FUNCTIONS ***
]=]--
-- Create regular present-tense forms
function present(data, stems, index)
if not stems then
stems = stems .. "e"
end
if not stems then
if mw.ustring.find(stems, "t$") then
stems = make_long(stems)
else
stems = make_long(stems) .. "t"
end
end
addform(data, "pres_indc_1sg", stems, index)
addform(data, "pres_indc_jij", stems, index)
if mw.ustring.find(stems, "t$") or mw.ustring.find(stems, "mag$") or mw.ustring.find(stems, "wil$") then
-- do nothing
else
addform(data, "pres_indc_jij_inversion", stems, index)
end
addform(data, "pres_indc_gij", stems, index)
addform(data, "pres_indc_u" , stems, index)
addform(data, "pres_indc_3sg", stems, index)
addform(data, "pres_indc_pl" , make_long(stems) .. "n", index)
addform(data, "pres_subj_sg" , stems, index)
addform(data, "impr_sg", stems, index)
addform(data, "impr_pl", stems, index)
addform(data, "infinitive", make_long(stems) .. "n", index)
addform(data, "pres_ptc", make_long(stems) .. "nd", index)
end
-- Create regular past-tense forms
function past(data, stems, index)
if not stems then
if mw.ustring.find(stems, "e$") then
stems = stems
else
stems = stems .. "e"
end
end
if not stems then
if mw.ustring.find(stems, "e$") or mw.ustring.find(stems, "$") then
stems = stems
else
stems = stems .. "t"
end
end
addform(data, "past_indc_sg" , stems, index)
addform(data, "past_indc_gij" , stems, index)
addform(data, "past_indc_pl" , stems .. "n", index)
addform(data, "past_subj_sg" , stems, index)
end
-- A small helper function for those few verbs that have a stem ending in a
-- vowel (like gaan, staan, skiën, echoën). This lengthens the stem-final vowel.
function make_long(form)
return (form:gsub("()()$", "%1%2%2"):gsub("()i$", "%1ie"))
end
-- Make the table
function make_table(data, hasSep)
local function show_form(form, inversion)
if not form then
return "—"
elseif type(form) ~= "table" then
error("a non-table value was given in the list of inflected forms.")
end
local ret = {}
for key, subform in ipairs(form) do
table.insert(ret, m_links.full_link({lang = lang, term = subform}))
end
if inversion then
return table.concat(ret, "<sup>2</sup>, ")
else
return table.concat(ret, ", ")
end
end
local function repl(param)
if param == "lemma" then
return m_links.full_link({lang = lang, alt = mw.title.getCurrentTitle().text}, "term")
elseif param == "info" then
return data.title and " (" .. data.title .. ")" or ""
elseif param:find("inversion") then
return show_form(data.forms, true)
else
return show_form(data.forms, false)
end
end
local wikicode = [=[
{| style="border:1px solid var(--wikt-palette-indigo-3,#CCCCFF); text-align:center; line-height:125%" class="inflection-table vsSwitcher" data-toggle-category="inflection" cellspacing="1" cellpadding="3"
|- style="background: var(--wikt-palette-indigo-3,#CCCCFF);"
! colspan="5" class="vsToggleElement" style="text-align: left" | Conjugation of {{{lemma}}}{{{info}}}
|- class="vsShow" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ]
| style="min-width: 12em;" | {{{infinitive}}}
|- class="vsShow" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ] ]
| ]=] .. (hasSep and "{{{past_indc_sg_main}}}" or "{{{past_indc_sg}}}") .. [=[
|- class="vsShow" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ] ]
| {{{past_ptc}}}
|- class="vsHide" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ]
| colspan="4" | {{{infinitive}}}
|- class="vsHide" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ]
| colspan="4" | {{{infinitive}}} ]=] .. require("Module:gender and number").format_list({"n"}) .. (hasSep and [=[
|- class="vsHide" style="background: var(--wikt-palette-indigo-1,#E6E6FF);"
|
! colspan="2" style="font-weight: bold;" | ]
! colspan="2" style="font-weight: bold;" | ]
|- class="vsHide" style="background: var(--wikt-palette-indigo-1,#E6E6FF);"
|
! style="min-width: 12em; font-weight: bold" | ]
! style="min-width: 12em; font-weight: bold" | ]
! style="min-width: 12em; font-weight: bold" | ]
! style="min-width: 12em; font-weight: bold" | ]]=] or [=[
|- class="vsHide" style="background: var(--wikt-palette-indigo-1,#E6E6FF);"
|
! style="min-width: 12em; font-weight: bold" | ]
! style="min-width: 12em; font-weight: bold" | ]
|-]=]) .. [=[
|- class="vsHide" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ] ]
| ]=] .. (hasSep and "{{{pres_indc_1sg_main}}} || {{{past_indc_sg_main}}} || " or "") .. [=[{{{pres_indc_1sg}}} || {{{past_indc_sg}}}
|- class="vsHide" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ] ] (<span lang="nl">]</span>)
| ]=] .. (hasSep and "{{{pres_indc_jij_main}}}, {{{pres_indc_jij_inversion_main}}}<sup>2</sup> || {{{past_indc_sg_main}}} || " or "")
.. (hasSep and "{{{pres_indc_jij}}} || {{{past_indc_sg}}} "
or "{{{pres_indc_jij}}}, {{{pres_indc_jij_inversion}}}<sup>2</sup> || {{{past_indc_sg}}}") .. [=[
|- class="vsHide" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ] ] (<span lang="nl">]</span>)
| ]=] .. (hasSep and "{{{pres_indc_u_main}}} || {{{past_indc_sg_main}}} || " or "") .. [=[{{{pres_indc_u}}} || {{{past_indc_sg}}}
|- class="vsHide" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ] ] (<span lang="nl">]</span>)
| ]=] .. (hasSep and "{{{pres_indc_gij_main}}} || {{{past_indc_gij_main}}} || " or "") .. [=[{{{pres_indc_gij}}} || {{{past_indc_gij}}}
|- class="vsHide" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ] ]
| ]=] .. (hasSep and "{{{pres_indc_3sg_main}}} || {{{past_indc_sg_main}}} || " or "") .. [=[{{{pres_indc_3sg}}} || {{{past_indc_sg}}}
|- class="vsHide" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ]
| ]=] .. (hasSep and "{{{pres_indc_pl_main}}} || {{{past_indc_pl_main}}} || " or "") .. [=[{{{pres_indc_pl}}} || {{{past_indc_pl}}}
|- class="vsHide" style="background: var(--wikt-palette-indigo-1,#E6E6FF); height: 0.5em"
|
| colspan="2" |]=] .. (hasSep and =] or "") .. [=[
|- class="vsHide" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ] ]<sup>1</sup>
| ]=] .. (hasSep and "{{{pres_subj_sg_main}}} || {{{past_subj_sg_main}}} || " or "") .. [=[{{{pres_subj_sg}}} || {{{past_subj_sg}}}
|- class="vsHide" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ] ]<sup>1</sup>
| ]=] .. (hasSep and "{{{pres_indc_pl_main}}} || {{{past_indc_pl_main}}} || " or "") .. [=[{{{pres_indc_pl}}} || {{{past_indc_pl}}}
|- class="vsHide" style="background: var(--wikt-palette-indigo-1,#E6E6FF); height: 0.5em"
|
| colspan="2" |]=] .. (hasSep and =] or "") .. [=[
|- class="vsHide" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ] ]
| {{{impr_sg}}}
| rowspan="2" style="background: var(--wikt-palette-indigo-1,#E6E6FF);" |
|- class="vsHide" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ] ]<sup>1</sup>
| {{{impr_pl}}}
|- class="vsHide" style="background: var(--wikt-palette-indigo-1,#E6E6FF); height: 0.5em"
|
| colspan="2" |
|- class="vsHide" style="background: var(--wikt-palette-indigo-0,#F2F2FF);"
! style="background: var(--wikt-palette-indigo-2,#CCCCFF);" | ]
| {{{pres_ptc}}} || {{{past_ptc}}}
|- class="vsHide" style="background: var(--wikt-palette-indigo-1,#E6E6FF);"
| colspan="5" style="text-align:left; vertical-align:top; font-size: smaller; line-height: 1em"| <sup>1)</sup> ]. <sup>2)</sup> In case of ].
|}]=]
wikicode = mw.ustring.gsub(wikicode, "{{{(+)}}}", repl)
-- remove 'empty' 2sg forms (duplicates in case of inversion) + note
if mw.ustring.find(wikicode, ", —<sup>2</sup>") then
wikicode = mw.ustring.gsub(wikicode, ', —<sup>2</sup>', '')
wikicode = mw.ustring.gsub(wikicode, ' <sup>2%)</sup> In case of %%]%.', '')
end
return wikicode
end
function make_bot_list(data, hasSep)
local ret = ""
if hasSep then
ret = ret .. "* sep=1\n"
end
for key, form in pairs(data.forms) do
if type(form) == "table" then
for key2, subform in ipairs(form) do
ret = ret .. "* " .. key .. "_" .. key2 .. "=" .. subform .. "\n"
end
else
ret = ret .. "* " .. key .. "=" .. form .. "\n"
end
end
return ret
end
return export