Wikiwordbōc
angwiktionary
https://ang.wiktionary.org/wiki/H%C4%93afodtramet
MediaWiki 1.47.0-wmf.22
case-sensitive
Media
Syndrig
Mōtung
Brūcend
Brūcendmōtung
Wikiwordbōc
Wikiwordbōcmōtung
Ymele
Ymelmōtung
MediaWiki
MediaWikimōtung
Bysen
Bysenmōtung
Help
Helpmōtung
Flocc
Floccmōtung
Ætēaca
Ætēacmōtung
TimedText
TimedText talk
Module
Module talk
Event
Event talk
bēon
0
1100
55172
50822
2026-10-02T21:58:58Z
Deadend0914
7211
/* Englisc */
55172
wikitext
text/x-wiki
==Englisc==
===Wordstǣr===
Englisc ''[[bēon]]''. Bēon cymþ of worde þǣre mǣnunge "weorðan", eom, is, eart of þǣm worde "wesan", wæs, wǣron of þǣm worde "belīfan".
===Declīnung===
{{ang-conj|bēon<i>}}
===Wendunga===
*[[Ealdseaxisc]]: [[wesan]]
*[[Niðerlendisc]]: [[zijn]]
*[[Nīwenglisc]]: [[be]]
*[[Þēodisc]]: [[sein]]
s1v5tmy9h4mif3asbedpi4u5qb7vx2j
wordstǣr
0
1967
55149
55111
2026-10-02T20:48:50Z
Deadend0914
7211
/* Nama */
55149
wikitext
text/x-wiki
=={{sprǣc|ang}}==
===Rihstefn===
* IPA: /wordstæːr/
===Wordstǣr===
*Þæs wordes [[word]] and [[stǣr]]
===Nāhwæðer Nama ===
{{ang-noun|n|head=wordstǣr}}
# (nīweword) Sēo stǣr sumes wordes, þæt is, hū þæt word ēode of his fruman tō his andweardlican ansīene.
mrqrla49a5iwgdh53rfhjpnoynm63kj
saddle
0
2750
55129
53687
2026-10-02T19:32:59Z
~2026-52950-48
7223
55129
wikitext
text/x-wiki
=={{sprǣc|en}}==
===Wordstǣr===
Of {{inh|en|enm|sadel}}, of {{inh|en|ang|sadol}}, of {{inh|en|gmw-pro|*sadul}}, of {{inh|en|gem-pro|*sadulaz|t=sadol}}
===Rihtstefn===
IPA:/ˈsædl̩/
===Nama===
{{en-noun}}
#[[sadol]]
b7rdxaqdgahl0jqaek8tz40doggeorx
Module:fun
828
7862
55140
54380
2026-10-02T19:43:48Z
Deadend0914
7211
55140
Scribunto
text/plain
local export = {}
local debug_track_module = "Module:debug/track"
local table_get_unprotected_metatable = "Module:table/getUnprotectedMetatable"
local chain -- defined below
local chain_iter -- defined below
local format = string.format
local gmatch = string.gmatch
local ipairs = ipairs
local is_callable -- defined below
local pairs = pairs
local pcall = pcall
local rawget = rawget
local require = require
local select = select
local tostring = tostring
local type = type
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local unroll -- defined below
local xpcall = xpcall
local function debug_track(...)
debug_track = require(debug_track_module)
return debug_track(...)
end
local function get_unprotected_metatable(...)
get_unprotected_metatable = require(table_get_unprotected_metatable)
return get_unprotected_metatable(...)
end
local function _iterString(iter, i)
i = i + 1
local char = iter()
if char ~= nil then
return i, char
end
end
-- Iterate over UTF-8-encoded codepoints in string.
local function iterString(str)
return _iterString, gmatch(str, ".[\128-\191]*"), 0
end
--[==[
Return {true} if the input is a function or functor (an object which can be called like a function, because it has a {__call} metamethod).
Note: if the input is an object with a {__call} metamethod, but this function is not able to find it because the object's metatable is protected with {__metatable}, then it will return {false} by default, or {nil} if the {allow_maybe} flag is set.]==]
function export.is_callable(f, allow_maybe)
if type(f) == "function" then
return true
end
-- An object is a functor if it has a `__call` metamethod. The only way to truly confirm this is by trying to call it, but that could be expensive or have side effects, so look for a `__call` metamethod instead. If the metatable is protected with `__metatable`, this may not be possible.
local mt = get_unprotected_metatable(f)
if mt == nil then
return false
-- `get_unprotected_metatable` returns false if the metatable is protected.
elseif mt == false then
debug_track("fun/is_callable/protected metatable")
if allow_maybe then
return nil
end
return false
end
-- `__call` metamethods have to be functions, so don't recurse to check it.
local __call = rawget(mt, "__call")
return __call and type(__call) == "function" or false
end
is_callable = export.is_callable
--[==[
A version of {xpcall} which takes any arguments to be given to {f} as additional arguments after the error handler.
This fixes a deficiency in the standard version of {xpcall}, which is not able to handle arguments to be given to {f}, and brings it in line with {pcall}.]==]
function export.xpcall(f, err_handler, ...)
-- If there are no arguments, just call xpcall() with `f`.
if select("#", ...) == 0 then
return xpcall(f, err_handler)
end
-- Any arguments have to be smuggled in via a table, as ... can't be an
-- upvalue, and it's not possible to use pcall() to get aroud this, because
-- xpcall() calls the error handler before the stack unwinds.
local args = {...}
return xpcall(function()
return f(unpack(args))
end, err_handler)
end
do
local function catch_values(f, success, ...)
if success then
return success, ...
-- Error message will only take this exact form if `f` is not callable,
-- because it will contain a traceback if it was thrown further up the
-- stack.
elseif (...) == format("attempt to call a %s value", type(f)) then
return false
end
return error(...)
end
--[==[
A special form of {pcall()}, which returns {true} plus the result value(s) if {f} is callable, or {false} if it isn't. Errors that occur within the called function are not protected.]==]
function export.try_call(f, ...)
local callable = is_callable(f, true)
if callable then
return true, f(...)
elseif callable == false then
return false
end
-- If `callable` is nil, there's a protected metatable, so there's no way to check without doing a protected call.
return catch_values(f, pcall(f, ...))
end
end
--[==[
Takes two or more functions as arguments, and returns a new function which calls each of the input functions in turn. Any arguments given to the returned function are given to the first function, and all other functions receive the output value(s) from the previous function.]==]
function export.chain(func1, func2, ...)
local function chained_func(...)
return func2(func1(...))
end
if select("#", ...) == 0 then
return chained_func
end
return chain(chained_func, ...)
end
chain = export.chain
--[==[
Takes the usual for-loop parameters (an iterator, plus an optional state and initial index), and unrolls the iterator by returning every (first) value returned by the iterator.
For instance, {unroll(pairs(t))} will return every key in {t}, and {unroll(string.gmatch(s, "%w+"))} will return every word in {s}.]==]
function export.unroll(iter, state, k)
k = iter(state, k)
if k ~= nil then
return k, unroll(iter, state, k)
end
end
unroll = export.unroll
--[==[
Takes a generator function (i.e. a function that returns an iterator, such as {ipairs}) and one or more additional functions, and returns a new generator function. Any arguments given to the new generator (e.g. an input table) are given to the original generator, and the additional functions are called on each iteration. The first additional function takes the output from the original iterator (i.e. the function returned by the original generator), and any further functions receive the output value(s) from the previous function. This can be used to modify the values returned from an iterator.]==]
function export.chainIter(gen, new_iter, ...)
if select("#", ...) > 0 then
new_iter = chain(new_iter, ...)
end
return function(...)
local orig_iter, state, k = gen(...)
-- k has to be the first value returned by orig_iter on the last iteration, not whatever new_iter returned.
local function catch_values(...)
k = ...
if k ~= nil then
return new_iter(...)
end
end
return function()
return catch_values(orig_iter(state, k))
end, state, k
end
end
chain_iter = export.chainIter
do
local function catch_values(start, iter, state, k, ...)
if start == k or k == nil then
return k, ...
end
return catch_values(start, iter, state, iter(state, k))
end
function export.iterateFrom(start, iter, state, k)
local first = true
return function(state, k)
if first then
first = false
return catch_values(start, iter, state, iter(state, k))
end
return iter(state, k)
end, state, k
end
end
-- map(function(number) return number ^ 2 end,
-- { 1, 2, 3 }) --> { 1, 4, 9 }
-- map(function (char) return string.char(string.byte(char) - 0x20) end,
-- "abc") --> { "A", "B", "C" }
function export.map(func, iterable, isArray)
local array = {}
for k, v in (type(iterable) == "string" and iterString or (isArray or iterable[1] ~= nil) and ipairs or pairs)(iterable) do
array[k] = func(v, k, iterable)
end
return array
end
function export.mapIter(func, iter, state, init)
-- init could be anything
local array, i = {}, 0
for x, y in iter, state, init do
i = i + 1
array[i] = func(y, x, state)
end
return array
end
do
local function iter_tuples(tuples)
local i = tuples.i
if i > 1 then
i = i - 1
tuples.i = i
return unpack(tuples[i])
end
end
-- Takes an iterator function, and returns a new iterator that iterates in reverse, given the same arguments.
-- Note: changes to the state during iteration are not taken into account, since all the return values are calculated in advance.
function export.reverseIter(func)
return function(...)
-- Store all returned values as a list of tuples, then iterate in reverse over that list.
local tuples, i, iter, state, val1 = {}, 0, func(...)
while true do
i = i + 1
local vals = {iter(state, val1)}
-- Terminates if the first return value is nil, even if other values are non-nil.
val1 = vals[1]
if val1 == nil then
tuples.i = i
return iter_tuples, tuples
end
tuples[i] = vals
end
end
end
end
function export.forEach(func, iterable, isArray)
for k, v in (type(iterable) == "string" and iterString or (isArray or iterable[1] ~= nil) and ipairs or pairs)(iterable) do
func(v, k, iterable)
end
return nil
end
-------------------------------------------------
-- From http://lua-users.org/wiki/CurriedLua
-- reverse(...) : take some tuple and return a tuple of elements in reverse order
--
-- e.g. "reverse(1,2,3)" returns 3,2,1
local function reverse(...)
-- reverse args by building a function to do it, similar to the unpack() example
local function reverseHelper(acc, v, ...)
if select("#", ...) == 0 then
return v, acc()
else
return reverseHelper(function() return v, acc() end, ...)
end
end
-- initial acc is the end of the list
return reverseHelper(function() return end, ...)
end
function export.curry(func, numArgs)
-- currying 2-argument functions seems to be the most popular application
numArgs = numArgs or 2
-- no sense currying for 1 arg or less
if numArgs <= 1 then return func end
-- helper takes an argTrace function, and number of arguments remaining to be applied
local function curryHelper(argTrace, n)
if n == 0 then
-- kick off argTrace, reverse argument list, and call the original function
return func(reverse(argTrace()))
else
-- "push" argument (by building a wrapper function) and decrement n
return function(onearg)
return curryHelper(function() return onearg, argTrace() end, n - 1)
end
end
end
-- push the terminal case of argTrace into the function first
return curryHelper(function() return end, numArgs)
end
-------------------------------------------------
-- some(function(val) return val % 2 == 0 end,
-- { 2, 3, 5, 7, 11 }) --> true
function export.some(func, t, isArray)
for k, v in ((isArray or t[1] ~= nil) and ipairs or pairs)(t) do
if func(v, k, t) then
return true
end
end
return false
end
-- all(function(val) return val % 2 == 0 end,
-- { 2, 4, 8, 10, 12 }) --> true
function export.all(func, t, isArray)
for k, v in ((isArray or t[1] ~= nil) and ipairs or pairs)(t) do
if not func(v, k, t) then
return false
end
end
return true
end
function export.filter(func, t, isArray)
local new_t = {}
if isArray or t[1] ~= nil then -- array
local new_i = 0
for i, v in ipairs(t) do
if func(v, i, t) then
new_i = new_i + 1
new_t[new_i] = v
end
end
else
for k, v in pairs(t) do
if func(v, k, t) then
new_t[k] = v -- or create array?
end
end
end
return new_t
end
function export.fold(func, t, accum)
for i, v in ipairs(t) do
accum = func(accum, v, i, t)
end
return accum
end
-------------------------------
-- Fancy stuff
local function capture(...)
local vals = {n = select("#", ...), ...}
return function()
return unpack(vals, 1, vals.n)
end
end
-- Log input and output of function.
-- Receives a function and returns a modified form of that function.
function export.logReturnValues(func, prefix)
return function(...)
local inputValues = capture(...)
local returnValues = capture(func(...))
if prefix then
mw.log(prefix, inputValues())
mw.log(returnValues())
else
mw.log(inputValues())
mw.log(returnValues())
end
return returnValues()
end
end
export.log = export.logReturnValues
-- Convenience function to make all functions in a table log their input and output.
function export.logAll(t)
for k, v in pairs(t) do
if is_callable(v) then
t[k] = export.logReturnValues(v, tostring(k))
end
end
return t
end
return export
mc1wbmetcrpjp1ihyth6j2ajabvak7y
Brūcend:Deadend0914
2
8070
55158
54893
2026-10-02T21:22:37Z
Deadend0914
7211
55158
wikitext
text/x-wiki
=Standardization!=
==Parts of Speach==
* (a lot of these are already established, this is just a list)
*Noun - Nama
** Masculine - Werlic
** Feminine - Wīflic
** Neuter - Nāhwæðer
*Adjective - Tōgeīecendlic (note: this is also an adjective)
*Adverb - Bīword
*Case - Cāsus
** Accusative - Wrēgendlic
** Dative - Forgifendlic
** Genitive - Āgniendlic
** Imperative - Bebēodendlic
** Instrumental - Tōllic
** Nominative - Nemniendlic
** Subjunctive - Underþēodendlic
* Comparable or Comparative - Wiþmetendlīc
*Conjunction - Fēgung
*Declension(s) - Declīnung(a)
*Gender - Cynn
*Inflection - Gebīegednes
*Infinitive (or Indefinite) - Ungeendigendlic
*Interjection - Betwuxālegednes
*Lemma - Frumcenned
*Part of Speech - Dæl
*Participle - Dǣlnimend
*Person - Hād
*Plural - Manigfealdlic (mnf.)
*Preposition - Foresetednes
*Pronoun - Bīnama
*Proper Noun - Āgennama
*Singular - Ānfealdlic (anf.)
*Time - Tīd
** Past - Forþgewiten
** Perfect - Fullfremed
** Present - Andweardnes
*Verb - Word
** Strong - Strang
** Weak - Unstrang
=Templates=
==Noun Example (use 2 "=")==
*(script used is sprǣc|language-code surrounded by brackets ({}).
=={{sprǣc|ang}}==
===Āwendednessa (use 3 "=")===
* Here, you put alternate forms of words. Optional.
===Rihtstefn (use 3 "=")===
* Here, you put the pronunciation of the word.
* IPA: /whatever-word/
===Wordstǣr (use 3 "=")===
* Here, you put where the word came from. I'm still working on the script but it will be inh|current-language|language-from|word
* For now, use this format below
* Of (language, use the dative)
====Gesibbword====
* Same language Cognates
====Sweostorword====
* Non-same language Cognates)
====Cildru====
* Descendants
===(Gender if applicable) Nama (use 3 "=")===
* Still working on the script here, for now use 3 ' around the word!
'''example'''
* For definitions, use a #, and for examples, use #:
# It will look like this
#: This is an example!
====Declīnung (use 4 "=")====
* Here, you put the inflection table! The script is depending on the specific noun's conjugation! I'll make a page for that soon!
====Wendunga (use 4 "=")====
* Here, you put translations! Only for Englisc words!
* Categories go further down, but it doesn't really matter where, because they don't appear on the actual page anyway. We use Flocc:(whatever category name) inside square brackets "[]"
9kc94x2u10g429krimshvfu3ag6xgg4
55168
55158
2026-10-02T21:42:34Z
Deadend0914
7211
55168
wikitext
text/x-wiki
=Standardization!=
==Parts of Speach==
* (a lot of these are already established, this is just a list)
*Noun - Nama
** Masculine - Werlic
** Feminine - Wīflic
** Neuter - Nāhwæðer
*Adjective - Tōgeīecendlic (note: this is also an adjective)
*Adverb - Bīword
*Case - Cāsus
** Accusative - Wrēgendlic
** Dative - Forgifendlic
** Genitive - Āgniendlic
** Imperative - Bebēodendlic
** Instrumental - Tōllic
** Nominative - Nemniendlic
** Subjunctive - Underþēodendlic
* Comparable or Comparative - Wiþmetendlīc
*Conjunction - Fēgung
*Declension(s) - Declīnung(a)
*Gender - Cynn
*Inflection - Gebīegednes
*Infinitive (or Indefinite) - Ungeendigendlic
*Interjection - Betwuxālegednes
*Lemma - Frumcenned
*Part of Speech - Dæl
*Participle - Dǣlnimend
*Person - Hād
*Plural - Manigfealdlic (mnf.)
*Preposition - Foresetednes
*Pronoun - Bīnama
*Proper Noun - Āgennama
*Regular - Gemǣne
** Irregular - Ungemǣne
*Singular - Ānfealdlic (anf.)
*Time - Tīd
** Past - Forþgewiten
** Perfect - Fullfremed
** Present - Andweardnes
*Verb - Word
** Strong - Strang
** Weak - Unstrang
=Templates=
==Noun Example (use 2 "=")==
*(script used is sprǣc|language-code surrounded by brackets ({}).
=={{sprǣc|ang}}==
===Āwendednessa (use 3 "=")===
* Here, you put alternate forms of words. Optional.
===Rihtstefn (use 3 "=")===
* Here, you put the pronunciation of the word.
* IPA: /whatever-word/
===Wordstǣr (use 3 "=")===
* Here, you put where the word came from. I'm still working on the script but it will be inh|current-language|language-from|word
* For now, use this format below
* Of (language, use the dative)
====Gesibbword====
* Same language Cognates
====Sweostorword====
* Non-same language Cognates)
====Tudru====
* Descendants
===(Gender if applicable) Nama (use 3 "=")===
* Still working on the script here, for now use 3 ' around the word!
'''example'''
* For definitions, use a #, and for examples, use #:
# It will look like this
#: This is an example!
====Declīnung (use 4 "=")====
* Here, you put the inflection table! The script is depending on the specific noun's conjugation! I'll make a page for that soon!
====Wendunga (use 4 "=")====
* Here, you put translations! Only for Englisc words!
* Categories go further down, but it doesn't really matter where, because they don't appear on the actual page anyway. We use Flocc:(whatever category name) inside square brackets "[]"
4xntwqibeddoevxbrymxrprco021cf7
Module:sprǣcnaman
828
8074
55173
55040
2026-10-02T22:09:51Z
Deadend0914
7211
55173
Scribunto
text/plain
--[=[
Rēgister of sprǣcnaman (language names) for the Old English Wiktionary.
This is the single place where the Old English name of a language is entered. Everything that
displays a language name on this wiki reads it from here:
* [[Bysen:sprǣc]] (the ==L2== heading template) is a thin wrapper around sprǣc() below.
* [[Module:etymology]] and [[Module:etymology/templates]] use get_name() for headings and
category names, and get_of() for the "of"-form, because Old English uses "of" + genitive
when an ancestor or source language is mentioned, e.g. "Of Englisce and".
Names are entered without leading or trailing spaces. get_of() applies the following rules in
order:
1. an explicit entry in `of_names` (for names that follow no rule);
2. `-isc` + "e" (Englisc -> Englisce, Nīwenglisc -> Nīwenglisce, Þēodisc -> Þēodisce);
3. otherwise the nominative name is returned unchanged and the miss is tracked in
[[Wiktionary:Tracking/sprǣcnaman/no of-form]] so that an entry can be supplied.
Codes with no name at all display "?" (as [[Bysen:sprǣc]] always has) and are tracked in
[[Wiktionary:Tracking/sprǣc/unknown code]], see [[Special:WhatLinksHere/Wiktionary:Tracking/sprǣc/unknown code]].
]=]
local export = {}
local names = {
aa = "Cafarisc",
ab = "Apscƿisc",
af = "Affricanisc",
ak = "Ækanisc",
ang = "Englisc",
bn = "Bengalisc",
ca = "Catalānisc",
cs = "Bæmisc",
da = "Denisc",
de = "Þēodisc",
el = "Crēacisc",
en = "Nīƿenglisc",
enm = "Middelenglisc",
eo = "Esperantisc",
es = "Spēonisc",
et = "Eotolisc",
eu = "Wascisc",
fa = "Persisc",
fi = "Finnisc",
fo = "Faerisc",
fr = "Frencisc",
fra = "Frencisc",
frk = "Frencisc",
frp = "Profencalisc",
ga = "Īrisc",
gem = "Germanisc",
["gem-pro"] = "Ealdoric Germanisc",
gl = "Galizisc",
gn = "Aƿaisc",
["gmq-pro"] = "Ealdoric Noren",
gmw = "Ƿesterngermanisc",
["gmw-pro"] = "Ealdoric Ƿesterngermanisc",
goh = "Ealdhēahþēodisc",
got = "Gotisc",
gv = "Manisc",
haw = "Haƿaiisc",
hi = "Hindisc",
hu = "Ungrisc",
id = "Indonesisc",
io = "Idoisc",
ine = "Indoeuropisc",
["ine-pro"] = "Ealdoric Indoeuropisc",
is = "Īslendisc",
it = "Italisc",
iu = "Inuctitutisc",
la = "Lǣden",
li = "Limburgisc",
lt = "Litƿisc",
lv = "Lettisc",
mul = "Þēodeorþe",
nap = "Neapolitisc",
nl = "Niðerlendisc",
no = "Norþƿegisc",
non = "Eald Noren",
ovd = "Ælfdælisc",
pl = "Polisc",
pt = "Portugisc",
qu = "Kescƿisc",
ro = "Rumǣnisc",
ru = "Rusisc",
sa = "Sanscritisc",
sco = "Niderscyttisc",
sq = "Albānisc",
sv = "Sƿēonisc",
tpi = "Tok Pisin",
vo = "Volapük",
xpi = "Pihtisc"
}
--[=[
Codes that are needed in etymology lines (ancestors and source languages) but that have no
name yet. They currently display their '''English''' name (via [[Module:languages]]) and should
be given an Old English name here. The forms below are suggestions only and are deliberately
commented out until they have been checked against a source.
-- gem-pro = "?", -- Proto-Germanic
-- gmw-pro = "?", -- Proto-West Germanic
-- ine-pro = "?", -- Proto-Indo-European
-- enm = "Middelenglisc", -- Middle English
-- gmh = "Middelhēahþēodisc", -- Middle High German
-- odt = "Ealdniðerlendisc", -- Old Dutch
-- dum = "Middelniðerlendisc", -- Middle Dutch
-- ofs = "?", -- Old Frisian
-- osx = "Ealdseaxisc", -- Old Saxon
-- gml = "Middelniðersaxisc", -- Middle Low German
-- cel-pro = "?", -- Proto-Celtic
-- gmq-pro = "?", -- Proto-North Germanic
]=]
--[=[
Explicit "of"-forms, for names that the `-isc` rule cannot handle. Add an entry whenever
[[Wiktionary:Tracking/sprǣcnaman/no of-form]] lists a code that needs one. Suggestions
(commented out until checked against a source):
-- la = "Lǣdenes", -- Latin
-- non = "Eald Norðrena", -- Old Norse
-- mul = "Þēodeorðan", -- Translingual
-- vo = "Volapük", -- Volapük (no ending to inflect)
-- tpi = "Tok Pisin", -- Tok Pisin (no ending to inflect)
]=]
local of_names = {}
-- Spellings that may be passed to {{sprǣc}} or found in a ==L2== heading, mapped to their code.
local aliases = {
["Ænglisc"] = "ang",
}
-- Codes with no name display "?" and are tracked, so that the gaps are visible.
local function track(key)
local ok, track_module = pcall(require, "Module:debug/track")
if ok then
track_module(key)
end
end
function export.track_missing_name(code)
code = tostring(code)
if code == "" then
code = "(empty)"
end
track("sprǣc/unknown code/" .. code)
end
local function track_no_of_form(code)
track("sprǣcnaman/no of-form/" .. tostring(code))
end
-- Accept either a language code or a language object (from [[Module:languages]]).
local function code_candidates(x)
if type(x) ~= "table" then
return { x }
end
local codes = {}
local code = x.getCode and x:getCode()
if code then
codes[#codes + 1] = code
end
local full_code = x.getFullCode and x:getFullCode()
if full_code and full_code ~= code then
codes[#codes + 1] = full_code
end
return codes
end
--[==[
Return the Old English name of the given language (code or language object), or nil if the
language has no name yet. Used for ==L2== headings and for category names.
]==]
function export.get_name(x)
for _, code in ipairs(code_candidates(x)) do
if names[code] then
return names[code]
end
end
return nil
end
--[==[
Return the "of"-form of the given language (code or language object), or nil if the language
has no name yet. Used wherever Old English needs "of" + genitive, e.g. "Of Englisce and".
Names that follow no rule fall back to the nominative and are tracked.
]==]
function export.get_of(x)
for _, code in ipairs(code_candidates(x)) do
if names[code] then
return export.get_of_for_code(code)
end
end
return nil
end
function export.get_of_for_code(code)
local name = names[code]
if not name then
return nil
end
if of_names[code] then
return of_names[code]
end
if name:sub(-3) == "isc" then
return name .. "e"
end
track_no_of_form(code)
return name
end
local code_of_name, lower_code_of_name
local function make_reverse_maps()
if code_of_name then
return
end
code_of_name, lower_code_of_name = {}, {}
for alias, code in pairs(aliases) do
code_of_name[alias] = code
lower_code_of_name[mw.ustring.lower(alias)] = code
end
for code, name in pairs(names) do
code_of_name[name] = code_of_name[name] or code
local lower = mw.ustring.lower(name)
lower_code_of_name[lower] = lower_code_of_name[lower] or code
end
end
--[==[
Return the code of the language with the given Old English name, or nil. Used by
[[Module:etymology/templates]] to match an ==L2== heading back to its language.
]==]
function export.get_code(name)
if type(name) ~= "string" then
return nil
end
name = mw.text.trim(name)
if name == "" then
return nil
end
make_reverse_maps()
return code_of_name[name] or lower_code_of_name[mw.ustring.lower(name)]
end
--[==[
Entry point for [[Bysen:sprǣc]]: {{sprǣc|CODE}} gives the name, {{sprǣc|CODE|of}} the
"of"-form. A code with no name gives "?" and is tracked, exactly as the template always has.
]==]
export["sprǣc"] = function(frame)
local args = frame and frame.args or {}
local code = mw.text.trim(args[1] or "")
local mode = mw.text.trim(args[2] or "")
if code == "" then
export.track_missing_name("")
return "?"
end
local name
if mode == "of" or mode == "gen" or mode == "genitive" then
name = export.get_of(code)
else
name = export.get_name(code)
if not name then
-- The argument may be a name rather than a code (e.g. "Englisc").
local matched_code = export.get_code(code)
name = matched_code and names[matched_code] or nil
end
end
if not name then
export.track_missing_name(code)
return "?"
end
return name
end
--[==[
Entry point for templates that need the "of"-form only:
{{#invoke:sprǣcnaman|of|CODE}}.
]==]
function export.of(frame)
local args = frame and frame.args or {}
local code = mw.text.trim(args[1] or "")
if code == "" then
export.track_missing_name("")
return "?"
end
local name = export.get_of(code)
if not name then
export.track_missing_name(code)
return "?"
end
return name
end
-- The tables are exposed for tests and maintenance scripts; use the getters elsewhere.
export.names = names
export.of_names = of_names
return export
gdhkb7x7mm1voqav3kab5tja9ms0cvk
Module:floccnaman
828
8082
55145
55116
2026-10-02T20:17:57Z
Deadend0914
7211
55145
Scribunto
text/plain
--[=[
Floccnaman (category names) for the Old English Wiktionary.
Every category that a reader sees on an entry page is built as "<sprǣc> <word>" or
"<sprǣc> <word> <word>", exactly like the categories that already exist by hand on this wiki
("Englisc nama", "Nīwenglisc fégung", "Eald Noren werlic nama"), so only the words need
translating, never the word order.
The modules that build such categories ([[Module:headword]], [[Module:headword utilities]],
[[Module:form of]], [[Module:gender and number]], [[Module:affix]], [[Module:etymology]],
[[Module:etymology/specialized]], [[Module:ang-headword]]) ask this module for the Old English
wording first and keep the English wording if it is not here yet. Every missing wording is
tracked in [[Wiktionary:Tracking/flocc/untranslated/<wording>]], so the list of what still needs
to be added is always up to date:
[[Special:WhatLinksHere/Wiktionary:Tracking/flocc/untranslated]]
Words are entered without leading or trailing spaces, in the singular for parts of speech
("nama", not "naman"), because that is what the pre-existing categories use. The plural forms
used for the lemma categories are entered separately ("lemmas", "non-lemma forms", ...).
Only categories a reader sees on an entry page are translated here. Maintenance and tracking
categories (sortkeys, script codes, requests, pages with ...), the categories of the template
namespace and the ones produced by MediaWiki itself stay English on purpose.
]=]
local export = {}
--[=[
English wording -> Old English wording.
The words in this first group are already used by categories and template names that exist on
this wiki, so their spelling is established ("Flocc:Nama", "Flocc:Bīnaman", "Flocc:Nīwenglisc
fégung", "Bysen:Tōgeīecendlic-Tabule", "Cynn 1 strang forþgewiten dǣlnimend"), and the gender
words match the existing "Eald Noren werlic nama" style.
]=]
local words = {
-- Parts of speech.
["nouns"] = "naman",
["noun forms"] = "nama cynde",
["verbs"] = "word",
["verb forms"] = "word gebīegednessa",
["adjectives"] = "tōgeīecendlice word",
["adverbs"] = "bīword",
["conjunctions"] = "fégunga",
["pronouns"] = "bīnaman",
["prepositions"] = "foresetnessa",
["participles"] = "dǣlnimend",
["past participles"] = "forþgewiten dǣlnimend",
["present participles"] = "andweard dǣlnimend",
["masculine"] = "werlic",
["masculine nouns"] = "werlic naman",
["masculine a-stem nouns"] = "werlic a-stefn naman",
["feminine"] = "wīflic",
["feminine nouns"] = "wīflic naman",
["neuter"] = "nāhwæðer",
["neuter nouns"] = "nāhwæðer naman",
["neuter a-stem nouns"] = "nāhwæðer a-stefn naman",
["lemmas"] = "frumcennede word",
["non-lemma forms"] = "gebīegede word",
["variant lemmas"] = "ōþre frumcennede word",
["variant non-lemma forms"] = "ōþre gebīegede word",
["proper nouns"] = "āgennama",
["numerals"] = "getælu",
["letters"] = "stafas",
["proverbs"] = "gecyndesprǣce",
["other languages"] = "ōþre sprǣce",
["terms borrowed from"] = "word borgodon of",
["terms borrowed back into"] = "word borgodon tō",
["terms inherited from"] = "word ierfde of",
["terms derived from"] = "word ofgangende fram",
["learned borrowings"] = "leornode borgiende",
["compound words"] = "manigfeald word",
["abbreviations"] = "scortnessa",
["plural"] = "manigfeald",
["phrases"] = "cwidas",
["determiners"] = "bīnama",
["symbols"] = "rūna",
["countable nouns"] = "tellendlīc naman",
["uncountable nouns"] = "untellendlīc naman",
["initialisms"] = "styrtende stæfgefēg",
["particles"] = "grot",
["pages with entries"] = "trāmetas mid word",
["terms spelled with"] = "word areahton mid"
}
--[=[
Wording still to be translated. Anything listed here (or used in a module but not listed at
all) falls back to its English form and shows up in
[[Wiktionary:Tracking/flocc/untranslated]], so nothing breaks while the table is filled in.
Suggestions, commented out until checked against a source:
-- ["suffixes"] = "?", -- "Englisc ?"
-- ["prefixes"] = "?",
-- ["interjections"] = "?",
-- ["Translingual"] = "?",
-- ["taxonomic names"] = "?",
]=]
--[=[
Wording that carries a variable part, as a leading phrase. For example the affix templates
build categories such as "terms suffixed with -kas", where only the beginning is fixed; the
language name is prepended by the caller. Longest phrase first, so the most specific rule wins.
]=]
local prefixes = {
{"terms spelled with ", "word areahton mid "}
-- {"terms suffixed with ", "?"},
-- {"terms prefixed with ", "?"},
-- {"terms circumfixed with ", "?"},
-- {"terms infixed with ", "?"},
-- {"terms interfixed with ", "?"},
}
local function track(text)
local ok, track_module = pcall(require, "Module:debug/track")
if ok then
track_module("flocc/untranslated/" .. tostring(text))
end
end
--[==[
Return the Old English wording for one category name, or nil if it is not known yet. `lang` is
accepted so that a wording can later be made language-specific if that turns out to be needed.
]==]
function export.translate(lang, text)
if type(text) ~= "string" or text == "" then
return nil
end
if words[text] then
return words[text]
end
for _, rule in ipairs(prefixes) do
if text:sub(1, #rule[1]) == rule[1] then
return rule[2] .. text:sub(#rule[1] + 1)
end
end
track(text)
return nil
end
--[==[
Return the Old English wording for one category name, or the English wording unchanged if it is
not known yet. Use this in the modules that build categories: the language name is prepended by
the caller, so only the wording itself is passed in.
]==]
function export.get(lang, text)
return export.translate(lang, text) or text
end
-- The table is exposed for tests and maintenance scripts; use get() elsewhere.
export.words = words
return export
d7eujeqcajs8zlkons77css84bv6eax
deth
0
8174
55147
55084
2026-10-02T20:33:54Z
Deadend0914
7211
/* Nama */
55147
wikitext
text/x-wiki
=={{sprǣc|enm}}==
===Rihtstefn===
* IPA: /dɛ̝ːθ/
===Wordstǣr===
{{inh+|enm|ang|dēaþ}}, from {{inh|enm|gmw-pro|*dauþu}}, from {{inh|enm|gem-pro|*dauþuz}}.
===Nama===
{{enm-noun|pl=es|-}}
# [[dēaþ]]
===Tudru===
* {{desctree|en|death|qq=obsolete {{en|deth}}|noalts=1}}
* {{desc|gmw-msc|dethe|deith|deth}}
** {{desc|sco|daeth|daith|death|deeth|deith}}
erhaxe2vmw5nczn4wahqs2l2wurvzse
sadel
0
8193
55130
2026-10-02T19:35:24Z
Deadend0914
7211
Gesceop tramet þe hafaþ '=={{sprǣc|enm}}== ===Wordstǣr=== Of {{inh|en|ang|sadol}}, of {{inh|en|gmw-pro|*sadul}}, of {{inh|en|gem-pro|*sadulaz|t=sadol}} ===Rihtstefn=== IPA:/ˈsadəl/ ===Nama=== {{enm-noun|sadels}} #[[sadol]]'
55130
wikitext
text/x-wiki
=={{sprǣc|enm}}==
===Wordstǣr===
Of {{inh|en|ang|sadol}}, of {{inh|en|gmw-pro|*sadul}}, of {{inh|en|gem-pro|*sadulaz|t=sadol}}
===Rihtstefn===
IPA:/ˈsadəl/
===Nama===
{{enm-noun|sadels}}
#[[sadol]]
gufs94rkduy5xtyoupcw6r1in68n8fq
Bysen:plural of
10
8194
55131
2026-10-02T19:37:02Z
Deadend0914
7211
Gesceop tramet þe hafaþ '{{ {{#if:{{{lang|}}}|check deprecated lang param usage|no deprecated lang param usage}}|lang={{{lang|}}}|<!-- -->{{#invoke:form of/templates|tagged_form_of_t|p}}<!-- -->}}<!-- (end of {{check deprecated lang param usage}}) --><noinclude>{{documentation}}</noinclude>'
55131
wikitext
text/x-wiki
{{ {{#if:{{{lang|}}}|check deprecated lang param usage|no deprecated lang param usage}}|lang={{{lang|}}}|<!--
-->{{#invoke:form of/templates|tagged_form_of_t|p}}<!--
-->}}<!-- (end of {{check deprecated lang param usage}})
--><noinclude>{{documentation}}</noinclude>
k1pd739jmndfrq1wg4ur8yjqyjsqdms
Bysen:no deprecated lang param usage
10
8195
55132
2026-10-02T19:37:23Z
Deadend0914
7211
Gesceop tramet þe hafaþ '<onlyinclude>{{{1|}}}</onlyinclude>{{documentation}}'
55132
wikitext
text/x-wiki
<onlyinclude>{{{1|}}}</onlyinclude>{{documentation}}
r4cd6eb8p4xjus4wmk4qvx6l1j575js
Module:form of/templates
828
8196
55133
2026-10-02T19:37:57Z
Deadend0914
7211
Gesceop tramet þe hafaþ 'local export = {} local debug_track_module = "Module:debug/track" local form_of_module = "Module:form of" local functions_module = "Module:fun" local headword_data_module = "Module:headword/data" local languages_module = "Module:languages" local load_module = "Module:load" local parameters_module = "Module:parameters" local parameter_utilities_module = "Module:parameter utilities" local parse_interface_module = "Module:parse interface" local string_utilities_mod...'
55133
Scribunto
text/plain
local export = {}
local debug_track_module = "Module:debug/track"
local form_of_module = "Module:form of"
local functions_module = "Module:fun"
local headword_data_module = "Module:headword/data"
local languages_module = "Module:languages"
local load_module = "Module:load"
local parameters_module = "Module:parameters"
local parameter_utilities_module = "Module:parameter utilities"
local parse_interface_module = "Module:parse interface"
local string_utilities_module = "Module:string utilities"
local table_module = "Module:table"
local utilities_module = "Module:utilities"
local insert = table.insert
local ipairs = ipairs
local pairs = pairs
local require = require
local boolean_param = {type = "boolean"}
-- FIXME: Finish [[Module:format utilities]].
-- local allowed_conj_set = require(format_utilities_module).allowed_conj_set_for_join_segments
local allowed_conj_set = {["and"] = true, ["or"] = true, ["and/or"] = true}
--[==[
Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no overhead after the first call, since the target functions are called directly in any subsequent calls.]==]
local function debug_track(...)
debug_track = require(debug_track_module)
return debug_track(...)
end
local function decode_entities(...)
decode_entities = require(string_utilities_module).decode_entities
return decode_entities(...)
end
local function extend(...)
extend = require(table_module).extend
return extend(...)
end
local function format_categories(...)
format_categories = require(utilities_module).format_categories
return format_categories(...)
end
local function format_form_of(...)
format_form_of = require(form_of_module).format_form_of
return format_form_of(...)
end
local function get_lang(...)
get_lang = require(languages_module).getByCode
return get_lang(...)
end
local function gsplit(...)
gsplit = require(string_utilities_module).gsplit
return gsplit(...)
end
local function is_callable(...)
is_callable = require(functions_module).is_callable
return is_callable(...)
end
local function load_data(...)
load_data = require(load_module).load_data
return load_data(...)
end
local function parse_inline_modifiers(...)
parse_inline_modifiers = require(parse_interface_module).parse_inline_modifiers
return parse_inline_modifiers(...)
end
local function pattern_escape(...)
pattern_escape = require(string_utilities_module).pattern_escape
return pattern_escape(...)
end
local function process_params(...)
process_params = require(parameters_module).process
return process_params(...)
end
local function safe_load_data(...)
safe_load_data = require(load_module).safe_load_data
return safe_load_data(...)
end
local function split(...)
split = require(string_utilities_module).split
return split(...)
end
local function split_tag_set(...)
split_tag_set = require(form_of_module).split_tag_set
return split_tag_set(...)
end
local function tagged_inflections(...)
tagged_inflections = require(form_of_module).tagged_inflections
return tagged_inflections(...)
end
local function trim(...)
trim = require(string_utilities_module).trim
return trim(...)
end
local function ucfirst(...)
ucfirst = require(string_utilities_module).ucfirst
return ucfirst(...)
end
--[==[
Loaders for objects, which load data (or some other object) into some variable, which can then be accessed as "foo or get_foo()", where the function get_foo sets the object to "foo" and then returns it. This ensures they are only loaded when needed, and avoids the need to check for the existence of the object each time, since once "foo" has been set, "get_foo" will not be called again.]==]
local force_cat
local function get_force_cat()
force_cat, get_force_cat = require(form_of_module).force_cat, nil
return force_cat
end
local m_form_of_pos
local function get_m_form_of_pos()
m_form_of_pos, get_m_form_of_pos = load_data(headword_data_module).pos_aliases, nil
return m_form_of_pos
end
local module_prefix
local function get_module_prefix()
module_prefix, get_module_prefix = require(form_of_module).form_of_lang_data_module_prefix, nil
return module_prefix
end
--[==[ intro:
This module contains code that directly implements {{tl|form of}}, {{tl|inflection of}}, and the various other
[[:Category:Form-of templates|form-of templates]]. It is meant to be called directly from templates. See also
[[Module:form of]], which contains the underlying implementing code and is meant to be called from other modules.
]==]
-- Add tracking category for PAGE when called from TEMPLATE. The tracking category linked to is
-- [[Wiktionary:Tracking/form of/TEMPLATE/PAGE]]. If TEMPLATE is omitted, the tracking category is of the form
-- [[Wiktionary:Tracking/form of/PAGE]].
local function track(page, template)
debug_track("form of/" .. (template and template .. "/" or "") .. page)
end
local function get_common_template_params()
return {
-- Named params not controlling link display
["cat"] = {list = true, sublist = "comma without whitespace", flatten = true},
["notext"] = boolean_param,
["sort"] = true,
["enclitic"] = true,
-- FIXME! The following should only be available when withcap=1 in invocation args or when withencap=1 and the
-- language is "en". Before doing that, need to remove all uses of nocap= in other circumstances.
["nocap"] = boolean_param,
["addl"] = true, -- additional text to display at the end, before the closing </span>
["pagename"] = true, -- for testing, etc.
}
end
-- Split TAGSPECS (inflection tag specifications) on SPLIT_REGEX, which
-- may be nil for no splitting.
local function split_inflection_tags(tagspecs, split_regex)
if not split_regex then
return tagspecs
end
local inflection_tags = {}
for _, tagspec in ipairs(tagspecs) do
for tag in gsplit(tagspec, split_regex) do
insert(inflection_tags, tag)
end
end
return inflection_tags
end
local function parse_terms_with_inline_modifiers(paramname, val, param_mods, lang)
local function generate_obj(term)
return {lang = lang, term = decode_entities(term)}
end
return parse_inline_modifiers(val, {
paramname = paramname,
param_mods = param_mods,
generate_obj = generate_obj,
splitchar = ",",
outer_container = {},
})
end
-- Need to do what [[Module:parameters]] does to string arguments from parent_args as we're running this
-- before calling [[Module:parameters]] on parent_args.
local function ine(arg)
if not arg then
return nil
end
arg = trim(arg)
return arg ~= "" and arg or nil
end
local function add_base_lemma_params(parent_args, iargs, params, compat)
-- Check the language-specific data for additional base lemma params. But if there's no language-specific data,
-- attempt any parent varieties as well (i.e. superordinate varieties).
local lang = get_lang(ine(parent_args[compat and "lang" or 1]) or ine(iargs.lang) or "und", nil, true)
while lang do
local langdata = safe_load_data((module_prefix or get_module_prefix()) .. lang:getCode())
if langdata then
local base_lemma_params = langdata.base_lemma_params
if base_lemma_params then
for _, param in ipairs(base_lemma_params) do
params[param.param] = true
end
return base_lemma_params
end
end
lang = lang:getParent()
end
end
--[=[
Modify `params` in-place by adding parameters that control the link to the main entry and any base lemmas. `term_param`
is the number of the param specifying the main entry itself; `term_param` + 1 will be the display text, and `term_param`
+ 2 will be the gloss, unless `no_numbered_gloss` is given. The base lemma parameters are determined by attempting to
load language-specific data for the language of the page; this comes from |lang= if `compat` is given, else from |1=.
]=]
local function add_link_and_base_lemma_params(iargs, parent_args, params, term_param, compat, no_numbered_gloss)
local base_lemma_params
if not iargs.nolink and not iargs.linktext then
-- Numbered params controlling link display
if iargs.with_multiple_parts then
params[term_param] = {list = true, allow_holes = true}
else
params[term_param + 1] = {alias_of = "alt"}
if not no_numbered_gloss then
params[term_param + 2] = {alias_of = "t"}
end
params[term_param] = true
end
base_lemma_params = add_base_lemma_params(parent_args, iargs, params, compat)
end
return base_lemma_params
end
local function handle_withdot_withcap(iargs, params)
local ignored_tracked_params = {}
if iargs.withdot then
params.dot = true
params.nodot = boolean_param
end
if iargs.withcap and iargs.withencap then
error("Internal error: Can specify only one of withcap= and withencap=")
end
if not iargs.withcap then
params.cap = boolean_param
ignored_tracked_params.nocap = iargs.withencap and "non-english" or "always"
end
return ignored_tracked_params
end
--[=[
Construct and return the full definition line for a form-of-type template invocation. `data` is an object with the
following fields:
* `template`: Approximate template name, for debug tracking;
* `iargs`: processed invocation arguments;
* `parent_args`: raw parent args from `frame:getParent().args`;
* `params`: partially constructed params structure of the sort passed to `process()` in [[Module:parameters]], but
without any link params;
* `ignored_tracked_params`: params that are ignored but should be tracked, to be eventually removed;
* `term_param`: the parent argument specifying the main entry;
* `compat`: true if the language code is found in args.lang instead of args[1];
* `base_lemma_params`: if non-nil, a list of base lemma param objects of the sort stored in the language-specific data;
* `do_form_of`: a function of one argument, `lemma_data`, that returns the actual definition-line text and any
language-specific categories. See below.
This function does several things:
# If link parameters are called for (neither `iargs.nolink` nor `iargs.linktext` are given), augment the `params`
structure with separate link parameters.
# Modify the parent args as appropriate if invocation arguments def= or ignore= are given.
# Parse the parent args, both for separate parameter properties and inline modifiers on the term parameter (which may
consist of multiple comma-separated terms).
# Compute categories to add to the page, including language-specific categories and any categories requested by the
invocation or parent args.
# Parse enclitic and extra base lemma parameters.
# Construct the actual text using `do_form_of`.
# Add a terminating period/dot as appropriate, along with the formatted categories.
`do_form_of` takes one argument, `lemma_data`, which looks like this:
{
lang = LANG,
args = {ARG = VALUE, ARG = VALUE, ...},
lemmas = {LEMMA_OBJ, LEMMA_OBJ, ...},
enclitics = {ENCLITIC_OBJ, ENCLITIC_OBJ, ...},
base_lemmas = {BASE_LEMMA_OBJ, BASE_LEMMA_OBJ, ...},
categories = {"CATEGORY", "CATEGORY", ...},
posttext = "POSTTEXT" or nil,
}
where
* LANG is the language code;
* ARGS is the parsed arguments, based on what the user specified;
* LEMMAS is a sequence of objects specifying the main entries/lemmas, as passed to full_link in [[Module:links]];
however, if the invocation argument linktext= is given, it will be a string consisting of that text, and if the
invocation argument nolink= is given, it will be nil;
* ENCLITICS is nil or a sequence of objects specifying the enclitics, as passed to full_link in [[Module:links]];
* BASE_LEMMA_OBJ is a sequence of objects specifying the base lemma(s), which are used when the lemma is itself a
form of another lemma (the base lemma), e.g. a comparative, superlative or participle; each object is of the form
{ paramobj = PARAM_OBJ, lemmas = {LEMMA_OBJ, LEMMA_OBJ, ...} } where PARAM_OBJ describes the properties of the
base lemma parameter (i.e. the relationship between the intermediate and base lemmas) and LEMMA_OBJ is of the same
format of ENCLITIC_OBJ, i.e. an object suitable to be passed to full_link in [[Module:links]]; PARAM_OBJ is of the
format { param = "PARAM", tags = {"TAG", "TAG", ...} } where PARAM is the name of the parameter to
{{inflection of}} etc. that holds the base lemma(s) of the specified relationship and the tags describe the
relationship, such as {"comd"} or {"past", "part"};
* CATEGORIES is the categories to add the page to (consisting of any categories specified in the invocation or
parent args and any tracking categories, but not any additional lang-specific categories that may be added by
{{inflection of}} or similar templates);
* POSTTEXT is text to display at the end of the form-of text, before the final </span> (or at the end of the first
line, before the colon, in a multiline {{infl of}} call).
`do_form_of` should return two arguments:
(1) The actual definition-line text, marked up appropriately with <span>...</span> but without any terminating
period/dot.
(2) Any extra categories to add the page to (other than those that can be derived from parameters specified to the
invocation or parent arguments, which will automatically be added to the page).
]=]
local function construct_form_of_text(data)
local template, iargs, parent_args, params, no_numbered_gloss, do_form_of =
data.template, data.iargs, data.parent_args, data.params, data.no_numbered_gloss, data.do_form_of
local term_param = iargs.term_param
local compat = iargs.lang or parent_args.lang
term_param = term_param or compat and 1 or 2
-- Numbered params
params[compat and "lang" or 1] = {
required = not iargs.lang,
type = "language",
default = iargs.lang or "und"
}
-- Error to catch most uses of old-style parameters for {{contraction of}}. (FIXME: Remove eventually.)
if iargs.with_multiple_parts then
if ine(parent_args[term_param + 2]) and not ine(parent_args[term_param + 1]) and not ine(parent_args.tr2) and not ine(parent_args.ts2)
and not ine(parent_args.t2) and not ine(parent_args.gloss2) and not ine(parent_args.g2)
and not ine(parent_args.alt2) then
error(("You specified a term in %s= and not one in %s=. You probably meant to use t= to specify a gloss instead. "
.. "If you intended to specify two terms, put the second term in %s=."):format(term_param + 2, term_param + 1,
term_param + 1))
end
if not ine(parent_args[term_param + 1]) and not ine(parent_args.alt2) and not ine(parent_args.tr2) and not ine(parent_args.ts2)
and ine(parent_args.g2) then
error(("You specified a gender in g2= but no term in %s=. You were probably trying to specify two genders for "
.. "a single term. To do that, put both genders in g=, comma-separated."):format(term_param + 1))
end
end
local base_lemma_params = add_link_and_base_lemma_params(iargs, parent_args, params, term_param, compat,
no_numbered_gloss)
local ignored_tracked_params = handle_withdot_withcap(iargs, params)
--[=[
Process parent arguments. This is similar to the following:
require("Module:parameters").process(parent_args, params)
but in addition it does the following:
(1) Supplies default values for unspecified parent arguments as specified in DEFAULTS, which consist of specs of the
form "ARG=VALUE". These are added to the parent arguments prior to processing, so boolean and number parameters
will process the value appropriately.
(2) Removes parent arguments specified in IGNORESPECS, which consist either of bare argument names to remove, or
list-argument names to remove of the form "ARG:list".
(3) Tracks the use of any parent arguments specified in TRACKED_PARAMS, which is a set where the keys are arguments
as they exist after processing (hence numeric arguments should be numbers, not strings) and the values should be
boolean true.
]=]--
local defaults = iargs.def
local ignorespecs = iargs.ignore
if defaults[1] or ignorespecs[1] then
local new_parent_args = {}
for _, default in ipairs(defaults) do
local defparam, defval = default:match("^(.-)=(.*)$")
if not defparam then
error("Bad default spec " .. default)
end
new_parent_args[defparam] = defval
end
local params_to_ignore = {}
local numbered_list_params_to_ignore = {}
local named_list_params_to_ignore = {}
for _, ignorespec in ipairs(ignorespecs) do
for ignore in gsplit(ignorespec, ",") do
local param = ignore:match("^(.*):list$")
if param then
if param:match("^%d+$") then
insert(numbered_list_params_to_ignore, tonumber(param))
else
insert(named_list_params_to_ignore, "^" .. pattern_escape(param) .. "%d*$")
end
else
if ignore:match("^%d+$") then
ignore = tonumber(ignore)
end
params_to_ignore[ignore] = true
end
end
end
for k, v in pairs(parent_args) do
if not params_to_ignore[k] then
local ignore_me = false
if type(k) == "number" then
for _, lparam in ipairs(numbered_list_params_to_ignore) do
if k >= lparam then
ignore_me = true
break
end
end
else
for _, lparam in ipairs(named_list_params_to_ignore) do
if k:match(lparam) then
ignore_me = true
break
end
end
end
if not ignore_me then
new_parent_args[k] = v
end
end
end
parent_args = new_parent_args
end
local param_mods_with_conj, param_mods_without_conj
local function get_param_mods(with_conj)
if with_conj then
if not param_mods_with_conj then
param_mods_with_conj = require(parameter_utilities_module).construct_param_mods {
{group = {"link", "q", "l", "ref"}},
{param = "conj", set = allowed_conj_set, overall = true},
}
end
return param_mods_with_conj
else
if not param_mods_without_conj then
param_mods_without_conj = require(parameter_utilities_module).construct_param_mods {
{group = {"link", "q", "l", "ref"}},
-- Override lit= to have a separate overall value
{param = "lit", separate_no_index = true},
}
end
return param_mods_without_conj
end
end
local terms, args
if iargs.nolink or iargs.linktext then
args = process_params(parent_args, params)
else
local m_param_utils = require(parameter_utilities_module)
if iargs.with_multiple_parts then
terms, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params {
params = params,
param_mods = get_param_mods(false),
raw_args = parent_args,
termarg = term_param,
track_module = "form of" .. (template and "/" .. template or ""),
lang = compat and "lang" or 1,
sc = "sc.default",
parse_lang_prefix = true,
default_separator = " +‎ ",
special_separators = {[";"] = " or "},
}
else
terms, args = m_param_utils.parse_term_with_inline_modifiers_and_separate_params {
params = params,
param_mods = get_param_mods("with conj"),
raw_args = parent_args,
termarg = term_param,
track_module = "form of" .. (template and "/" .. template or ""),
lang = compat and "lang" or 1,
sc = "sc",
parse_lang_prefix = true,
make_separate_g_into_list = true,
splitchar = ",",
subitem_param_handling = "last",
}
end
end
local lang = args[compat and "lang" or 1]
-- Tracking for certain user-specified params. This is generally used for
-- parameters that we accept but ignore, so that we can eventually remove
-- all uses of these params and stop accepting them.
if ignored_tracked_params then
for ignored_tracked_param, condition in pairs(ignored_tracked_params) do
if parent_args[ignored_tracked_param] and (condition ~= "non-english" or lang:getCode() ~= "en") then
track("arg/" .. ignored_tracked_param, template)
track("arg/" .. ignored_tracked_param)
end
end
end
-- Determine categories for the page, including tracking categories
local categories = {}
if not args.nocat then
for _, cat in ipairs(iargs.cat) do
insert(categories, lang:getFullName() .. " " .. cat)
end
end
for _, cat in ipairs(args.cat) do
insert(categories, lang:getFullName() .. " " .. cat)
end
-- Format the link, preceding text and categories
local function add_term_tracking_categories(term)
-- add tracking category if term is same as page title
if term and mw.loadData("Module:headword/data").pagename == lang:stripDiacritics(term) then
insert(categories, "Forms linking to themselves")
end
-- maybe add tracking category if primary entry doesn't exist (this is an
-- expensive call so we don't do it by default)
if iargs.noprimaryentrycat and term and mw.title.getCurrentTitle().nsText == ""
and not mw.title.new(term):getContent() then
insert(categories, lang:getFullName() .. " " .. iargs.noprimaryentrycat)
end
end
local lemmas
if iargs.nolink then
lemmas = nil
elseif iargs.linktext then
lemmas = iargs.linktext
else
if iargs.with_multiple_parts then
lemmas = terms
else
lemmas = terms.terms
end
if not lemmas[1] then
if mw.title.getCurrentTitle().nsText == "Template" then
lemmas[1] = {
lang = lang,
term = "term"
}
else
error("No linked-to term specified")
end
end
for _, termobj in ipairs(lemmas) do
if termobj.term then
add_term_tracking_categories(termobj.term)
end
-- NOTE: Formerly, template arg sc= overrode inline modifier <sc:...>, which seems backwards, so I've
-- changed it. Hopefully nothing depended on the old behavior.
end
end
local enclitics, enclitic_conj
if args.enclitic then
local enclitics_obj = parse_terms_with_inline_modifiers("enclitic", args.enclitic, get_param_mods("with conj"),
lang)
enclitics = enclitics_obj.terms
enclitic_conj = enclitics_obj.conj
end
local base_lemmas = {}
if base_lemma_params then
for _, base_lemma_param_obj in ipairs(base_lemma_params) do
local param = base_lemma_param_obj.param
if args[param] then
local base_lemmas_obj = parse_terms_with_inline_modifiers(param, args[param],
get_param_mods("with conj"), lang)
insert(base_lemmas, {
paramobj = base_lemma_param_obj,
lemmas = base_lemmas_obj.terms,
conj = base_lemmas_obj.conj,
})
end
end
end
local posttext = iargs.posttext
local addl = args.addl
if addl then
posttext = posttext or ""
if addl:find("^[;:]") then
posttext = posttext .. addl
elseif addl:find("^_") then
posttext = posttext .. " " .. addl:sub(2)
else
posttext = posttext .. ", " .. addl
end
end
local conj
if iargs.with_multiple_parts then
conj = false -- signals to use 'separator' field
else
conj = terms and terms.conj or iargs.conj
end
local lemma_data = {
lang = lang,
args = args,
lemmas = lemmas,
conj = conj,
enclitics = enclitics,
enclitic_conj = enclitic_conj,
base_lemmas = base_lemmas,
categories = categories,
posttext = posttext,
lit = iargs.with_multiple_parts and args.lit.default or nil,
}
local form_of_text, lang_cats = do_form_of(lemma_data)
extend(lemma_data.categories, lang_cats)
local text = form_of_text .. (
args.nodot and "" or args.dot or iargs.withdot and "." or ""
)
if not lemma_data.categories[1] then
return text
end
return text .. format_categories(lemma_data.categories, lemma_data.lang, args.sort,
-- If lemma_is_sort_key is given, supply the first lemma term as the sort base if possible. If sort= is given,
-- it will override the base; otherwise, the base will be converted appropriately to a sort key using the
-- same algorithm applied to pagenames.
iargs.lemma_is_sort_key and type(lemma_data.lemmas) == "table" and lemma_data.lemmas[1].term,
-- Supply the first lemma's script for sort key computation.
force_cat or get_force_cat(), type(lemma_data.lemmas) == "table" and lemma_data.lemmas[1].sc)
end
-- Invocation parameters shared between form_of_t(), tagged_form_of_t() and inflection_of_t(). `calling_func` is the
-- invoking function ("form_of_t", "tagged_form_of_t" or "inflection_of_t"), for handling parameters shared by two but
-- not all three invoking functions.
local function get_common_invocation_params(calling_func)
local iparams = {
["term_param"] = {type = "number"},
["lang"] = true, -- To be used as the default code in params.
["sc"] = {type = "script"},
["cat"] = {list = true, sublist = "comma without whitespace", flatten = true},
["ignore"] = {list = true},
["def"] = {list = true},
["conj"] = {set = allowed_conj_set, default = "and"},
["withcap"] = boolean_param,
["withencap"] = boolean_param,
["withdot"] = boolean_param,
["nolink"] = boolean_param,
["linktext"] = true,
["posttext"] = true,
["noprimaryentrycat"] = true,
["lemma_is_sort_key"] = true,
}
if calling_func ~= "inflection_of_t" then
iparams.with_multiple_parts = boolean_param
end
return iparams
end
local function should_ucfirst_text(args, iargs, lang)
local code = lang:getCode()
return args.cap or (iargs.withcap or iargs.withencap and code == "en" or code == "mul") and not args.nocap
end
--[==[
Function that implements {{tl|form of}} and the various more specific form-of templates (but not {{tl|inflection of}}
or templates that take tagged inflection parameters).
Invocation params:
; {{para|1|req=1}}
: Text to display before the link.
; {{para|term_param}}
: Numbered param holding the term linked to. Other numbered params come after. Defaults to 1 if invocation or template
param {{para|lang}} is present, otherwise 2.
; {{para|with_multiple_parts|1}}
: If specified, higher numbered parameters above the numbered param in {{para|term_param}} specify additional parts out
of which the term was constructed, for use by templates like {{tl|contraction of}}. (If not specified, the parameter
at <code><var>term_param</var> + 1</code> is the display form, same as {{para|alt}}, and the parameter at
at <code><var>term_param</var> + 2</code> is the gloss, same as {{para|t}}.)
; {{para|lang}}
: Default language code for language-specific templates. If specified, no language code needs to be specified, and if
specified it needs to be set using {{para|lang}}, not {{para|1}}.
; {{para|sc}}
: Default script code for language-specific templates. The script code can still be overridden using template param
{{para|sc}}.
; {{para|cat}}, {{para|cat2}}, ...:
: Categories to place the page into. The language name will automatically be prepended. Note that there is also a
template param {{para|cat}} to specify categories at the template level. Use of {{para|nocat}} disables categorization
of categories specified using invocation param {{para|cat}}, but not using template param {{para|cat}}. A single param
can specify multiple comma-separated categories if no space follows the comma.
; {{para|ignore}}, {{para|ignore2}}, ...:
: One or more template params to silently accept and ignore. Useful e.g. when the template takes additional parameters
such as {{para|from}} or {{para|POS}}. Each value is a comma-separated list of either bare parameter names or
specifications of the form `PARAM:list` to specify that the parameter is a list parameter.
; {{para|def}}, {{para|def2}}, ...:
: One or more default values to supply for template args. For example, specifying {{para|def|2=tr=-}} causes the default
for template param {{para|tr}} to be `-`. Actual template params override these defaults.
; {{para|withcap|1}}
: Capitalize the first character of the text preceding the link, unless template param {{para|nocap}} is given.
; {{para|withencap|1}}
: Capitalize the first character of the text preceding the link if the language is English and template param
{{para|nocap}} is not given.
; {{para|withdot|1}}
: Add a final period after the link, unless template param {{para|nodot}} is given to suppress the period, or
{{para|dot}} is given to specify an alternative punctuation character.
; {{para|nolink|1}}
: Suppress the display of the link. If specified, none of the template params that control the link
({{para|<var>term_param</var>}}, {{para|<var>term_param</var> + 1}}, {{para|<var>term_param</var> + 2}}, {{para|t}},
{{para|gloss}}, {{para|sc}}, {{para|tr}}, {{para|ts}}, {{para|pos}}, {{para|g}}, {{para|id}}, {{para|lit}}) will be
available. If the calling template uses any of these parameters, they must be ignored using {{para|ignore}}.
{{para|linktext}}
: Override the display of the link with the specified text. This is useful if a custom template is available to format
the link (e.g. in Hebrew, Chinese and Japanese). If specified, none of the template params that control the link
({{para|<var>term_param</var>}}, {{para|<var>term_param</var> + 1}}, {{para|<var>term_param</var> + 2}}, {{para|t}},
{{para|gloss}}, {{para|sc}}, {{para|tr}}, {{para|ts}}, {{para|pos}}, {{para|g}}, {{para|id}}, {{para|lit}}) will be
available. If the calling template uses any of these parameters, they must be ignored using {{para|ignore}}.
; {{para|posttext}}
: Additional text to display directly after the formatted link, before any terminating period/dot and inside of
`<span class='use-with-mention'>`.
; {{para|noprimaryentrycat}}
: Category to add the page to if the primary entry linked to doesn't exist. The language name will automatically be
prepended.
; {{para|lemma_is_sort_key|1}}
: If the user didn't specify a sort key, use the lemma as the sort key (instead of the page itself).
]==]
function export.form_of_t(frame)
local iparams = get_common_invocation_params("form_of_t")
iparams[1] = {required = true}
local iargs = process_params(frame.args, iparams)
local parent_args = frame:getParent().args
local params = get_common_template_params()
if next(iargs.cat) then
params.nocat = boolean_param
end
return construct_form_of_text {
template = "form-of-t",
iargs = iargs,
parent_args = parent_args,
params = params,
do_form_of = function(lemma_data)
local args = lemma_data.args
local text
if args.notext then
text = ""
else
text = iargs[1]
if should_ucfirst_text(args, iargs, lemma_data.lang) then
text = ucfirst(text)
end
end
-- This returns two values, which we pass up to the caller.
return format_form_of {
lang = lemma_data.lang, text = text, lemmas = lemma_data.lemmas, conj = lemma_data.conj,
enclitics = lemma_data.enclitics, base_lemmas = lemma_data.base_lemmas, lemma_face = "term",
lit = lemma_data.lit, posttext = lemma_data.posttext
}
end
}
end
--[=[
Construct and return the full definition line for a form-of-type template invocation that is based on inflection tags.
This is a wrapper around construct_form_of_text() and takes the following arguments: processed invocation arguments
IARGS, processed parent arguments ARGS, TERM_PARAM (the parent argument specifying the main entry), COMPAT (true if the
language code is found in args.lang instead of args[1]), and TAGS, the list of (non-canonicalized) inflection tags.
It returns that actual definition-line text including terminating period/full-stop, formatted categories, etc. and
should be directly returned as the template function's return value.
]=]
local function construct_tagged_form_of_text(data)
local template, iargs, parent_args, params, no_numbered_gloss, tags =
data.template, data.iargs, data.parent_args, data.params, data.no_numbered_gloss, data.tags
-- Named params not controlling link display
-- Always included because lang-specific categories may be added
params.nocat = boolean_param
params.p = true
params.POS = {alias_of = "p"}
return construct_form_of_text {
template = template,
iargs = iargs,
parent_args = parent_args,
params = params,
no_numbered_gloss = no_numbered_gloss,
do_form_of = function(lemma_data)
local args = lemma_data.args
if is_callable(tags) then
tags = tags(args)
end
-- NOTE: tagged_inflections returns two values, so we do too.
return tagged_inflections {
lang = lemma_data.lang,
tags = tags,
lemmas = lemma_data.lemmas,
conj = lemma_data.conj,
enclitics = lemma_data.enclitics,
enclitic_conj = lemma_data.enclitic_conj,
base_lemmas = lemma_data.base_lemmas,
lemma_face = "term",
POS = args.p,
pagename = args.pagename,
-- Set no_format_categories because we do it ourselves in construct_form_of_text().
no_format_categories = true,
nocat = args.nocat,
notext = args.notext,
capfirst = should_ucfirst_text(args, iargs, lemma_data.lang),
posttext = lemma_data.posttext,
}
end
}
end
--[==[
Function that implements form-of templates that are defined by specific tagged inflections (typically a template
referring to a non-lemma inflection, such as {{tl|plural of}}). This works exactly like {form_of_t()} except that the
"form of" text displayed before the link is based off of a pre-specified set of inflection tags (which will be
appropriately linked to the glossary) instead of arbitrary text. From the user's perspective, there is no difference
between templates implemented using {form_of_t()} and {tagged_form_of_t()}; they accept exactly the same parameters and
work the same. See also {inflection_of_t()} below, which is intended for templates with user-specified inflection tags.
Invocation params:
; {{para|1|req=1}}, {{para|2}}, ...
: One or more inflection tags describing the inflection in question.
; {{para|split_tags}}
: If specified, character to split specified inflection tags on. This allows multiple tags to be included in a single
argument, simplifying template code.
; {{para|term_param}}
; {{para|with_multiple_parts|1}}
; {{para|lang}}
; {{para|sc}}
; {{para|cat}}, {{para|cat2}}, ...
; {{para|ignore}}, {{para|ignore2}}, ...
; {{para|def}}, {{para|def2}}, ...
; {{para|withcap|1}}
; {{para|withencap|1}}
; {{para|withdot|1}}
; {{para|nolink|1}}
; {{para|linktext}}
; {{para|posttext}}
; {{para|noprimaryentrycat}}
; {{para|lemma_is_sort_key|1}}
: All of these are the same as in {form_of_t()}.
]==]
function export.tagged_form_of_t(frame)
local iparams = get_common_invocation_params("tagged_form_of_t")
iparams[1] = {list = true, required = true}
iparams.split_tags = true
local iargs = process_params(frame.args, iparams)
local parent_args = frame:getParent().args
local params = get_common_template_params()
return construct_tagged_form_of_text {
template = "tagged-form-of-t",
iargs = iargs,
parent_args = parent_args,
params = params,
tags = split_inflection_tags(iargs[1], iargs.split_tags),
}
end
--[==[
Function that implements {{tl|inflection of}} and certain semi-specific variants, such as {{tl|participle of}} and
{{tl|past participle form of}}. This function is intended for templates that allow the user to specify a set of
inflection tags.
It works similarly to {form_of_t()} and {tagged_form_of_t()} except that the calling convention for the calling
template is
: { {{TEMPLATE|LANG|MAIN_ENTRY_LINK|MAIN_ENTRY_DISPLAY_TEXT|TAG|TAG|...}}}
instead of
: { {{TEMPLATE|LANG|MAIN_ENTRY_LINK|MAIN_ENTRY_DISPLAY_TEXT|GLOSS}}}
Note that there isn't a numbered parameter for the gloss, but it can still be specified using {{para|t}} or
{{para|gloss}}.
Invocation params:
; {{para|preinfl}}, {{para|preinfl2}}, ...
: Extra inflection tags to automatically prepend to the tags specified by the template.
; {{para|postinfl}}, {{para|postinfl2}}, ...
: Extra inflection tags to automatically append to the tags specified by the template. Used for example by
{{tl|past participle form of}} to add the tags `of the|past|p` onto the user-specified tags, which indicate which
past participle form the page refers to.
; {{para|split_tags}}
: If specified, character to split specified inflection tags on. This allows multiple tags to be included in a single
argument, simplifying template code. Note that this applies *ONLY* to inflection tags specified in the invocation
arguments using {{para|preinfl}} or {{para|postinfl}}, not to user-specified inflection tags.
; {{para|term_param}}
; {{para|lang}}
; {{para|sc}}
; {{para|cat}}, {{para|cat2}}, ...
; {{para|ignore}}, {{para|ignore2}}, ...
; {{para|def}}, {{para|def2}}, ...
; {{para|withcap|1}}
; {{para|withencap|1}}
; {{para|withdot|1}}
; {{para|nolink|1}}
; {{para|linktext}}
; {{para|posttext}}
; {{para|noprimaryentrycat}}
; {{para|lemma_is_sort_key|1}}
: All of these are the same as in {form_of_t()}.
]==]
function export.inflection_of_t(frame)
local iparams = get_common_invocation_params("inflection_of_t")
iparams.preinfl = {list = true}
iparams.postinfl = {list = true}
iparams.split_tags = true
local iargs = process_params(frame.args, iparams)
local parent_args = frame:getParent().args
local params = get_common_template_params()
local compat = iargs.lang or parent_args.lang
local tagsind = (iargs.term_param or compat and 1 or 2) + 2
params[tagsind] = {list = true,
-- at least one inflection tag is required unless preinfl or postinfl tags are given
required = #iargs.preinfl == 0 and #iargs.postinfl == 0}
return construct_tagged_form_of_text {
template = "inflection-of-t",
iargs = iargs,
parent_args = parent_args,
params = params,
no_numbered_gloss = true,
tags = function(args)
local infls
if not next(iargs.preinfl) and not next(iargs.postinfl) then
-- If no preinfl or postinfl tags, just use the user-specified tags directly.
infls = args[tagsind]
else
-- Otherwise, we need to prepend the preinfl tags and postpend the postinfl tags. If there's only one tag set
-- (no semicolon), it's easier. Since this is common, we optimize for it.
infls = {}
local saw_semicolon = false
for _, infl in ipairs(args[tagsind]) do
if infl == ";" then
saw_semicolon = true
break
end
end
local split_preinfl = split_inflection_tags(iargs.preinfl, iargs.split_tags)
local split_postinfl = split_inflection_tags(iargs.postinfl, iargs.split_tags)
if not saw_semicolon then
extend(infls, split_preinfl)
extend(infls, args[tagsind])
extend(infls, split_postinfl)
else
local groups = split_tag_set(args[tagsind])
for _, group in ipairs(groups) do
if #infls > 0 then
insert(infls, ";")
end
extend(infls, split_preinfl)
extend(infls, group)
extend(infls, split_postinfl)
end
end
end
return infls
end,
}
end
--[==[
Normalize a part-of-speech tag given a possible abbreviation (passed in as {{para|1}} of the invocation args). If the
abbreviation isn't recognized, the original POS tag is returned. If no POS tag is passed in, return the value of
invocation arg {{para|default}}.
]==]
function export.normalize_pos(frame)
local iparams = {
[1] = true,
["default"] = true,
}
local iargs = process_params(frame.args, iparams)
if not iargs[1] and not iargs.default then
error("Either 1= or default= must be given in the invocation args")
end
if not iargs[1] then
return iargs.default
end
return (m_form_of_pos or get_m_form_of_pos())[iargs[1]] or iargs[1]
end
return export
qngi7g0ngefkunhqwao6b90egp7n7t7
Module:form of/data/1
828
8197
55134
2026-10-02T19:39:05Z
Deadend0914
7211
Gesceop tramet þe hafaþ '--[=[ This module lists the more common recognized inflection tags, along with their shortcut aliases, the corresponding glossary entry or page describing the tag, and the corresponding wikidata entry. The less common tags are in [[Module:form of/data/2]]. We divide the tags this way to save memory space. Be careful adding more tags to this module; add them to the other module unless you're sure they are common. TAGS is a table where keys are the canonical form...'
55134
Scribunto
text/plain
--[=[
This module lists the more common recognized inflection tags, along with their shortcut aliases, the corresponding
glossary entry or page describing the tag, and the corresponding wikidata entry. The less common tags are in
[[Module:form of/data/2]]. We divide the tags this way to save memory space. Be careful adding more tags to this module;
add them to the other module unless you're sure they are common.
TAGS is a table where keys are the canonical form of an inflection tag and the corresponding values are tables
describing the tags, consisting of the following keys:
- 1: Type of the tag ("person", "number", "gender", "case", "animacy", "tense-aspect", "mood", "voice-valence",
etc.).
- 2: Anchor or page describing the inflection tag, with the following values:
* nil: No link.
* APPENDIX: Anchor in [[Appendix:Glossary]] whose name is the same as the tag
* WIKT: Page in the English Wiktionary whose name is the same as the tag.
* WP: Page in the English Wikipedia whose name is the same as the tag.
* A string: If prefixed by 'w:' the specified page in the English Wikipedia. If prefixed by 'wikt:', the
specified page in the English Wiktionary. Otherwise, an anchor in [[Appendix:Glossary]].
NOTE: GLOSSARY ANCHORS ARE PREFERRED. Other types of entries should be migrated to the glossary, with links to
Wikipedia and/or Wiktionary entries as appropriate.
- 3: List of shortcuts (i.e. aliases for the inflection tag) or a single shortcut string, or nil.
- 4: Numeric value of Wikidata identifier (see wikidata.org) for the concept most closely describing this tag.
(The actual Wikidata identifier is a string formed by prefixing the number with Q.)
- display: If specified, consists of text to display in the definition line, in lieu of the canonical form of the
inflection tag. If there is a glossary entry, the displayed text forms the right side of the two-part
glossary link.
- no_space_on_left: If specified, don't display a space to the left of the tag. Used for punctuation.
- no_space_on_right: If specified, don't display a space to the right of the tag. Used for punctuation.
SHORTCUTS is a table mapping shortcut aliases to canonical inflection tag names. Shortcuts are of one of three types:
(1) A simple alias of a tag. These do not need to be entered explicitly into the table; code at the end of the module
automatically fills in these entries based on the information in TAGS.
(2) An alias to a multipart tag. For example, the alias "mf" maps to the multipart tag "m//f", which will in turn be
expanded into the canonical multipart tag {"masculine", "feminine"}, which will display as (approximately)
"[[Appendix:Glossary#gender|masculine]] and [[Appendix:Glossary#gender|feminine]]". The number of such aliases
should be liminted, and should cover only the most common combinations.
Normally, multipart tags are displayed using serialCommaJoin() in [[Module:table]] to appropriately join the display
form of the individual tags using commas and/or "and". However, some multipart tags are displayed specially; see
DISPLAY_HANDLERS below. Note that aliases to multipart tags can themselves contain simple aliases in them.
(3) An alias to a list of multiple tags (which may themselves be simple or multipart aliases). Specifying the alias is
exactly equivalent to specifying the tags in the list in order, one after another. An example is "1s", which maps to
the list {"1", "s"}. The number of such aliases should be limited, and should cover only the most common
combinations.
NOTE: In some cases below, multiple tags point to the same wikidata, because Wikipedia considers them synonyms. Examples
are indirect case vs. objective case vs. oblique case, and inferential mood vs. renarrative mood. We do this because
(a) we want to allow users to choose their own terminology; (b) we want to be able to use the terminology most common
for the language in question; (c) terms considered synonyms may or may not actually be synonyms, as different languages
may use the terms differently. For example, although the Wikipedia page on [[w:inferential mood]] claims that
inferential and renarrative moods are the same, the page on [[w:Bulgarian_verbs#Evidentials]] claims that Bulgarian has
both, and that they are not the same.
]=]
local m_form_of_data = require("Module:form of/data")
local APPENDIX = m_form_of_data.APPENDIX
local WP = m_form_of_data.WP
local WIKT = m_form_of_data.WIKT
local tags = {}
local shortcuts = {}
----------------------- Person -----------------------
tags["first-person"] = {
"person",
"first person",
"1",
21714344,
}
tags["second-person"] = {
"person",
"second person",
"2",
51929049,
}
tags["third-person"] = {
"person",
"third person",
"3",
51929074,
}
tags["impersonal"] = {
"person",
APPENDIX,
"impers",
}
shortcuts["12"] = "1//2"
shortcuts["13"] = "1//3"
shortcuts["23"] = "2//3"
shortcuts["123"] = "1//2//3"
----------------------- Number -----------------------
tags["singular"] = {
"number",
"singular number",
{"s", "sg"},
110786,
}
tags["dual"] = {
"number",
"dual number",
{"d", "du"},
110022,
}
tags["plural"] = {
"number",
"plural number",
{"p", "pl"},
146786,
}
tags["single-possession"] = {
"number",
"singular number",
"spos",
110786, -- Singular
}
tags["multiple-possession"] = {
"number",
"plural number",
"mpos",
146786, -- Plural
}
shortcuts["1s"] = {"1", "s"}
shortcuts["2s"] = {"2", "s"}
shortcuts["3s"] = {"3", "s"}
shortcuts["1d"] = {"1", "d"}
shortcuts["2d"] = {"2", "d"}
shortcuts["3d"] = {"3", "d"}
shortcuts["1p"] = {"1", "p"}
shortcuts["2p"] = {"2", "p"}
shortcuts["3p"] = {"3", "p"}
----------------------- Gender -----------------------
tags["masculine"] = {
"gender",
"gender",
"m",
499327,
}
-- This is useful e.g. in Swedish.
tags["natural masculine"] = {
"gender",
"gender",
"natm",
}
tags["feminine"] = {
"gender",
"gender",
"f",
1775415,
}
tags["neuter"] = {
"gender",
"gender",
"n",
1775461,
}
tags["common"] = {
"gender",
"gender",
"c",
1305037,
}
tags["nonvirile"] = {
"gender",
APPENDIX,
"nv",
}
shortcuts["mf"] = "m//f"
shortcuts["mn"] = "m//n"
shortcuts["fn"] = "f//n"
shortcuts["mfn"] = "m//f//n"
----------------------- Animacy -----------------------
-- (may be useful sometimes for [[Module:object usage]].)
tags["animate"] = {
"animacy",
APPENDIX,
"an",
51927507,
}
tags["inanimate"] = {
"animacy",
APPENDIX,
{"in", "inan"},
51927539,
}
tags["personal"] = {
"animacy",
APPENDIX,
{"pr", "pers"},
63302102,
}
----------------------- Tense/aspect -----------------------
tags["present"] = {
"tense-aspect",
"present tense",
"pres",
192613,
}
tags["past"] = {
"tense-aspect",
"past tense",
nil,
1994301,
}
tags["future"] = {
"tense-aspect",
"future tense",
{"fut", "futr"},
501405,
}
tags["future perfect"] = {
"tense-aspect",
APPENDIX,
{"futp", "fperf"},
1234617,
}
tags["non-past"] = {
"tense-aspect",
"non-past tense",
"npast",
16916993,
}
tags["progressive"] = {
"tense-aspect",
APPENDIX,
"prog",
56653945,
}
tags["preterite"] = {
"tense-aspect",
APPENDIX,
"pret",
442485,
}
tags["perfect"] = {
"tense-aspect",
APPENDIX,
"perf",
625420,
}
tags["imperfect"] = {
"tense-aspect",
APPENDIX,
{"impf", "imperf"},
}
tags["pluperfect"] = {
"tense-aspect",
APPENDIX,
{"plup", "pluperf"},
623742,
}
tags["aorist"] = {
"tense-aspect",
"aorist tense",
{"aor", "aori"},
216497,
}
tags["past historic"] = {
"tense-aspect",
"past historic tense",
"phis",
442485, -- Preterite
}
tags["imperfective"] = {
"tense-aspect",
APPENDIX,
{"impfv", "imperfv"},
371427,
}
tags["perfective"] = {
"tense-aspect",
APPENDIX,
{"pfv", "perfv"},
1424306,
}
shortcuts["spast"] = {"simple", "past"}
shortcuts["simple past"] = {"simple", "past"}
shortcuts["spres"] = {"simple", "present"}
shortcuts["simple present"] = {"simple", "present"}
----------------------- Mood -----------------------
tags["imperative"] = {
"mood",
"imperative mood",
{"imp", "impr", "impv"},
22716,
}
tags["indicative"] = {
"mood",
"indicative mood",
{"ind", "indc", "indic"},
682111,
}
tags["subjunctive"] = {
"mood",
"subjunctive mood",
{"sub", "subj"},
473746,
}
tags["conditional"] = {
"mood",
"conditional mood",
"cond",
625581,
}
tags["modal"] = {
"mood",
"w:modality (linguistics)",
"mod",
1243600,
}
tags["optative"] = {
"mood",
"optative mood",
{"opt", "opta"},
527205,
}
tags["jussive"] = {
"mood",
"jussive mood",
{"jus", "juss"},
462367,
}
tags["hortative"] = {
"mood",
WP,
"hort",
5906629,
}
----------------------- Voice/valence -----------------------
-- This tag type combines what is normally called "voice" (active, passive, middle, mediopassive) with other tags that
-- aren't normally called voice but are similar in that they control the valence/valency (number and structure of the
-- arguments of a verb).
tags["active"] = {
"voice-valence",
"active voice",
{"act", "actv"},
1317831,
}
tags["middle"] = {
"voice-valence",
"middle voice",
{"mid", "midl"},
}
tags["passive"] = {
"voice-valence",
"passive voice",
{"pass", "pasv"},
1194697,
}
tags["mediopassive"] = {
"voice-valence",
APPENDIX,
{"mp", "mpass", "mpasv", "mpsv"},
1601545,
}
tags["reflexive"] = {
"voice-valence",
APPENDIX,
"refl",
13475484, -- for "reflexive verb"
}
tags["transitive"] = {
"voice-valence",
"transitive verb",
{"tr", "vt"},
1774805, -- for "transitive verb"
}
tags["intransitive"] = {
"voice-valence",
"intransitive verb",
{"intr", "vi"},
1166153, -- for "intransitive verb"
}
tags["ditransitive"] = {
"voice-valence",
"ditransitive verb",
"ditr",
2328313, -- for "ditransitive verb"
}
tags["causative"] = {
"voice-valence",
APPENDIX,
"caus",
56677011, -- for "causative verb"
}
----------------------- Non-finite -----------------------
tags["infinitive"] = {
"non-finite",
APPENDIX,
"inf",
179230,
}
-- A form found in Portuguese and Galician, as well as in Hungarian. This is probably unnecessary and can be replaced
-- with the regular "infinitive" tag. A personal infinitive is not a separate infinitive from the plain infinitive, just
-- an inflection of the infinitive.
tags["personal infinitive"] = {
"non-finite",
"w:Portuguese verb conjugation",
"pinf",
}
tags["participle"] = {
"non-finite",
APPENDIX,
{"part", "ptcp"},
814722,
}
tags["verbal noun"] = {
"non-finite",
APPENDIX,
"vnoun",
1350145,
}
tags["gerund"] = {
"non-finite",
APPENDIX,
"ger",
1923028,
}
tags["supine"] = {
"non-finite",
APPENDIX,
"sup",
548470,
}
tags["transgressive"] = {
"non-finite",
APPENDIX,
nil,
904896,
}
----------------------- Case -----------------------
tags["ablative"] = {
"case",
"ablative case",
"abl",
156986,
}
tags["accusative"] = {
"case",
"accusative case",
"acc",
146078,
}
tags["dative"] = {
"case",
"dative case",
"dat",
145599,
}
tags["genitive"] = {
"case",
"genitive case",
"gen",
146233,
}
tags["instrumental"] = {
"case",
"instrumental case",
"ins",
192997,
}
tags["locative"] = {
"case",
"locative case",
"loc",
202142,
}
tags["nominative"] = {
"case",
"nominative case",
"nom",
131105,
}
tags["prepositional"] = {
"case",
"prepositional case",
{"pre", "prep"},
2114906,
}
tags["vocative"] = {
"case",
"vocative case",
"voc",
185077,
}
----------------------- State -----------------------
tags["construct"] = {
"state",
"construct state",
{"cons", "construct state"},
1641446,
display = "construct state",
}
tags["definite"] = {
"state",
APPENDIX,
{"def", "defn", "definite state"},
53997851,
}
tags["indefinite"] = {
"state",
APPENDIX,
{"indef", "indf", "indefinite state"},
53997857,
}
tags["possessive"] = {
"state",
WP,
"poss",
2105891,
}
tags["strong"] = {
"state",
"indefinite",
"str",
53997857, -- Indefinite
}
tags["weak"] = {
"state",
"definite",
"wk",
53997851, -- Definite
}
tags["mixed"] = {
"state",
APPENDIX,
"mix",
63302161,
}
tags["attributive"] = {
"state",
APPENDIX,
"attr",
}
tags["predicative"] = {
"state",
APPENDIX,
"pred",
}
----------------------- Degrees of comparison -----------------------
tags["positive degree"] = {
"comparison",
"positive",
{"posd", "positive"},
3482678, -- Doesn't exist in English; only in Czech, Estonian, Finnish and various Nordic languages.
}
tags["comparative degree"] = {
"comparison",
"comparative",
{"comd", "comparative"},
14169499,
}
tags["superlative degree"] = {
"comparison",
"superlative",
{"supd", "superlative"},
1817208,
}
----------------------- Register -----------------------
----------------------- Deixis -----------------------
----------------------- Clusivity -----------------------
----------------------- Inflectional class -----------------------
tags["pronominal"] = {
"class",
WIKT,
"pron",
12721180, -- for "pronominal attribute", existing only in the Romanian Wikipedia
}
----------------------- Attitude -----------------------
-- This is a vague tag type grouping augmentative, diminutive and pejorative, which generally indicate the speaker's
-- attitude towards the object in question (as well as often indicating size).
tags["augmentative"] = {
"attitude",
APPENDIX,
{"aug", "augmentive"}, -- augm = augmented
1358239,
}
tags["diminutive"] = {
"attitude",
APPENDIX,
"dim",
108709,
}
tags["pejorative"] = {
"attitude",
APPENDIX,
"pej",
545779,
}
----------------------- Sound changes -----------------------
tags["augmented"] = {
"sound change",
"augment",
"augm", -- aug = augmentative
760437,
}
tags["contracted"] = {
"sound change",
"contraction",
"contr",
126473,
}
tags["unaugmented"] = {
"sound change",
"augment",
"unaugm",
760437,
}
tags["uncontracted"] = {
"sound change",
"contraction",
"uncontr",
126473,
}
----------------------- Misc grammar -----------------------
shortcuts["past-cl"] = {"past", "-", "tense", "clause"}
shortcuts["pres-cl"] = {"pres", "-", "tense", "clause"}
shortcuts["fut-cl"] = {"fut", "-", "tense", "clause"}
shortcuts["ind-cl"] = {"ind", "clause"}
shortcuts["sub-cl"] = {"sub", "clause"}
shortcuts["past-sub-cl"] = {"past", "sub", "clause"}
shortcuts["pres-sub-cl"] = {"pres", "sub", "clause"}
shortcuts["fut-sub-cl"] = {"fut", "sub", "clause"}
shortcuts["cond-cl"] = {"cond", "clause"}
shortcuts["cond-past-cl"] = {"cond", "past", "clause"}
tags["simple"] = {
"grammar",
nil,
"sim",
}
tags["short"] = {
"grammar",
}
tags["long"] = {
"grammar",
}
tags["form"] = {
"grammar",
}
tags["adjectival"] = {
"grammar",
WIKT,
"adj",
}
tags["adverbial"] = {
"grammar",
APPENDIX,
"adv",
}
tags["negative"] = {
"grammar",
"w:affirmation and negation",
"neg",
63302088,
}
tags["nominalized"] = {
"grammar",
nil,
"nomz",
4683152, -- entry for "nominalized adjective"
}
tags["nominalization"] = {
"grammar",
nil,
"nomzn",
1500667,
}
tags["root"] = {
"grammar",
nil,
nil,
111029,
}
tags["stem"] = {
"grammar",
nil,
nil,
210523,
}
tags["dependent"] = {
"grammar",
nil,
"dep",
1122094, -- entry for "dependent clause"
}
tags["independent"] = {
"grammar",
nil,
"indep",
1419215, -- entry for "independent clause"
}
tags["subject"] = {
"grammar",
APPENDIX,
"sbj", -- sub and subj used for subjunctive
164573,
}
tags["object"] = {
"grammar",
APPENDIX,
"obj",
175026,
}
tags["direct object"] = {
"grammar",
APPENDIX,
"dirobj",
2990574,
}
tags["indirect object"] = {
"grammar",
APPENDIX,
"indirobj",
1094061,
}
tags["tense"] = {
"grammar",
APPENDIX,
nil,
177691,
}
tags["clause"] = {
"grammar",
APPENDIX,
nil,
117364,
}
tags["phrase"] = {
"grammar",
APPENDIX,
nil,
187931,
}
tags["indirect question"] = {
"grammar",
WP,
{"indq", "indirq"},
1661444,
}
----------------------- Other tags -----------------------
-- This consists of non-content words like "and" as well as punctuation characters. If the punctuation characters appear
-- by themselves as tags, we special-case the handling of surrounding spaces so the output looks correct.
tags["and"] = {
"other",
}
-- HACK! "in" is a shortcut for "inanimate" so create "!in" to display "in". We should generalize this like for labels.
tags["!in"] = {
"other",
display = "in",
}
tags[","] = {
"other",
no_space_on_left = true,
}
tags[":"] = {
"other",
no_space_on_left = true,
}
tags["/"] = {
"other",
no_space_on_left = true,
no_space_on_right = true,
}
tags["("] = {
"other",
no_space_on_right = true,
}
tags[")"] = {
"other",
no_space_on_left = true,
}
tags["["] = {
"other",
no_space_on_right = true,
}
tags["]"] = {
"other",
no_space_on_left = true,
}
tags["-"] = { -- regular hyphen-minus
"other",
no_space_on_left = true,
no_space_on_right = true,
}
----------------------- Create the shortcuts list -----------------------
m_form_of_data.finalize(tags, shortcuts)
return {tags = tags, shortcuts = shortcuts}
m4t6mw0hppmbdtj76brwy5o3hw4dcah
55142
55134
2026-10-02T20:07:24Z
Deadend0914
7211
55142
Scribunto
text/plain
--[=[
This module lists the more common recognized inflection tags, along with their shortcut aliases, the corresponding
glossary entry or page describing the tag, and the corresponding wikidata entry. The less common tags are in
[[Module:form of/data/2]]. We divide the tags this way to save memory space. Be careful adding more tags to this module;
add them to the other module unless you're sure they are common.
TAGS is a table where keys are the canonical form of an inflection tag and the corresponding values are tables
describing the tags, consisting of the following keys:
- 1: Type of the tag ("person", "number", "gender", "case", "animacy", "tense-aspect", "mood", "voice-valence",
etc.).
- 2: Anchor or page describing the inflection tag, with the following values:
* nil: No link.
* APPENDIX: Anchor in [[Appendix:Glossary]] whose name is the same as the tag
* WIKT: Page in the English Wiktionary whose name is the same as the tag.
* WP: Page in the English Wikipedia whose name is the same as the tag.
* A string: If prefixed by 'w:' the specified page in the English Wikipedia. If prefixed by 'wikt:', the
specified page in the English Wiktionary. Otherwise, an anchor in [[Appendix:Glossary]].
NOTE: GLOSSARY ANCHORS ARE PREFERRED. Other types of entries should be migrated to the glossary, with links to
Wikipedia and/or Wiktionary entries as appropriate.
- 3: List of shortcuts (i.e. aliases for the inflection tag) or a single shortcut string, or nil.
- 4: Numeric value of Wikidata identifier (see wikidata.org) for the concept most closely describing this tag.
(The actual Wikidata identifier is a string formed by prefixing the number with Q.)
- display: If specified, consists of text to display in the definition line, in lieu of the canonical form of the
inflection tag. If there is a glossary entry, the displayed text forms the right side of the two-part
glossary link.
- no_space_on_left: If specified, don't display a space to the left of the tag. Used for punctuation.
- no_space_on_right: If specified, don't display a space to the right of the tag. Used for punctuation.
SHORTCUTS is a table mapping shortcut aliases to canonical inflection tag names. Shortcuts are of one of three types:
(1) A simple alias of a tag. These do not need to be entered explicitly into the table; code at the end of the module
automatically fills in these entries based on the information in TAGS.
(2) An alias to a multipart tag. For example, the alias "mf" maps to the multipart tag "m//f", which will in turn be
expanded into the canonical multipart tag {"masculine", "feminine"}, which will display as (approximately)
"[[Appendix:Glossary#gender|masculine]] and [[Appendix:Glossary#gender|feminine]]". The number of such aliases
should be liminted, and should cover only the most common combinations.
Normally, multipart tags are displayed using serialCommaJoin() in [[Module:table]] to appropriately join the display
form of the individual tags using commas and/or "and". However, some multipart tags are displayed specially; see
DISPLAY_HANDLERS below. Note that aliases to multipart tags can themselves contain simple aliases in them.
(3) An alias to a list of multiple tags (which may themselves be simple or multipart aliases). Specifying the alias is
exactly equivalent to specifying the tags in the list in order, one after another. An example is "1s", which maps to
the list {"1", "s"}. The number of such aliases should be limited, and should cover only the most common
combinations.
NOTE: In some cases below, multiple tags point to the same wikidata, because Wikipedia considers them synonyms. Examples
are indirect case vs. objective case vs. oblique case, and inferential mood vs. renarrative mood. We do this because
(a) we want to allow users to choose their own terminology; (b) we want to be able to use the terminology most common
for the language in question; (c) terms considered synonyms may or may not actually be synonyms, as different languages
may use the terms differently. For example, although the Wikipedia page on [[w:inferential mood]] claims that
inferential and renarrative moods are the same, the page on [[w:Bulgarian_verbs#Evidentials]] claims that Bulgarian has
both, and that they are not the same.
]=]
local m_form_of_data = require("Module:form of/data")
local APPENDIX = m_form_of_data.APPENDIX
local WP = m_form_of_data.WP
local WIKT = m_form_of_data.WIKT
local tags = {}
local shortcuts = {}
----------------------- Person -----------------------
tags["first-person"] = {
"person",
"first person",
"1",
21714344,
}
tags["second-person"] = {
"person",
"second person",
"2",
51929049,
}
tags["third-person"] = {
"person",
"third person",
"3",
51929074,
}
tags["impersonal"] = {
"person",
APPENDIX,
"impers",
}
shortcuts["12"] = "1//2"
shortcuts["13"] = "1//3"
shortcuts["23"] = "2//3"
shortcuts["123"] = "1//2//3"
----------------------- Number -----------------------
tags["singular"] = {
"number",
"singular number",
{"s", "sg"},
110786,
}
tags["dual"] = {
"number",
"dual number",
{"d", "du"},
110022,
}
tags["plural"] = {
"number",
"plural number",
{"p", "pl"},
146786,
display = "manigfeald"
}
tags["single-possession"] = {
"number",
"singular number",
"spos",
110786, -- Singular
}
tags["multiple-possession"] = {
"number",
"plural number",
"mpos",
146786, -- Plural
}
shortcuts["1s"] = {"1", "s"}
shortcuts["2s"] = {"2", "s"}
shortcuts["3s"] = {"3", "s"}
shortcuts["1d"] = {"1", "d"}
shortcuts["2d"] = {"2", "d"}
shortcuts["3d"] = {"3", "d"}
shortcuts["1p"] = {"1", "p"}
shortcuts["2p"] = {"2", "p"}
shortcuts["3p"] = {"3", "p"}
----------------------- Gender -----------------------
tags["masculine"] = {
"gender",
"gender",
"m",
499327,
}
-- This is useful e.g. in Swedish.
tags["natural masculine"] = {
"gender",
"gender",
"natm",
}
tags["feminine"] = {
"gender",
"gender",
"f",
1775415,
}
tags["neuter"] = {
"gender",
"gender",
"n",
1775461,
}
tags["common"] = {
"gender",
"gender",
"c",
1305037,
}
tags["nonvirile"] = {
"gender",
APPENDIX,
"nv",
}
shortcuts["mf"] = "m//f"
shortcuts["mn"] = "m//n"
shortcuts["fn"] = "f//n"
shortcuts["mfn"] = "m//f//n"
----------------------- Animacy -----------------------
-- (may be useful sometimes for [[Module:object usage]].)
tags["animate"] = {
"animacy",
APPENDIX,
"an",
51927507,
}
tags["inanimate"] = {
"animacy",
APPENDIX,
{"in", "inan"},
51927539,
}
tags["personal"] = {
"animacy",
APPENDIX,
{"pr", "pers"},
63302102,
}
----------------------- Tense/aspect -----------------------
tags["present"] = {
"tense-aspect",
"present tense",
"pres",
192613,
}
tags["past"] = {
"tense-aspect",
"past tense",
nil,
1994301,
}
tags["future"] = {
"tense-aspect",
"future tense",
{"fut", "futr"},
501405,
}
tags["future perfect"] = {
"tense-aspect",
APPENDIX,
{"futp", "fperf"},
1234617,
}
tags["non-past"] = {
"tense-aspect",
"non-past tense",
"npast",
16916993,
}
tags["progressive"] = {
"tense-aspect",
APPENDIX,
"prog",
56653945,
}
tags["preterite"] = {
"tense-aspect",
APPENDIX,
"pret",
442485,
}
tags["perfect"] = {
"tense-aspect",
APPENDIX,
"perf",
625420,
}
tags["imperfect"] = {
"tense-aspect",
APPENDIX,
{"impf", "imperf"},
}
tags["pluperfect"] = {
"tense-aspect",
APPENDIX,
{"plup", "pluperf"},
623742,
}
tags["aorist"] = {
"tense-aspect",
"aorist tense",
{"aor", "aori"},
216497,
}
tags["past historic"] = {
"tense-aspect",
"past historic tense",
"phis",
442485, -- Preterite
}
tags["imperfective"] = {
"tense-aspect",
APPENDIX,
{"impfv", "imperfv"},
371427,
}
tags["perfective"] = {
"tense-aspect",
APPENDIX,
{"pfv", "perfv"},
1424306,
}
shortcuts["spast"] = {"simple", "past"}
shortcuts["simple past"] = {"simple", "past"}
shortcuts["spres"] = {"simple", "present"}
shortcuts["simple present"] = {"simple", "present"}
----------------------- Mood -----------------------
tags["imperative"] = {
"mood",
"imperative mood",
{"imp", "impr", "impv"},
22716,
}
tags["indicative"] = {
"mood",
"indicative mood",
{"ind", "indc", "indic"},
682111,
}
tags["subjunctive"] = {
"mood",
"subjunctive mood",
{"sub", "subj"},
473746,
}
tags["conditional"] = {
"mood",
"conditional mood",
"cond",
625581,
}
tags["modal"] = {
"mood",
"w:modality (linguistics)",
"mod",
1243600,
}
tags["optative"] = {
"mood",
"optative mood",
{"opt", "opta"},
527205,
}
tags["jussive"] = {
"mood",
"jussive mood",
{"jus", "juss"},
462367,
}
tags["hortative"] = {
"mood",
WP,
"hort",
5906629,
}
----------------------- Voice/valence -----------------------
-- This tag type combines what is normally called "voice" (active, passive, middle, mediopassive) with other tags that
-- aren't normally called voice but are similar in that they control the valence/valency (number and structure of the
-- arguments of a verb).
tags["active"] = {
"voice-valence",
"active voice",
{"act", "actv"},
1317831,
}
tags["middle"] = {
"voice-valence",
"middle voice",
{"mid", "midl"},
}
tags["passive"] = {
"voice-valence",
"passive voice",
{"pass", "pasv"},
1194697,
}
tags["mediopassive"] = {
"voice-valence",
APPENDIX,
{"mp", "mpass", "mpasv", "mpsv"},
1601545,
}
tags["reflexive"] = {
"voice-valence",
APPENDIX,
"refl",
13475484, -- for "reflexive verb"
}
tags["transitive"] = {
"voice-valence",
"transitive verb",
{"tr", "vt"},
1774805, -- for "transitive verb"
}
tags["intransitive"] = {
"voice-valence",
"intransitive verb",
{"intr", "vi"},
1166153, -- for "intransitive verb"
}
tags["ditransitive"] = {
"voice-valence",
"ditransitive verb",
"ditr",
2328313, -- for "ditransitive verb"
}
tags["causative"] = {
"voice-valence",
APPENDIX,
"caus",
56677011, -- for "causative verb"
}
----------------------- Non-finite -----------------------
tags["infinitive"] = {
"non-finite",
APPENDIX,
"inf",
179230,
}
-- A form found in Portuguese and Galician, as well as in Hungarian. This is probably unnecessary and can be replaced
-- with the regular "infinitive" tag. A personal infinitive is not a separate infinitive from the plain infinitive, just
-- an inflection of the infinitive.
tags["personal infinitive"] = {
"non-finite",
"w:Portuguese verb conjugation",
"pinf",
}
tags["participle"] = {
"non-finite",
APPENDIX,
{"part", "ptcp"},
814722,
}
tags["verbal noun"] = {
"non-finite",
APPENDIX,
"vnoun",
1350145,
}
tags["gerund"] = {
"non-finite",
APPENDIX,
"ger",
1923028,
}
tags["supine"] = {
"non-finite",
APPENDIX,
"sup",
548470,
}
tags["transgressive"] = {
"non-finite",
APPENDIX,
nil,
904896,
}
----------------------- Case -----------------------
tags["ablative"] = {
"case",
"ablative case",
"abl",
156986,
}
tags["accusative"] = {
"case",
"accusative case",
"acc",
146078,
}
tags["dative"] = {
"case",
"dative case",
"dat",
145599,
}
tags["genitive"] = {
"case",
"genitive case",
"gen",
146233,
}
tags["instrumental"] = {
"case",
"instrumental case",
"ins",
192997,
}
tags["locative"] = {
"case",
"locative case",
"loc",
202142,
}
tags["nominative"] = {
"case",
"nominative case",
"nom",
131105,
}
tags["prepositional"] = {
"case",
"prepositional case",
{"pre", "prep"},
2114906,
}
tags["vocative"] = {
"case",
"vocative case",
"voc",
185077,
}
----------------------- State -----------------------
tags["construct"] = {
"state",
"construct state",
{"cons", "construct state"},
1641446,
display = "construct state",
}
tags["definite"] = {
"state",
APPENDIX,
{"def", "defn", "definite state"},
53997851,
}
tags["indefinite"] = {
"state",
APPENDIX,
{"indef", "indf", "indefinite state"},
53997857,
}
tags["possessive"] = {
"state",
WP,
"poss",
2105891,
}
tags["strong"] = {
"state",
"indefinite",
"str",
53997857, -- Indefinite
}
tags["weak"] = {
"state",
"definite",
"wk",
53997851, -- Definite
}
tags["mixed"] = {
"state",
APPENDIX,
"mix",
63302161,
}
tags["attributive"] = {
"state",
APPENDIX,
"attr",
}
tags["predicative"] = {
"state",
APPENDIX,
"pred",
}
----------------------- Degrees of comparison -----------------------
tags["positive degree"] = {
"comparison",
"positive",
{"posd", "positive"},
3482678, -- Doesn't exist in English; only in Czech, Estonian, Finnish and various Nordic languages.
}
tags["comparative degree"] = {
"comparison",
"comparative",
{"comd", "comparative"},
14169499,
}
tags["superlative degree"] = {
"comparison",
"superlative",
{"supd", "superlative"},
1817208,
}
----------------------- Register -----------------------
----------------------- Deixis -----------------------
----------------------- Clusivity -----------------------
----------------------- Inflectional class -----------------------
tags["pronominal"] = {
"class",
WIKT,
"pron",
12721180, -- for "pronominal attribute", existing only in the Romanian Wikipedia
}
----------------------- Attitude -----------------------
-- This is a vague tag type grouping augmentative, diminutive and pejorative, which generally indicate the speaker's
-- attitude towards the object in question (as well as often indicating size).
tags["augmentative"] = {
"attitude",
APPENDIX,
{"aug", "augmentive"}, -- augm = augmented
1358239,
}
tags["diminutive"] = {
"attitude",
APPENDIX,
"dim",
108709,
}
tags["pejorative"] = {
"attitude",
APPENDIX,
"pej",
545779,
}
----------------------- Sound changes -----------------------
tags["augmented"] = {
"sound change",
"augment",
"augm", -- aug = augmentative
760437,
}
tags["contracted"] = {
"sound change",
"contraction",
"contr",
126473,
}
tags["unaugmented"] = {
"sound change",
"augment",
"unaugm",
760437,
}
tags["uncontracted"] = {
"sound change",
"contraction",
"uncontr",
126473,
}
----------------------- Misc grammar -----------------------
shortcuts["past-cl"] = {"past", "-", "tense", "clause"}
shortcuts["pres-cl"] = {"pres", "-", "tense", "clause"}
shortcuts["fut-cl"] = {"fut", "-", "tense", "clause"}
shortcuts["ind-cl"] = {"ind", "clause"}
shortcuts["sub-cl"] = {"sub", "clause"}
shortcuts["past-sub-cl"] = {"past", "sub", "clause"}
shortcuts["pres-sub-cl"] = {"pres", "sub", "clause"}
shortcuts["fut-sub-cl"] = {"fut", "sub", "clause"}
shortcuts["cond-cl"] = {"cond", "clause"}
shortcuts["cond-past-cl"] = {"cond", "past", "clause"}
tags["simple"] = {
"grammar",
nil,
"sim",
}
tags["short"] = {
"grammar",
}
tags["long"] = {
"grammar",
}
tags["form"] = {
"grammar",
}
tags["adjectival"] = {
"grammar",
WIKT,
"adj",
}
tags["adverbial"] = {
"grammar",
APPENDIX,
"adv",
}
tags["negative"] = {
"grammar",
"w:affirmation and negation",
"neg",
63302088,
}
tags["nominalized"] = {
"grammar",
nil,
"nomz",
4683152, -- entry for "nominalized adjective"
}
tags["nominalization"] = {
"grammar",
nil,
"nomzn",
1500667,
}
tags["root"] = {
"grammar",
nil,
nil,
111029,
}
tags["stem"] = {
"grammar",
nil,
nil,
210523,
}
tags["dependent"] = {
"grammar",
nil,
"dep",
1122094, -- entry for "dependent clause"
}
tags["independent"] = {
"grammar",
nil,
"indep",
1419215, -- entry for "independent clause"
}
tags["subject"] = {
"grammar",
APPENDIX,
"sbj", -- sub and subj used for subjunctive
164573,
}
tags["object"] = {
"grammar",
APPENDIX,
"obj",
175026,
}
tags["direct object"] = {
"grammar",
APPENDIX,
"dirobj",
2990574,
}
tags["indirect object"] = {
"grammar",
APPENDIX,
"indirobj",
1094061,
}
tags["tense"] = {
"grammar",
APPENDIX,
nil,
177691,
}
tags["clause"] = {
"grammar",
APPENDIX,
nil,
117364,
}
tags["phrase"] = {
"grammar",
APPENDIX,
nil,
187931,
}
tags["indirect question"] = {
"grammar",
WP,
{"indq", "indirq"},
1661444,
}
----------------------- Other tags -----------------------
-- This consists of non-content words like "and" as well as punctuation characters. If the punctuation characters appear
-- by themselves as tags, we special-case the handling of surrounding spaces so the output looks correct.
tags["and"] = {
"other",
}
-- HACK! "in" is a shortcut for "inanimate" so create "!in" to display "in". We should generalize this like for labels.
tags["!in"] = {
"other",
display = "in",
}
tags[","] = {
"other",
no_space_on_left = true,
}
tags[":"] = {
"other",
no_space_on_left = true,
}
tags["/"] = {
"other",
no_space_on_left = true,
no_space_on_right = true,
}
tags["("] = {
"other",
no_space_on_right = true,
}
tags[")"] = {
"other",
no_space_on_left = true,
}
tags["["] = {
"other",
no_space_on_right = true,
}
tags["]"] = {
"other",
no_space_on_left = true,
}
tags["-"] = { -- regular hyphen-minus
"other",
no_space_on_left = true,
no_space_on_right = true,
}
----------------------- Create the shortcuts list -----------------------
m_form_of_data.finalize(tags, shortcuts)
return {tags = tags, shortcuts = shortcuts}
43h16zwgxhg391gpz5qch6szaoexjd8
55144
55142
2026-10-02T20:11:38Z
Deadend0914
7211
55144
Scribunto
text/plain
--[=[
This module lists the more common recognized inflection tags, along with their shortcut aliases, the corresponding
glossary entry or page describing the tag, and the corresponding wikidata entry. The less common tags are in
[[Module:form of/data/2]]. We divide the tags this way to save memory space. Be careful adding more tags to this module;
add them to the other module unless you're sure they are common.
TAGS is a table where keys are the canonical form of an inflection tag and the corresponding values are tables
describing the tags, consisting of the following keys:
- 1: Type of the tag ("person", "number", "gender", "case", "animacy", "tense-aspect", "mood", "voice-valence",
etc.).
- 2: Anchor or page describing the inflection tag, with the following values:
* nil: No link.
* APPENDIX: Anchor in [[Appendix:Glossary]] whose name is the same as the tag
* WIKT: Page in the English Wiktionary whose name is the same as the tag.
* WP: Page in the English Wikipedia whose name is the same as the tag.
* A string: If prefixed by 'w:' the specified page in the English Wikipedia. If prefixed by 'wikt:', the
specified page in the English Wiktionary. Otherwise, an anchor in [[Appendix:Glossary]].
NOTE: GLOSSARY ANCHORS ARE PREFERRED. Other types of entries should be migrated to the glossary, with links to
Wikipedia and/or Wiktionary entries as appropriate.
- 3: List of shortcuts (i.e. aliases for the inflection tag) or a single shortcut string, or nil.
- 4: Numeric value of Wikidata identifier (see wikidata.org) for the concept most closely describing this tag.
(The actual Wikidata identifier is a string formed by prefixing the number with Q.)
- display: If specified, consists of text to display in the definition line, in lieu of the canonical form of the
inflection tag. If there is a glossary entry, the displayed text forms the right side of the two-part
glossary link.
- no_space_on_left: If specified, don't display a space to the left of the tag. Used for punctuation.
- no_space_on_right: If specified, don't display a space to the right of the tag. Used for punctuation.
SHORTCUTS is a table mapping shortcut aliases to canonical inflection tag names. Shortcuts are of one of three types:
(1) A simple alias of a tag. These do not need to be entered explicitly into the table; code at the end of the module
automatically fills in these entries based on the information in TAGS.
(2) An alias to a multipart tag. For example, the alias "mf" maps to the multipart tag "m//f", which will in turn be
expanded into the canonical multipart tag {"masculine", "feminine"}, which will display as (approximately)
"[[Appendix:Glossary#gender|masculine]] and [[Appendix:Glossary#gender|feminine]]". The number of such aliases
should be liminted, and should cover only the most common combinations.
Normally, multipart tags are displayed using serialCommaJoin() in [[Module:table]] to appropriately join the display
form of the individual tags using commas and/or "and". However, some multipart tags are displayed specially; see
DISPLAY_HANDLERS below. Note that aliases to multipart tags can themselves contain simple aliases in them.
(3) An alias to a list of multiple tags (which may themselves be simple or multipart aliases). Specifying the alias is
exactly equivalent to specifying the tags in the list in order, one after another. An example is "1s", which maps to
the list {"1", "s"}. The number of such aliases should be limited, and should cover only the most common
combinations.
NOTE: In some cases below, multiple tags point to the same wikidata, because Wikipedia considers them synonyms. Examples
are indirect case vs. objective case vs. oblique case, and inferential mood vs. renarrative mood. We do this because
(a) we want to allow users to choose their own terminology; (b) we want to be able to use the terminology most common
for the language in question; (c) terms considered synonyms may or may not actually be synonyms, as different languages
may use the terms differently. For example, although the Wikipedia page on [[w:inferential mood]] claims that
inferential and renarrative moods are the same, the page on [[w:Bulgarian_verbs#Evidentials]] claims that Bulgarian has
both, and that they are not the same.
]=]
local m_form_of_data = require("Module:form of/data")
local APPENDIX = m_form_of_data.APPENDIX
local WP = m_form_of_data.WP
local WIKT = m_form_of_data.WIKT
local tags = {}
local shortcuts = {}
----------------------- Person -----------------------
tags["first-person"] = {
"person",
"first person",
"1",
21714344,
}
tags["second-person"] = {
"person",
"second person",
"2",
51929049,
}
tags["third-person"] = {
"person",
"third person",
"3",
51929074,
}
tags["impersonal"] = {
"person",
APPENDIX,
"impers",
}
shortcuts["12"] = "1//2"
shortcuts["13"] = "1//3"
shortcuts["23"] = "2//3"
shortcuts["123"] = "1//2//3"
----------------------- Number -----------------------
tags["singular"] = {
"number",
"singular number",
{"s", "sg"},
110786,
display = "ānfeald"
}
tags["dual"] = {
"number",
"dual number",
{"d", "du"},
110022,
}
tags["plural"] = {
"number",
"plural number",
{"p", "pl"},
146786,
display = "manigfeald"
}
tags["single-possession"] = {
"number",
"singular number",
"spos",
110786, -- Singular
}
tags["multiple-possession"] = {
"number",
"plural number",
"mpos",
146786, -- Plural
}
shortcuts["1s"] = {"1", "s"}
shortcuts["2s"] = {"2", "s"}
shortcuts["3s"] = {"3", "s"}
shortcuts["1d"] = {"1", "d"}
shortcuts["2d"] = {"2", "d"}
shortcuts["3d"] = {"3", "d"}
shortcuts["1p"] = {"1", "p"}
shortcuts["2p"] = {"2", "p"}
shortcuts["3p"] = {"3", "p"}
----------------------- Gender -----------------------
tags["masculine"] = {
"gender",
"gender",
"m",
499327,
}
-- This is useful e.g. in Swedish.
tags["natural masculine"] = {
"gender",
"gender",
"natm",
}
tags["feminine"] = {
"gender",
"gender",
"f",
1775415,
}
tags["neuter"] = {
"gender",
"gender",
"n",
1775461,
}
tags["common"] = {
"gender",
"gender",
"c",
1305037,
}
tags["nonvirile"] = {
"gender",
APPENDIX,
"nv",
}
shortcuts["mf"] = "m//f"
shortcuts["mn"] = "m//n"
shortcuts["fn"] = "f//n"
shortcuts["mfn"] = "m//f//n"
----------------------- Animacy -----------------------
-- (may be useful sometimes for [[Module:object usage]].)
tags["animate"] = {
"animacy",
APPENDIX,
"an",
51927507,
}
tags["inanimate"] = {
"animacy",
APPENDIX,
{"in", "inan"},
51927539,
}
tags["personal"] = {
"animacy",
APPENDIX,
{"pr", "pers"},
63302102,
}
----------------------- Tense/aspect -----------------------
tags["present"] = {
"tense-aspect",
"present tense",
"pres",
192613,
}
tags["past"] = {
"tense-aspect",
"past tense",
nil,
1994301,
}
tags["future"] = {
"tense-aspect",
"future tense",
{"fut", "futr"},
501405,
}
tags["future perfect"] = {
"tense-aspect",
APPENDIX,
{"futp", "fperf"},
1234617,
}
tags["non-past"] = {
"tense-aspect",
"non-past tense",
"npast",
16916993,
}
tags["progressive"] = {
"tense-aspect",
APPENDIX,
"prog",
56653945,
}
tags["preterite"] = {
"tense-aspect",
APPENDIX,
"pret",
442485,
}
tags["perfect"] = {
"tense-aspect",
APPENDIX,
"perf",
625420,
}
tags["imperfect"] = {
"tense-aspect",
APPENDIX,
{"impf", "imperf"},
}
tags["pluperfect"] = {
"tense-aspect",
APPENDIX,
{"plup", "pluperf"},
623742,
}
tags["aorist"] = {
"tense-aspect",
"aorist tense",
{"aor", "aori"},
216497,
}
tags["past historic"] = {
"tense-aspect",
"past historic tense",
"phis",
442485, -- Preterite
}
tags["imperfective"] = {
"tense-aspect",
APPENDIX,
{"impfv", "imperfv"},
371427,
}
tags["perfective"] = {
"tense-aspect",
APPENDIX,
{"pfv", "perfv"},
1424306,
}
shortcuts["spast"] = {"simple", "past"}
shortcuts["simple past"] = {"simple", "past"}
shortcuts["spres"] = {"simple", "present"}
shortcuts["simple present"] = {"simple", "present"}
----------------------- Mood -----------------------
tags["imperative"] = {
"mood",
"imperative mood",
{"imp", "impr", "impv"},
22716,
}
tags["indicative"] = {
"mood",
"indicative mood",
{"ind", "indc", "indic"},
682111,
}
tags["subjunctive"] = {
"mood",
"subjunctive mood",
{"sub", "subj"},
473746,
}
tags["conditional"] = {
"mood",
"conditional mood",
"cond",
625581,
}
tags["modal"] = {
"mood",
"w:modality (linguistics)",
"mod",
1243600,
}
tags["optative"] = {
"mood",
"optative mood",
{"opt", "opta"},
527205,
}
tags["jussive"] = {
"mood",
"jussive mood",
{"jus", "juss"},
462367,
}
tags["hortative"] = {
"mood",
WP,
"hort",
5906629,
}
----------------------- Voice/valence -----------------------
-- This tag type combines what is normally called "voice" (active, passive, middle, mediopassive) with other tags that
-- aren't normally called voice but are similar in that they control the valence/valency (number and structure of the
-- arguments of a verb).
tags["active"] = {
"voice-valence",
"active voice",
{"act", "actv"},
1317831,
}
tags["middle"] = {
"voice-valence",
"middle voice",
{"mid", "midl"},
}
tags["passive"] = {
"voice-valence",
"passive voice",
{"pass", "pasv"},
1194697,
}
tags["mediopassive"] = {
"voice-valence",
APPENDIX,
{"mp", "mpass", "mpasv", "mpsv"},
1601545,
}
tags["reflexive"] = {
"voice-valence",
APPENDIX,
"refl",
13475484, -- for "reflexive verb"
}
tags["transitive"] = {
"voice-valence",
"transitive verb",
{"tr", "vt"},
1774805, -- for "transitive verb"
}
tags["intransitive"] = {
"voice-valence",
"intransitive verb",
{"intr", "vi"},
1166153, -- for "intransitive verb"
}
tags["ditransitive"] = {
"voice-valence",
"ditransitive verb",
"ditr",
2328313, -- for "ditransitive verb"
}
tags["causative"] = {
"voice-valence",
APPENDIX,
"caus",
56677011, -- for "causative verb"
}
----------------------- Non-finite -----------------------
tags["infinitive"] = {
"non-finite",
APPENDIX,
"inf",
179230,
}
-- A form found in Portuguese and Galician, as well as in Hungarian. This is probably unnecessary and can be replaced
-- with the regular "infinitive" tag. A personal infinitive is not a separate infinitive from the plain infinitive, just
-- an inflection of the infinitive.
tags["personal infinitive"] = {
"non-finite",
"w:Portuguese verb conjugation",
"pinf",
}
tags["participle"] = {
"non-finite",
APPENDIX,
{"part", "ptcp"},
814722,
}
tags["verbal noun"] = {
"non-finite",
APPENDIX,
"vnoun",
1350145,
}
tags["gerund"] = {
"non-finite",
APPENDIX,
"ger",
1923028,
}
tags["supine"] = {
"non-finite",
APPENDIX,
"sup",
548470,
}
tags["transgressive"] = {
"non-finite",
APPENDIX,
nil,
904896,
}
----------------------- Case -----------------------
tags["ablative"] = {
"case",
"ablative case",
"abl",
156986,
}
tags["accusative"] = {
"case",
"accusative case",
"acc",
146078,
}
tags["dative"] = {
"case",
"dative case",
"dat",
145599,
}
tags["genitive"] = {
"case",
"genitive case",
"gen",
146233,
}
tags["instrumental"] = {
"case",
"instrumental case",
"ins",
192997,
}
tags["locative"] = {
"case",
"locative case",
"loc",
202142,
}
tags["nominative"] = {
"case",
"nominative case",
"nom",
131105,
}
tags["prepositional"] = {
"case",
"prepositional case",
{"pre", "prep"},
2114906,
}
tags["vocative"] = {
"case",
"vocative case",
"voc",
185077,
}
----------------------- State -----------------------
tags["construct"] = {
"state",
"construct state",
{"cons", "construct state"},
1641446,
display = "construct state",
}
tags["definite"] = {
"state",
APPENDIX,
{"def", "defn", "definite state"},
53997851,
}
tags["indefinite"] = {
"state",
APPENDIX,
{"indef", "indf", "indefinite state"},
53997857,
}
tags["possessive"] = {
"state",
WP,
"poss",
2105891,
}
tags["strong"] = {
"state",
"indefinite",
"str",
53997857, -- Indefinite
}
tags["weak"] = {
"state",
"definite",
"wk",
53997851, -- Definite
}
tags["mixed"] = {
"state",
APPENDIX,
"mix",
63302161,
}
tags["attributive"] = {
"state",
APPENDIX,
"attr",
}
tags["predicative"] = {
"state",
APPENDIX,
"pred",
}
----------------------- Degrees of comparison -----------------------
tags["positive degree"] = {
"comparison",
"positive",
{"posd", "positive"},
3482678, -- Doesn't exist in English; only in Czech, Estonian, Finnish and various Nordic languages.
}
tags["comparative degree"] = {
"comparison",
"comparative",
{"comd", "comparative"},
14169499,
}
tags["superlative degree"] = {
"comparison",
"superlative",
{"supd", "superlative"},
1817208,
}
----------------------- Register -----------------------
----------------------- Deixis -----------------------
----------------------- Clusivity -----------------------
----------------------- Inflectional class -----------------------
tags["pronominal"] = {
"class",
WIKT,
"pron",
12721180, -- for "pronominal attribute", existing only in the Romanian Wikipedia
}
----------------------- Attitude -----------------------
-- This is a vague tag type grouping augmentative, diminutive and pejorative, which generally indicate the speaker's
-- attitude towards the object in question (as well as often indicating size).
tags["augmentative"] = {
"attitude",
APPENDIX,
{"aug", "augmentive"}, -- augm = augmented
1358239,
}
tags["diminutive"] = {
"attitude",
APPENDIX,
"dim",
108709,
}
tags["pejorative"] = {
"attitude",
APPENDIX,
"pej",
545779,
}
----------------------- Sound changes -----------------------
tags["augmented"] = {
"sound change",
"augment",
"augm", -- aug = augmentative
760437,
}
tags["contracted"] = {
"sound change",
"contraction",
"contr",
126473,
}
tags["unaugmented"] = {
"sound change",
"augment",
"unaugm",
760437,
}
tags["uncontracted"] = {
"sound change",
"contraction",
"uncontr",
126473,
}
----------------------- Misc grammar -----------------------
shortcuts["past-cl"] = {"past", "-", "tense", "clause"}
shortcuts["pres-cl"] = {"pres", "-", "tense", "clause"}
shortcuts["fut-cl"] = {"fut", "-", "tense", "clause"}
shortcuts["ind-cl"] = {"ind", "clause"}
shortcuts["sub-cl"] = {"sub", "clause"}
shortcuts["past-sub-cl"] = {"past", "sub", "clause"}
shortcuts["pres-sub-cl"] = {"pres", "sub", "clause"}
shortcuts["fut-sub-cl"] = {"fut", "sub", "clause"}
shortcuts["cond-cl"] = {"cond", "clause"}
shortcuts["cond-past-cl"] = {"cond", "past", "clause"}
tags["simple"] = {
"grammar",
nil,
"sim",
}
tags["short"] = {
"grammar",
}
tags["long"] = {
"grammar",
}
tags["form"] = {
"grammar",
}
tags["adjectival"] = {
"grammar",
WIKT,
"adj",
}
tags["adverbial"] = {
"grammar",
APPENDIX,
"adv",
}
tags["negative"] = {
"grammar",
"w:affirmation and negation",
"neg",
63302088,
}
tags["nominalized"] = {
"grammar",
nil,
"nomz",
4683152, -- entry for "nominalized adjective"
}
tags["nominalization"] = {
"grammar",
nil,
"nomzn",
1500667,
}
tags["root"] = {
"grammar",
nil,
nil,
111029,
}
tags["stem"] = {
"grammar",
nil,
nil,
210523,
}
tags["dependent"] = {
"grammar",
nil,
"dep",
1122094, -- entry for "dependent clause"
}
tags["independent"] = {
"grammar",
nil,
"indep",
1419215, -- entry for "independent clause"
}
tags["subject"] = {
"grammar",
APPENDIX,
"sbj", -- sub and subj used for subjunctive
164573,
}
tags["object"] = {
"grammar",
APPENDIX,
"obj",
175026,
}
tags["direct object"] = {
"grammar",
APPENDIX,
"dirobj",
2990574,
}
tags["indirect object"] = {
"grammar",
APPENDIX,
"indirobj",
1094061,
}
tags["tense"] = {
"grammar",
APPENDIX,
nil,
177691,
}
tags["clause"] = {
"grammar",
APPENDIX,
nil,
117364,
}
tags["phrase"] = {
"grammar",
APPENDIX,
nil,
187931,
}
tags["indirect question"] = {
"grammar",
WP,
{"indq", "indirq"},
1661444,
}
----------------------- Other tags -----------------------
-- This consists of non-content words like "and" as well as punctuation characters. If the punctuation characters appear
-- by themselves as tags, we special-case the handling of surrounding spaces so the output looks correct.
tags["and"] = {
"other",
}
-- HACK! "in" is a shortcut for "inanimate" so create "!in" to display "in". We should generalize this like for labels.
tags["!in"] = {
"other",
display = "in",
}
tags[","] = {
"other",
no_space_on_left = true,
}
tags[":"] = {
"other",
no_space_on_left = true,
}
tags["/"] = {
"other",
no_space_on_left = true,
no_space_on_right = true,
}
tags["("] = {
"other",
no_space_on_right = true,
}
tags[")"] = {
"other",
no_space_on_left = true,
}
tags["["] = {
"other",
no_space_on_right = true,
}
tags["]"] = {
"other",
no_space_on_left = true,
}
tags["-"] = { -- regular hyphen-minus
"other",
no_space_on_left = true,
no_space_on_right = true,
}
----------------------- Create the shortcuts list -----------------------
m_form_of_data.finalize(tags, shortcuts)
return {tags = tags, shortcuts = shortcuts}
5r7jeen6niifmdb7z7vu3mmx7a0bcma
55156
55144
2026-10-02T21:16:03Z
Deadend0914
7211
55156
Scribunto
text/plain
--[=[
This module lists the more common recognized inflection tags, along with their shortcut aliases, the corresponding
glossary entry or page describing the tag, and the corresponding wikidata entry. The less common tags are in
[[Module:form of/data/2]]. We divide the tags this way to save memory space. Be careful adding more tags to this module;
add them to the other module unless you're sure they are common.
TAGS is a table where keys are the canonical form of an inflection tag and the corresponding values are tables
describing the tags, consisting of the following keys:
- 1: Type of the tag ("person", "number", "gender", "case", "animacy", "tense-aspect", "mood", "voice-valence",
etc.).
- 2: Anchor or page describing the inflection tag, with the following values:
* nil: No link.
* APPENDIX: Anchor in [[Appendix:Glossary]] whose name is the same as the tag
* WIKT: Page in the English Wiktionary whose name is the same as the tag.
* WP: Page in the English Wikipedia whose name is the same as the tag.
* A string: If prefixed by 'w:' the specified page in the English Wikipedia. If prefixed by 'wikt:', the
specified page in the English Wiktionary. Otherwise, an anchor in [[Appendix:Glossary]].
NOTE: GLOSSARY ANCHORS ARE PREFERRED. Other types of entries should be migrated to the glossary, with links to
Wikipedia and/or Wiktionary entries as appropriate.
- 3: List of shortcuts (i.e. aliases for the inflection tag) or a single shortcut string, or nil.
- 4: Numeric value of Wikidata identifier (see wikidata.org) for the concept most closely describing this tag.
(The actual Wikidata identifier is a string formed by prefixing the number with Q.)
- display: If specified, consists of text to display in the definition line, in lieu of the canonical form of the
inflection tag. If there is a glossary entry, the displayed text forms the right side of the two-part
glossary link.
- no_space_on_left: If specified, don't display a space to the left of the tag. Used for punctuation.
- no_space_on_right: If specified, don't display a space to the right of the tag. Used for punctuation.
SHORTCUTS is a table mapping shortcut aliases to canonical inflection tag names. Shortcuts are of one of three types:
(1) A simple alias of a tag. These do not need to be entered explicitly into the table; code at the end of the module
automatically fills in these entries based on the information in TAGS.
(2) An alias to a multipart tag. For example, the alias "mf" maps to the multipart tag "m//f", which will in turn be
expanded into the canonical multipart tag {"masculine", "feminine"}, which will display as (approximately)
"[[Appendix:Glossary#gender|masculine]] and [[Appendix:Glossary#gender|feminine]]". The number of such aliases
should be liminted, and should cover only the most common combinations.
Normally, multipart tags are displayed using serialCommaJoin() in [[Module:table]] to appropriately join the display
form of the individual tags using commas and/or "and". However, some multipart tags are displayed specially; see
DISPLAY_HANDLERS below. Note that aliases to multipart tags can themselves contain simple aliases in them.
(3) An alias to a list of multiple tags (which may themselves be simple or multipart aliases). Specifying the alias is
exactly equivalent to specifying the tags in the list in order, one after another. An example is "1s", which maps to
the list {"1", "s"}. The number of such aliases should be limited, and should cover only the most common
combinations.
NOTE: In some cases below, multiple tags point to the same wikidata, because Wikipedia considers them synonyms. Examples
are indirect case vs. objective case vs. oblique case, and inferential mood vs. renarrative mood. We do this because
(a) we want to allow users to choose their own terminology; (b) we want to be able to use the terminology most common
for the language in question; (c) terms considered synonyms may or may not actually be synonyms, as different languages
may use the terms differently. For example, although the Wikipedia page on [[w:inferential mood]] claims that
inferential and renarrative moods are the same, the page on [[w:Bulgarian_verbs#Evidentials]] claims that Bulgarian has
both, and that they are not the same.
]=]
local m_form_of_data = require("Module:form of/data")
local APPENDIX = m_form_of_data.APPENDIX
local WP = m_form_of_data.WP
local WIKT = m_form_of_data.WIKT
local tags = {}
local shortcuts = {}
----------------------- Person -----------------------
tags["first-person"] = {
"person",
"first person",
"1",
21714344,
}
tags["second-person"] = {
"person",
"second person",
"2",
51929049,
}
tags["third-person"] = {
"person",
"third person",
"3",
51929074,
}
tags["impersonal"] = {
"person",
APPENDIX,
"impers",
}
shortcuts["12"] = "1//2"
shortcuts["13"] = "1//3"
shortcuts["23"] = "2//3"
shortcuts["123"] = "1//2//3"
----------------------- Number -----------------------
tags["singular"] = {
"number",
"singular number",
{"s", "sg"},
110786,
display = "ānfeald"
}
tags["dual"] = {
"number",
"dual number",
{"d", "du"},
110022,
}
tags["plural"] = {
"number",
"plural number",
{"p", "pl"},
146786,
display = "manigfeald"
}
tags["single-possession"] = {
"number",
"singular number",
"spos",
110786, -- Singular
}
tags["multiple-possession"] = {
"number",
"plural number",
"mpos",
146786, -- Plural
}
shortcuts["1s"] = {"1", "s"}
shortcuts["2s"] = {"2", "s"}
shortcuts["3s"] = {"3", "s"}
shortcuts["1d"] = {"1", "d"}
shortcuts["2d"] = {"2", "d"}
shortcuts["3d"] = {"3", "d"}
shortcuts["1p"] = {"1", "p"}
shortcuts["2p"] = {"2", "p"}
shortcuts["3p"] = {"3", "p"}
----------------------- Gender -----------------------
tags["masculine"] = {
"gender",
"gender",
"m",
499327,
display = "werlīc"
}
-- This is useful e.g. in Swedish.
tags["natural masculine"] = {
"gender",
"gender",
"natm",
}
tags["feminine"] = {
"gender",
"gender",
"f",
1775415,
}
tags["neuter"] = {
"gender",
"gender",
"n",
1775461,
display = "nāhwæðer"
}
tags["common"] = {
"gender",
"gender",
"c",
1305037,
}
tags["nonvirile"] = {
"gender",
APPENDIX,
"nv",
}
shortcuts["mf"] = "m//f"
shortcuts["mn"] = "m//n"
shortcuts["fn"] = "f//n"
shortcuts["mfn"] = "m//f//n"
----------------------- Animacy -----------------------
-- (may be useful sometimes for [[Module:object usage]].)
tags["animate"] = {
"animacy",
APPENDIX,
"an",
51927507,
}
tags["inanimate"] = {
"animacy",
APPENDIX,
{"in", "inan"},
51927539,
}
tags["personal"] = {
"animacy",
APPENDIX,
{"pr", "pers"},
63302102,
}
----------------------- Tense/aspect -----------------------
tags["present"] = {
"tense-aspect",
"present tense",
"pres",
192613,
}
tags["past"] = {
"tense-aspect",
"past tense",
nil,
1994301,
}
tags["future"] = {
"tense-aspect",
"future tense",
{"fut", "futr"},
501405,
}
tags["future perfect"] = {
"tense-aspect",
APPENDIX,
{"futp", "fperf"},
1234617,
}
tags["non-past"] = {
"tense-aspect",
"non-past tense",
"npast",
16916993,
}
tags["progressive"] = {
"tense-aspect",
APPENDIX,
"prog",
56653945,
}
tags["preterite"] = {
"tense-aspect",
APPENDIX,
"pret",
442485,
}
tags["perfect"] = {
"tense-aspect",
APPENDIX,
"perf",
625420,
}
tags["imperfect"] = {
"tense-aspect",
APPENDIX,
{"impf", "imperf"},
}
tags["pluperfect"] = {
"tense-aspect",
APPENDIX,
{"plup", "pluperf"},
623742,
}
tags["aorist"] = {
"tense-aspect",
"aorist tense",
{"aor", "aori"},
216497,
}
tags["past historic"] = {
"tense-aspect",
"past historic tense",
"phis",
442485, -- Preterite
}
tags["imperfective"] = {
"tense-aspect",
APPENDIX,
{"impfv", "imperfv"},
371427,
}
tags["perfective"] = {
"tense-aspect",
APPENDIX,
{"pfv", "perfv"},
1424306,
}
shortcuts["spast"] = {"simple", "past"}
shortcuts["simple past"] = {"simple", "past"}
shortcuts["spres"] = {"simple", "present"}
shortcuts["simple present"] = {"simple", "present"}
----------------------- Mood -----------------------
tags["imperative"] = {
"mood",
"imperative mood",
{"imp", "impr", "impv"},
22716,
}
tags["indicative"] = {
"mood",
"indicative mood",
{"ind", "indc", "indic"},
682111,
}
tags["subjunctive"] = {
"mood",
"subjunctive mood",
{"sub", "subj"},
473746,
}
tags["conditional"] = {
"mood",
"conditional mood",
"cond",
625581,
}
tags["modal"] = {
"mood",
"w:modality (linguistics)",
"mod",
1243600,
}
tags["optative"] = {
"mood",
"optative mood",
{"opt", "opta"},
527205,
}
tags["jussive"] = {
"mood",
"jussive mood",
{"jus", "juss"},
462367,
}
tags["hortative"] = {
"mood",
WP,
"hort",
5906629,
}
----------------------- Voice/valence -----------------------
-- This tag type combines what is normally called "voice" (active, passive, middle, mediopassive) with other tags that
-- aren't normally called voice but are similar in that they control the valence/valency (number and structure of the
-- arguments of a verb).
tags["active"] = {
"voice-valence",
"active voice",
{"act", "actv"},
1317831,
}
tags["middle"] = {
"voice-valence",
"middle voice",
{"mid", "midl"},
}
tags["passive"] = {
"voice-valence",
"passive voice",
{"pass", "pasv"},
1194697,
}
tags["mediopassive"] = {
"voice-valence",
APPENDIX,
{"mp", "mpass", "mpasv", "mpsv"},
1601545,
}
tags["reflexive"] = {
"voice-valence",
APPENDIX,
"refl",
13475484, -- for "reflexive verb"
}
tags["transitive"] = {
"voice-valence",
"transitive verb",
{"tr", "vt"},
1774805, -- for "transitive verb"
}
tags["intransitive"] = {
"voice-valence",
"intransitive verb",
{"intr", "vi"},
1166153, -- for "intransitive verb"
}
tags["ditransitive"] = {
"voice-valence",
"ditransitive verb",
"ditr",
2328313, -- for "ditransitive verb"
}
tags["causative"] = {
"voice-valence",
APPENDIX,
"caus",
56677011, -- for "causative verb"
}
----------------------- Non-finite -----------------------
tags["infinitive"] = {
"non-finite",
APPENDIX,
"inf",
179230,
}
-- A form found in Portuguese and Galician, as well as in Hungarian. This is probably unnecessary and can be replaced
-- with the regular "infinitive" tag. A personal infinitive is not a separate infinitive from the plain infinitive, just
-- an inflection of the infinitive.
tags["personal infinitive"] = {
"non-finite",
"w:Portuguese verb conjugation",
"pinf",
}
tags["participle"] = {
"non-finite",
APPENDIX,
{"part", "ptcp"},
814722,
}
tags["verbal noun"] = {
"non-finite",
APPENDIX,
"vnoun",
1350145,
}
tags["gerund"] = {
"non-finite",
APPENDIX,
"ger",
1923028,
}
tags["supine"] = {
"non-finite",
APPENDIX,
"sup",
548470,
}
tags["transgressive"] = {
"non-finite",
APPENDIX,
nil,
904896,
}
----------------------- Case -----------------------
tags["ablative"] = {
"case",
"ablative case",
"abl",
156986,
}
tags["accusative"] = {
"case",
"accusative case",
"acc",
146078,
}
tags["dative"] = {
"case",
"dative case",
"dat",
145599,
}
tags["genitive"] = {
"case",
"genitive case",
"gen",
146233,
display = "geāgniendlīc"
}
tags["instrumental"] = {
"case",
"instrumental case",
"ins",
192997,
}
tags["locative"] = {
"case",
"locative case",
"loc",
202142,
}
tags["nominative"] = {
"case",
"nominative case",
"nom",
131105,
}
tags["prepositional"] = {
"case",
"prepositional case",
{"pre", "prep"},
2114906,
}
tags["vocative"] = {
"case",
"vocative case",
"voc",
185077,
}
----------------------- State -----------------------
tags["construct"] = {
"state",
"construct state",
{"cons", "construct state"},
1641446,
display = "construct state",
}
tags["definite"] = {
"state",
APPENDIX,
{"def", "defn", "definite state"},
53997851,
}
tags["indefinite"] = {
"state",
APPENDIX,
{"indef", "indf", "indefinite state"},
53997857,
}
tags["possessive"] = {
"state",
WP,
"poss",
2105891,
}
tags["strong"] = {
"state",
"indefinite",
"str",
53997857, -- Indefinite
}
tags["weak"] = {
"state",
"definite",
"wk",
53997851, -- Definite
}
tags["mixed"] = {
"state",
APPENDIX,
"mix",
63302161,
}
tags["attributive"] = {
"state",
APPENDIX,
"attr",
}
tags["predicative"] = {
"state",
APPENDIX,
"pred",
}
----------------------- Degrees of comparison -----------------------
tags["positive degree"] = {
"comparison",
"positive",
{"posd", "positive"},
3482678, -- Doesn't exist in English; only in Czech, Estonian, Finnish and various Nordic languages.
}
tags["comparative degree"] = {
"comparison",
"comparative",
{"comd", "comparative"},
14169499,
}
tags["superlative degree"] = {
"comparison",
"superlative",
{"supd", "superlative"},
1817208,
}
----------------------- Register -----------------------
----------------------- Deixis -----------------------
----------------------- Clusivity -----------------------
----------------------- Inflectional class -----------------------
tags["pronominal"] = {
"class",
WIKT,
"pron",
12721180, -- for "pronominal attribute", existing only in the Romanian Wikipedia
}
----------------------- Attitude -----------------------
-- This is a vague tag type grouping augmentative, diminutive and pejorative, which generally indicate the speaker's
-- attitude towards the object in question (as well as often indicating size).
tags["augmentative"] = {
"attitude",
APPENDIX,
{"aug", "augmentive"}, -- augm = augmented
1358239,
}
tags["diminutive"] = {
"attitude",
APPENDIX,
"dim",
108709,
}
tags["pejorative"] = {
"attitude",
APPENDIX,
"pej",
545779,
}
----------------------- Sound changes -----------------------
tags["augmented"] = {
"sound change",
"augment",
"augm", -- aug = augmentative
760437,
}
tags["contracted"] = {
"sound change",
"contraction",
"contr",
126473,
}
tags["unaugmented"] = {
"sound change",
"augment",
"unaugm",
760437,
}
tags["uncontracted"] = {
"sound change",
"contraction",
"uncontr",
126473,
}
----------------------- Misc grammar -----------------------
shortcuts["past-cl"] = {"past", "-", "tense", "clause"}
shortcuts["pres-cl"] = {"pres", "-", "tense", "clause"}
shortcuts["fut-cl"] = {"fut", "-", "tense", "clause"}
shortcuts["ind-cl"] = {"ind", "clause"}
shortcuts["sub-cl"] = {"sub", "clause"}
shortcuts["past-sub-cl"] = {"past", "sub", "clause"}
shortcuts["pres-sub-cl"] = {"pres", "sub", "clause"}
shortcuts["fut-sub-cl"] = {"fut", "sub", "clause"}
shortcuts["cond-cl"] = {"cond", "clause"}
shortcuts["cond-past-cl"] = {"cond", "past", "clause"}
tags["simple"] = {
"grammar",
nil,
"sim",
}
tags["short"] = {
"grammar",
}
tags["long"] = {
"grammar",
}
tags["form"] = {
"grammar",
}
tags["adjectival"] = {
"grammar",
WIKT,
"adj",
}
tags["adverbial"] = {
"grammar",
APPENDIX,
"adv",
}
tags["negative"] = {
"grammar",
"w:affirmation and negation",
"neg",
63302088,
}
tags["nominalized"] = {
"grammar",
nil,
"nomz",
4683152, -- entry for "nominalized adjective"
}
tags["nominalization"] = {
"grammar",
nil,
"nomzn",
1500667,
}
tags["root"] = {
"grammar",
nil,
nil,
111029,
}
tags["stem"] = {
"grammar",
nil,
nil,
210523,
}
tags["dependent"] = {
"grammar",
nil,
"dep",
1122094, -- entry for "dependent clause"
}
tags["independent"] = {
"grammar",
nil,
"indep",
1419215, -- entry for "independent clause"
}
tags["subject"] = {
"grammar",
APPENDIX,
"sbj", -- sub and subj used for subjunctive
164573,
}
tags["object"] = {
"grammar",
APPENDIX,
"obj",
175026,
}
tags["direct object"] = {
"grammar",
APPENDIX,
"dirobj",
2990574,
}
tags["indirect object"] = {
"grammar",
APPENDIX,
"indirobj",
1094061,
}
tags["tense"] = {
"grammar",
APPENDIX,
nil,
177691,
}
tags["clause"] = {
"grammar",
APPENDIX,
nil,
117364,
}
tags["phrase"] = {
"grammar",
APPENDIX,
nil,
187931,
}
tags["indirect question"] = {
"grammar",
WP,
{"indq", "indirq"},
1661444,
}
----------------------- Other tags -----------------------
-- This consists of non-content words like "and" as well as punctuation characters. If the punctuation characters appear
-- by themselves as tags, we special-case the handling of surrounding spaces so the output looks correct.
tags["and"] = {
"other",
}
-- HACK! "in" is a shortcut for "inanimate" so create "!in" to display "in". We should generalize this like for labels.
tags["!in"] = {
"other",
display = "in",
}
tags[","] = {
"other",
no_space_on_left = true,
}
tags[":"] = {
"other",
no_space_on_left = true,
}
tags["/"] = {
"other",
no_space_on_left = true,
no_space_on_right = true,
}
tags["("] = {
"other",
no_space_on_right = true,
}
tags[")"] = {
"other",
no_space_on_left = true,
}
tags["["] = {
"other",
no_space_on_right = true,
}
tags["]"] = {
"other",
no_space_on_left = true,
}
tags["-"] = { -- regular hyphen-minus
"other",
no_space_on_left = true,
no_space_on_right = true,
}
----------------------- Create the shortcuts list -----------------------
m_form_of_data.finalize(tags, shortcuts)
return {tags = tags, shortcuts = shortcuts}
7blbkzhi8k45jxxr7tjv14xbtimg80q
Module:form of/data
828
8198
55135
2026-10-02T19:39:33Z
Deadend0914
7211
Gesceop tramet þe hafaþ 'local export = {} local ipairs = ipairs local next = next local type = type export.TAG_TYPE = 1 export.GLOSSARY = 2 local SHORTCUTS = 3; export.SHORTCUTS = SHORTCUTS export.WIKIDATA = 4 export.APPENDIX = true export.WIKT = 0 export.WP = false local function process_shortcut(tags, shortcuts, name, shortcut) -- If the shortcut is already in the list, then there is a duplicate. if shortcuts[shortcut] then error("The shortcut \"" .. shortcut .. "\" (for the i...'
55135
Scribunto
text/plain
local export = {}
local ipairs = ipairs
local next = next
local type = type
export.TAG_TYPE = 1
export.GLOSSARY = 2
local SHORTCUTS = 3; export.SHORTCUTS = SHORTCUTS
export.WIKIDATA = 4
export.APPENDIX = true
export.WIKT = 0
export.WP = false
local function process_shortcut(tags, shortcuts, name, shortcut)
-- If the shortcut is already in the list, then there is a duplicate.
if shortcuts[shortcut] then
error("The shortcut \"" .. shortcut .. "\" (for the inflection tag \"" .. name .. "\") conflicts with an existing shortcut for the tag \"" .. shortcuts[shortcut] .. "\".")
elseif tags[shortcut] then
error("The shortcut \"" .. shortcut .. "\" (for the inflection tag \"" .. name .. "\") conflicts with an existing tag with that name.")
end
shortcuts[shortcut] = name
end
function export.finalize(tags, shortcuts)
for name, data in next, tags do
local data_shortcuts = data[SHORTCUTS]
if data_shortcuts then
if type(data_shortcuts) == "string" then
process_shortcut(tags, shortcuts, name, data_shortcuts)
else
for _, shortcut in ipairs(data_shortcuts) do
process_shortcut(tags, shortcuts, name, shortcut)
end
end
end
end
end
return export
mxr0ilpfejbl0ove2gt0ylcegf7jfyp
Module:form of/cats
828
8199
55136
2026-10-02T19:40:07Z
Deadend0914
7211
Gesceop tramet þe hafaþ 'local cats = {} --[=[ -- FIXME: Data structure is highly inefficient, as it involves lots of nested tables. This contains categorization specs for specific languages and for all languages. The particular categories listed are listed without the preceding canonical language name, which will automatically be prepended, and the text "<<p>>" in a category will be replaced with the user-specified part of speech. The value of an entry in the cats[] table is a list...'
55136
Scribunto
text/plain
local cats = {}
--[=[
-- FIXME: Data structure is highly inefficient, as it involves lots of nested tables.
This contains categorization specs for specific languages and for all languages.
The particular categories listed are listed without the preceding canonical
language name, which will automatically be prepended, and the text "<<p>>"
in a category will be replaced with the user-specified part of speech.
The value of an entry in the cats[] table is a list of specifications to apply
to inflections in a specific language (except that the entry for "und" applies
to all languages). Each specification indicates the conditions under which a
given category is applied. Each specification is processed independently; if
multiple specifications apply, all the resulting categories will be added to
the page. (This is equivalent to wrapping the specifications in a
{"multi", ...} clause; see below.)
A specification is one of:
(1) A string:
Always apply that category.
(2) A list {"has", TAG, SPEC} or {"has", TAG, SPEC, ELSESPEC}:
TAG is an inflection tag, and can either be the full form or any
abbreviation; if that tag is present among the user-supplied tags, SPEC is
applied, otherwise ELSESPEC is applied if present. SPEC and ELSESPEC are
specifications just as at the top level; i.e. they can be strings, nested
conditions, etc.
(2) A list {"hasall", TAGS, SPEC} or {"hasall", TAGS, SPEC, ELSESPEC}:
Similar to {"has", ...} but only activates if all of the tags in TAGS
(a list) are present among the user-supplied tags (in any order, and
other tags may be present, including between the tags in TAGS).
(3) A list {"hasany", TAGS, SPEC} or {"hasany", TAGS, SPEC, ELSESPEC}:
Similar to {"has", ...} but activates if any of the tags in TAGS
(a list) are present among the user-supplied tags.
(4) A list {"tags=", TAGS, SPEC} or {"tags=", TAGS, SPEC, ELSESPEC}:
Similar to {"hasall", ...} but activates only if the
user-supplied tags exactly match the tags in TAGS, including
the order. (But, as above, any tag abbreviation can be given
in TAGS, and will match any equivalent abbreviation or full
form.)
(5) A list {"p=", VALUE, SPEC} or {"p=", VALUE, SPEC, ELSESPEC}:
Similar to {"has", ...} but activates if the value supplied for the p=
or POS= parameters is the specified value (which can be either the full
form or any abbreviation).
(6) A list {"pany", VALUES, SPEC} or {"pany", VALUES, SPEC, ELSESPEC}:
Similar to {"p=", ...} but activates if the value supplied for the p=
or POS= parameters is any of the specified values (which can be either
the full forms or any abbreviation).
(7) A list {"pexists", SPEC} or {"pexists", SPEC, ELSESPEC}:
Activates if any value was specified for the p= or POS= parameters.
(8) A list {"cond", SPEC1, SPEC2, ...}:
If SPEC1 applies, it will be applied; otherwise, if SPEC2 applies, it
will be applied; etc. This stops processing specifications as soon as it
finds one that applies.
(9) A list {"multi", SPEC1, SPEC2, ...}:
If SPEC1 applies, it will be applied; in addition, if SPEC2 applies, it
will also be applied; etc. Unlike {"cond", ...}, this continues
processing specifications even if a previous one has applied.
(10) A list {"not", CONDITION, SPEC} or {"not", CONDITION, SPEC, ELSESPEC}:
If CONDITION does *NOT* apply, SPEC will be applied, otherwise ELSESPEC
will be applied if present. CONDITION is one of:
-- {"has", TAG}
-- {"hasall", TAGS}
-- {"hasany", TAGS}
-- {"tags=", TAGS},
-- {"p=", VALUE}
-- {"pany", VALUES}
-- {"pexists"}
-- {"not", CONDITION}
-- {"and", CONDITION1, CONDITION2}
-- {"or", CONDITION1, CONDITION2}
-- {"call", FUNCTION} where FUNCTION is a string naming a function listed
in cat_functions in [[Module:form of/functions]], which is passed a
single argument (see (10) below) and should return true or false.
That is, conditions are similar to if-else SPECS but without any
specifications given.
(11) A list {"and", CONDITION1, CONDITION2, SPEC} or {"and", CONDITION1, CONDITION2, SPEC, ELSESPEC}:
If CONDITION1 and CONDITION2 both apply, SPEC will be applied, otherwise
ELSESPEC will be applied if present. CONDITION is as above for "not".
(12) A list {"or", CONDITION1, CONDITION2, SPEC} or {"or", CONDITION1, CONDITION2, SPEC, ELSESPEC}:
If either CONDITION1 or CONDITION2 apply, SPEC will be applied, otherwise
ELSESPEC will be applied if present. CONDITION is as above for "not".
(13) A list {"call", FUNCTION}:
FUNCTION is the name of a function listed in cat_functions in
[[Module:form of/functions]], which is passed a single argument, a table
containing the parameters given to the template call, and which should
return a specification (a string naming a category, a list of any of the
formats described above). In the table, the following keys are present:
"lang": the structure describing the language (usually the first
parameter);
"tags": the list of tags (canonicalized to their full forms);
"term": the term to link to (will be missing if no term is given);
"alt": the display form of the term (will be missing if no display form
is given);
"t": the gloss of the term (will be missing if no gloss is given);
In addition, any other parameters specified will be located under a key
corresponding to the parameter name.
As a simple example, consider this:
cats["et"] = {
{"has", "part", "participles"},
}
This says that, for language code "et" (Estonian), if the "part" tag is
present (or if "participle" is present, which is the equivalent full form),
the page will be categorized into [[:Category:Estonian participles]].
Another example:
cats["lt"] = {
{"p=", "part",
{"has", "pron",
"pronominal dalyvis participle forms",
"dalyvis participle forms",
}
}
}
This says that, for language code "lt" (Lithuanian), if the "p=" parameter
was given with the value "part" (or "participle", the equivalent full form),
then if the "pron" tag is present (or the equivalent full form "pronominal"),
categorize into [[:Category:Lithuanian pronominal dalyvis participle forms]],
else categorize into [["Category:Lithuanian dalyvis participle forms]]. Note
that, if p= isn't specified, or has a value other than "part" or
"participle", no categories will be added to the page, because there is no
"else" specification associated with the "p=" specification.
--]=]
-- First, the language-independent categories; be careful here not to
-- overcategorize. In practice we achieve this using tags=; we should
-- probably be smarter. But we don't e.g. want to categorize a page
-- into "present participles" if it has the tags f|s|pres|part, which
-- is a participle form rather than a participle itself.
--
-- We include the categorization here rather than in e.g. {{augmentative of}}
-- because we want the categorization to also apply when e.g. an augmentative
-- is specified using {{inflection of|LANG|...|aug}} rather than
-- {{augmentative of|LANG}}.
--[==[Disable all of these for now as they are somewhat controversial.
cats["und"] = {
{"tags=", {"aug"}, "augmentative <<p=n>>s"},
{"tags=", {"dim"}, "diminutive <<p=n>>s"},
{"or", {"tags=", {"end"}},
{"or", {"tags=", {"end", "form"}}, {"tags=", {"end", "dim"}}},
"endearing <<p=n>>s"},
{"tags=", {"pej"}, "derogatory terms"},
{"tags=", {"comd"}, "comparative <<p=a>>s"},
{"tags=", {"supd"}, "superlative <<p=a>>s"},
{"tags=", {"equd"}, "<<p=a>> equative forms"},
{"tags=", {"caus"}, "causative <<p=v>>s"},
{"tags=", {"freq"}, "frequentative <<p=v>>s"},
{"tags=", {"iter"}, "iterative <<p=v>>s"},
{"tags=", {"refl"}, "reflexive <<p=v>>s"},
{"or", {"tags=", {"impfv"}}, {"tags=", {"impfv", "form"}}, "imperfective <<p=v>>s"},
{"or", {"tags=", {"pfv"}}, {"tags=", {"pfv", "form"}}, "perfective <<p=v>>s"},
{"tags=", {"nomzn"}, "nominalized adjectives"},
{"tags=", {"ger"}, "gerunds"},
{"tags=", {"vnoun"}, "verbal nouns"},
{"tags=", {"pass"}, "<<p=v>> passive forms"},
-- [[User:Rua]] objects to these categories
{"tags=", {"past", "act", "part"}, "past active participles"},
{"tags=", {"past", "pass", "part"}, "past passive participles"},
{"tags=", {"past", "part"}, "past participles"},
{"tags=", {"pres", "act", "part"}, "present active participles"},
{"tags=", {"pres", "pass", "part"}, "present passive participles"},
{"tags=", {"pres", "part"}, "present participles"},
{"tags=", {"perf", "part"}, "perfect participles"},
}]==]
cats["az"] = {
{"hasall", {"subject", "past", "participle"}, "subject past participles"},
{"hasall", {"broken", "plural"}, "broken noun plural forms"},
}
cats["bg"] = {
{"cond",
{"hasall", {"adv", "part"}, "adverbial participles"},
{"has", "part",
-- If this is a lemma participle form, categorize appropriately
-- for the type of participle, otherwise put into
-- "participle forms". We determine a lemma if all of the
-- following apply:
-- (1) either is masculine, or no gender listed; and
-- (2) either is indefinite, or no definiteness listed; and
-- (3) not listed as either subjective or objective form.
{"and",
{"or", {"has", "m"}, {"not", {"hasany", {"f", "n", "p"}}}},
{"and",
{"or", {"has", "indef"}, {"not", {"has", "def"}}},
{"not", {"hasany", {"sbjv", "objv"}}},
},
{"cond",
{"hasall", {"pres", "act"}, "present active participles"},
{"hasall", {"past", "pass"}, "past passive participles"},
{"hasall", {"past", "act", "aor"}, "past active aorist participles"},
{"hasall", {"past", "act", "impf"}, "past active imperfect participles"},
},
-- FIXME: "participle forms" probably not necessary,
-- should be handled by headword
"participle forms"
}
}
},
}
cats["br"] = {
{"p=", "n",
{"has", "p", "noun plural forms"}
},
}
cats["ca"] = {
{"has", "part",
{"cond",
-- FIXME, not clear if we need all of these conditions;
-- may partly be handled by headword
{"hasany", {"f", "p"}, "participle forms"},
{"has", "pres", "present participles"},
{"has", "past", "past participles"},
}
},
}
cats["de"] = {
{"hasall", {"pres", "part"}, "present participles"},
{"hasall", {"past", "part"}, "past participles"},
}
cats["el"] = {
{"has", "dat", "dative forms"},
{"cond",
{"hasall", {"1", "s", "past"}, "verb past tense forms"},
{"has", "nonfinite", "verb nonfinite forms"},
},
}
cats["en"] = {
{"cond",
-- The display of these labels and their categorization is controlled by [[Module:labels/data/lang/en]].
-- This label will categorize into [[:Category:English archaic third-person singular forms]].
{"has", "3-th", {labels = {"archaic third singular"}}},
-- This label will categorize into [[:Category:English second-person singular forms]].
{"hasall", {"2-st", "pres"}, {labels = {"archaic second singular present"}}},
-- This label will categorize into [[:Category:English second-person singular past tense forms]].
{"hasall", {"2-st", "past"}, {labels = {"archaic second singular past"}}},
},
-- Add irregular plural categories. The corresponding code is in [[Module:form of/lang-data/en/functions]].
{"tags=", {"p"}, {"call", "en-irregular-plural-categories"}},
}
cats["enm"] = {
{"not", {"hasany", {"sub", "imp"}},
{"multi",
{"hasall", {"1", "s", "pres"}, "first-person singular forms"},
{"hasall", {"2", "s", "pres"}, "second-person singular forms"},
{"hasall", {"3", "s", "pres"}, "third-person singular forms"},
{"hasall", {"1//3", "s", "past"}, "first/third-person singular past forms"},
{"hasall", {"2", "s", "past"}, "second-person singular past forms"},
{"hasall", {"p", "pres"}, "plural forms"},
},
},
{"hasall", {"p", "pres", "ind"}, "plural forms"},
{"hasall", {"p", "pres", "sub"}, "plural subjunctive forms"},
{"hasall", {"p", "past"}, "plural past forms"},
{"hasall", {"s", "pres", "sub"}, "singular subjunctive forms"},
{"hasall", {"s", "past", "sub"}, "singular past subjunctive forms"},
{"hasall", {"s", "imp"}, "singular imperative forms"},
{"hasall", {"p", "imp"}, "plural imperative forms"},
{"hasall", {"pres", "part"}, "present participles"},
{"hasall", {"past", "part"}, "past participles"},
}
cats["et"] = {
{"has", "part", "participles"},
}
cats["fi"] = {
{"has", "inf",
{"cond",
{"hasall", {"long", "first"}, "long first infinitives"},
{"hasall", {"second", "act"}, "active second infinitives"},
{"hasall", {"second", "pass"}, "passive second infinitives"},
{"hasall", {"third", "act"}, "active third infinitives"},
{"hasall", {"third", "pass"}, "passive third infinitives"},
{"has", "fifth", "fifth infinitives"},
}
},
}
cats["got"] = {
{"hasall", {"pres", "part"}, "present participles"},
{"hasall", {"past", "part"}, "past participles"},
}
cats["hu"] = {
{"hasall", {"past", "part"}, "past participles"},
{"hasall", {"pres", "part"}, "present participles"},
{"hasall", {"fut", "part"}, "future participles"},
{"hasall", {"adv", "part"}, "adverbial participles"},
{"hasall", {"verbal", "part"}, "verbal participles"},
}
cats["ja"] = {
{"p=", "v",
{"multi",
{"has", "past", "past tense verb forms"},
{"has", "conj", "conjunctive verb forms"},
}
},
}
cats["kmr"] = {
{"hasall", {"pres", "part"}, "present participles"},
{"hasall", {"past", "part"}, "past participles"},
}
cats["liv"] = {
{"has", "part",
{"cond",
{"hasall", {"pres", "act"}, "present active participles"},
{"hasall", {"pres", "pass"}, "present passive participles"},
{"hasall", {"past", "act"}, "past active participles"},
{"hasall", {"past", "pass"}, "past passive participles"},
},
},
{"cond",
{"has", "ger", "gerunds"},
{"hasall", {"sup", "abe"}, "supine abessives"},
{"has", "sup", "supines"},
{"has", "deb", "debitives"},
},
}
cats["lt"] = {
{"has", "part",
{"cond",
-- Three types of adverbial participles.
{"has", "budinys", "būdinys participles"},
{"has", "padalyvis", "padalyvis participles"},
{"has", "pusdalyvis", "pusdalyvis participles"},
-- If it's a non-adverbial participle, it's a dalyvis = regular
-- adjectival participle. It's a participle per se if it has
-- no case, number or gender listed.
{"not", {"hasany", {
"nom", "gen", "dat", "acc", "ins", "loc", "voc",
"m", "f", "s", "p"
}}, "dalyvis participles"},
}
},
{"p=", "a",
{"has", "pron",
{"cond",
{"has", "comd", "comparative pronominal adjective forms"},
{"has", "supd", "superlative pronominal adjective forms"},
},
{"cond",
{"has", "comd", "comparative adjective forms"},
{"has", "supd", "superlative adjective forms"},
},
}
},
}
cats["lv"] = {
{"has", "neg", "negative verb forms"},
{"has", "comd", "comparative adjectives"},
{"has", "supd", "superlative adjectives"},
{"has", "part",
{"cond",
{"hasall", {"pres", "act"}, "present active participles"},
{"hasall", {"pres", "pass"}, "present passive participles"},
{"hasall", {"past", "act"}, "past active participles"},
{"hasall", {"past", "pass"}, "past passive participles"},
},
},
}
cats["mk"] = {
{"has", "vnoun",
{"multi", "verbal nouns", "verb forms"},
},
{"has", "part",
{"multi",
"participles",
"verb forms",
{"cond",
{"hasall", {"adj", "part"}, "adjectival participles"},
{"hasall", {"adv", "part"}, "adverbial participles"},
{"hasall", {"perf", "part"}, "perfect participles"},
{"hasall", {"aor", "act", "part"}, "aorist l-participles"},
{"hasall", {"impf", "act", "part"}, "imperfect l-participles"},
},
}
},
{"has", "lptcp",
{"multi",
{"has", "aor", "aorist l-participles"},
{"has", "impf", "imperfect l-participles"},
{"hasall", {"m", "s"}, "participles", "participle forms"},
},
},
{"hasall", {"col", "pl"}, "collective plurals"},
}
cats["nl"] = {
{"tags=", {"pl", "imp"}, {labels = {"plural imperative"}}},
{"has", "sub", {labels = {"subjunctive"}}},
-- Depending on the part of speech, a specific case-form category is added, or if no
-- recognized part of speech is present, the generic case-form category is used. The
-- label "archaic" will also be added, for which see [[Module:labels/data/lang/nl]].
{"hasany", {"acc", "dat", "gen"},
{"multi",
{labels = {"archaic case form"}},
{"cond",
{"p=", "n", "noun case forms"},
{"p=", "a", "adjective case forms"},
-- Only goes to "case forms" umbrella cat if no (/no recognized) POS given
"case forms"
}
}
}
}
cats["pl"] = {
{"has", "short", "short adjective forms"},
}
cats["sa"] = {
{"has", "desid",
{"multi",
"desiderative verbs",
"verbs derived from primitive verbs"
},
},
{"has", "freq",
{"multi",
"frequentative verbs",
"verbs derived from primitive verbs"
},
},
{"has", "root", "root forms"},
}
cats["sv"] = {
{"cond",
-- The display of these labels is controlled by [[Module:labels/data/lang/sv]].
{"hasall", {"past", "sub"}, {labels = {"past subjunctive"}}},
{"hasall", {"pres", "sub"}, {labels = {"present subjunctive"}}},
-- If it just has 'sub' (subjunctive), not labeled as present or past, treat it like the past subjunctive, whose label
-- is "weaker" than the present subjunctive (dated vs. archaic).
{"has", "sub", {labels = {"past subjunctive"}}},
{"hasall", {"1", "p", "pres"}, {labels = {"1st plural present indicative"}}},
{"hasall", {"2", "p", "pres"}, {labels = {"2nd plural present indicative"}}},
{"hasall", {"p", "pres"}, {labels = {"plural present indicative"}}},
{"hasall", {"1", "p", "past"}, {labels = {"1st plural past indicative"}}},
{"hasall", {"2", "p", "past"}, {labels = {"2nd plural past indicative"}}},
{"hasall", {"p", "past"}, {labels = {"plural past indicative"}}},
{"hasall", {"1", "p", "imp"}, {labels = {"1st plural imperative"}}},
{"hasall", {"p", "imp"}, {labels = {"2nd plural imperative"}}},
},
}
cats["uk"] = {
{"has", "part",
{"multi",
"participles",
"verb forms",
{"cond",
{"hasall", {"pres", "act"}, "present active participles"},
{"hasall", {"pres", "pass"}, "present passive participles"},
{"hasall", {"pres", "adv"}, "present adverbial participles"},
{"hasall", {"past", "act"}, "past active participles"},
{"hasall", {"past", "pass"}, "past passive participles"},
{"hasall", {"past", "adv"}, "past adverbial participles"},
},
}
},
}
return cats
cnhxumcr3cajnqtfpficwhzfl7ttnla
Module:form of/data/2
828
8200
55137
2026-10-02T19:40:52Z
Deadend0914
7211
Gesceop tramet þe hafaþ '--[=[ This module lists the less common recognized inflection tags, in the same format as for [[Module:form of/data/1]] (which contains the more common tags). We split the tags this way to save memory, so we avoid loading the less common tags in the majority of cases. ]=] local m_form_of_data = require("Module:form of/data") local APPENDIX = m_form_of_data.APPENDIX local WP = m_form_of_data.WP local WIKT = m_form_of_data.WIKT local tags = {} local shortcuts =...'
55137
Scribunto
text/plain
--[=[
This module lists the less common recognized inflection tags, in the same format as for [[Module:form of/data/1]] (which
contains the more common tags). We split the tags this way to save memory, so we avoid loading the less common tags in
the majority of cases.
]=]
local m_form_of_data = require("Module:form of/data")
local APPENDIX = m_form_of_data.APPENDIX
local WP = m_form_of_data.WP
local WIKT = m_form_of_data.WIKT
local tags = {}
local shortcuts = {}
----------------------- Person -----------------------
tags["fourth-person"] = {
"person",
"wikt:fourth person",
"4",
3348541,
}
tags["second-person-object form"] = {
"person",
APPENDIX,
"2o",
}
----------------------- Number -----------------------
tags["associative plural"] = {
"number",
WIKT,
{"ass p", "ass pl", "assoc p", "assoc pl"},
}
tags["collective"] = {
"number",
"collective number",
"col",
694268,
}
tags["collective-possession"] = {
"number",
"collective number",
{"cpos", "colpos"},
}
-- same as "count form" below, but included for backwards-compatibility with uses of "count|form"
tags["count"] = {
"number",
"count form",
nil,
12273953,
}
tags["count form"] = {
"number",
WIKT,
nil,
12273953,
}
tags["distributive paucal"] = {
"number",
WIKT,
"dpau",
}
tags["paucal"] = {
"number",
WIKT,
"pau",
489410,
}
tags["singulative"] = {
"number",
"singulative number",
"sgl",
1450795,
}
tags["transnumeral"] = {
"number",
APPENDIX,
"trn",
113631596,
display = "singular or plural",
}
tags["trial"] = {
"number",
"trial number",
"tri",
2142560,
}
----------------------- Gender -----------------------
tags["natural feminine"] = {
"gender",
"gender",
"natf",
}
tags["virile"] = {
"gender",
APPENDIX,
"vr",
}
----------------------- Animacy -----------------------
----------------------- Tense/aspect -----------------------
tags["abtemporal"] = {
"tense-aspect",
WIKT,
"abtemp",
}
tags["anterior"] = {
"tense-aspect",
"w:relative and absolute tense",
"ant",
}
tags["cessative"] = {
"tense-aspect",
WP,
"cess",
17027342,
}
-- Aspect in Tagalog; presumably similar to the perfect tense/aspect but not necessarily similar enough to use the same
-- Wikidata ID
tags["complete"] = {
"tense-aspect",
"w:Tagalog grammar#Aspect",
"compl",
}
tags["concomitant"] = {
"tense-aspect",
WIKT,
"concom",
}
tags["confirmative"] = {
"tense-aspect",
WIKT,
"conf",
}
-- Aspect in Tagalog
tags["contemplative"] = {
"tense-aspect",
"w:Tagalog grammar#Aspect",
"contem",
}
tags["contemporal"] = {
"tense-aspect",
WIKT,
"contemp",
}
tags["continuative"] = {
"tense-aspect",
WP,
nil,
28130104,
}
tags["continuous"] = {
"tense-aspect",
"w:continuous aspect",
"cont",
12721117,
}
tags["delimitative"] = {
"tense-aspect",
"w:delimitative aspect",
"delim",
5316270,
}
tags["durative"] = {
"tense-aspect",
WP,
"dur",
}
tags["futuritive"] = {
"tense-aspect",
WP,
{"futv", "futrv"},
}
tags["frequentative"] = {
"tense-aspect",
WP,
{"freq", "frequentive"},
467562,
}
tags["habitual"] = {
"tense-aspect",
"w:habitual aspect",
"hab",
5636904,
}
-- same as the habitual; used in Mongolian linguistics
tags["habitive"] = {
"tense-aspect",
WP,
"habv",
}
-- same as the habitual; used in Celtic linguistics
tags["consuetudinal"] = {
"tense-aspect",
WIKT,
"consu",
}
tags["immediative"] = {
"tense-aspect",
WIKT,
{"imm", "immed"},
}
tags["incidental"] = {
"tense-aspect",
WIKT,
"incid",
}
tags["iterative"] = {
"tense-aspect",
"w:iterative aspect",
"iter",
2866772,
}
tags["momentane"] = {
"tense-aspect",
WP,
nil,
6897160,
}
tags["momentaneous"] = {
"tense-aspect",
WIKT,
"mom",
115110791,
}
tags["posterior"] = {
"tense-aspect",
"w:relative and absolute tense",
"post",
}
tags["preconditional"] = {
"tense-aspect",
WIKT,
"precond",
}
-- Type of participle in Hindi; also called agentive or agentive-prospective
tags["prospective"] = {
"tense-aspect",
"w:prospective aspect",
"pros",
}
tags["purposive"] = {
"tense-aspect",
WIKT,
"purp",
}
-- Aspect in Tagalog; presumably similar to the perfect tense/aspect but not necessarily similar enough to use the same
-- Wikidata ID
tags["recently complete"] = {
"tense-aspect",
"w:Tagalog grammar#Aspect",
"rcompl",
}
tags["resultative"] = {
"tense-aspect",
WP,
{"res", "resultive"},
7316356,
}
tags["semelfactive"] = {
"tense-aspect",
WP,
"semf",
7449203,
}
tags["serial"] = {
"tense-aspect",
WIKT,
"ser",
}
tags["successive"] = {
"tense-aspect",
WIKT,
"succ",
}
-- be careful not to clash with terminative case tag
tags["terminative aspect"] = {
"tense-aspect",
"w:cessative aspect",
"term",
display = "terminative",
}
----------------------- Mood -----------------------
tags["benedictive"] = {
"mood",
WP,
"bened",
4887358,
}
tags["cohortative"] = {
"mood",
"w:cohortative mood",
{"coho", "cohort"},
}
tags["concessive"] = {
"mood",
WIKT,
"conc",
}
tags["contrafactual"] = {
"mood",
WIKT,
"cfact",
110323459,
}
-- Same as the contrafactual, but terminology depends on language.
tags["counterfactual"] = {
"mood",
WP,
"counterf",
1783264, -- for "counterfactual conditional"
}
tags["desiderative"] = {
"mood",
WP,
{"des", "desid"},
1200631,
}
tags["dubitative"] = {
"mood",
"w:dubitative mood",
"dub",
1263049,
}
tags["energetic"] = {
"mood",
"w:energetic mood",
"ener",
}
tags["inferential"] = {
"mood",
"w:inferential mood",
{"infer", "infr"},
-- Per [[w:inferential mood]], also called "renarrative mood" or (in Estonian) "oblique mood" (but
-- "renarrative mood" may be different, see its entry).
3332616,
}
-- It's not clear that this is exactly a mood, but I'm not sure where
-- else to group it
tags["intensive"] = {
"mood",
WP,
{"inten", "intens"}, -- FIXME: "inten" is too ambiguous (e.g. with "intentional")
10965321, -- for "intensive word form"
}
tags["intentional"] = {
"mood",
WIKT,
"intent",
}
tags["injunctive"] = {
"mood",
APPENDIX,
{"inj", "injunc"},
1431843,
}
tags["interrogative"] = {
"mood",
WP,
{"interr", "interrog"},
12021746,
}
tags["necessitative"] = {
"mood",
WIKT,
{"nec", "necessitive"},
}
tags["permissive"] = {
"mood",
"w:permissive mood",
"perm",
4351483,
}
tags["potential"] = {
"mood",
"w:potential mood",
"potn",
2296856,
}
tags["precative"] = {
"mood",
WIKT,
"prec",
}
tags["prescriptive"] = {
"mood",
WIKT,
"prescr",
}
tags["presumptive"] = {
"mood",
"w:presumptive mood",
"presump",
25463575,
}
-- Exists at least in Estonian
tags["quotative"] = {
"mood",
"w:quotative evidential mood",
"quot",
-- 7272884, -- this is for "quotative" morphemes, not the same
}
tags["renarrative"] = {
"mood",
"w:renarrative mood",
"renarr",
-- Per [[w:inferential mood]], renarrative and inferential mood are the same; but per
-- [[w:Bulgarian verbs#Evidentials]], they are different, and Bulgarian has both.
3332616,
}
tags["volitive"] = {
"mood",
"w:volitive mood",
"voli",
10716592,
}
tags["voluntative"] = {
"mood",
WIKT,
{"voln", "volun"},
}
----------------------- Voice/valence -----------------------
tags["antipassive"] = {
"voice-valence",
"w:antipassive voice",
{"apass", "apasv", "apsv"},
287232,
}
tags["applicative"] = {
"voice-valence",
"w:applicative voice",
"appl",
621634,
}
tags["cooperative"] = { -- ("all together") used in Mongolian
"voice-valence",
"wikt:cooperative voice",
"coop",
114033228,
}
tags["pluritative"] = { -- ("many together") used in Mongolian
"voice-valence",
"wikt:pluritative voice",
"plur",
114033289,
}
tags["reciprocal"] = {
"voice-valence",
"w:reciprocal (grammar)",
{"recp", "recip"},
1964083,
}
-- Specific to Modern Irish, similar to impersonal
tags["autonomous"] = {
"voice-valence",
WIKT,
"auton",
}
----------------------- Non-finite -----------------------
-- be careful not to clash with agentive case tag
tags["agentive"] = {
"non-finite",
"w:agent noun",
{"ag", "agent"},
}
-- Latin etc.
tags["gerundive"] = {
"non-finite",
WP,
"gerv",
731298, -- Wikidata claims this is a grammatical mood, which is not really correct
}
-- Old Irish etc.
tags["verbal of necessity"] = {
"non-finite",
"w:gerundive",
"verbnec",
731298, -- gerundive
}
tags["l-participle"] = {
"non-finite",
"participle",
{"l-ptcp", "lptcp"},
814722, -- "participle"
}
-- Finnish agent participle
tags["agent participle"] = {
"non-finite",
"w:Finnish grammar#Agent participle",
"agentpart",
}
-- Hungarian participle
tags["verbal participle"] = {
"non-finite",
WIKT,
nil,
2361676, -- attributive verb, aka verbal participle
}
tags["converb"] = {
"non-finite",
WP,
"conv",
149761,
}
tags["connegative"] = {
"non-finite",
APPENDIX,
{"conn", "conneg"},
5161718,
}
-- Occurs in Hindi as a type of participle used to conjoin two clauses; similarly occurs in Japanese as the "te-form"
tags["conjunctive"] = {
"non-finite",
"w:serial verb construction", -- FIXME! No good link for "conjunctive"; another possibility is "converb"
"conj",
}
tags["absolutive verb form"] = {
"non-finite",
"wikt:absolutive#Noun",
"absvf",
display = "absolutive",
}
-- FIXME! Should this be a mood?
tags["debitive"] = {
"non-finite",
WP,
"deb",
17119041,
}
----------------------- Case -----------------------
tags["abessive"] = {
"case",
"w:abessive case",
"abe",
319822,
}
tags["absolutive"] = {
"case",
"w:absolutive case",
"absv", -- FIXME, find uses of "abs" = absolutive
332734,
}
tags["adessive"] = {
"case",
"w:adessive case",
"ade",
281954,
}
-- be careful not to clash with adverbial grammar tag
tags["adverbial case"] = {
"case",
WP,
"advc",
display = "adverbial",
}
-- be careful not to clash with agentive non-finite tag
tags["agentive case"] = {
"case",
WP,
"agc",
display = "agentive",
}
tags["allative"] = {
"case",
"wikt:allative case",
"all",
655020,
}
--No evidence of the existence of this case on the web, and the shortcuts are better used elsewhere.
--tags["anterior"] = {
-- "case",
-- nil,
-- {"ant"},
--}
tags["associative"] = {
"case",
"w:associative case",
{"ass", "assoc"},
15948746,
}
tags["benefactive"] = {
"case",
"w:benefactive case",
{"ben", "bene"},
664905,
}
tags["causal"] = {
"case",
"w:causal case",
{"cauc", "causc"},
2943136,
}
tags["causal-final"] = {
"case",
"w:causal-final case",
{"cfi", "cfin"},
18012653,
}
tags["comitative"] = {
"case",
"w:comitative case",
"com",
838581,
}
-- be careful not to clash with comparative degree
tags["comparative case"] = {
"case",
WP,
"comc",
5155633,
display = "comparative",
}
tags["delative"] = {
"case",
"w:delative case",
"del",
1183901,
}
tags["direct"] = {
"case",
"w:direct case",
"dir",
1751855,
}
tags["directive"] = {
"case",
"wikt:directive case",
"dirc",
56526905,
}
tags["distributive"] = {
"case",
"w:distributive case",
{"dis", "dist", "distr"},
492457,
}
tags["elative"] = {
"case",
"elative case",
"ela",
394253,
}
tags["ergative"] = {
"case",
"ergative case",
"erg",
324305,
}
-- be careful not to clash with equative degree tag
tags["equative"] = {
"case",
"w:equative case",
"equc",
3177653,
}
tags["essive-formal"] = {
"case",
"w:essive-formal case",
{"esf", "efor"},
3827688,
}
tags["essive-modal"] = {
"case",
"w:essive-modal case",
{"esm", "emod"},
3827703,
}
tags["essive"] = {
"case",
"w:essive case",
"ess",
148465,
}
--No evidence of the existence of this case on the web, and the shortcuts are better used elsewhere.
--tags["exclusive"] = {
-- "case",
-- nil,
-- {"exc", "excl"},
--}
tags["illative"] = {
"case",
"w:illative case",
"ill",
474668,
}
tags["indirect"] = {
"case",
"w:direct case",
"indir",
1233197, -- Same as oblique.
}
tags["inessive"] = {
"case",
"w:inessive case",
"ine",
282031,
}
tags["instructive"] = {
"case",
"w:instructive case",
"ist",
1665275,
}
tags["lative"] = {
"case",
"w:lative case",
"lat",
260425,
}
tags["limitative"] = {
"case",
"w:list of grammatical cases",
{"lim", "limitive"},
35870079,
}
tags["locative-qualitative"] = {
"case",
"locative-qualitative case",
{"lqu", "lqua", "locative-qualitive"},
}
tags["objective"] = {
"case",
"objective case",
"objv", -- obj used for "object"
1233197, -- Same as oblique.
}
tags["oblique"] = {
"case",
"oblique case",
"obl",
1233197,
}
tags["partitive"] = {
"case",
"w:partitive case",
{"ptv", "par"},
857325,
}
--certain languages use this term for the abessive
tags["privative"] = {
"case",
"w:privative case",
"priv",
319822,
}
tags["prolative"] = {
"case",
"w:prolative case",
{"pro", "prol"},
952933,
}
tags["semblative"] = {
"case",
"w:semblative case",
"smbl",
7449178, -- Same as similative.
}
tags["similative"] = {
"case",
"w:similative case",
"simv",
7449178, -- Same as semblative.
}
tags["sociative"] = {
"case",
"w:sociative case",
"soc",
3773161,
}
tags["subjective"] = {
"case",
"w:subjective case",
{"subjv", "sbjv"}, -- "sub" and "subj" used for subjunctive, "sbj" for "subject"
131105, -- Same as nominative.
}
tags["sublative"] = {
"case",
"w:sublative case",
{"sbl", "subl"},
2120615,
}
tags["superessive"] = {
"case",
"w:superessive case",
{"spe", "supe"},
222355,
}
tags["temporal"] = {
"case",
"w:temporal case",
{"tem", "temp"},
3235219,
}
-- be careful not to clash with terminative aspect tag
tags["terminative case"] = {
"case",
"w:terminative case",
"ter",
747019,
display = "terminative",
}
tags["translative"] = {
"case",
"w:translative case",
{"tra", "tran"},
950170,
}
----------------------- State -----------------------
tags["independent genitive"] = {
"state",
WIKT,
"indgen",
}
tags["possessor"] = {
"state",
WIKT,
{"posr", "possr"},
}
tags["reflexive possessive"] = {
"state",
WIKT,
{"reflposs", "refl poss"},
}
tags["substantive"] = {
"state",
APPENDIX,
{"subs", "subst"},
}
tags["free state"] = {
"state",
APPENDIX,
{"free"},
}
tags["annexed state"] = {
"state",
APPENDIX,
{"annex", "annexed"},
}
----------------------- Degrees of comparison -----------------------
tags["absolute superlative degree"] = {
"comparison",
"wikt:absolute superlative",
{"asupd", "absolute superlative"},
}
tags["relative superlative degree"] = {
"comparison",
"wikt:relative superlative",
{"rsupd", "relative superlative"},
}
tags["elative degree"] = {
"comparison",
"elative",
"elad", -- Can't use "elative" as shortcut because that's already used for the elative case
1555419,
}
-- be careful not to clash with equative case tag
tags["equative degree"] = {
"comparison",
"w:equative",
"equd",
5384239,
}
tags["excessive degree"] = {
"comparison",
nil,
"excd",
}
----------------------- Register -----------------------
tags["familiar"] = {
"register",
"w:T–V distinction",
"fam",
}
tags["polite"] = {
"register",
"w:T–V distinction",
"pol",
}
tags["intimate"] = {
"register",
-- "intimate" is also a possible formality level in the sociolinguistic register sense.
"w:T–V distinction",
"intim",
}
tags["formal"] = {
"register",
"w:register (sociolinguistics)",
}
tags["informal"] = {
"register",
"w:register (sociolinguistics)",
"inform",
}
tags["colloquial"] = {
"register",
"w:colloquialism",
"colloq",
}
tags["slang"] = {
"register",
WP,
}
tags["contemporary"] = {
"register",
WIKT,
"conty",
}
tags["literary"] = {
"register",
"w:literary language",
"lit",
}
tags["dated"] = {
"register",
WIKT,
}
tags["archaic"] = {
"register",
"w:archaism",
"arch",
}
tags["obsolete"] = {
"register",
WIKT,
"obs",
}
tags["emphatic"] = {
"register",
WIKT,
"emph",
}
----------------------- Deixis -----------------------
tags["proximal"] = {
"deixis",
"w:deixis",
{"prox", "prxl"},
}
tags["medial"] = {
"deixis",
"w:deixis",
"medl",
}
tags["distal"] = {
"deixis",
"w:deixis",
"dstl",
}
----------------------- Clusivity -----------------------
tags["inclusive"] = {
"clusivity",
"w:clusivity",
"incl",
}
tags["exclusive"] = {
"clusivity",
"w:clusivity",
"excl",
}
tags["obviative"] = {
"clusivity",
"w:clusivity",
"obv",
}
----------------------- Inflectional class -----------------------
tags["absolute"] = {
"grammar",
WIKT,
"abs",
}
tags["conjunct"] = {
"grammar",
WP,
"conjt",
}
tags["deuterotonic"] = {
"grammar",
"w:dependent and independent verb forms",
"deut",
}
tags["prototonic"] = {
"grammar",
"w:dependent and independent verb forms",
"prot",
}
----------------------- Attitude -----------------------
tags["endearing"] = {
"attitude",
-- FIXME! No good glossary entry for this; the entry for "hypocoristic" refers specifically to proper names.
"w:hypocoristic",
"end",
1130279, -- entry for "hypocorism"
}
tags["moderative"] = {
"attitude",
WIKT,
"moder",
}
----------------------- Sound changes -----------------------
tags["alliterative"] = {
"sound change",
"w:alliteration",
nil,
484495,
}
tags["back"] = {
"sound change",
"w:back vowel",
nil,
853589,
}
tags["front"] = {
"sound change",
"w:front vowel",
nil,
5505949,
}
tags["rounded"] = {
"sound change",
"w:roundedness",
"round",
}
tags["sigmatic"] = {
"sound change",
WIKT,
"sigm",
}
tags["unrounded"] = {
"sound change",
"w:roundedness",
"unround",
}
tags["vowel harmonic"] = {
"sound change",
"w:vowel harmony",
"vharm",
147137,
}
----------------------- Misc grammar -----------------------
tags["relative"] = {
"grammar",
WIKT,
"rel",
}
tags["direct relative"] = {
"grammar",
"w:relative_clause#Celtic_languages",
"dirrel",
}
tags["indirect relative"] = {
"grammar",
"w:relative_clause#Celtic_languages",
"indrel",
}
tags["synthetic"] = {
"grammar",
WIKT,
"synth",
}
tags["analytic"] = {
"grammar",
WIKT,
{"anal", "analytical"},
}
tags["periphrastic"] = {
"grammar",
WIKT,
"peri",
}
tags["affirmative"] = {
"grammar",
"w:affirmation and negation",
"aff",
}
tags["possessed"] = {
"grammar",
"w:possessive affix",
{"possd", "possed"}, -- posd = positive degree
804020, -- for possessive affix
}
tags["non-possessed"] = {
"grammar",
"w:possessive affix",
{"npossd", "npossed", "nonpossessed"},
}
tags["complement"] = {
"grammar",
"w:complement (linguistics)",
"comp", -- formerly used for comparative, which has been split into comparative case (comc) and comparative degree (comd)
1051175,
}
tags["possessive affix"] = {
"grammar",
WP,
{"posaf", "possaf"},
804020,
}
tags["possessive suffix"] = {
"grammar",
"w:possessive affix",
"possuf",
804020,
}
tags["possessive prefix"] = {
"grammar",
"w:possessive affix",
{"pospref", "posspref"},
804020,
}
tags["prefix"] = {
"grammar",
APPENDIX,
"pref", -- pre = prepositional
134830,
}
tags["prefixal"] = {
"grammar",
WIKT,
"prefl", -- pre = prepositional
134830,
}
tags["suffix"] = {
"grammar",
APPENDIX,
{"suf", "suff"},
102047,
}
tags["suffixal"] = {
"grammar",
WIKT,
{"sufl", "suffl"},
102047,
}
tags["affix"] = {
"grammar",
WP,
"af", -- aff = affirmative
62155,
}
tags["affixal"] = {
"grammar",
WIKT,
"afl", -- aff = affirmative
62155,
}
tags["circumfix"] = {
"grammar",
WP,
{"circ", "cirf", "circf"},
124939,
}
tags["circumfixal"] = {
"grammar",
WIKT,
{"circl", "cirfl", "circfl"},
124939,
}
tags["infix"] = {
"grammar",
WP,
"infx",
201322,
}
tags["infixal"] = {
"grammar",
WIKT,
"infxl",
201322,
}
tags["nonfinite"] = {
"grammar",
APPENDIX,
"nonfin",
1050494, -- entry for "non-finite verb"
}
tags["tenseless"] = {
"grammar",
WIKT,
}
tags["aspect"] = {
"grammar",
APPENDIX,
"asp",
208084,
}
----------------------- Other tags -----------------------
tags["–"] = { -- Unicode en-dash
"other",
no_space_on_left = true,
no_space_on_right = true,
}
tags["—"] = { -- Unicode em-dash
"other",
no_space_on_left = true,
no_space_on_right = true,
}
----------------------- Create the shortcuts list -----------------------
m_form_of_data.finalize(tags, shortcuts)
return {tags = tags, shortcuts = shortcuts}
0idosx8jed79blmq3txx7nv19rjoe2a
Module:form of/functions
828
8201
55138
2026-10-02T19:41:18Z
Deadend0914
7211
Gesceop tramet þe hafaþ '--[=[ DISPLAY_HANDLERS is a list of one or more functions that provide special handling for multipart tags. Each function takes formerly a single argument (the multipart tag), now temporarily two arguments (the multipart tag and the join strategy, which can be nil to use the default), and should either return the formatted display text or nil to check the next handler. If no handlers apply, there is a default handler that appropriately formats most multipart tags...'
55138
Scribunto
text/plain
--[=[
DISPLAY_HANDLERS is a list of one or more functions that provide special handling for multipart tags. Each function
takes formerly a single argument (the multipart tag), now temporarily two arguments (the multipart tag and the join
strategy, which can be nil to use the default), and should either return the formatted display text or nil to check the
next handler. If no handlers apply, there is a default handler that appropriately formats most multipart tags.
CAT_FUNCTIONS is a map from function names to functions of a single argument, as described in [[Module:form of/cats]].
There are two types of functions: condition handlers (which return true or false) and spec handlers (which return a
specification, as described in [[Module:form of/cats]]). We need to put the functions here rather than in
[[Module:form of/cats]] because that module is loaded using mw.loadData(), which can't directly handle functions.
]=]
local export = {}
function export.multipart_join_strategy()
-- Recognized values:
-- "and": Join with "and", using commas for 3 or more items
-- "en-dash": Join with – (en-dash)
-- "slash": Join with / (slash)
return "slash"
end
local function wrap_in_inflection_of_sep(text)
return '<span class="inflection-of-sep">' .. text .. '</span>'
end
-- This is a local version of serialCommaJoin from [[Module:table]] that
-- implements it a bit differently.
local function join_multiparts_with_serial_comma(seq)
local length = #seq
if length == 0 then
return ""
elseif length == 1 then
return seq[1] -- nothing to join
elseif length == 2 then
return seq[1] .. wrap_in_inflection_of_sep(" and ") .. seq[2]
else
local comma = '<span class="serial-comma">,</span>'
local conj = '<span class="serial-and"> and </span>'
return table.concat(seq, wrap_in_inflection_of_sep(", "), 1, length - 1) ..
wrap_in_inflection_of_sep(comma .. conj) .. seq[length]
end
end
function export.join_multiparts(parts, joiner)
-- Display the elements of a multipart tag. Currently we use "and",
-- with commas when then are three or more elements, of the form
-- "foo, bar, baz and bat"; but we are seriously considering switching
-- to en-dash, e.g. "foo–bar–baz–bat". Arguably,
-- dative–ablative masculine–feminine–neuter plural
-- looks better then
-- dative and ablative masculine, feminine and neuter plural
-- and
-- first–second–third-person singular present subjunctive
-- looks better than
-- first-, second- and third-person singular present subjunctive
local strategy = joiner or export.multipart_join_strategy()
local retval
if strategy == "and" then
retval = join_multiparts_with_serial_comma(parts)
elseif strategy == "en-dash" then
retval = table.concat(parts, wrap_in_inflection_of_sep("–"))
elseif strategy == "slash" then
retval = table.concat(parts, wrap_in_inflection_of_sep("/"))
else
error("Unrecognized multipart join strategy: " .. strategy)
end
return '<span class="inflection-of-conjoined">' .. retval .. '</span>'
end
export.cat_functions = {}
export.display_handlers = {}
-- Display handler to clean up display of multiple persons by omitting
-- redundant "person" in all but the last element. For example, the tag
-- "123" maps to "1//2//3", which in turn gets displayed as (approximately)
-- "first-, second- and third-person" (with appropriate glossary links, and
-- appropriate spans marking the serial comma).
table.insert(export.display_handlers,
function(tags, joiner)
local els = {}
local numtags = #tags
local strategy = joiner or export.multipart_join_strategy()
for i, tag in ipairs(tags) do
local suffix = i == numtags and "-person]]" or
strategy == "and" and "-]]" or "]]"
if tag == "first-person" then
table.insert(els, "[[Appendix:Glossary#first person|first" .. suffix)
elseif tag == "second-person" then
table.insert(els, "[[Appendix:Glossary#second person|second" .. suffix)
elseif tag == "third-person" then
table.insert(els, "[[Appendix:Glossary#third person|third" .. suffix)
else
return nil
end
end
return export.join_multiparts(els, joiner)
end
)
return export
2vjpws88qwen88nsixuztqzubyuzhu3
Module:form of/lang-data/en
828
8202
55139
2026-10-02T19:42:39Z
Deadend0914
7211
Gesceop tramet þe hafaþ '--[=[ This module contains lang-specific tags for English. ]=] local m_form_of_data = require("Module:form of/data") local APPENDIX = m_form_of_data.APPENDIX local WP = m_form_of_data.WP local WIKT = m_form_of_data.WIKT local tags = {} local shortcuts = {} shortcuts["ed-form"] = {"spast", "and", "past", "part"} shortcuts["ing-form"] = {"pres", "part", "and", "ger"} shortcuts["s-verb-form"] = {"3", "s", "spres", "ind"} shortcuts["st-form"] = {"2-st", "s", "spr...'
55139
Scribunto
text/plain
--[=[
This module contains lang-specific tags for English.
]=]
local m_form_of_data = require("Module:form of/data")
local APPENDIX = m_form_of_data.APPENDIX
local WP = m_form_of_data.WP
local WIKT = m_form_of_data.WIKT
local tags = {}
local shortcuts = {}
shortcuts["ed-form"] = {"spast", "and", "past", "part"}
shortcuts["ing-form"] = {"pres", "part", "and", "ger"}
shortcuts["s-verb-form"] = {"3", "s", "spres", "ind"}
shortcuts["st-form"] = {"2-st", "s", "spres", "ind"}
shortcuts["st-past-form"] = {"2-st", "s", "spast", "ind"}
shortcuts["th-form"] = {"3-th", "s", "spres", "ind"}
----------------------- Person -----------------------
-- These tags exist so we can add appropriate 'archaic FOO' labels in [[Module:form of/cats]].
tags["second-person (-st)"] = {
"person",
nil,
"2-st",
display = "[[Appendix:Glossary#second person|second-person]]",
}
tags["third-person (-th)"] = {
"person",
nil,
"3-th",
display = "[[Appendix:Glossary#third person|third-person]]",
}
----------------------- Create the shortcuts list -----------------------
m_form_of_data.finalize(tags, shortcuts)
return {tags = tags, shortcuts = shortcuts}
npdxdtkb0i13egap2p5f7qo9t4ws27o
Bysen:inflection of
10
8203
55141
2026-10-02T19:46:59Z
Deadend0914
7211
Gesceop tramet þe hafaþ '{{ {{#if:{{{lang|}}}|check deprecated lang param usage|no deprecated lang param usage}}|lang={{{lang|}}}|<!-- -->{{#invoke:form of/templates|inflection_of_t}}<!-- -->}}<!-- --><noinclude>{{documentation}}</noinclude>'
55141
wikitext
text/x-wiki
{{ {{#if:{{{lang|}}}|check deprecated lang param usage|no deprecated lang param usage}}|lang={{{lang|}}}|<!--
-->{{#invoke:form of/templates|inflection_of_t}}<!--
-->}}<!--
--><noinclude>{{documentation}}</noinclude>
pbx4m25a7bhwoqyt9gtape8lta7t6ez
sadels
0
8204
55143
2026-10-02T20:07:38Z
Deadend0914
7211
Gesceop tramet þe hafaþ '=={{sprǣc|enm}}== ===Wordstǣr=== Of {{inh|en|ang|sadol}}, of {{inh|en|gmw-pro|*sadul}}, of {{inh|en|gem-pro|*sadulaz|t=sadol}} ===Nama=== {{head|enm|noun form}} # {{plural of|enm|sadel}}'
55143
wikitext
text/x-wiki
=={{sprǣc|enm}}==
===Wordstǣr===
Of {{inh|en|ang|sadol}}, of {{inh|en|gmw-pro|*sadul}}, of {{inh|en|gem-pro|*sadulaz|t=sadol}}
===Nama===
{{head|enm|noun form}}
# {{plural of|enm|sadel}}
64ynezv5xbafg72rtxmyqfg4a3johyl
sadol
0
8205
55146
2026-10-02T20:31:05Z
Deadend0914
7211
Gesceop tramet þe hafaþ '=={{sprǣc|ang}}== ===Rihtstefn=== * IPA: /ˈsɑ.dol/ ===Wordstǣr=== {{inh+|ang|gmw-pro|*sadul}}, of {{inh|ang|gem-pro|*sadulaz}}. ===Werlic Nama=== {{ang-noun|m}} # þæt [[set]] on [[hors|horsa]] bacu, þǣr wē [[hyrsian|hyrsiaþ]]; oft [[leþer]] macod and getīegeþ on þæt horsa.'
55146
wikitext
text/x-wiki
=={{sprǣc|ang}}==
===Rihtstefn===
* IPA: /ˈsɑ.dol/
===Wordstǣr===
{{inh+|ang|gmw-pro|*sadul}}, of {{inh|ang|gem-pro|*sadulaz}}.
===Werlic Nama===
{{ang-noun|m}}
# þæt [[set]] on [[hors|horsa]] bacu, þǣr wē [[hyrsian|hyrsiaþ]]; oft [[leþer]] macod and getīegeþ on þæt horsa.
qqdlz8scjduj7yxrrntkbb1m6rza04j
55151
55146
2026-10-02T20:51:40Z
Deadend0914
7211
/* Werlic Nama */
55151
wikitext
text/x-wiki
=={{sprǣc|ang}}==
===Rihtstefn===
* IPA: /ˈsɑ.dol/
===Wordstǣr===
{{inh+|ang|gmw-pro|*sadul}}, of {{inh|ang|gem-pro|*sadulaz}}.
===Werlic Nama===
{{ang-noun|m}}
# þæt [[set]] on [[hors|horsa]] bacu, þǣr wē [[hyrsian|hyrsiaþ]]; oft [[leþer]] macod and getīegeþ on þæt horsa.
====Declīnung====
{{ang-decl-noun-a-m|sadol}}
====Wendunga====
* Nīwenglisc: [[saddle]]
kqvnnm8hkf1q7ovl8vy2hwzpibs0aq1
hors
0
8206
55148
2026-10-02T20:48:05Z
Deadend0914
7211
Gesceop tramet þe hafaþ '=={{sprǣc|ang}}== ===Rihstefn=== * IPA: /xors/ ===Wordstǣr=== Of {{inh|ang|gmw-pro|*hross}}, of {{inh|ang|gem-pro|*hrussą|t=hors}}, of {{der|ang|ine-pro|*ḱers-|t=rinnan}}. ===Nāhwæðer Nama=== {{ang-noun|n|head=hors}} # ''Equus ferus caballus''; þā dēor menn rītt, mid [[sadol|sadolas]] oþþe on heora bæc. Eallswā notaþ for weorc. Hīe habbaþ [[hōfas]]. Gehwā cnāwaþ hors.'
55148
wikitext
text/x-wiki
=={{sprǣc|ang}}==
===Rihstefn===
* IPA: /xors/
===Wordstǣr===
Of {{inh|ang|gmw-pro|*hross}}, of {{inh|ang|gem-pro|*hrussą|t=hors}}, of {{der|ang|ine-pro|*ḱers-|t=rinnan}}.
===Nāhwæðer Nama===
{{ang-noun|n|head=hors}}
# ''Equus ferus caballus''; þā dēor menn rītt, mid [[sadol|sadolas]] oþþe on heora bæc. Eallswā notaþ for weorc. Hīe habbaþ [[hōfas]]. Gehwā cnāwaþ hors.
57jf3nqvfx6le6emkvgzyp2cmx2opbe
55150
55148
2026-10-02T20:50:13Z
Deadend0914
7211
/* Nāhwæðer Nama */
55150
wikitext
text/x-wiki
=={{sprǣc|ang}}==
===Rihstefn===
* IPA: /xors/
===Wordstǣr===
Of {{inh|ang|gmw-pro|*hross}}, of {{inh|ang|gem-pro|*hrussą|t=hors}}, of {{der|ang|ine-pro|*ḱers-|t=rinnan}}.
===Nāhwæðer Nama===
{{ang-noun|n|head=hors}}
# ''Equus ferus caballus''; þā dēor menn rītt, mid [[sadol|sadolas]] oþþe on heora bæc. Eallswā notaþ for weorc. Hīe habbaþ [[hōfas]]. Gehwā cnāwaþ hors.
====Declīnung====
{{ang-decl-noun-a-n|hors}}
====Wendunga====
* Nīwenglisc: [[horse]]
enh1red30b33lu5pyk7d5pn3hfc1fic
55152
55150
2026-10-02T20:55:20Z
Deadend0914
7211
/* Nāhwæðer Nama */
55152
wikitext
text/x-wiki
=={{sprǣc|ang}}==
===Rihstefn===
* IPA: /xors/
===Wordstǣr===
Of {{inh|ang|gmw-pro|*hross}}, of {{inh|ang|gem-pro|*hrussą|t=hors}}, of {{der|ang|ine-pro|*ḱers-|t=rinnan}}.
===Nāhwæðer Nama===
{{ang-noun|n|head=hors}}
# ''Equus ferus caballus''; þā [[dēor]] menn rītt, mid [[sadol|sadolas]] oþþe on heora bæc. Eallswā notaþ for weorc. Hīe habbaþ [[hōfas]]. Gehwā cnāwaþ hors.
====Declīnung====
{{ang-decl-noun-a-n|hors}}
====Wendunga====
* Nīwenglisc: [[horse]]
2s861jxdp82dfczjphlcnqo56p4l6hz
55153
55152
2026-10-02T20:55:48Z
Deadend0914
7211
55153
wikitext
text/x-wiki
=={{sprǣc|ang}}==
===Rihstefn===
* IPA: /xors/
===Wordstǣr===
Of {{inh|ang|gmw-pro|*hross}}, of {{inh|ang|gem-pro|*hrussą|t=hors}}, of {{der|ang|ine-pro|*ḱers-|t=rinnan}}.
===Nāhwæðer Nama===
{{ang-noun|n|head=hors}}
# ''Equus ferus caballus''; þā [[dēor]] menn rītt, mid [[sadol|sadolas]] oþþe on heora bæc. Eallswā notaþ for weorc. Hīe habbaþ [[hōfas]]. Gehwā cnāwaþ hors.
====Declīnung====
{{ang-decl-noun-a-n|hors}}
====Wendunga====
* Nīwenglisc: [[horse]]
[[Flocc: Englisc dēor]]
53fq1zawg46npd1ltqo80uu87r8rip7
þæs
0
8207
55154
2026-10-02T21:10:28Z
Deadend0914
7211
Gesceop tramet þe hafaþ '=={{sprǣc|ang}}== ===Rihtstefn=== * IPA: θæs ===Ēowigendlic=== {{head|ang|article form}} # {{inflection of|ang|se||gen|m//n|s}} ===Tudru=== * {{desc|enm|þæs|þas}}'
55154
wikitext
text/x-wiki
=={{sprǣc|ang}}==
===Rihtstefn===
* IPA: θæs
===Ēowigendlic===
{{head|ang|article form}}
# {{inflection of|ang|se||gen|m//n|s}}
===Tudru===
* {{desc|enm|þæs|þas}}
4mm2qifzj7q5onnei279fn0zewrpsf7
55155
55154
2026-10-02T21:12:07Z
Deadend0914
7211
/* {{sprǣc|ang}} */
55155
wikitext
text/x-wiki
=={{sprǣc|ang}}==
===Āwendednessa===
* ðæs
===Rihtstefn===
* IPA: /θæs/
===Ēowigendlic===
{{head|ang|article form}}
# {{inflection of|ang|se||gen|m//n|s}}
===Tudru===
* {{desc|enm|þæs|þas}}
2gkufpytrp5jj34n0x79sfowevdignu
55157
55155
2026-10-02T21:16:10Z
Deadend0914
7211
/* Ēowigendlic */
55157
wikitext
text/x-wiki
=={{sprǣc|ang}}==
===Āwendednessa===
* ðæs
===Rihtstefn===
* IPA: /θæs/
===Ēowigendlic===
{{head|ang|article form}}
# {{inflection of|ang|se||gen|m//n|s}}
===Tudru===
* {{desc|enm|þæs|þas}}
6n6qcw1i91k5a6xzt5yymdzbkzfnsjc
binama
0
8208
55159
2026-10-02T21:23:05Z
Deadend0914
7211
Redirected page to [[bīnama]]
55159
wikitext
text/x-wiki
#redirect [[bīnama]]
p0w7smsvr7c5rglbkak9jxt57d61mep
bīnama
0
8209
55160
2026-10-02T21:31:41Z
Deadend0914
7211
Gesceop tramet þe hafaþ '=={{sprǣc|ang}}== ===Rihtstefn=== * IPA: /ˈbiːˌnɑ.mɑ/ ===Wordstǣr=== Of {{prefix|ang|bi|nama}}. ===Werlic Nama=== # (''stæfcræft'') sē [[dæl]] þe nemneþ, þe gearwe ǣrra namode ====Declīnung==== {{ang-decl-noun-n-m|bīnam}} ====Wendunga==== * Nīwenglisc: [[pronoun]]'
55160
wikitext
text/x-wiki
=={{sprǣc|ang}}==
===Rihtstefn===
* IPA: /ˈbiːˌnɑ.mɑ/
===Wordstǣr===
Of {{prefix|ang|bi|nama}}.
===Werlic Nama===
# (''stæfcræft'') sē [[dæl]] þe nemneþ, þe gearwe ǣrra namode
====Declīnung====
{{ang-decl-noun-n-m|bīnam}}
====Wendunga====
* Nīwenglisc: [[pronoun]]
63m6esjha0txzh0bjgxp7vjb5qm8vgc
Bysen:ang-decl-noun-n-m
10
8210
55161
2026-10-02T21:32:24Z
Deadend0914
7211
Gesceop tramet þe hafaþ '{{#invoke:checkparams|error}}<!-- Validate template parameters -->{{ang-decl-noun<!-- -->|type=unstrang<!-- -->|1={{{1}}}{{#if:{{{vowel|}}}||a}}<!-- -->|3={{{1}}}{{#if:{{{vowel|}}}||a}}n<!-- -->|5={{{1}}}{{#if:{{{vowel|}}}||a}}n<!-- -->|7={{{1}}}{{#if:{{{vowel|}}}||a}}n<!-- -->|2={{{2|{{{1}}}}}}{{#if:{{{vowel|}}}||a}}n<!-- -->|4={{{2|{{{1}}}}}}{{#if:{{{vowel|}}}||a}}n<!-- -->|6={{{2|{{{1}}}}}}{{#if:{{{vowel|}}}||e}}na<!-- -->|8={{{2|{{{1}}}}}}{{#if:{{{vowel|}}}...'
55161
wikitext
text/x-wiki
{{#invoke:checkparams|error}}<!-- Validate template parameters
-->{{ang-decl-noun<!--
-->|type=unstrang<!--
-->|1={{{1}}}{{#if:{{{vowel|}}}||a}}<!--
-->|3={{{1}}}{{#if:{{{vowel|}}}||a}}n<!--
-->|5={{{1}}}{{#if:{{{vowel|}}}||a}}n<!--
-->|7={{{1}}}{{#if:{{{vowel|}}}||a}}n<!--
-->|2={{{2|{{{1}}}}}}{{#if:{{{vowel|}}}||a}}n<!--
-->|4={{{2|{{{1}}}}}}{{#if:{{{vowel|}}}||a}}n<!--
-->|6={{{2|{{{1}}}}}}{{#if:{{{vowel|}}}||e}}na<!--
-->|8={{{2|{{{1}}}}}}{{#if:{{{vowel|}}}||u}}m{{#if:{{{vowel|}}}|,{{{2|{{{1}}}}}}um}}<!--
-->|num={{{num|}}}<!--
-->|title={{{title|}}}<!--
-->}}<!--
-->{{cln|ang|masculine n-stem nouns}}<!--
--><noinclude>{{documentation}}</noinclude>
k4a0cgklis2hp45tvg9ab9owivfjw95
55162
55161
2026-10-02T21:32:50Z
Deadend0914
7211
55162
wikitext
text/x-wiki
{{#invoke:checkparams|error}}<!-- Validate template parameters
-->{{ang-decl-noun<!--
-->|type=unstrang<!--
-->|1={{{1}}}{{#if:{{{vowel|}}}||a}}<!--
-->|3={{{1}}}{{#if:{{{vowel|}}}||a}}n<!--
-->|5={{{1}}}{{#if:{{{vowel|}}}||a}}n<!--
-->|7={{{1}}}{{#if:{{{vowel|}}}||a}}n<!--
-->|2={{{2|{{{1}}}}}}{{#if:{{{vowel|}}}||a}}n<!--
-->|4={{{2|{{{1}}}}}}{{#if:{{{vowel|}}}||a}}n<!--
-->|6={{{2|{{{1}}}}}}{{#if:{{{vowel|}}}||e}}na<!--
-->|8={{{2|{{{1}}}}}}{{#if:{{{vowel|}}}||u}}m{{#if:{{{vowel|}}}|,{{{2|{{{1}}}}}}um}}<!--
-->|num={{{num|}}}<!--
-->|title={{{title|}}}<!--
-->}}<!--
-->{{cln|ang|werlic n-stefn naman}}<!--
--><noinclude>{{documentation}}</noinclude>
5u1ok0k6dvjzbdoc0nijfkrs7buumw2
Bysen:prefix
10
8211
55163
2026-10-02T21:33:24Z
Deadend0914
7211
Gesceop tramet þe hafaþ '{{#invoke:affix/templates|prefix}}<noinclude>{{documentation}}</noinclude>'
55163
wikitext
text/x-wiki
{{#invoke:affix/templates|prefix}}<noinclude>{{documentation}}</noinclude>
mmebbul72q1n89syvgj9nybin6h6y1m
Module:affix/templates
828
8212
55164
2026-10-02T21:33:50Z
Deadend0914
7211
Gesceop tramet þe hafaþ 'local export = {} local m_affix = require("Module:affix") local en_utilities_module = "Module:en-utilities" local parameter_utilities_module = "Module:parameter utilities" local pseudo_loan_module = "Module:affix/pseudo-loan" local insert = table.insert local boolean_param = {type = "boolean"} local function is_property_key(k) return require(parameter_utilities_module).item_key_is_property(k) end local recognized_affix_types = { prefix = "prefix", pre =...'
55164
Scribunto
text/plain
local export = {}
local m_affix = require("Module:affix")
local en_utilities_module = "Module:en-utilities"
local parameter_utilities_module = "Module:parameter utilities"
local pseudo_loan_module = "Module:affix/pseudo-loan"
local insert = table.insert
local boolean_param = {type = "boolean"}
local function is_property_key(k)
return require(parameter_utilities_module).item_key_is_property(k)
end
local recognized_affix_types = {
prefix = "prefix",
pre = "prefix",
suffix = "suffix",
suf = "suffix",
interfix = "interfix",
inter = "interfix",
infix = "infix",
["in"] = "infix",
circumfix = "circumfix",
circum = "circumfix",
["non-affix"] = "non-affix",
naf = "non-affix",
root = "non-affix",
}
local function pre_normalize_affix_type(data)
local modtext = data.modtext
modtext = modtext:match("^<(.*)>$")
if not modtext then
error(("Internal error: Passed-in modifier isn't surrounded by angle brackets: %s"):format(data.modtext))
end
if recognized_affix_types[modtext] then
modtext = "type:" .. modtext
end
return "<" .. modtext .. ">"
end
-- Parse raw arguments. A single parameter `data` is passed in, with the following fields:
-- * `raw_args`: The raw arguments to parse, normally taken from `frame:getParent().args`.
-- * `extra_params`: An optional function of one argument that is called on the `params` structure before parsing; its
-- purpose is to specify additional allowed parameters or possibly disable parameters.
-- * `has_source`: There is a source-language parameter following 1= (which becomes the "destination" language
-- parameter) and preceding the terms. This is currently used for {{pseudo-loan}}.
-- * `ilang`: If given, it is a language object that serves as the default for the language. If specified, there is no
-- language code specified in 1=; instead the term parameters start directly at 1= (or at 2= if `has_source` is
-- given).
-- * `require_index_for_pos`: There is no separate |pos= parameter distinct from |pos1=, |pos2=, etc. Instead,
-- specifying |pos= results in an error.
-- * `dont_require_index`: Allow |foo= to be specified as a synonym for |foo1= (except for |lit=, which remains
-- distinct).
-- * `allow_type`: Allow |type1=, |type2=, etc. or inline <type:...> for the affix type, and allow a separate |type=
-- parameter for the etymology type (FIXME: this may be confusing; consider changing the etymology type to |etype=).
-- * `allow_semicolon_separator`: Allow semicolon as a separator, displaying as " or ". This requires changes in the
-- display of the output, to not always put a + between the items.
--
-- Note that all language parameters are allowed to be etymology-only languages.
--
-- Return five values ARGS, ITEMS, LANG_OBJ, SCRIPT_OBJ, SOURCE_LANG_OBJ where ARGS is a table of the parsed arguments;
-- ITEMS is the list of parsed items; LANG_OBJ is the language object corresponding to the language code specified in 1=
-- (or taken from `ilang` if given); SCRIPT_OBJ is the script object corresponding to sc= (if given, otherwise nil); and
-- SOURCE_LANG_OBJ is the language object corresponding to the source-language code specified in 2= (or 1= if `ilang` is
-- given) if `has_source` is specified (otherwise nil).
local function parse_args(data)
local raw_args = data.raw_args
local has_source = data.has_source
local ilang = data.ilang
if raw_args.lang then
error("The |lang= parameter is not used by this template. Place the language code in parameter 1 instead.")
end
local term_index = (ilang and 1 or 2) + (has_source and 1 or 0)
local params = {
[term_index] = {list = true, allow_holes = true},
["sort"] = {},
["nocap"] = boolean_param, -- always allow this even if not used, for use with {{surf}}, which adds it
}
if not ilang then
params[1] = {required = true, type = "language", default = "und"}
end
local source_index
if has_source then
source_index = term_index - 1
params[source_index] = {required = true, type = "language", default = "und"}
end
local m_param_utils = require(parameter_utilities_module)
local param_mod_source = {}
if not data.dont_require_index then
insert(param_mod_source,
-- We want to require an index for all params (or use separate_no_index, which also requires an index for the
-- param corresponding to the first item).
{default = true, require_index = true}
)
end
insert(param_mod_source, {group = {"link", "ref", "lang", "q", "l", "infl"}})
-- Override lit= to be separate from lit1=.
insert(param_mod_source, {param = "lit", separate_no_index = true})
if not data.dont_require_index and not data.require_index_for_pos then
-- Override pos= to be separate from pos1=.
insert(param_mod_source, {param = "pos", separate_no_index = true})
end
if data.allow_type then
insert(param_mod_source, {param = "type", separate_no_index = true})
end
local param_mods = m_param_utils.construct_param_mods(param_mod_source)
if data.extra_params then
data.extra_params(params)
end
local items, args = m_param_utils.parse_list_with_inline_modifiers_and_separate_params {
params = params,
param_mods = param_mods,
raw_args = raw_args,
termarg = term_index,
parse_lang_prefix = true,
track_module = "homophones",
-- the inclusion of ‎ is what [[Module:affix]] has always done
default_separator = data.allow_semicolon_separator and " +‎ " or nil,
special_separators = data.allow_semicolon_separator and {[";"] = " or "} or nil,
disallow_custom_separators = not data.allow_semicolon_separator,
-- For compatibility, we need to not skip completely unspecified items. It is common, for example, to do
-- {{suffix|lang||foo}} to generate "+ -foo".
dont_skip_items = true,
-- Allow e.g. <infix> to be specified in place of <type:infix>.
pre_normalize_modifiers = pre_normalize_affix_type,
-- Don't pass in `lang` or `sc`, as they will be used as defaults to initialize the items, which we don't want
-- (particularly for `lang`), as the code in [[Module:affix]] uses the presence of `lang` as an indicator that
-- a part-specific language was explicitly given.
}
local lang = ilang or args[1]
local source
if has_source then
source = args[source_index]
end
-- For compatibility with the prior code, we need to convert items without term or properties to nil.
for i = 1, #items do
local item = items[i]
local saw_item_property = item.term
if not saw_item_property then
for k, v in pairs(item) do
if is_property_key(k) then
saw_item_property = true
break
end
end
end
if not saw_item_property then
items[i] = nil
elseif item.type then
-- Validate and canonicalize affix types.
if not recognized_affix_types[item.type] then
local valid_types = {}
for k in pairs(recognized_affix_types) do
insert(valid_types, ("'%s'"):format(k))
end
table.sort(recognized_affix_types)
error(("Unrecognized affix type '%s' in item %s; valid values are %s"):format(
item.type, item.itemno, table.concat(valid_types, ", ")))
else
item.type = recognized_affix_types[item.type]
end
end
end
if args.type and args.type.default and not m_affix.etymology_types[args.type.default] then
error("Unrecognized etymology type: '" .. args.type.default .. "'")
end
return args, items, lang, args.sc.default, source
end
local function augment_affix_data(data, args, lang, sc)
data.lang = lang
data.sc = sc
data.pos = args.pos and args.pos.default
data.lit = args.lit and args.lit.default
data.sort_key = args.sort
data.type = args.type and args.type.default
data.nocap = args.nocap
data.notext = args.notext
data.nocat = args.nocat
data.force_cat = args.force_cat
data.l = args.l.default
data.ll = args.ll.default
data.q = args.q.default
data.qq = args.qq.default
data.infl = args.infl.default
return data
end
function export.affix(frame)
local function extra_params(params)
params.notext = boolean_param
params.nocat = boolean_param
params.force_cat = boolean_param
end
local args, parts, lang, sc = parse_args {
raw_args = frame:getParent().args,
extra_params = extra_params,
allow_type = true,
allow_semicolon_separator = true,
}
-- There must be at least one part to display. If there are gaps, a term
-- request will be shown.
if not next(parts) and not args.type.default then
if mw.title.getCurrentTitle().nsText == "Template" then
parts = { {term = "prefix-"}, {term = "base"}, {term = "-suffix"} }
else
error("You must provide at least one part.")
end
end
return m_affix.show_affix(augment_affix_data({ parts = parts }, args, lang, sc))
end
function export.compound(frame)
local function extra_params(params)
params.notext = boolean_param
params.nocat = boolean_param
params.force_cat = boolean_param
end
local args, parts, lang, sc = parse_args {
raw_args = frame:getParent().args,
extra_params = extra_params,
allow_type = true,
allow_semicolon_separator = true,
}
-- There must be at least one part to display. If there are gaps, a term
-- request will be shown.
if not next(parts) and not args.type.default then
if mw.title.getCurrentTitle().nsText == "Template" then
parts = { {term = "first"}, {separator = " +‎ ", term = "second"} }
else
error("You must provide at least one part of a compound.")
end
end
return m_affix.show_compound(augment_affix_data({ parts = parts }, args, lang, sc))
end
function export.compound_like(frame)
local iparams = {
["lang"] = {type = "language"},
["template"] = {},
["text"] = {},
["oftext"] = {},
["cat"] = {},
["noaffixcat"] = boolean_param,
["dont_require_index"] = boolean_param,
}
local iargs = require("Module:parameters").process(frame.args, iparams)
local parent_args = frame:getParent().args
local function extra_params(params)
params.notext = boolean_param
params.nocat = boolean_param
params.force_cat = boolean_param
end
local args, parts, lang, sc = parse_args {
raw_args = parent_args,
extra_params = extra_params,
ilang = iargs.lang,
dont_require_index = iargs.dont_require_index,
-- FIXME, why are we doing this? Formerly we had 'params.pos = nil' whose intention was to disable the overall
-- pos= while preserving posN=, which is equivalent to the following using the new syntax. But why is this
-- necessary?
require_index_for_pos = not iargs.dont_require_index,
allow_semicolon_separator = true,
}
local nocat = args.nocat
local notext = args.notext
local text = not notext and iargs.text
local oftext = not notext and (iargs.oftext or text and "of")
local cat = not nocat and iargs.cat
local noaffixcat = nocat or iargs.noaffixcat
if not next(parts) then
if mw.title.getCurrentTitle().nsText == "Template" then
parts = { {term = "first"}, {separator = " +‎ ", term = "second"} }
end
end
return m_affix.show_compound_like(augment_affix_data({ parts = parts, text = text, oftext = oftext, cat = cat, noaffixcat = noaffixcat },
args, lang, sc))
end
function export.surface_analysis(frame)
local function ine(arg)
-- Since we're operating before calling [[Module:parameters]], we need to imitate how that module processes
-- arguments, including trimming since numbered arguments don't have automatic whitespace trimming.
if not arg then
return arg
end
arg = mw.text.trim(arg)
if arg == "" then
arg = nil
end
return arg
end
local parent_args = frame:getParent().args
local etymtext
local arg1 = ine(parent_args[1])
if not arg1 then
-- Allow omitted first argument to just display "By surface analysis".
etymtext = ""
elseif arg1:find("^%+") then
-- If the first argument (normally a language code) is prefixed with a +, it's a template name.
local template_name = arg1:sub(2)
local new_args = {}
for i, v in pairs(parent_args) do
if type(i) == "number" then
if i > 1 then
new_args[i - 1] = v
end
else
new_args[i] = v
end
end
new_args.nocap = true
etymtext = ", " .. frame:expandTemplate { title = template_name, args = new_args }
end
if etymtext then
return (ine(parent_args.nocap) and "b" or "B") .. "y [[Appendix:Glossary#surface analysis|surface analysis]]" ..
etymtext
end
local function extra_params(params)
params.notext = boolean_param
params.nocat = boolean_param
params.force_cat = boolean_param
end
local args, parts, lang, sc = parse_args {
raw_args = parent_args,
extra_params = extra_params,
allow_type = true,
allow_semicolon_separator = true,
}
-- There must be at least one part to display. If there are gaps, a term
-- request will be shown.
if not next(parts) then
if mw.title.getCurrentTitle().nsText == "Template" then
parts = { {term = "first"}, {separator = " +‎ ", term = "second"} }
else
error("You must provide at least one part.")
end
end
return m_affix.show_surface_analysis(augment_affix_data({ parts = parts }, args, lang, sc))
end
local function check_max_items(items, max_allowed)
if #items > max_allowed then
local bad_item = items[max_allowed + 1]
if bad_item.term then
error(("At most %s terms can be specified but saw a term specified for term #%s")
:format(max_allowed, max_allowed + 1))
else
for k, v in pairs(bad_item) do
if is_property_key(k) then
error(("At most %s terms can be specified but saw a value for property '%s' of term #%s")
:format(max_allowed, k, max_allowed + 1))
end
end
end
error(("Internal error: Something wrong, %s items generated when there should be at most %s, but item #%s doesn't have a term or any properties")
:format(#items, max_allowed, max_allowed + 1))
end
end
function export.circumfix(frame)
local function extra_params(params)
params.nocat = boolean_param
params.force_cat = boolean_param
end
local args, parts, lang, sc = parse_args {
raw_args = frame:getParent().args,
extra_params = extra_params,
}
check_max_items(parts, 3)
local prefix = parts[1]
local base = parts[2]
local suffix = parts[3]
-- Just to make sure someone didn't use the template in a silly way
if not (prefix and base and suffix) then
if mw.title.getCurrentTitle().nsText == "Template" then
prefix = {term = "circumfix", alt = "prefix"}
base = {term = "base"}
suffix = {term = "circumfix", alt = "suffix"}
else
error("You must specify a prefix part, a base term and a suffix part.")
end
end
return m_affix.show_circumfix(augment_affix_data({ prefix = prefix, base = base, suffix = suffix }, args, lang, sc))
end
function export.confix(frame)
local function extra_params(params)
params.nocat = boolean_param
params.force_cat = boolean_param
end
local args, parts, lang, sc = parse_args {
raw_args = frame:getParent().args,
extra_params = extra_params,
}
check_max_items(parts, 3)
local prefix = parts[1]
local base = parts[3] and parts[2] or nil
local suffix = parts[3] or parts[2]
-- Just to make sure someone didn't use the template in a silly way
if not (prefix and suffix) then
if mw.title.getCurrentTitle().nsText == "Template" then
prefix = {term = "prefix"}
suffix = {term = "suffix"}
else
error("You must specify a prefix part, an optional base term and a suffix part.")
end
end
return m_affix.show_confix(augment_affix_data({ prefix = prefix, base = base, suffix = suffix }, args, lang, sc))
end
function export.pseudo_loan(frame)
local function extra_params(params)
params.notext = boolean_param
params.nocat = boolean_param
params.force_cat = boolean_param
end
local args, parts, lang, sc, source = parse_args {
raw_args = frame:getParent().args,
extra_params = extra_params,
has_source = true,
-- FIXME, why are we doing this? Formerly we had 'params.pos = nil' whose intention was to disable the overall
-- pos= while preserving posN=, which is equivalent to the following using the new syntax. But why is this
-- necessary?
require_index_for_pos = true,
allow_semicolon_separator = true,
}
return require(pseudo_loan_module).show_pseudo_loan(
augment_affix_data({ source = source, parts = parts }, args, lang, sc))
end
function export.infix(frame)
local function extra_params(params)
params.nocat = boolean_param
params.force_cat = boolean_param
end
local args, parts, lang, sc = parse_args {
raw_args = frame:getParent().args,
extra_params = extra_params,
}
check_max_items(parts, 3)
local base = parts[1]
local infix = parts[2]
-- Just to make sure someone didn't use the template in a silly way
if not (base and infix) then
if mw.title.getCurrentTitle().nsText == "Template" then
base = {term = "base"}
infix = {term = "infix"}
else
error("You must provide a base term and an infix.")
end
end
return m_affix.show_infix(augment_affix_data({ base = base, infix = infix }, args, lang, sc))
end
function export.prefix(frame)
local function extra_params(params)
params.nocat = boolean_param
params.force_cat = boolean_param
end
local args, parts, lang, sc = parse_args {
raw_args = frame:getParent().args,
extra_params = extra_params,
}
local prefixes = parts
local base = nil
local max_prefix = 0
for k, v in pairs(prefixes) do
max_prefix = math.max(k, max_prefix)
end
if max_prefix >= 2 then
base = prefixes[max_prefix]
prefixes[max_prefix] = nil
end
-- Just to make sure someone didn't use the template in a silly way
if not next(prefixes) then
if mw.title.getCurrentTitle().nsText == "Template" then
base = {term = "base"}
prefixes = { {term = "prefix"} }
else
error("You must provide at least one prefix.")
end
end
return m_affix.show_prefix(augment_affix_data({ prefixes = prefixes, base = base }, args, lang, sc))
end
function export.suffix(frame)
local function extra_params(params)
params.nocat = boolean_param
params.force_cat = boolean_param
end
local args, parts, lang, sc = parse_args {
raw_args = frame:getParent().args,
extra_params = extra_params,
}
local base = parts[1]
local suffixes = {}
for k, v in pairs(parts) do
suffixes[k - 1] = v
end
-- Just to make sure someone didn't use the template in a silly way
if not next(suffixes) then
if mw.title.getCurrentTitle().nsText == "Template" then
base = {term = "base"}
suffixes = { {term = "suffix"} }
else
error("You must provide at least one suffix.")
end
end
return m_affix.show_suffix(augment_affix_data({ base = base, suffixes = suffixes }, args, lang, sc))
end
function export.derivsee(frame)
local iparams = {
["derivtype"] = {},
}
local iargs = require("Module:parameters").process(frame.args, iparams)
local params = {
id = true,
["sc"] = {type = "script"},
pos = true,
pagename = true,
head = {alias_of = "pagename"},
}
local derivtype = iargs.derivtype
params[1] = {required = "true", type = "language", default = "und"}
params[2] = {}
local args = require("Module:parameters").process(frame:getParent().args, params)
local lang = args[1]
local term = args[2] or args.pagename
local id = args.id
local sc = args.sc
local pos = require(en_utilities_module).pluralize(args.pos or "term")
if not term then
local SUBPAGE = mw.loadData("Module:headword/data").pagename
if lang:hasType("reconstructed") or mw.title.getCurrentTitle().nsText == "Reconstruction" then
term = "*" .. SUBPAGE
elseif lang:hasType("appendix-constructed") then
term = SUBPAGE
else
term = SUBPAGE
end
end
local category
local langname = lang:getFullName()
if (derivtype == "compound" and pos == nil) then
category = langname .. " compounds with " .. term
elseif derivtype == "compound" and pos == "verbs" then
category = langname .. " compound " .. pos .. " formed with " .. term
elseif derivtype == "compound" then
category = langname .. " compound " .. pos .. " with " .. term
else
category = langname .. " " .. pos .. " " .. derivtype .. "ed with " .. term .. (id and " (" .. id .. ")" or "")
end
return require("Module:collapsible category list").make {
lang = lang,
sc = sc,
category = category,
}
end
return export
bnae85onh3bdcskrxoj4ahfhg3h99dl
Bysen:ang-conj
10
8213
55165
2026-10-02T21:39:39Z
Deadend0914
7211
Gesceop tramet þe hafaþ '{{#invoke:ang-verb|show}}<!-- --><noinclude>{{documentation}}</noinclude>'
55165
wikitext
text/x-wiki
{{#invoke:ang-verb|show}}<!--
--><noinclude>{{documentation}}</noinclude>
kyhnfnivdgwuuzpyjv3mypmauzr0g1m
Module:ang-verb
828
8214
55166
2026-10-02T21:40:02Z
Deadend0914
7211
Gesceop tramet þe hafaþ 'local m_links = require("Module:links") local m_utilities = require("Module:utilities") local strutils = require("Module:string utilities") local m_table = require("Module:table") local com = require("Module:ang-common") local lang = require("Module:languages").getByCode("ang") local rfind = mw.ustring.find local rmatch = mw.ustring.match local rsplit = mw.text.split local rsubn = mw.ustring.gsub local insert = table.insert local concat = table.concat -- vers...'
55166
Scribunto
text/plain
local m_links = require("Module:links")
local m_utilities = require("Module:utilities")
local strutils = require("Module:string utilities")
local m_table = require("Module:table")
local com = require("Module:ang-common")
local lang = require("Module:languages").getByCode("ang")
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rsplit = mw.text.split
local rsubn = mw.ustring.gsub
local insert = table.insert
local concat = table.concat
-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar, n)
local retval = rsubn(term, foo, bar, n)
return retval
end
-- like str:gsub() but discards all but the first return value
local function gsub(term, foo, bar, n)
local retval = term:gsub(foo, bar, n)
return retval
end
local function track(page)
require("Module:debug").track("ang-verb/" .. page)
return true
end
local export = {}
local long_vowel = "āēīōūȳǣ" .. com.MACRON -- No precomposed œ + macron
local short_vowel = "aeiouyæœ"
local short_vowel_c = "[" .. short_vowel .. "]"
local vowel = long_vowel .. short_vowel
local vowel_c = "[" .. vowel .. "]"
local long_vowel_c = "[" .. long_vowel .. "]"
local non_vowel_c = "[^" .. vowel .. "]"
local always_unvoiced_cons = "cċkptxz"
local always_unvoiced_cons_c = "[" .. always_unvoiced_cons .. "]"
local unvoiced_cons = always_unvoiced_cons .. "fsþð"
local unvoiced_cons_c = "[" .. unvoiced_cons .. "]"
local single_cons = "bcċdfgġhklmnprstwþðƿ"
local single_cons_c = "[" .. single_cons .. "]"
local cons = single_cons .. "xz"
local cons_c = "[" .. cons .. "]"
local slots_and_accel = {
["infinitive"] = "inf",
["infinitive2"] = "inflected|inf",
["1sg_pres_indc"] = "1|s|pres|ind",
["2sg_pres_indc"] = "2|s|pres|ind",
["3sg_pres_indc"] = "3|s|pres|ind",
["pl_pres_indc"] = "p|pres|ind",
["sg_pres_subj"] = "s|pres|sub",
["pl_pres_subj"] = "p|pres|sub",
["1sg_past_indc"] = "1|s|pret|ind",
["2sg_past_indc"] = "2|s|pret|ind",
["3sg_past_indc"] = "3|s|pret|ind",
["pl_past_indc"] = "p|pret|ind",
["sg_past_subj"] = "s|pret|sub",
["pl_past_subj"] = "p|pret|sub",
["sg_impr"] = "s|imp",
["pl_impr"] = "p|imp",
["pres_ptc"] = "pres|part",
["past_ptc"] = "past|part",
}
local function ends_in_long_vowel(word)
if rfind(word, long_vowel_c .. "$") then
return true
elseif rfind(word, "ē[ao]$") then
return true
elseif rfind(word, "ī[eo]$") then
return true
else
return false
end
end
local function begins_with_verbal_prefix(word)
word = com.decompose(word)
for _, prefixspec in ipairs(com.prefixes) do
local prefix = prefixspec[1]
local specs = prefixspec[2]
if specs.verb then
local main = rmatch(word, "^" .. prefix .. "(.-)$")
if main and (not specs.restriction or rfind(main, specs.restriction)) then
return true
end
end
end
return false
end
local function make_table(forms)
local title = forms.title
local accel_lemma = m_links.remove_links(forms.infinitive[1] or mw.loadData("Module:headword/data").pagename)
local function typetext()
local typ = forms["type"]
local class = (forms["class"] and tonumber(forms["class"])) or nil
local id
if typ == "strong" then
local class_roman = {"I", "II", "III", "IV", "V", "VI", "VII"}
class = class_roman[class]
id = (class and "Class_" .. class) or "Strong_verbs"
return "[[Appendix:Old English verbs#Strong_verbs|strong]]" .. (class and ", " .. "[[Appendix:Old English verbs#" .. id .. "|class " .. class .. "]]" or "")
elseif typ == "weak" then
id = (class and class>=1 and class<=3 and "Class_" .. class) or "Weak_verbs"
return "[[Appendix:Old English verbs#Weak_verbs|weak]]" .. (class and ", " .. "[[Appendix:Old English verbs#" .. id .. "|class " .. class .. "]]" or "")
elseif typ == "pretpres" then
return "[[Appendix:Old English verbs#Preterite-present_verbs|preterite-present]]"
elseif typ == "irreg" or typ == "anomalous" then
return "[[Appendix:Old English verbs#Anomalous_verbs|irregular]]"
else
error("Unrecognized verb type: " .. typ)
end
end
if not title then
title = "Conjugation of " .. m_links.full_link({lang = lang, alt = accel_lemma}, "term")
if forms["type"] then
title = title .. " (" .. typetext() .. ")"
end
end
local table_args = {
title = title,
style = forms.style == "right" and "float:right; clear:right;" or "",
width = forms.width or "30",
}
for slot, accel_form in pairs(slots_and_accel) do
local table_arg = {}
local slotforms = forms[slot] and #forms[slot] > 0 and forms[slot] or {"—"}
for _, form in ipairs(slotforms) do
insert(table_arg, form == "—" and form or m_links.full_link{
lang = lang, term = form, accel = {
form = accel_form ~= "" and accel_form or nil,
lemma = accel_lemma,
}
})
table_args[slot] = concat(table_arg, ", ")
end
end
local table = [=[
<div class="NavFrame" style="{style}max-width:{width}em">
<div class="NavHead" style="background: var(--wikt-palette-grey-blue-1,#EFF7FF)" >{title}
</div>
<div class="NavContent">
{\op}| style="background:var(--wikt-palette-grey-0,#F9F9F9);text-align:center;width:100%" class="inflection-table"
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | infinitive
| {infinitive}
| {infinitive2}
|-
! style="font-size:80%;" | indicative mood
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | present tense
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | past tense
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | first person singular
| {1sg_pres_indc}
| {1sg_past_indc}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | second person singular
| {2sg_pres_indc}
| {2sg_past_indc}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | third person singular
| {3sg_pres_indc}
| {3sg_past_indc}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | plural
| {pl_pres_indc}
| {pl_past_indc}
|-
! style="font-size:80%;" | subjunctive
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | present tense
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | past tense
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | singular
| {sg_pres_subj}
| {sg_past_subj}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | plural
| {pl_pres_subj}
| {pl_past_subj}
|-
! style="font-size:80%;" | imperative
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" colspan="2" |
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | singular
| colspan="2" | {sg_impr}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | plural
| colspan="2" | {pl_impr}
|-
! style="font-size:80%;" | participle
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | present
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | past
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" |
| {pres_ptc}
| {past_ptc}
|{\cl}</div></div>]=]
return strutils.format(table, table_args)
end
function export.make_table(frame)
local parent_args = frame:getParent().args
local params = {
["title"] = {default = "—"},
["type"] = {},
["width"] = {},
["style"] = {},
}
for slot, _ in pairs(slots_and_accel) do
params[slot] = {}
end
local args = require("Module:parameters").process(parent_args, params)
return make_table(args)
end
local function vernerize_cons(suf, verner)
if not verner then
return suf
end
local first_cons, cons = rmatch(suf, "^(.*)([sþðh])$")
if not first_cons then
return suf
end
if cons == "s" then
cons = "r"
elseif cons == "þ" or cons == "ð" then
cons = "d"
elseif cons == "h" then
cons = "g"
else
error("Internal error in vernerize_cons(): Unexpected suffix " .. suf)
end
return first_cons .. cons
end
local function depalatalize_final_cons_before_cons(word)
if word:find("sċ$") then
return word
elseif word:find("nċġ$") then
-- crinċġan etc.
return gsub(word, "nċġ$", "ng")
else
return rsub(word, "([nċġ]?[ċġ])$", {
["ċ"] = "c",
["nċ"] = "nc",
["ċċ"] = "cc",
["ġċ"] = "ġc",
["nġ"] = "ng",
["ċġ"] = "cg",
-- ġ and ġġ stay as-is
})
end
end
local function depalatalize_final_cons_before_back_vowel(word)
local word = depalatalize_final_cons_before_cons(word)
return gsub(word, "ġ$", "g")
end
local function palatalize_final_cons(word)
return rsub(word, "([cg]?[cg])$", {
["c"] = "ċ",
["cc"] = "ċċ",
["cg"] = "ċġ",
["g"] = "ġ",
["gc"] = "gċ", -- ??
["gg"] = "ċġ",
})
end
-- Add an ending that begins with a consonant onto a stem, making adjustments
-- as necessary when two consonants come together. Currently recognizes only
-- the three endings "st", "þ" and "d".
local function construct_cons_stem_ending(stem, ending)
-- If the stem ends in a geminate, reduce to single consonant
-- (e.g. fyll-, sett-).
local origstem = stem
local base, final_geminated = rmatch(stem, "^(.-)(" .. non_vowel_c .. ")%2$")
if base then
stem = base .. final_geminated
end
stem = depalatalize_final_cons_before_cons(stem)
if ending == "st" then
-- For 2sg:
-- cyssan + -st -> cyst, tǣsan + -st -> tǣst
-- settan + -st -> setst, myntan + -st -> myn(t)st (?), restan + -st -> restst/rest (?)
-- bǣdan + -st -> bǣtst, sendan + -st -> sen(t)st
-- cȳþan + -st -> cȳst, cwiþ- + -st -> cwist
-- wiex- + -st -> wiext
-- drenċan + -st -> drencst
-- senġan + -st -> sengst
if stem:find("s$") then
return stem .. "t"
elseif stem:find("[dt]$") then
if rfind(stem, vowel_c .. "[dt]$") then
return gsub(stem, "[dt]$", "tst")
elseif rfind(stem, "s[dt]$") then
return gsub(stem, "s[dt]$", "st")
else
return {gsub(stem, "[dt]$", "st"), gsub(stem, "[dt]$", "tst")}
end
elseif rfind(stem, "[þð]$") then
return rsub(stem, "[þð]$", "st")
elseif stem:find("x$") then
return stem .. "t"
else
return stem .. "st"
end
elseif ending == "þ" then
-- For 3sg:
-- cyssan + -þ -> cyst, tǣsan + -þ -> tǣst
-- settan + -þ -> set(t), myntan + -þ -> mynt, restan + -þ -> rest
-- bǣdan + -þ -> bǣt(t), sendan + -þ -> sent
-- cȳþan + -þ -> cȳþ(þ), cwiþ- + -þ -> cwiþ(þ)
-- wiex- + -þ -> wiext
-- drenċan + -þ -> drencþ
-- senġan + -þ -> sengþ
if rfind(stem, vowel_c .. "[dt]$") then
return {gsub(stem, "[dt]$", "tt"), gsub(stem, "[dt]$", "t")}
elseif stem:find("[dt]$") then
return gsub(stem, "[dt]$", "t")
elseif stem:find("[sx]$") then
return stem .. "t"
elseif rfind(stem, "[þð]$") then
return {rsub(stem, "[þð]$", "þþ"), stem}
else
return stem .. "þ"
end
elseif ending == "d" then
-- For past:
-- cyssan + -de -> cyste, tǣsan + -de -> tǣsde
-- settan + -de -> sette, myntan + -de -> mynte, restan + -de -> reste, mētan + -de -> mētte
-- bǣdan + -de -> bǣdde, sendan + -de -> sende, hreddan + -de -> hredde
-- cȳþan + -de -> cȳþde (later cȳdde), ġeorwirþan + -de -> ġeorwirþde, sċeþþan + -de -> sċeþte
-- (? Bosworth-Toller has only sċeþede, and has pæþde for *pæþte from pæþþan)
-- līexan + -de -> līexte
-- pyffan + -de -> pyfte, ġelīefan + -de -> ġelīefde
-- drenċan + -de -> drencte
-- senġan + -de -> sengde
-- cīepan + -de -> cīepte, clyppan + -de -> clypte
-- spillan + -de -> spilde, cierran + -de -> cierde, wemman + -de -> wemde, etc.
if rfind(stem, vowel_c .. "t$") then
return stem .. "t"
elseif rfind(stem, vowel_c .. "d$") then
return stem .. "d"
elseif stem:find("[dt]$") then
return stem
elseif rfind(stem, always_unvoiced_cons_c .. "$") or rfind(origstem, unvoiced_cons_c .. "[sfþð]$") then
return stem .. "t"
else
return stem .. "d"
end
else
error("Unrecognized ending: '" .. ending .. "'")
end
end
-- Default function for combining a stem and an ending. This makes no adjustments
-- to the result other than returning an optional variant ending in -h if the result
-- ends in -g. Example: stīgan preterite stāg or stāh. (Does not apply to a form
-- ending in -ġ.) If adjustments are necessary at the stem/ending boundary, use e.g.
-- construct_cons_stem_ending.
local function default_construct_stem_ending(stem, ending)
local form = stem .. ending
if form:find("g$") and not form:find("[ncg]g$") then
return {form, gsub(form, "g$", "h")}
else
return form
end
end
local function add_form_to_slot(args, slot, form)
if not args[slot] then
args[slot] = {}
end
if type(form) == "string" then
m_table.insertIfNot(args[slot], form)
else
for _, f in ipairs(form) do
m_table.insertIfNot(args[slot], f)
end
end
end
local function add_ending_with_prefix(args, slot, pref, stems, ending, construct_stem_ending)
construct_stem_ending = construct_stem_ending or default_construct_stem_ending
if type(stems) ~= "table" then
stems = {stems}
end
for _, stem in ipairs(stems) do
local form = construct_stem_ending(pref and pref .. stem or stem, ending)
add_form_to_slot(args, slot, form)
end
end
local function add_ending(args, slot, stems, ending, construct_stem_ending)
add_ending_with_prefix(args, slot, nil, stems, ending, construct_stem_ending)
end
local function construct_optional_ge_stem_ending(stem, ending)
return "([[ge" .. stem .. ending .. "|ġe]])[[" .. stem .. ending .. "]]"
end
local function make_non_past(args, presa, presefin, presenfin, pres23, impsg, pp, with_ge)
add_ending(args, "infinitive", presa, "n")
add_ending(args, "infinitive2", presenfin, "nne")
add_ending(args, "1sg_pres_indc", presefin, "")
add_ending(args, "2sg_pres_indc", pres23, "st", construct_cons_stem_ending)
add_ending(args, "3sg_pres_indc", pres23, "þ", construct_cons_stem_ending)
add_ending(args, "pl_pres_indc", presa, "þ")
add_ending(args, "sg_pres_subj", presefin, "")
add_ending(args, "pl_pres_subj", presefin, "n")
add_ending(args, "sg_impr", impsg, "")
add_ending(args, "pl_impr", presa, "þ")
add_ending(args, "pres_ptc", presenfin, "nde")
if with_ge then
add_ending(args, "past_ptc", pp, "", construct_optional_ge_stem_ending)
else
add_ending(args, "past_ptc", pp, "")
end
end
local function make_strong_past(args, pref, pastsg, pastpl)
add_ending_with_prefix(args, "1sg_past_indc", pref, pastsg, "")
add_ending_with_prefix(args, "2sg_past_indc", pref, pastpl, "e")
add_ending_with_prefix(args, "3sg_past_indc", pref, pastsg, "")
add_ending_with_prefix(args, "pl_past_indc", pref, pastpl, "on")
add_ending_with_prefix(args, "sg_past_subj", pref, pastpl, "e")
add_ending_with_prefix(args, "pl_past_subj", pref, pastpl, "en")
end
local function make_strong(presa, prese, pres23, impsg, pastsg, pastpl, pp, with_ge)
local args = {}
make_non_past(args, presa, prese, prese, pres23, impsg, pp, with_ge)
make_strong_past(args, nil, pastsg, pastpl)
return args
end
local function make_weak_past(args, pref, past)
add_ending_with_prefix(args, "1sg_past_indc", pref, past, "e")
add_ending_with_prefix(args, "2sg_past_indc", pref, past, "est")
add_ending_with_prefix(args, "3sg_past_indc", pref, past, "e")
add_ending_with_prefix(args, "pl_past_indc", pref, past, "on")
add_ending_with_prefix(args, "sg_past_subj", pref, past, "e")
add_ending_with_prefix(args, "pl_past_subj", pref, past, "en")
end
local function make_weak(presa, presefin, presenfin, pres23, impsg, past, pp, with_ge)
local args = {}
make_non_past(args, presa, presefin, presenfin, pres23, impsg, pp, with_ge)
make_weak_past(args, nil, past)
return args
end
local strong_verbs = {}
strong_verbs["1"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ī(" .. cons_c .. "+)an$")
if pref then
-- bīdan "await", ācwīnan "dwindle away", sċīnan "shine", spīwan "spew, spit", etc.;
-- stīgan "ascend" (þū stīġst, stāg/stāh [handled by default_construct_stem_ending],
-- stigon, stiġen); blīcan "shine" (þū blīcst/blīċest)
data.pres23 = pref .. "ī" .. palatalize_final_cons(suf)
if suf == "g" then
data.impsg = pref .. "īġ"
else
data.impsg = pref .. "ī" .. suf
end
-- ġīnan "yawn" (gān, ġinon, ġinen)
data.pastsg = depalatalize_final_cons_before_back_vowel(pref) .. "ā" .. suf
-- snīþan "cut" -> snidon; sċrīþan "go, proceed" -> sċridon
-- (but not mīþan "avoid", wrīþan "twist")
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pref .. "i" .. pastsuf
if pastsuf == "g" then
data.pp = pref .. "iġen"
else
data.pp = data.pastpl .. "en"
end
return
end
pref = rmatch(data.inf, "^(.-)[ēī]on$")
if pref then
-- tēon/tīon "accuse" < *tīhanan, similarly lēon "lend" < *līhwanan,
-- sēon "strain" < *sīhwanan, þēon "thrive" < *þinhanan (originally strong 3),
-- wrēon < *wrīhanan. Beware of homonyms e.g. tēon "pull, draw" (strong 2) < *teuhanan,
-- tēon "make, create" (weak) ?< *tīhanan (strong);
-- þēon/þēowan/þȳ(g)(a)n "press" (weak) < *þunhijanan;
-- sēon "see" (strong 5) < *sehwanan
data.contracted = true
data.pres23 = pref .. "īeh"
data.impsg = gsub(data.inf, "n$", "h")
data.pastsg = pref .. "āh"
if rfind(pref, "[þð]$") then
-- þēon "thrive", has remnant strong 3 parts
data.pastpl = {pref .. "ig", pref .. "ung"}
data.pp = {pref .. "iġen", pref .. "ungen"}
else
data.pastpl = pref .. "ig"
if pref:find("s$") then
-- sēon "strain" alt past part siwen
data.pp = {pref .. "iġen", pref .. "iwen"}
else
data.pp = pref .. "iġen"
end
end
return
end
end
strong_verbs["2"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ēo(" .. cons_c .. "+)an$")
if pref then
-- bēodan "command", crēopan "creep"; rēocan "smoke, reek" (þū rīecst/rīeċest);
-- drēogan "endure" (þū drīeġst, drēag/drēah [handled by default_construct_stem_ending],
-- drugon, drogen)
data.pres23 = pref .. "īe" .. palatalize_final_cons(suf)
data.impsg = pref .. "ēo" .. suf
data.pastsg = pref .. "ēa" .. suf
-- ġēotan "pour" (ġēat, guton, goten); ċēosan "choose" (ċēas, curon, coren)
local pastpref = depalatalize_final_cons_before_back_vowel(pref)
-- ċēosan "choose" -> curon; forlēosan "lose" -> forluron; sēoþan "boil" -> sudon
-- (but not ābrēoþan "perish, ruin")
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pastpref .. "u" .. pastsuf
data.pp = pastpref .. "o" .. pastsuf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ū(" .. cons_c .. "+)an$")
if pref then
-- sċūfan "shove"; brūcan "use" (þū brīecst/brīeċest);
-- būgan "bend" (þū bīeġst, bēag/bēah [handled by default_construct_stem_ending],
-- bugon, bogen)
data.pres23 = pref .. "ȳ" .. palatalize_final_cons(suf)
data.impsg = pref .. "ū" .. suf
-- could have palatalization here, but no known examples
data.pastsg = pref .. "ēa" .. suf
-- no known examples of Vernerization, but just in case
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pref .. "u" .. pastsuf
data.pp = pref .. "o" .. pastsuf .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)ēon$")
if pref then
-- tēon "pull, draw" < *teuhanan, flēon "flee"
-- Beware of homonyms, e.g. tēon/tīon "accuse" (strong 1) < *tīhanan,
-- tēon "make, create" (weak) ?< *tīhan (strong)
data.contracted = true
data.pres23 = pref .. "īeh"
data.impsg = gsub(data.inf, "n$", "h")
data.pastsg = pref .. "ēah"
-- no examples where depalatalization is needed
data.pastpl = pref .. "ug"
data.pp = pref .. "ogen"
return
end
end
strong_verbs["3"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)i([mn]" .. cons_c .. "+)an$")
if pref then
-- bindan "bind", climban "climb", ġelimpan "happen", winnan "win",
-- swimman "swim", etc.; ācwincan "vanish" (þū ācwincst/ācwinċest);
-- cringan (þū cringst/crinġest), variant crinċġan (þū cringst/crinċġest)
data.pres23 = pref .. "i" .. palatalize_final_cons(suf)
data.impsg = pref .. "i" .. suf
-- onġinnan "begin" (ongann, ongunnon, ongunnen), ċimban "join"
local pastpref = depalatalize_final_cons_before_back_vowel(pref)
-- no Verner alternation here; expected #fīþan, #fōþ, #fundon <
-- *finþanan, *fanþ, *fundund regularized into findan, fand, fundon;
-- but depalatalize to handle crin(ċ)ġan past crang/crungon/crungen
-- and (maybe?) variant crinċan past cranc/cruncon/cruncen
local pastsuf = depalatalize_final_cons_before_cons(suf)
data.pastsg = pastpref .. "a" .. pastsuf
data.pastpl = pastpref .. "u" .. pastsuf
data.pp = pastpref .. "u" .. pastsuf .. "en"
return
end
local pref, vowel, suf = rmatch(data.inf, "^(.-)(ie)(l" .. cons_c .. "+)an$")
if not pref then
-- ġeldan/ġildan/ġyldan variants of ġieldan; helpan/bellan/delfan etc.
pref, vowel, suf = rmatch(data.inf, "^(.-)([eiy])(l" .. cons_c .. "+)an$")
end
if not pref then
pref, vowel, suf = rmatch(data.inf, "^(.-)(eo)(" .. cons_c .. "+)an$")
end
if pref then
-- helpan "help" (þū hilpst), bellan "bellow", beteldan "cover", delfan "dig",
-- sweltan "die", etc.; belgan "swell with anger" (þū bielġst, bealg/bealh
-- [handled by default_construct_stem_ending])
--
-- ġieldan "yield, pay" (þū ġiel(t)st, hē ġieldeþ/ġielt, ġeald, guldon, golden),
-- ġiellan "yell", ġielpan "boast"
--
-- weorpan "throw" (þū wierpst), feohtan "fight", sċeorfan "gnaw";
-- āseolcan "languish" (þū āsielcst/āsielċest), beorgan "protect"
-- (þū bierġst, bearg/bearh [handled by default_construct_stem_ending])
data.pres23 = pref .. (vowel == "e" and "i" or vowel == "eo" and "ie" or vowel) .. palatalize_final_cons(suf)
data.impsg = pref .. vowel .. suf
data.pastsg = pref .. "ea" .. suf
-- ġieldan etc. (see above)
local pastpref = depalatalize_final_cons_before_back_vowel(pref)
-- weorþan -> wurdon
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pastpref .. "u" .. pastsuf
data.pp = pastpref .. "o" .. pastsuf .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)eġdan$")
if pref then
-- breġdan "brandish" (þū breġdest, hē breġdeþ, bræġd/brǣd, brugdon, brogden)
-- streġdan "strew" (like breġdan)
data.pres23 = pref .. "eġde"
data.impsg = pref .. "eġd"
data.pastsg = {pref .. "æġd", pref .. "ǣd"}
data.pastpl = pref .. "ugd"
data.pp = pref .. "ogden"
return
end
local pref, suf = rmatch(data.inf, "^(.-)(ie?rn)an$")
if not pref then
pref, suf = rmatch(data.inf, "^(.-)(yrn)an$")
end
if pref then
-- biernan/birnan/byrnan "burn" < *brinnanan (þū biernst, barn/born/bearn, burnon, burnen)
-- iernan/irnan/yrnan "run" < *rinnan (like biernan)
data.pres23 = pref .. suf
data.impsg = data.pres23
data.pastsg = {pref .. "arn", pref .. "orn", pref .. "earn"}
data.pastpl = pref .. "urn"
data.pp = pref .. "urnen"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)([ou])rnan$")
if pref then
-- murnan "mourn" (þū myrnst, mearn, murnon, — but BT documents mornen)
-- spurnan/spornan "spurn" (þū spyrnst, spearn, spurnon, spornen)
data.pres23 = pref .. "yrn"
data.impsg = pref .. vowel .. "rn"
data.pastsg = pref .. "earn"
data.pastpl = pref .. "urn"
data.pp = pref .. "ornen"
return
end
local pref, suf = rmatch(data.inf, "^(.-)e(r" .. cons_c .. "+)an$")
if pref then
-- berstan "burst" < *brestanan (þū birst, hē birsteþ/birst, bærst, burston, borsten)
-- þersċan "thrash, thresh" < *þreskanan (þū þirsċst, hē þirsċeþ, þærsċ, þursċon, þorsċen)
data.pres23 = pref .. "i" .. suf
data.impsg = pref .. "e" .. suf
data.pastsg = pref .. "æ" .. suf
data.pastpl = pref .. "u" .. suf
data.pp = pref .. "o" .. suf .. "en"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)fr([ei])ġnan$")
if pref then
-- friġnan "ask", variant freġnan
data.pres23 = {pref .. "friġne", pref .. "friġn"}
data.impsg = pref .. "fr" .. vowel .. "ġn"
data.pastsg = pref .. "fræġn"
data.pastpl = pref .. "frugn"
data.pp = pref .. "frugnen"
return
end
local pref = rmatch(data.inf, "^(.-)frīnan$")
if pref then
-- frīnan "ask" variant of friġnan
data.pres23 = {pref .. "frīne", pref .. "frīn"}
data.impsg = pref .. "frīn"
data.pastsg = pref .. "frān"
data.pastpl = pref .. "frūn"
data.pp = pref .. "frūnen"
return
end
local pref = rmatch(data.inf, "^(.-)fēolan$")
if pref then
-- fēolan "enter, penetrate"
data.pres23 = {pref .. "fielh", pref .. "filh"}
data.impsg = pref .. "feolh"
data.pastsg = pref .. "fealh"
data.pastpl = {pref .. "fǣl", pref .. "fulg", pref .. "fūl"}
data.pp = {pref .. "folgen", pref .. "fōlen"}
return
end
end
strong_verbs["4"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ie(" .. cons_c .. ")an$")
if pref then
-- sċieran "shear"
data.pres23 = {pref .. "ie" .. suf .. "e", pref .. "ie" .. suf}
data.impsg = pref .. "ie" .. suf
-- no Verner alternation or depalatalization here
data.pastsg = pref .. "ea" .. suf
data.pastpl = pref .. "ēa" .. suf
data.pp = pref .. "o" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)e(" .. cons_c .. ")an$")
if pref then
-- beran "bear, carry", cwelan "die", brecan "break" (þū bricst/briċest), etc.
if suf == "r" or suf == "l" then
data.pres23 = {pref .. "i" .. suf .. "e", pref .. "i" .. suf}
else
data.pres23 = pref .. "i" .. palatalize_final_cons(suf)
end
data.impsg = pref .. "e" .. suf
-- no Verner alternation or depalatalization here
data.pastsg = pref .. "æ" .. suf
data.pastpl = pref .. "ǣ" .. suf
data.pp = pref .. "o" .. suf .. "en"
return
end
-- Next two are irregular but occur with so many prefixes that we special-case them here.
local pref = rmatch(data.inf, "^(.-)cuman$")
if pref then
-- cuman "come"
data.pres23 = {pref .. "cyme", pref .. "cym"}
data.impsg = pref .. "cum"
data.pastsg = {pref .. "cōm", pref .. "cwōm"}
data.pastpl = data.pastsg
data.pp = {pref .. "cumen", pref .. "cymen"}
return
end
local pref = rmatch(data.inf, "^(.-)niman$")
if pref then
-- niman "take"
data.pres23 = {pref .. "nime", pref .. "nim"}
data.impsg = pref .. "nim"
data.pastsg = pref .. "nōm"
data.pastpl = data.pastsg
data.pp = pref .. "numen"
return
end
end
strong_verbs["5"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ie(" .. cons_c .. ")an$")
if not pref then
pref, suf = rmatch(data.inf, "^(.-ġ)[eiy](" .. cons_c .. ")an$")
end
if pref then
-- ġiefan "give", forġietan "forget"
data.pres23 = pref .. "ie" .. suf
data.impsg = data.pres23
data.pastsg = pref .. "ea" .. suf
data.pastpl = pref .. "ēa" .. suf
data.pp = pref .. "e" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)e(" .. cons_c .. ")an$")
if suf == "g" then
-- wegan "carry"; special-case
data.pres23 = pref .. "iġ"
data.impsg = pref .. "eġ"
data.pastsg = pref .. "æġ"
data.pastpl = {pref .. "ǣg", pref .. "āg"}
data.pp = pref .. "eġen"
return
elseif pref then
-- metan "measure", sprecan "speak", cnedan "knead", wefan "weave", etc.
data.pres23 = pref .. "i" .. palatalize_final_cons(suf)
data.impsg = pref .. "e" .. suf
if suf == "t" and not pref:find("m$") and not pref:find("ġ$") then
-- etan "eat", fretan "devour", compounds; exclude metan "measure",
-- ġetan (potential variant of ġietan)
data.pastsg = pref .. "ǣ" .. suf
else
data.pastsg = pref .. "æ" .. suf
end
-- cweþan "say" -> cwǣdon, wesan "be" -> wǣron
-- (but not ġenesan "be saved", lesan "collect, gather")
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pref .. "ǣ" .. pastsuf
if data.inf:find("drepan$") then
-- Special-case drepan "strike, slay"; Wright lists brecan here with
-- pp only brocen, but that just makes it a strong-4 verb and that's
-- where it's normally listed in dictionaries
data.pp = {pref .. "epen", pref .. "open"}
else
data.pp = pref .. "e" .. pastsuf .. "en"
end
return
end
local pref, last_cons = rmatch(data.inf, "^(.-)i([dt])%2an$")
if pref then
-- biddan "pray", sittan "sit"
data.jpres = true
data.pres23 = pref .. "i" .. last_cons
data.impsg = data.pres23 .. "e"
data.pastsg = pref .. "æ" .. last_cons
data.pastpl = pref .. "ǣ" .. last_cons
data.pp = pref .. "e" .. last_cons .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)iċġe?an$")
if pref then
-- liċġan "lie down", þiċġan "receive", friċġan "ask, inquire"
data.jpres = true
data.pres23 = pref .. "iġ"
data.impsg = data.pres23 .. "e"
if rfind(data.inf, "[þð]iċġe?an$") then
data.pastsg = {pref .. "eah", pref .. "ah"}
else
data.pastsg = pref .. "æġ"
end
data.pastpl = {pref .. "ǣg", pref .. "āg"}
if data.inf:find("friċġe?an$") then
data.pp = {pref .. "iġen", pref .. "ugen"}
else
data.pp = pref .. "eġen"
end
return
end
local pref = rmatch(data.inf, "^(.-)ēon$")
if pref then
-- sēon "see" < *sehwanan, ġefēon "rejoice" < *gafehanan, plēon "risk" < *plehanan
data.contracted = true
data.pres23 = pref .. "ieh"
data.impsg = pref .. "eoh"
data.pastsg = pref .. "eah"
if pref:find("s$") then
-- sēon "see"
data.pastpl = pref .. "āw"
data.pp = pref .. "ewen"
else
data.pastpl = pref .. "ǣg"
data.pp = pref .. "eġen"
end
return
end
end
strong_verbs["6"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ea(" .. cons_c .. "+)an$")
if pref then
-- sċ(e)acan "shake", sċ(e)afan "shave, scrape"
data.pres23 = pref .. "ea" .. suf
data.impsg = {pref .. "a" .. suf, data.pres23}
data.pastsg = {pref .. "ō" .. suf, pref .. "eō" .. suf}
data.pastpl = data.pastsg
data.pp = {pref .. "a" .. suf .. "en", pref .. "ea" .. suf .. "en"}
return
end
local pref, vowel, suf = rmatch(data.inf, "^(.-)(a)(" .. cons_c .. "+)an$")
if not pref then
-- stondan variant of standan, sponan variant of spanan
pref, vowel, suf = rmatch(data.inf, "^(.-)(o)(n" .. cons_c .. "*)an$")
end
if not pref then
-- wæsċan/wasċean/wæsċean variant of wasċan
pref, vowel, suf = rmatch(data.inf, "^(.-)([aæ])(sċ" .. cons_c .. "*)e?an$")
end
if suf == "g" then
-- gnagan "gnaw", dragan "draw"
data.pres23 = pref .. "æġ"
data.impsg = pref .. "ag"
data.pastsg = pref .. "ōg"
data.pastpl = data.pastsg
data.pp = {pref .. "æġen", pref .. "agen"}
return
elseif suf == "nd" and pref:find("st$") then
-- standan/stondan "stand"
data.pres23 = pref .. "end"
data.impsg = pref .. vowel .. "nd"
data.pastsg = pref .. "ōd"
data.pastpl = data.pastsg
data.pp = pref .. vowel .. "nden"
return
elseif suf == "n" and pref:find("sp$") then
-- spanon/sponan "allure"
data.pres23 = {pref .. "ene", pref .. "en"}
data.impsg = pref .. vowel .. "n"
data.pastsg = {pref .. "ōn", pref .. "ēon"} -- has alt class VII past
data.pastpl = data.pastsg
data.pp = pref .. vowel .. "nen"
return
elseif pref then
-- faran "go", alan "grow", bacan "bake", hladan "lade", wasċan "wash", etc.
if suf == "r" or suf == "l" or suf == "sċ" then
data.pres23 = {pref .. "æ" .. suf .. "e", pref .. "æ" .. suf}
else
data.pres23 = pref .. "æ" .. palatalize_final_cons(suf)
end
data.impsg = pref .. "a" .. suf
data.pastsg = pref .. "ō" .. suf
-- Apparently no Verner variation here
data.pastpl = data.pastsg
data.pp = {pref .. "æ" .. suf .. "en", pref .. "a" .. suf .. "en"}
return
end
local pref = rmatch(data.inf, "^(.-)ēan$")
if pref then
-- slēan "strike", flēan "flay", lēan "blame", þwēan "wash"
data.contracted = true
data.pres23 = pref .. "ieh"
data.impsg = pref .. "eah"
data.pastsg = pref .. "ōg" -- also slōh etc., which will get automatically added
data.pastpl = data.pastsg
data.pp = {pref .. "æġen", pref .. "agen", pref .. "eġen"}
return
end
-- All the j-present verbs have to be handled individually as each has
-- idiosyncrasies.
local pref, last_cons = rmatch(data.inf, "^(.-)hebban$")
if pref then
-- hebban "raise"
data.jpres = true
data.pres23 = pref .. "hefe"
data.impsg = data.pres23
data.pastsg = pref .. "hōf"
data.pastpl = data.pastsg
data.pp = {pref .. "hæfen", pref .. "hafen", pref .. "hefen"}
return
end
local pref, vowel = rmatch(data.inf, "^(.-)hl([iy]?e?)hhan$")
if pref then
-- hliehhan "laugh"
data.jpres = true
data.pres23 = pref .. "hl" .. vowel .. "h"
data.impsg = data.pres23
data.pastsg = pref .. "hlōg"
data.pastpl = data.pastsg
data.pp = pref .. "hlæġen"
return
end
local pref, cons = rmatch(data.inf, "^(.-)sċe([þð])%2an$")
if pref then
-- sċeþþan "injure" (for some reason, expected #sċieþþan doesn't occur)
data.jpres = true
data.pres23 = pref .. "sċe" .. cons .. "e"
data.impsg = data.pres23
data.pastsg = "sċōd"
data.pastpl = data.pastsg
data.pp = "sċeaþen"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)sċ([iy]?e?)ppan$")
if pref then
-- sċieppan "create"
data.jpres = true
data.pres23 = pref .. "sċ" .. vowel .. "pe"
data.impsg = data.pres23
data.pastsg = {pref .. "sċōp", pref .. "sċeōp"}
data.pastpl = data.pastsg
data.pp = {pref .. "sċeapen", pref .. "sċapen"}
return
end
local pref, vowel = rmatch(data.inf, "^(.-)st([æe])ppan$")
if pref then
-- stæppan "step, go"
data.jpres = true
data.pres23 = pref .. "st" .. vowel .. "pe"
data.impsg = data.pres23
data.pastsg = pref .. "stōp"
data.pastpl = data.pastsg
data.pp = {pref .. "stæpen", pref .. "stapen"}
return
end
local pref = rmatch(data.inf, "^(.-s[wƿ])erian$")
if pref then
-- swerian "swear"
data.jpres = true
data.pres23 = pref .. "ere"
data.impsg = data.pres23
data.pastsg = pref .. "ōr"
data.pastpl = data.pastsg
data.pp = pref .. "oren" -- on the analogy of class IV verbs like beran
return
end
end
strong_verbs["7"] = function(data)
-- Type (7a) verbs
local pref = rmatch(data.inf, "^(.-)hātan$")
if pref then
-- hātan "call"
data.pres23 = pref .. "hǣt"
data.impsg = pref .. "hāt"
data.pastsg = {pref .. "hēt", pref .. "hēht"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "hāten"
return
end
local pref = rmatch(data.inf, "^(.-)lācan$")
if pref then
-- lācan "play"
data.pres23 = pref .. "lǣċ"
data.impsg = pref .. "lāc"
data.pastsg = {pref .. "lēc", pref .. "leolc"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "lācen"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)sċ(e?ā)dan$")
if not pref then
pref, vowel = rmatch(data.inf, "^(.-)sċ(ēa)dan$")
end
if pref then
-- sċ(e)ādan or sċēadan "separate"
data.pres23 = pref .. "sċēad"
data.impsg = pref .. "sċ" .. vowel .. "d"
data.pastsg = {pref .. "sċēd", pref .. "sċēad"}
data.pastpl = data.pastsg
data.pp = pref .. "sċ" .. vowel .. "den"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)lǣtan$")
if pref then
-- lǣtan "let, allow"
data.pres23 = pref .. "lǣt"
data.impsg = pref .. "lǣt"
data.pastsg = {pref .. "lēt", pref .. "leort"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "lǣten"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)ondrǣdan$")
if pref then
-- ondrǣdan "dread, fear"
data.pres23 = pref .. "ondrǣd"
data.impsg = pref .. "ondrǣd"
data.pastsg = {pref .. "ondrēd", pref .. "ondreord"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
make_weak_past(data.extraforms, pref, "ondrǣdd")
data.pp = pref .. "ondrǣden"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)rǣdan$")
if pref then
-- rǣdan "advise"
data.pres23 = pref .. "rǣd"
data.impsg = pref .. "rǣd"
-- NOTE: Also (mostly) has weak past rǣdde and pp (ġe)rǣdd; can be handled
-- by declaring the verb as both weak 1b and strong 7.
data.pastsg = {pref .. "rēd", pref .. "reord"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "rǣden"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)slǣpan$")
if pref then
-- slǣpan "sleep"
data.pres23 = pref .. "slǣp"
data.impsg = pref .. "slǣp"
data.pastsg = pref .. "slēp"
data.pastpl = data.pastsg
make_weak_past(data.extraforms, pref, "slǣpt")
data.pp = pref .. "slǣpen"
return
end
local pref, main = rmatch(data.inf, "^(.-)(gr[ǣē]t)an$")
if pref then
-- grǣtan "wail"
data.pres23 = pref .. main
data.impsg = pref .. main
data.pastsg = pref .. "grēt"
data.pastpl = data.pastsg
data.pp = pref .. main .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)blandan$")
if pref then
-- blandan "mix"
data.pres23 = pref .. "blend"
data.impsg = pref .. "bland"
data.pastsg = pref .. "blēnd"
data.pastpl = data.pastsg
data.pp = pref .. "blanden"
return
end
local pref = rmatch(data.inf, "^(.-)ōn$")
if pref then
-- fōn "seize", hōn "hang"
data.contracted = true
data.pres23 = pref .. "ēh"
data.impsg = pref .. "ōh"
data.pastsg = pref .. "ēng"
data.pastpl = data.pastsg
data.pp = {pref .. "angen"}
return
end
-- Type (7b) verbs
local pref = rmatch(data.inf, "^(.-)annan$")
if pref then
-- bannan "summon", spannan "join, clasp"
data.pres23 = pref .. "enn"
data.impsg = pref .. "ann"
data.pastsg = {pref .. "ēonn", pref .. "ēon"}
data.pastpl = data.pastsg
data.pp = pref .. "annen"
return
end
local pref = rmatch(data.inf, "^(.-)gangan$")
if pref then
-- gangan "go"
data.pres23 = pref .. "geng"
data.impsg = pref .. "gang"
data.pastsg = {pref .. "ġēng", pref .. "ġīeng"}
data.pastpl = data.pastsg
data.pp = pref .. "gangen"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ea(" .. cons_c .. "+)an$")
if pref then
-- fealdan "fold", feallan "fall", healdan "hold", stealdan "possess",
-- wealcan "roll", wealdan "rule", weallan "boil", weaxan "grow"
data.pres23 = pref .. "ie" .. palatalize_final_cons(suf)
data.impsg = pref .. "ea" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ea" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ā(" .. cons_c .. "+)an$")
if pref then
-- blāwan "blow", cnāwan "know", crāwan "crow", māwan "mow", sāwan "sow",
-- swāpan "sweep", þrāwan "turn, twist", wāwan "blow"
data.pres23 = pref .. "ǣ" .. palatalize_final_cons(suf)
data.impsg = pref .. "ā" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ā" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ēa(" .. cons_c .. "+)an$")
if pref then
-- bēatan "beat", āhnēapan "pluck off", hēawan "hew", hlēapan "leap"
data.pres23 = pref .. "īe" .. palatalize_final_cons(suf)
data.impsg = pref .. "ēa" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ēa" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ō(" .. cons_c .. "+)an$")
if pref then
if suf == "g" and pref:find("sw$") then
-- swōgan "sound"
data.pres23 = pref .. "ēġ"
data.impsg = pref .. "ōg"
data.pastsg = {} -- no preterite
data.pastpl = {}
data.pp = pref .. "ōgen"
return
end
if suf == "c" and pref:find("fl$") or suf == "t" and rfind(pref, "[wƿ]r$") then
-- flōcan "clap, strike", wrōtan "root up"
data.pres23 = pref .. "ē" .. palatalize_final_cons(suf)
data.impsg = pref .. "ō" .. suf
data.pastsg = {} -- no preterite
data.pastpl = {}
data.pp = pref .. "ō" .. suf .. "en"
return
end
-- blōtan "sacrifice", blōwan "bloom, blossom", hrōpan "shout",
-- hwōpan "threaten", flōwan "flow", grōwan "grow", hlōwan "low, bellow",
-- spōwan "succeed"; also rōwan "row", which has alt pret pl rēon
data.pres23 = pref .. "ē" .. palatalize_final_cons(suf)
data.impsg = pref .. "ō" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ō" .. suf .. "en"
if (suf == "w" or suf == "ƿ") and pref:find("r$") and not pref:find("gr$") then
-- rōwan "row"
data.extraforms["pl_past_indc"] = {pref .. "ēon"}
end
return
end
local pref = rmatch(data.inf, "^(.-[wƿ])ēpan$")
if pref then
-- wēpan "weep"; j-present
data.jpres = true
data.pres23 = pref .. "ēp"
data.impsg = pref .. "ēp"
data.pastsg = pref .. "ēop"
data.pastpl = data.pastsg
data.pp = pref .. "ōpen"
return
end
end
local weak_verbs = {}
weak_verbs["1a"] = function(data)
data.stem_weight = "light"
local pref = rmatch(data.inf, "^(.-)ian$")
if pref then
data.pres23 = pref .. "e"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
local pref, last_cons = rmatch(data.inf, "^(.-)([dt])%2an$")
if pref then
data.pres23 = pref .. last_cons
data.impsg = data.pres23 .. "e"
data.past = data.pres23 .. last_cons
data.pp = {data.pres23 .. "ed", data.past, data.pres23}
return
end
local pref = rmatch(data.inf, "^(.-)ċġe?an$")
if pref then
data.pres23 = pref .. "ġ"
data.impsg = data.pres23 .. "e"
data.past = data.pres23 .. "d"
data.pp = {data.pres23 .. "ed", data.past}
return
end
local pref = rmatch(data.inf, "^(.-)bban$")
if pref then
-- swebban etc.
data.pres23 = pref .. "fe"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
local pref, last_cons = rmatch(data.inf, "^(.-)(.)%2an$")
if not pref then
pref, last_cons = rmatch(data.inf, "^(.-)(ċ)ċean$")
end
if pref then
data.pres23 = pref .. last_cons .. "e"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
end
weak_verbs["1b"] = function(data)
data.stem_weight = "heavy"
local pref, cons = rmatch(data.inf, "^(.-[rl])([wƿ])an$")
if pref then
-- ġierwan, hierwan, nierwan, sierwan, smierwan, wielwan (?)
data.pres23 = pref .. "e"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = {pref .. cons .. "ed", pref .. "ed"}
return
end
local pref = rmatch(data.inf, "^(.-" .. cons_c .. "[rlmnwƿ])an$")
if pref and not pref:find("[rl][mn]$") and not pref:find("rl$") and not rfind(pref, "(" .. cons_c .. ")%1$") then
-- hyngran, dīeglan, bīecnan, þrysman, etc.
data.pres23 = pref .. "e"
data.impsg = data.pres23
local vowel = rmatch(pref, "^.-(" .. vowel_c .. "+)" .. single_cons_c .. "[rlmnwƿ]$")
if vowel and not ends_in_long_vowel(vowel) then
-- efnan, bytlan, eġlan, ræfnan, seġlan, þrysman; form without -ed is older
data.past = {pref .. "d", pref .. "ed"}
else
-- dīeglan, forglendran, wrixlan, frēfran, timbran, symblan, etc.
data.past = pref .. "ed"
end
data.pp = pref .. "ed"
return
end
if data.inf:find("ēan$") or rfind(data.inf, vowel_c .. "n$") and not data.inf:find("an$") then
-- contracted verb, e.g. hēan, þēon, tȳn, rȳn, þȳn
-- FIXME, verify in Campbell that all of the following are correct
data.pres23 = data.presa
data.impsg = data.presa
data.past = data.presa .. "d"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)an$")
if pref then
data.pres23 = {pref .. "e", pref}
data.impsg = pref
data.past = construct_cons_stem_ending(pref, "d")
data.pp = pref .. "ed"
return
end
end
weak_verbs["1"] = function(data)
local weaktype
if data.inf:find("ian$") then
weaktype = "1a"
elseif rfind(data.inf, "(" .. cons_c .. ")%1an$") or data.inf:find("ċċean$") or data.inf:find("cgan$") or data.inf:find("ċġan$") then
local prev = rmatch(data.inf, "^(.-)....$")
if rfind(prev, vowel_c .. "$") and not ends_in_long_vowel(prev) then
weaktype = "1a"
else
weaktype = "1b"
end
else
weaktype = "1b"
end
weak_verbs[weaktype](data)
end
weak_verbs["2"] = function(data)
-- lufian
local pref, suf = rmatch(data.inf, "^(.-)(ian)$")
if not pref then
-- lufiġan, lufeġan, lufiġean, lufeġean (alternative spellings)
pref, suf = rmatch(data.inf, "^(.-)([ei]ġe?an)$")
end
if pref then
data.pres23 = pref .. "a"
data.presenfin = data.prese
data.presefin = suf == "ian" and pref .. "iġe" or data.presenfin
data.impsg = data.pres23
data.past = pref .. "od"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)ġe?an$")
if pref then
-- twēoġan, smēaġ(e)an
data.pres23 = pref
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
end
weak_verbs["3"] = function(data)
local pref = rmatch(data.inf, "^(.-)abban$")
if pref then
data.prese = pref .. "æbbe"
data.pres23 = pref .. "æf"
data.impsg = pref .. "afa"
data.past = pref .. "æfd"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)libban$")
if pref then
-- libban, compounds
data.pres23 = pref .. "leofa"
data.impsg = data.pres23
data.past = pref .. "lifd"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)seċġe?an$")
if pref then
-- seċġan, compounds
data.pres23 = pref .. "sæġ"
data.impsg = pref .. "sæġe"
data.past = pref .. "sæġd"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)hyċġe?an$")
if pref then
-- hyċġan, compounds
data.pres23 = pref .. "hyġ"
data.impsg = pref .. "hyġe"
data.past = pref .. "hogd"
data.pp = data.past
return
end
end
local function make_irregular_non_past(args, inf, pref, pres1, pres2, pres3, prespl,
presp, subj, impsg, imppl, pp, with_ge)
add_ending(args, "infinitive", inf, "")
add_ending_with_prefix(args, "infinitive2", pref, presp, "ne")
add_ending_with_prefix(args, "1sg_pres_indc", pref, pres1, "")
add_ending_with_prefix(args, "2sg_pres_indc", pref, pres2, "")
add_ending_with_prefix(args, "3sg_pres_indc", pref, pres3, "")
add_ending_with_prefix(args, "pl_pres_indc", pref, prespl, "")
add_ending_with_prefix(args, "sg_pres_subj", pref, subj, "")
add_ending_with_prefix(args, "pl_pres_subj", pref, subj, "n")
add_ending_with_prefix(args, "sg_impr", pref, impsg, "")
add_ending_with_prefix(args, "pl_impr", pref, imppl, "")
add_ending_with_prefix(args, "pres_ptc", pref, presp, "de")
if with_ge then
add_ending_with_prefix(args, "past_ptc", pref, pp, "", construct_optional_ge_stem_ending)
else
add_ending_with_prefix(args, "past_ptc", pref, pp, "")
end
end
-- Construct all preterite-present forms. Each of the arguments can be a single string or list.
-- If a given argument is missing, supply an empty list {}.
-- Arguments:
-- INF: Infinitive.
-- PREF: Prefix to add to all forms other than the infinitive.
-- PRES13: 1st/3rd singular present form.
-- PRES2: 2nd singular present form.
-- PRESPL: Plural present form.
-- PRESP: Present participle stem (up through -en, missing final -de; also used to construct
-- second infinitive by adding -ne)
-- SUBJ: Singular present subjunctive form (also used to construct plural subjunctive by adding -n)
-- IMPSG: 2nd singular imperative form.
-- IMPPL: 2nd plural imperative form.
-- PAST: Stem of past tense.
-- PP: Past participle.
local function make_preterite_present_forms(inf, pref, pres13, pres2, prespl,
presp, subj, impsg, imppl, past, pp, with_ge)
local args = {}
make_irregular_non_past(args, inf, pref, pres13, pres2, pres13, prespl, presp, subj,
impsg, imppl, pp, with_ge)
make_weak_past(args, pref, past)
return args
end
local function make_preterite_present(inf, with_ge)
local pref, vowel = rmatch(inf, "^(.-[wƿn])([iy])[oe]?tan$")
if pref then
return make_preterite_present_forms(
inf, pref, "āt", "āst", vowel .. "ton", vowel .. "ten",
vowel .. "te", vowel .. "te", vowel .. "taþ", {vowel .. "ss", vowel .. "st"},
vowel .. "ten", with_ge)
end
local pref = rmatch(inf, "^(.-)dugan$")
if pref then
return make_preterite_present_forms(
inf, pref, "dēag", "dēaht", "dugon", "dugen", "dyġe", "dyġe", "dugaþ", "doht", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)cunnan$")
if pref then
return make_preterite_present_forms(
inf, pref, "cann", "canst", "cunnon", "cunnen", "cunne",
"cunne", "cunnaþ", "cūþ", "cunnen", with_ge)
end
local pref = rmatch(inf, "^(.-)unnan$")
if pref then
return make_preterite_present_forms(
inf, pref, "ann", "anst", "unnon", "unnen", "unne", "unne", "unnaþ", "ūþ", "unnen", with_ge)
end
local pref = rmatch(inf, "^(.-[þð])urfan$")
if pref then
return make_preterite_present_forms(
inf, pref, "earf", "earft", "urfon", "earfen", "yrfe", "yrfe", "urfaþ", "orft", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)durran$")
if pref then
return make_preterite_present_forms(
inf, pref, "dearr", "dearst", "durron", {}, "dyrre", "dyrre", "durfaþ",
"dorst", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)sċulan$")
if not pref then
pref = rmatch(inf, "^(.-)sċeolan$")
end
if pref then
return make_preterite_present_forms(
inf, pref, "sċeal", "sċealt", "sċulon", {}, "sċyle",
{}, {}, "sċeold", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)munan$")
if pref then
return make_preterite_present_forms(
inf, pref, "man", "manst", "munon", "munen", "myne",
{"mun", "myne"}, "munaþ", "mund", "munen", with_ge)
end
local pref = rmatch(inf, "^(.-)magan$")
if pref then
return make_preterite_present_forms(
inf, pref, "mæġ", "meaht", "magon", "magen", "mæġe", {}, {},
{"meaht", "meht"}, {}, with_ge)
end
local pref = rmatch(inf, "^(.-)nugan$")
if pref then
return make_preterite_present_forms(
inf, pref, "neah", {}, "nugon", {}, "nuge", {}, {}, "noht", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)mōtan$")
if pref then
return make_preterite_present_forms(
inf, pref, "mōt", "mōst", "mōton", {}, "mōte", {}, {}, "mōst", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)āgan$")
if pref then
return make_preterite_present_forms(
inf, pref, "āh", "āhst", "āgon", "āgen", "āge", "āge", "āgaþ", "āht", "āgen", with_ge)
end
error("Unrecognized preterite-present verb: " .. inf)
end
local function make_irregular(inf, with_ge)
local args = {}
local pref, cons = rmatch(inf, "^(.-)([wƿ])esan$")
if pref then
make_irregular_non_past(args, inf, pref, "eom", "eart", "is", {"sind", "sindon"},
cons .. "esen", "sīe", cons .. "es", cons .. "esaþ", {}, with_ge)
make_strong_past(args, pref, cons .. "æs", cons .. "ǣr")
return args
end
local pref = rmatch(inf, "^(.-)nesan$")
if pref then
make_irregular_non_past(args, inf, pref, "neom", "neart", "nis", {"ne sind", "ne sindon"},
"nesen", "ne sīe", "nes", "nesaþ", {}, with_ge)
make_strong_past(args, pref, "næs", "nǣr")
return args
end
local pref, vowel = rmatch(inf, "^(.-)b([īē]o)n$")
if pref then
make_irregular_non_past(args, inf, pref, "b" .. vowel, "bist", "biþ", "b" .. vowel .. "þ",
"b" .. vowel .. "n", "b" .. vowel, "b" .. vowel, "b" .. vowel .. "þ", "b" .. vowel .. "n", with_ge)
return args
end
local pref = rmatch(inf, "^(.-)dōn$")
if pref then
make_irregular_non_past(args, inf, pref, "dō", "dēst", "dēþ", "dōþ", "dōn",
"dō", "dō", "dōþ", "dōn", with_ge)
make_weak_past(args, pref, "dyd")
return args
end
local pref = rmatch(inf, "^(.-)gān$")
if pref then
make_irregular_non_past(args, inf, pref, "gā", "gǣst", "gǣþ", "gāþ", "gān",
"gā", "gā", "gāþ", "gān", with_ge)
make_weak_past(args, pref, "ēod")
return args
end
local pref = rmatch(inf, "^(.-[wƿ])illan$")
if pref then
make_irregular_non_past(args, inf, pref, "ille", "ilt", "ile", "illaþ", "illen",
"ille", {}, {}, {}, with_ge)
make_weak_past(args, pref, "old")
return args
end
local pref, vowel = rmatch(inf, "^(.-)n([eiy])llan$")
if pref then
make_irregular_non_past(args, inf, pref, "n" .. vowel .. "lle", "n" .. vowel .. "lt",
"n" .. vowel .. "le", "n" .. vowel .. "llaþ",
"n" .. vowel .. "llen", "n" .. vowel .. "lle",
{}, {}, {}, with_ge)
make_weak_past(args, pref, "nold")
return args
end
error("Unrecognized irregular verb: " .. inf)
end
local function set_categories(typ, class, jpres, stem_weight, contracted)
local cats = {}
local classtext = class and "class " .. class .. " " or ""
if typ == "strong" then
insert(cats, "Old English " .. classtext .. "strong verbs")
if jpres then
insert(cats, "Old English " .. classtext .. "strong j-present verbs")
elseif contracted then
insert(cats, "Old English " .. classtext .. "strong contracted verbs")
end
elseif typ == "weak" then
insert(cats, "Old English " .. classtext .. "weak verbs")
if jpres then
insert(cats, "Old English " .. classtext .. "weak j-present verbs")
elseif stem_weight then
insert(cats, "Old English " .. classtext .. "weak " .. stem_weight .. "-stem verbs")
end
elseif typ == "pretpres" then
insert(cats, "Old English preterite-present verbs")
elseif typ == "irreg" or typ == "anomalous" then
insert(cats, "Old English irregular verbs")
elseif typ then
error("Unrecognized verb type: " .. typ)
end
return cats
end
function export.show(frame)
local parent_args = frame:getParent().args
local params = {
[1] = {required = true, list = true, default = "beran<s4>"},
}
for slot, _ in pairs(slots_and_accel) do
params[slot] = {}
end
local args = require("Module:parameters").process(parent_args, params)
local allforms
local allcats = {}
if #args[1] > 1 then
insert(allcats, "Old English verbs with multiple conjugations")
end
for _, infspec in ipairs(args[1]) do
local inf, spec = rmatch(infspec, "^(.-)<(.*)>$")
if not inf then
error("Verb spec should look like e.g. 'beran<s4>' or 'dēman<w1>': " .. infspec)
end
local specs = rsplit(spec, "/")
local class = specs[1]
local verner = rfind(class, "v")
class = gsub(class, "v", "")
local presa = gsub(inf, "n$", "")
data = {
inf = inf,
presa = presa,
prese = presa:find("ēa$") and presa or gsub(presa, "e?a$", "e"),
verner = verner,
with_ge = not begins_with_verbal_prefix(inf),
extraforms = {},
}
local typ
if class:find("^s") then
typ = "strong"
class = gsub(class, "^s", "")
if strong_verbs[class] then
strong_verbs[class](data)
else
error("Unrecognized strong class: " .. class)
end
elseif class:find("^w") then
typ = "weak"
class = gsub(class, "^w", "")
if weak_verbs[class] then
weak_verbs[class](data)
data.presenfin = data.presenfin or data.prese
data.presefin = data.presefin or data.prese
else
error("Unrecognized weak class: " .. class)
end
elseif class == "pp" then
typ = "pretpres"
elseif class == "i" then
typ = "irreg"
else
error("Unrecognized verb class: " .. class)
end
local overrides = {}
for i, spec in ipairs(specs) do
if i > 1 then
local parts = rsplit(spec, ":")
if #parts ~= 2 then
error("Verb modified spec must be of the form 'KEY:VALUE': " .. spec)
end
local k = parts[1]
local v = parts[2]
local splitv = rsplit(v, ", *")
local unrecognized = false
if slots_and_accel[k] then
overrides[k] = splitv
elseif k == "ge" then
data.with_ge = require("Module:yesno")(v)
elseif k == "impers" then
data.impers = require("Module:yesno")(v)
elseif typ == "weak" or typ == "strong" then
if k == "pres" then
data.presa = splitv
data.prese = splitv
data.presefin = splitv
data.presenfin = splitv
data.pres23 = splitv
data.impsg = splitv
elseif k == "pres1456" then
data.presa = splitv
data.prese = splitv
data.presefin = splitv
data.presenfin = splitv
elseif k == "pres23" then
data.pres23 = splitv
elseif k == "presa" then
data.presa = splitv
elseif k == "prese" then
data.prese = splitv
data.presefin = splitv
data.presenfin = splitv
elseif typ == "weak" and k == "presefin" then
data.presefin = splitv
elseif typ == "weak" and k == "presenfin" then
data.presenfin = splitv
elseif k == "past" then
data.past = splitv
data.pastsg = splitv
data.pastpl = splitv
elseif typ == "strong" and k == "pastsg" then
data.pastsg = splitv
elseif typ == "strong" and k == "pastpl" then
data.pastpl = splitv
elseif k == "impsg" then
data.impsg = splitv
elseif k == "pp" then
data.pp = splitv
elseif typ == "weak" and k == "papp" then
data.past = splitv
data.pp = splitv
else
unrecognized = true
end
else
unrecognized = true
end
if unrecognized then
error("Unrecognized spec key '" .. k .. "' (value '" .. v .. "')")
end
end
end
if typ == "weak" or typ == "strong" then
local missing_fields = {}
local fields_to_check =
typ == "weak" and {"presa", "presefin", "presenfin", "pres23", "impsg", "past", "pp"} or
{"presa", "prese", "pres23", "impsg", "pastsg", "pastpl", "pp"}
for _, field in ipairs(fields_to_check) do
if not data[field] then
insert(missing_fields, field)
end
end
if #missing_fields > 0 then
error("Required spec(s) " .. concat(missing_fields, ",") ..
" missing, i.e. the form of the infinitive '" .. inf ..
"' was not recognized as a " .. typ .. " class-" .. class .. " verb and the " ..
"overriding specs weren't (all) supplied")
end
end
local forms
if typ == "strong" then
forms = make_strong(data.presa, data.prese, data.pres23, data.impsg, data.pastsg,
data.pastpl, data.pp, data.with_ge)
elseif typ == "weak" then
forms = make_weak(data.presa, data.presefin, data.presenfin,
data.pres23, data.impsg, data.past, data.pp, data.with_ge)
elseif typ == "pretpres" then
forms = make_preterite_present(inf, data.with_ge)
elseif typ == "irreg" then
forms = make_irregular(inf, data.with_ge)
else
error("Internal error: Unrecognized verb type: " .. typ)
end
for k, v in pairs(data.extraforms) do
add_form_to_slot(forms, k, v)
end
for k, v in pairs(overrides) do
forms[k] = v
end
if data.impers then
-- e.g. mǣtan; clear personal non-3sg forms
forms["1sg_pres_indc"] = {}
forms["2sg_pres_indc"] = {}
forms["pl_pres_indc"] = {}
forms["pl_pres_subj"] = {}
forms["1sg_past_indc"] = {}
forms["2sg_past_indc"] = {}
forms["pl_past_indc"] = {}
forms["pl_past_subj"] = {}
forms["sg_impr"] = {}
forms["pl_impr"] = {}
end
class = rsub(class, "[a-z]", "")
if class == "" then
class = nil
end
if not allforms then
allforms = forms
allforms["type"] = typ
allforms["class"] = class
else
for k, v in pairs(forms) do
for _, form in ipairs(v) do
m_table.insertIfNot(allforms[k], form)
end
end
end
local cats = set_categories(typ, class, data.jpres, data.stem_weight, data.contracted)
for _, cat in ipairs(cats) do
m_table.insertIfNot(allcats, cat)
end
end
local table = make_table(allforms)
return table .. m_utilities.format_categories(allcats, lang)
end
return export
fs99da3yoj2u28wy612vsp23l2shh1s
55169
55166
2026-10-02T21:57:30Z
Deadend0914
7211
55169
Scribunto
text/plain
local m_links = require("Module:links")
local m_utilities = require("Module:utilities")
local strutils = require("Module:string utilities")
local m_table = require("Module:table")
local com = require("Module:ang-common")
local lang = require("Module:languages").getByCode("ang")
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rsplit = mw.text.split
local rsubn = mw.ustring.gsub
local insert = table.insert
local concat = table.concat
-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar, n)
local retval = rsubn(term, foo, bar, n)
return retval
end
-- like str:gsub() but discards all but the first return value
local function gsub(term, foo, bar, n)
local retval = term:gsub(foo, bar, n)
return retval
end
local function track(page)
require("Module:debug").track("ang-verb/" .. page)
return true
end
local export = {}
local long_vowel = "āēīōūȳǣ" .. com.MACRON -- No precomposed œ + macron
local short_vowel = "aeiouyæœ"
local short_vowel_c = "[" .. short_vowel .. "]"
local vowel = long_vowel .. short_vowel
local vowel_c = "[" .. vowel .. "]"
local long_vowel_c = "[" .. long_vowel .. "]"
local non_vowel_c = "[^" .. vowel .. "]"
local always_unvoiced_cons = "cċkptxz"
local always_unvoiced_cons_c = "[" .. always_unvoiced_cons .. "]"
local unvoiced_cons = always_unvoiced_cons .. "fsþð"
local unvoiced_cons_c = "[" .. unvoiced_cons .. "]"
local single_cons = "bcċdfgġhklmnprstwþðƿ"
local single_cons_c = "[" .. single_cons .. "]"
local cons = single_cons .. "xz"
local cons_c = "[" .. cons .. "]"
local slots_and_accel = {
["infinitive"] = "inf",
["infinitive2"] = "inflected|inf",
["1sg_pres_indc"] = "1|s|pres|ind",
["2sg_pres_indc"] = "2|s|pres|ind",
["3sg_pres_indc"] = "3|s|pres|ind",
["pl_pres_indc"] = "p|pres|ind",
["sg_pres_subj"] = "s|pres|sub",
["pl_pres_subj"] = "p|pres|sub",
["1sg_past_indc"] = "1|s|pret|ind",
["2sg_past_indc"] = "2|s|pret|ind",
["3sg_past_indc"] = "3|s|pret|ind",
["pl_past_indc"] = "p|pret|ind",
["sg_past_subj"] = "s|pret|sub",
["pl_past_subj"] = "p|pret|sub",
["sg_impr"] = "s|imp",
["pl_impr"] = "p|imp",
["pres_ptc"] = "pres|part",
["past_ptc"] = "past|part",
}
local function ends_in_long_vowel(word)
if rfind(word, long_vowel_c .. "$") then
return true
elseif rfind(word, "ē[ao]$") then
return true
elseif rfind(word, "ī[eo]$") then
return true
else
return false
end
end
local function begins_with_verbal_prefix(word)
word = com.decompose(word)
for _, prefixspec in ipairs(com.prefixes) do
local prefix = prefixspec[1]
local specs = prefixspec[2]
if specs.verb then
local main = rmatch(word, "^" .. prefix .. "(.-)$")
if main and (not specs.restriction or rfind(main, specs.restriction)) then
return true
end
end
end
return false
end
local function make_table(forms)
local title = forms.title
local accel_lemma = m_links.remove_links(forms.infinitive[1] or mw.loadData("Module:headword/data").pagename)
local function typetext()
local typ = forms["type"]
local class = (forms["class"] and tonumber(forms["class"])) or nil
local id
if typ == "strong" then
local class_roman = {"I", "II", "III", "IV", "V", "VI", "VII"}
class = class_roman[class]
id = (class and "Class_" .. class) or "Strong_verbs"
return "[[Appendix:Old English verbs#Strong_verbs|strang]]" .. (class and ", " .. "[[Appendix:Old English verbs#" .. id .. "|class " .. class .. "]]" or "")
elseif typ == "weak" then
id = (class and class>=1 and class<=3 and "Class_" .. class) or "Weak_verbs"
return "[[Appendix:Old English verbs#Weak_verbs|unstrang]]" .. (class and ", " .. "[[Appendix:Old English verbs#" .. id .. "|class " .. class .. "]]" or "")
elseif typ == "pretpres" then
return "[[Appendix:Old English verbs#Preterite-present_verbs|forþgewiten-anweard]]"
elseif typ == "irreg" or typ == "anomalous" then
return "[[Appendix:Old English verbs#Anomalous_verbs|ungemǣne]]"
else
error("Unrecognized verb type: " .. typ)
end
end
if not title then
title = "Fēgung of " .. m_links.full_link({lang = lang, alt = accel_lemma}, "word")
if forms["type"] then
title = title .. " (" .. typetext() .. ")"
end
end
local table_args = {
title = title,
style = forms.style == "right" and "float:right; clear:right;" or "",
width = forms.width or "30",
}
for slot, accel_form in pairs(slots_and_accel) do
local table_arg = {}
local slotforms = forms[slot] and #forms[slot] > 0 and forms[slot] or {"—"}
for _, form in ipairs(slotforms) do
insert(table_arg, form == "—" and form or m_links.full_link{
lang = lang, term = form, accel = {
form = accel_form ~= "" and accel_form or nil,
lemma = accel_lemma,
}
})
table_args[slot] = concat(table_arg, ", ")
end
end
local table = [=[
<div class="NavFrame" style="{style}max-width:{width}em">
<div class="NavHead" style="background: var(--wikt-palette-grey-blue-1,#EFF7FF)" >{title}
</div>
<div class="NavContent">
{\op}| style="background:var(--wikt-palette-grey-0,#F9F9F9);text-align:center;width:100%" class="inflection-table"
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | infinitive
| {infinitive}
| {infinitive2}
|-
! style="font-size:80%;" | bēacniendlīc
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | present tense
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | past tense
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | forma hād ānfealdlic
| {1sg_pres_indc}
| {1sg_past_indc}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | ōþer hād ānfealdlic
| {2sg_pres_indc}
| {2sg_past_indc}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | þridda hād ānfealdlic
| {3sg_pres_indc}
| {3sg_past_indc}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | manigfealdlic
| {pl_pres_indc}
| {pl_past_indc}
|-
! style="font-size:80%;" | underþēodendlic
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | andweardnes tīd
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | forþgewiten tīd
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | ānfealdlic
| {sg_pres_subj}
| {sg_past_subj}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | manigfealdlic
| {pl_pres_subj}
| {pl_past_subj}
|-
! style="font-size:80%;" | bebēodendlic
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" colspan="2" |
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | ānfealdlic
| colspan="2" | {sg_impr}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | manigfealdlic
| colspan="2" | {pl_impr}
|-
! style="font-size:80%;" | dǣlnimend
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | andweardnes
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | forþgewiten
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" |
| {pres_ptc}
| {past_ptc}
|{\cl}</div></div>]=]
return strutils.format(table, table_args)
end
function export.make_table(frame)
local parent_args = frame:getParent().args
local params = {
["title"] = {default = "—"},
["type"] = {},
["width"] = {},
["style"] = {},
}
for slot, _ in pairs(slots_and_accel) do
params[slot] = {}
end
local args = require("Module:parameters").process(parent_args, params)
return make_table(args)
end
local function vernerize_cons(suf, verner)
if not verner then
return suf
end
local first_cons, cons = rmatch(suf, "^(.*)([sþðh])$")
if not first_cons then
return suf
end
if cons == "s" then
cons = "r"
elseif cons == "þ" or cons == "ð" then
cons = "d"
elseif cons == "h" then
cons = "g"
else
error("Internal error in vernerize_cons(): Unexpected suffix " .. suf)
end
return first_cons .. cons
end
local function depalatalize_final_cons_before_cons(word)
if word:find("sċ$") then
return word
elseif word:find("nċġ$") then
-- crinċġan etc.
return gsub(word, "nċġ$", "ng")
else
return rsub(word, "([nċġ]?[ċġ])$", {
["ċ"] = "c",
["nċ"] = "nc",
["ċċ"] = "cc",
["ġċ"] = "ġc",
["nġ"] = "ng",
["ċġ"] = "cg",
-- ġ and ġġ stay as-is
})
end
end
local function depalatalize_final_cons_before_back_vowel(word)
local word = depalatalize_final_cons_before_cons(word)
return gsub(word, "ġ$", "g")
end
local function palatalize_final_cons(word)
return rsub(word, "([cg]?[cg])$", {
["c"] = "ċ",
["cc"] = "ċċ",
["cg"] = "ċġ",
["g"] = "ġ",
["gc"] = "gċ", -- ??
["gg"] = "ċġ",
})
end
-- Add an ending that begins with a consonant onto a stem, making adjustments
-- as necessary when two consonants come together. Currently recognizes only
-- the three endings "st", "þ" and "d".
local function construct_cons_stem_ending(stem, ending)
-- If the stem ends in a geminate, reduce to single consonant
-- (e.g. fyll-, sett-).
local origstem = stem
local base, final_geminated = rmatch(stem, "^(.-)(" .. non_vowel_c .. ")%2$")
if base then
stem = base .. final_geminated
end
stem = depalatalize_final_cons_before_cons(stem)
if ending == "st" then
-- For 2sg:
-- cyssan + -st -> cyst, tǣsan + -st -> tǣst
-- settan + -st -> setst, myntan + -st -> myn(t)st (?), restan + -st -> restst/rest (?)
-- bǣdan + -st -> bǣtst, sendan + -st -> sen(t)st
-- cȳþan + -st -> cȳst, cwiþ- + -st -> cwist
-- wiex- + -st -> wiext
-- drenċan + -st -> drencst
-- senġan + -st -> sengst
if stem:find("s$") then
return stem .. "t"
elseif stem:find("[dt]$") then
if rfind(stem, vowel_c .. "[dt]$") then
return gsub(stem, "[dt]$", "tst")
elseif rfind(stem, "s[dt]$") then
return gsub(stem, "s[dt]$", "st")
else
return {gsub(stem, "[dt]$", "st"), gsub(stem, "[dt]$", "tst")}
end
elseif rfind(stem, "[þð]$") then
return rsub(stem, "[þð]$", "st")
elseif stem:find("x$") then
return stem .. "t"
else
return stem .. "st"
end
elseif ending == "þ" then
-- For 3sg:
-- cyssan + -þ -> cyst, tǣsan + -þ -> tǣst
-- settan + -þ -> set(t), myntan + -þ -> mynt, restan + -þ -> rest
-- bǣdan + -þ -> bǣt(t), sendan + -þ -> sent
-- cȳþan + -þ -> cȳþ(þ), cwiþ- + -þ -> cwiþ(þ)
-- wiex- + -þ -> wiext
-- drenċan + -þ -> drencþ
-- senġan + -þ -> sengþ
if rfind(stem, vowel_c .. "[dt]$") then
return {gsub(stem, "[dt]$", "tt"), gsub(stem, "[dt]$", "t")}
elseif stem:find("[dt]$") then
return gsub(stem, "[dt]$", "t")
elseif stem:find("[sx]$") then
return stem .. "t"
elseif rfind(stem, "[þð]$") then
return {rsub(stem, "[þð]$", "þþ"), stem}
else
return stem .. "þ"
end
elseif ending == "d" then
-- For past:
-- cyssan + -de -> cyste, tǣsan + -de -> tǣsde
-- settan + -de -> sette, myntan + -de -> mynte, restan + -de -> reste, mētan + -de -> mētte
-- bǣdan + -de -> bǣdde, sendan + -de -> sende, hreddan + -de -> hredde
-- cȳþan + -de -> cȳþde (later cȳdde), ġeorwirþan + -de -> ġeorwirþde, sċeþþan + -de -> sċeþte
-- (? Bosworth-Toller has only sċeþede, and has pæþde for *pæþte from pæþþan)
-- līexan + -de -> līexte
-- pyffan + -de -> pyfte, ġelīefan + -de -> ġelīefde
-- drenċan + -de -> drencte
-- senġan + -de -> sengde
-- cīepan + -de -> cīepte, clyppan + -de -> clypte
-- spillan + -de -> spilde, cierran + -de -> cierde, wemman + -de -> wemde, etc.
if rfind(stem, vowel_c .. "t$") then
return stem .. "t"
elseif rfind(stem, vowel_c .. "d$") then
return stem .. "d"
elseif stem:find("[dt]$") then
return stem
elseif rfind(stem, always_unvoiced_cons_c .. "$") or rfind(origstem, unvoiced_cons_c .. "[sfþð]$") then
return stem .. "t"
else
return stem .. "d"
end
else
error("Unrecognized ending: '" .. ending .. "'")
end
end
-- Default function for combining a stem and an ending. This makes no adjustments
-- to the result other than returning an optional variant ending in -h if the result
-- ends in -g. Example: stīgan preterite stāg or stāh. (Does not apply to a form
-- ending in -ġ.) If adjustments are necessary at the stem/ending boundary, use e.g.
-- construct_cons_stem_ending.
local function default_construct_stem_ending(stem, ending)
local form = stem .. ending
if form:find("g$") and not form:find("[ncg]g$") then
return {form, gsub(form, "g$", "h")}
else
return form
end
end
local function add_form_to_slot(args, slot, form)
if not args[slot] then
args[slot] = {}
end
if type(form) == "string" then
m_table.insertIfNot(args[slot], form)
else
for _, f in ipairs(form) do
m_table.insertIfNot(args[slot], f)
end
end
end
local function add_ending_with_prefix(args, slot, pref, stems, ending, construct_stem_ending)
construct_stem_ending = construct_stem_ending or default_construct_stem_ending
if type(stems) ~= "table" then
stems = {stems}
end
for _, stem in ipairs(stems) do
local form = construct_stem_ending(pref and pref .. stem or stem, ending)
add_form_to_slot(args, slot, form)
end
end
local function add_ending(args, slot, stems, ending, construct_stem_ending)
add_ending_with_prefix(args, slot, nil, stems, ending, construct_stem_ending)
end
local function construct_optional_ge_stem_ending(stem, ending)
return "([[ge" .. stem .. ending .. "|ġe]])[[" .. stem .. ending .. "]]"
end
local function make_non_past(args, presa, presefin, presenfin, pres23, impsg, pp, with_ge)
add_ending(args, "infinitive", presa, "n")
add_ending(args, "infinitive2", presenfin, "nne")
add_ending(args, "1sg_pres_indc", presefin, "")
add_ending(args, "2sg_pres_indc", pres23, "st", construct_cons_stem_ending)
add_ending(args, "3sg_pres_indc", pres23, "þ", construct_cons_stem_ending)
add_ending(args, "pl_pres_indc", presa, "þ")
add_ending(args, "sg_pres_subj", presefin, "")
add_ending(args, "pl_pres_subj", presefin, "n")
add_ending(args, "sg_impr", impsg, "")
add_ending(args, "pl_impr", presa, "þ")
add_ending(args, "pres_ptc", presenfin, "nde")
if with_ge then
add_ending(args, "past_ptc", pp, "", construct_optional_ge_stem_ending)
else
add_ending(args, "past_ptc", pp, "")
end
end
local function make_strong_past(args, pref, pastsg, pastpl)
add_ending_with_prefix(args, "1sg_past_indc", pref, pastsg, "")
add_ending_with_prefix(args, "2sg_past_indc", pref, pastpl, "e")
add_ending_with_prefix(args, "3sg_past_indc", pref, pastsg, "")
add_ending_with_prefix(args, "pl_past_indc", pref, pastpl, "on")
add_ending_with_prefix(args, "sg_past_subj", pref, pastpl, "e")
add_ending_with_prefix(args, "pl_past_subj", pref, pastpl, "en")
end
local function make_strong(presa, prese, pres23, impsg, pastsg, pastpl, pp, with_ge)
local args = {}
make_non_past(args, presa, prese, prese, pres23, impsg, pp, with_ge)
make_strong_past(args, nil, pastsg, pastpl)
return args
end
local function make_weak_past(args, pref, past)
add_ending_with_prefix(args, "1sg_past_indc", pref, past, "e")
add_ending_with_prefix(args, "2sg_past_indc", pref, past, "est")
add_ending_with_prefix(args, "3sg_past_indc", pref, past, "e")
add_ending_with_prefix(args, "pl_past_indc", pref, past, "on")
add_ending_with_prefix(args, "sg_past_subj", pref, past, "e")
add_ending_with_prefix(args, "pl_past_subj", pref, past, "en")
end
local function make_weak(presa, presefin, presenfin, pres23, impsg, past, pp, with_ge)
local args = {}
make_non_past(args, presa, presefin, presenfin, pres23, impsg, pp, with_ge)
make_weak_past(args, nil, past)
return args
end
local strong_verbs = {}
strong_verbs["1"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ī(" .. cons_c .. "+)an$")
if pref then
-- bīdan "await", ācwīnan "dwindle away", sċīnan "shine", spīwan "spew, spit", etc.;
-- stīgan "ascend" (þū stīġst, stāg/stāh [handled by default_construct_stem_ending],
-- stigon, stiġen); blīcan "shine" (þū blīcst/blīċest)
data.pres23 = pref .. "ī" .. palatalize_final_cons(suf)
if suf == "g" then
data.impsg = pref .. "īġ"
else
data.impsg = pref .. "ī" .. suf
end
-- ġīnan "yawn" (gān, ġinon, ġinen)
data.pastsg = depalatalize_final_cons_before_back_vowel(pref) .. "ā" .. suf
-- snīþan "cut" -> snidon; sċrīþan "go, proceed" -> sċridon
-- (but not mīþan "avoid", wrīþan "twist")
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pref .. "i" .. pastsuf
if pastsuf == "g" then
data.pp = pref .. "iġen"
else
data.pp = data.pastpl .. "en"
end
return
end
pref = rmatch(data.inf, "^(.-)[ēī]on$")
if pref then
-- tēon/tīon "accuse" < *tīhanan, similarly lēon "lend" < *līhwanan,
-- sēon "strain" < *sīhwanan, þēon "thrive" < *þinhanan (originally strong 3),
-- wrēon < *wrīhanan. Beware of homonyms e.g. tēon "pull, draw" (strong 2) < *teuhanan,
-- tēon "make, create" (weak) ?< *tīhanan (strong);
-- þēon/þēowan/þȳ(g)(a)n "press" (weak) < *þunhijanan;
-- sēon "see" (strong 5) < *sehwanan
data.contracted = true
data.pres23 = pref .. "īeh"
data.impsg = gsub(data.inf, "n$", "h")
data.pastsg = pref .. "āh"
if rfind(pref, "[þð]$") then
-- þēon "thrive", has remnant strong 3 parts
data.pastpl = {pref .. "ig", pref .. "ung"}
data.pp = {pref .. "iġen", pref .. "ungen"}
else
data.pastpl = pref .. "ig"
if pref:find("s$") then
-- sēon "strain" alt past part siwen
data.pp = {pref .. "iġen", pref .. "iwen"}
else
data.pp = pref .. "iġen"
end
end
return
end
end
strong_verbs["2"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ēo(" .. cons_c .. "+)an$")
if pref then
-- bēodan "command", crēopan "creep"; rēocan "smoke, reek" (þū rīecst/rīeċest);
-- drēogan "endure" (þū drīeġst, drēag/drēah [handled by default_construct_stem_ending],
-- drugon, drogen)
data.pres23 = pref .. "īe" .. palatalize_final_cons(suf)
data.impsg = pref .. "ēo" .. suf
data.pastsg = pref .. "ēa" .. suf
-- ġēotan "pour" (ġēat, guton, goten); ċēosan "choose" (ċēas, curon, coren)
local pastpref = depalatalize_final_cons_before_back_vowel(pref)
-- ċēosan "choose" -> curon; forlēosan "lose" -> forluron; sēoþan "boil" -> sudon
-- (but not ābrēoþan "perish, ruin")
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pastpref .. "u" .. pastsuf
data.pp = pastpref .. "o" .. pastsuf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ū(" .. cons_c .. "+)an$")
if pref then
-- sċūfan "shove"; brūcan "use" (þū brīecst/brīeċest);
-- būgan "bend" (þū bīeġst, bēag/bēah [handled by default_construct_stem_ending],
-- bugon, bogen)
data.pres23 = pref .. "ȳ" .. palatalize_final_cons(suf)
data.impsg = pref .. "ū" .. suf
-- could have palatalization here, but no known examples
data.pastsg = pref .. "ēa" .. suf
-- no known examples of Vernerization, but just in case
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pref .. "u" .. pastsuf
data.pp = pref .. "o" .. pastsuf .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)ēon$")
if pref then
-- tēon "pull, draw" < *teuhanan, flēon "flee"
-- Beware of homonyms, e.g. tēon/tīon "accuse" (strong 1) < *tīhanan,
-- tēon "make, create" (weak) ?< *tīhan (strong)
data.contracted = true
data.pres23 = pref .. "īeh"
data.impsg = gsub(data.inf, "n$", "h")
data.pastsg = pref .. "ēah"
-- no examples where depalatalization is needed
data.pastpl = pref .. "ug"
data.pp = pref .. "ogen"
return
end
end
strong_verbs["3"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)i([mn]" .. cons_c .. "+)an$")
if pref then
-- bindan "bind", climban "climb", ġelimpan "happen", winnan "win",
-- swimman "swim", etc.; ācwincan "vanish" (þū ācwincst/ācwinċest);
-- cringan (þū cringst/crinġest), variant crinċġan (þū cringst/crinċġest)
data.pres23 = pref .. "i" .. palatalize_final_cons(suf)
data.impsg = pref .. "i" .. suf
-- onġinnan "begin" (ongann, ongunnon, ongunnen), ċimban "join"
local pastpref = depalatalize_final_cons_before_back_vowel(pref)
-- no Verner alternation here; expected #fīþan, #fōþ, #fundon <
-- *finþanan, *fanþ, *fundund regularized into findan, fand, fundon;
-- but depalatalize to handle crin(ċ)ġan past crang/crungon/crungen
-- and (maybe?) variant crinċan past cranc/cruncon/cruncen
local pastsuf = depalatalize_final_cons_before_cons(suf)
data.pastsg = pastpref .. "a" .. pastsuf
data.pastpl = pastpref .. "u" .. pastsuf
data.pp = pastpref .. "u" .. pastsuf .. "en"
return
end
local pref, vowel, suf = rmatch(data.inf, "^(.-)(ie)(l" .. cons_c .. "+)an$")
if not pref then
-- ġeldan/ġildan/ġyldan variants of ġieldan; helpan/bellan/delfan etc.
pref, vowel, suf = rmatch(data.inf, "^(.-)([eiy])(l" .. cons_c .. "+)an$")
end
if not pref then
pref, vowel, suf = rmatch(data.inf, "^(.-)(eo)(" .. cons_c .. "+)an$")
end
if pref then
-- helpan "help" (þū hilpst), bellan "bellow", beteldan "cover", delfan "dig",
-- sweltan "die", etc.; belgan "swell with anger" (þū bielġst, bealg/bealh
-- [handled by default_construct_stem_ending])
--
-- ġieldan "yield, pay" (þū ġiel(t)st, hē ġieldeþ/ġielt, ġeald, guldon, golden),
-- ġiellan "yell", ġielpan "boast"
--
-- weorpan "throw" (þū wierpst), feohtan "fight", sċeorfan "gnaw";
-- āseolcan "languish" (þū āsielcst/āsielċest), beorgan "protect"
-- (þū bierġst, bearg/bearh [handled by default_construct_stem_ending])
data.pres23 = pref .. (vowel == "e" and "i" or vowel == "eo" and "ie" or vowel) .. palatalize_final_cons(suf)
data.impsg = pref .. vowel .. suf
data.pastsg = pref .. "ea" .. suf
-- ġieldan etc. (see above)
local pastpref = depalatalize_final_cons_before_back_vowel(pref)
-- weorþan -> wurdon
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pastpref .. "u" .. pastsuf
data.pp = pastpref .. "o" .. pastsuf .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)eġdan$")
if pref then
-- breġdan "brandish" (þū breġdest, hē breġdeþ, bræġd/brǣd, brugdon, brogden)
-- streġdan "strew" (like breġdan)
data.pres23 = pref .. "eġde"
data.impsg = pref .. "eġd"
data.pastsg = {pref .. "æġd", pref .. "ǣd"}
data.pastpl = pref .. "ugd"
data.pp = pref .. "ogden"
return
end
local pref, suf = rmatch(data.inf, "^(.-)(ie?rn)an$")
if not pref then
pref, suf = rmatch(data.inf, "^(.-)(yrn)an$")
end
if pref then
-- biernan/birnan/byrnan "burn" < *brinnanan (þū biernst, barn/born/bearn, burnon, burnen)
-- iernan/irnan/yrnan "run" < *rinnan (like biernan)
data.pres23 = pref .. suf
data.impsg = data.pres23
data.pastsg = {pref .. "arn", pref .. "orn", pref .. "earn"}
data.pastpl = pref .. "urn"
data.pp = pref .. "urnen"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)([ou])rnan$")
if pref then
-- murnan "mourn" (þū myrnst, mearn, murnon, — but BT documents mornen)
-- spurnan/spornan "spurn" (þū spyrnst, spearn, spurnon, spornen)
data.pres23 = pref .. "yrn"
data.impsg = pref .. vowel .. "rn"
data.pastsg = pref .. "earn"
data.pastpl = pref .. "urn"
data.pp = pref .. "ornen"
return
end
local pref, suf = rmatch(data.inf, "^(.-)e(r" .. cons_c .. "+)an$")
if pref then
-- berstan "burst" < *brestanan (þū birst, hē birsteþ/birst, bærst, burston, borsten)
-- þersċan "thrash, thresh" < *þreskanan (þū þirsċst, hē þirsċeþ, þærsċ, þursċon, þorsċen)
data.pres23 = pref .. "i" .. suf
data.impsg = pref .. "e" .. suf
data.pastsg = pref .. "æ" .. suf
data.pastpl = pref .. "u" .. suf
data.pp = pref .. "o" .. suf .. "en"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)fr([ei])ġnan$")
if pref then
-- friġnan "ask", variant freġnan
data.pres23 = {pref .. "friġne", pref .. "friġn"}
data.impsg = pref .. "fr" .. vowel .. "ġn"
data.pastsg = pref .. "fræġn"
data.pastpl = pref .. "frugn"
data.pp = pref .. "frugnen"
return
end
local pref = rmatch(data.inf, "^(.-)frīnan$")
if pref then
-- frīnan "ask" variant of friġnan
data.pres23 = {pref .. "frīne", pref .. "frīn"}
data.impsg = pref .. "frīn"
data.pastsg = pref .. "frān"
data.pastpl = pref .. "frūn"
data.pp = pref .. "frūnen"
return
end
local pref = rmatch(data.inf, "^(.-)fēolan$")
if pref then
-- fēolan "enter, penetrate"
data.pres23 = {pref .. "fielh", pref .. "filh"}
data.impsg = pref .. "feolh"
data.pastsg = pref .. "fealh"
data.pastpl = {pref .. "fǣl", pref .. "fulg", pref .. "fūl"}
data.pp = {pref .. "folgen", pref .. "fōlen"}
return
end
end
strong_verbs["4"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ie(" .. cons_c .. ")an$")
if pref then
-- sċieran "shear"
data.pres23 = {pref .. "ie" .. suf .. "e", pref .. "ie" .. suf}
data.impsg = pref .. "ie" .. suf
-- no Verner alternation or depalatalization here
data.pastsg = pref .. "ea" .. suf
data.pastpl = pref .. "ēa" .. suf
data.pp = pref .. "o" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)e(" .. cons_c .. ")an$")
if pref then
-- beran "bear, carry", cwelan "die", brecan "break" (þū bricst/briċest), etc.
if suf == "r" or suf == "l" then
data.pres23 = {pref .. "i" .. suf .. "e", pref .. "i" .. suf}
else
data.pres23 = pref .. "i" .. palatalize_final_cons(suf)
end
data.impsg = pref .. "e" .. suf
-- no Verner alternation or depalatalization here
data.pastsg = pref .. "æ" .. suf
data.pastpl = pref .. "ǣ" .. suf
data.pp = pref .. "o" .. suf .. "en"
return
end
-- Next two are irregular but occur with so many prefixes that we special-case them here.
local pref = rmatch(data.inf, "^(.-)cuman$")
if pref then
-- cuman "come"
data.pres23 = {pref .. "cyme", pref .. "cym"}
data.impsg = pref .. "cum"
data.pastsg = {pref .. "cōm", pref .. "cwōm"}
data.pastpl = data.pastsg
data.pp = {pref .. "cumen", pref .. "cymen"}
return
end
local pref = rmatch(data.inf, "^(.-)niman$")
if pref then
-- niman "take"
data.pres23 = {pref .. "nime", pref .. "nim"}
data.impsg = pref .. "nim"
data.pastsg = pref .. "nōm"
data.pastpl = data.pastsg
data.pp = pref .. "numen"
return
end
end
strong_verbs["5"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ie(" .. cons_c .. ")an$")
if not pref then
pref, suf = rmatch(data.inf, "^(.-ġ)[eiy](" .. cons_c .. ")an$")
end
if pref then
-- ġiefan "give", forġietan "forget"
data.pres23 = pref .. "ie" .. suf
data.impsg = data.pres23
data.pastsg = pref .. "ea" .. suf
data.pastpl = pref .. "ēa" .. suf
data.pp = pref .. "e" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)e(" .. cons_c .. ")an$")
if suf == "g" then
-- wegan "carry"; special-case
data.pres23 = pref .. "iġ"
data.impsg = pref .. "eġ"
data.pastsg = pref .. "æġ"
data.pastpl = {pref .. "ǣg", pref .. "āg"}
data.pp = pref .. "eġen"
return
elseif pref then
-- metan "measure", sprecan "speak", cnedan "knead", wefan "weave", etc.
data.pres23 = pref .. "i" .. palatalize_final_cons(suf)
data.impsg = pref .. "e" .. suf
if suf == "t" and not pref:find("m$") and not pref:find("ġ$") then
-- etan "eat", fretan "devour", compounds; exclude metan "measure",
-- ġetan (potential variant of ġietan)
data.pastsg = pref .. "ǣ" .. suf
else
data.pastsg = pref .. "æ" .. suf
end
-- cweþan "say" -> cwǣdon, wesan "be" -> wǣron
-- (but not ġenesan "be saved", lesan "collect, gather")
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pref .. "ǣ" .. pastsuf
if data.inf:find("drepan$") then
-- Special-case drepan "strike, slay"; Wright lists brecan here with
-- pp only brocen, but that just makes it a strong-4 verb and that's
-- where it's normally listed in dictionaries
data.pp = {pref .. "epen", pref .. "open"}
else
data.pp = pref .. "e" .. pastsuf .. "en"
end
return
end
local pref, last_cons = rmatch(data.inf, "^(.-)i([dt])%2an$")
if pref then
-- biddan "pray", sittan "sit"
data.jpres = true
data.pres23 = pref .. "i" .. last_cons
data.impsg = data.pres23 .. "e"
data.pastsg = pref .. "æ" .. last_cons
data.pastpl = pref .. "ǣ" .. last_cons
data.pp = pref .. "e" .. last_cons .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)iċġe?an$")
if pref then
-- liċġan "lie down", þiċġan "receive", friċġan "ask, inquire"
data.jpres = true
data.pres23 = pref .. "iġ"
data.impsg = data.pres23 .. "e"
if rfind(data.inf, "[þð]iċġe?an$") then
data.pastsg = {pref .. "eah", pref .. "ah"}
else
data.pastsg = pref .. "æġ"
end
data.pastpl = {pref .. "ǣg", pref .. "āg"}
if data.inf:find("friċġe?an$") then
data.pp = {pref .. "iġen", pref .. "ugen"}
else
data.pp = pref .. "eġen"
end
return
end
local pref = rmatch(data.inf, "^(.-)ēon$")
if pref then
-- sēon "see" < *sehwanan, ġefēon "rejoice" < *gafehanan, plēon "risk" < *plehanan
data.contracted = true
data.pres23 = pref .. "ieh"
data.impsg = pref .. "eoh"
data.pastsg = pref .. "eah"
if pref:find("s$") then
-- sēon "see"
data.pastpl = pref .. "āw"
data.pp = pref .. "ewen"
else
data.pastpl = pref .. "ǣg"
data.pp = pref .. "eġen"
end
return
end
end
strong_verbs["6"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ea(" .. cons_c .. "+)an$")
if pref then
-- sċ(e)acan "shake", sċ(e)afan "shave, scrape"
data.pres23 = pref .. "ea" .. suf
data.impsg = {pref .. "a" .. suf, data.pres23}
data.pastsg = {pref .. "ō" .. suf, pref .. "eō" .. suf}
data.pastpl = data.pastsg
data.pp = {pref .. "a" .. suf .. "en", pref .. "ea" .. suf .. "en"}
return
end
local pref, vowel, suf = rmatch(data.inf, "^(.-)(a)(" .. cons_c .. "+)an$")
if not pref then
-- stondan variant of standan, sponan variant of spanan
pref, vowel, suf = rmatch(data.inf, "^(.-)(o)(n" .. cons_c .. "*)an$")
end
if not pref then
-- wæsċan/wasċean/wæsċean variant of wasċan
pref, vowel, suf = rmatch(data.inf, "^(.-)([aæ])(sċ" .. cons_c .. "*)e?an$")
end
if suf == "g" then
-- gnagan "gnaw", dragan "draw"
data.pres23 = pref .. "æġ"
data.impsg = pref .. "ag"
data.pastsg = pref .. "ōg"
data.pastpl = data.pastsg
data.pp = {pref .. "æġen", pref .. "agen"}
return
elseif suf == "nd" and pref:find("st$") then
-- standan/stondan "stand"
data.pres23 = pref .. "end"
data.impsg = pref .. vowel .. "nd"
data.pastsg = pref .. "ōd"
data.pastpl = data.pastsg
data.pp = pref .. vowel .. "nden"
return
elseif suf == "n" and pref:find("sp$") then
-- spanon/sponan "allure"
data.pres23 = {pref .. "ene", pref .. "en"}
data.impsg = pref .. vowel .. "n"
data.pastsg = {pref .. "ōn", pref .. "ēon"} -- has alt class VII past
data.pastpl = data.pastsg
data.pp = pref .. vowel .. "nen"
return
elseif pref then
-- faran "go", alan "grow", bacan "bake", hladan "lade", wasċan "wash", etc.
if suf == "r" or suf == "l" or suf == "sċ" then
data.pres23 = {pref .. "æ" .. suf .. "e", pref .. "æ" .. suf}
else
data.pres23 = pref .. "æ" .. palatalize_final_cons(suf)
end
data.impsg = pref .. "a" .. suf
data.pastsg = pref .. "ō" .. suf
-- Apparently no Verner variation here
data.pastpl = data.pastsg
data.pp = {pref .. "æ" .. suf .. "en", pref .. "a" .. suf .. "en"}
return
end
local pref = rmatch(data.inf, "^(.-)ēan$")
if pref then
-- slēan "strike", flēan "flay", lēan "blame", þwēan "wash"
data.contracted = true
data.pres23 = pref .. "ieh"
data.impsg = pref .. "eah"
data.pastsg = pref .. "ōg" -- also slōh etc., which will get automatically added
data.pastpl = data.pastsg
data.pp = {pref .. "æġen", pref .. "agen", pref .. "eġen"}
return
end
-- All the j-present verbs have to be handled individually as each has
-- idiosyncrasies.
local pref, last_cons = rmatch(data.inf, "^(.-)hebban$")
if pref then
-- hebban "raise"
data.jpres = true
data.pres23 = pref .. "hefe"
data.impsg = data.pres23
data.pastsg = pref .. "hōf"
data.pastpl = data.pastsg
data.pp = {pref .. "hæfen", pref .. "hafen", pref .. "hefen"}
return
end
local pref, vowel = rmatch(data.inf, "^(.-)hl([iy]?e?)hhan$")
if pref then
-- hliehhan "laugh"
data.jpres = true
data.pres23 = pref .. "hl" .. vowel .. "h"
data.impsg = data.pres23
data.pastsg = pref .. "hlōg"
data.pastpl = data.pastsg
data.pp = pref .. "hlæġen"
return
end
local pref, cons = rmatch(data.inf, "^(.-)sċe([þð])%2an$")
if pref then
-- sċeþþan "injure" (for some reason, expected #sċieþþan doesn't occur)
data.jpres = true
data.pres23 = pref .. "sċe" .. cons .. "e"
data.impsg = data.pres23
data.pastsg = "sċōd"
data.pastpl = data.pastsg
data.pp = "sċeaþen"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)sċ([iy]?e?)ppan$")
if pref then
-- sċieppan "create"
data.jpres = true
data.pres23 = pref .. "sċ" .. vowel .. "pe"
data.impsg = data.pres23
data.pastsg = {pref .. "sċōp", pref .. "sċeōp"}
data.pastpl = data.pastsg
data.pp = {pref .. "sċeapen", pref .. "sċapen"}
return
end
local pref, vowel = rmatch(data.inf, "^(.-)st([æe])ppan$")
if pref then
-- stæppan "step, go"
data.jpres = true
data.pres23 = pref .. "st" .. vowel .. "pe"
data.impsg = data.pres23
data.pastsg = pref .. "stōp"
data.pastpl = data.pastsg
data.pp = {pref .. "stæpen", pref .. "stapen"}
return
end
local pref = rmatch(data.inf, "^(.-s[wƿ])erian$")
if pref then
-- swerian "swear"
data.jpres = true
data.pres23 = pref .. "ere"
data.impsg = data.pres23
data.pastsg = pref .. "ōr"
data.pastpl = data.pastsg
data.pp = pref .. "oren" -- on the analogy of class IV verbs like beran
return
end
end
strong_verbs["7"] = function(data)
-- Type (7a) verbs
local pref = rmatch(data.inf, "^(.-)hātan$")
if pref then
-- hātan "call"
data.pres23 = pref .. "hǣt"
data.impsg = pref .. "hāt"
data.pastsg = {pref .. "hēt", pref .. "hēht"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "hāten"
return
end
local pref = rmatch(data.inf, "^(.-)lācan$")
if pref then
-- lācan "play"
data.pres23 = pref .. "lǣċ"
data.impsg = pref .. "lāc"
data.pastsg = {pref .. "lēc", pref .. "leolc"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "lācen"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)sċ(e?ā)dan$")
if not pref then
pref, vowel = rmatch(data.inf, "^(.-)sċ(ēa)dan$")
end
if pref then
-- sċ(e)ādan or sċēadan "separate"
data.pres23 = pref .. "sċēad"
data.impsg = pref .. "sċ" .. vowel .. "d"
data.pastsg = {pref .. "sċēd", pref .. "sċēad"}
data.pastpl = data.pastsg
data.pp = pref .. "sċ" .. vowel .. "den"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)lǣtan$")
if pref then
-- lǣtan "let, allow"
data.pres23 = pref .. "lǣt"
data.impsg = pref .. "lǣt"
data.pastsg = {pref .. "lēt", pref .. "leort"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "lǣten"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)ondrǣdan$")
if pref then
-- ondrǣdan "dread, fear"
data.pres23 = pref .. "ondrǣd"
data.impsg = pref .. "ondrǣd"
data.pastsg = {pref .. "ondrēd", pref .. "ondreord"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
make_weak_past(data.extraforms, pref, "ondrǣdd")
data.pp = pref .. "ondrǣden"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)rǣdan$")
if pref then
-- rǣdan "advise"
data.pres23 = pref .. "rǣd"
data.impsg = pref .. "rǣd"
-- NOTE: Also (mostly) has weak past rǣdde and pp (ġe)rǣdd; can be handled
-- by declaring the verb as both weak 1b and strong 7.
data.pastsg = {pref .. "rēd", pref .. "reord"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "rǣden"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)slǣpan$")
if pref then
-- slǣpan "sleep"
data.pres23 = pref .. "slǣp"
data.impsg = pref .. "slǣp"
data.pastsg = pref .. "slēp"
data.pastpl = data.pastsg
make_weak_past(data.extraforms, pref, "slǣpt")
data.pp = pref .. "slǣpen"
return
end
local pref, main = rmatch(data.inf, "^(.-)(gr[ǣē]t)an$")
if pref then
-- grǣtan "wail"
data.pres23 = pref .. main
data.impsg = pref .. main
data.pastsg = pref .. "grēt"
data.pastpl = data.pastsg
data.pp = pref .. main .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)blandan$")
if pref then
-- blandan "mix"
data.pres23 = pref .. "blend"
data.impsg = pref .. "bland"
data.pastsg = pref .. "blēnd"
data.pastpl = data.pastsg
data.pp = pref .. "blanden"
return
end
local pref = rmatch(data.inf, "^(.-)ōn$")
if pref then
-- fōn "seize", hōn "hang"
data.contracted = true
data.pres23 = pref .. "ēh"
data.impsg = pref .. "ōh"
data.pastsg = pref .. "ēng"
data.pastpl = data.pastsg
data.pp = {pref .. "angen"}
return
end
-- Type (7b) verbs
local pref = rmatch(data.inf, "^(.-)annan$")
if pref then
-- bannan "summon", spannan "join, clasp"
data.pres23 = pref .. "enn"
data.impsg = pref .. "ann"
data.pastsg = {pref .. "ēonn", pref .. "ēon"}
data.pastpl = data.pastsg
data.pp = pref .. "annen"
return
end
local pref = rmatch(data.inf, "^(.-)gangan$")
if pref then
-- gangan "go"
data.pres23 = pref .. "geng"
data.impsg = pref .. "gang"
data.pastsg = {pref .. "ġēng", pref .. "ġīeng"}
data.pastpl = data.pastsg
data.pp = pref .. "gangen"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ea(" .. cons_c .. "+)an$")
if pref then
-- fealdan "fold", feallan "fall", healdan "hold", stealdan "possess",
-- wealcan "roll", wealdan "rule", weallan "boil", weaxan "grow"
data.pres23 = pref .. "ie" .. palatalize_final_cons(suf)
data.impsg = pref .. "ea" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ea" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ā(" .. cons_c .. "+)an$")
if pref then
-- blāwan "blow", cnāwan "know", crāwan "crow", māwan "mow", sāwan "sow",
-- swāpan "sweep", þrāwan "turn, twist", wāwan "blow"
data.pres23 = pref .. "ǣ" .. palatalize_final_cons(suf)
data.impsg = pref .. "ā" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ā" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ēa(" .. cons_c .. "+)an$")
if pref then
-- bēatan "beat", āhnēapan "pluck off", hēawan "hew", hlēapan "leap"
data.pres23 = pref .. "īe" .. palatalize_final_cons(suf)
data.impsg = pref .. "ēa" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ēa" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ō(" .. cons_c .. "+)an$")
if pref then
if suf == "g" and pref:find("sw$") then
-- swōgan "sound"
data.pres23 = pref .. "ēġ"
data.impsg = pref .. "ōg"
data.pastsg = {} -- no preterite
data.pastpl = {}
data.pp = pref .. "ōgen"
return
end
if suf == "c" and pref:find("fl$") or suf == "t" and rfind(pref, "[wƿ]r$") then
-- flōcan "clap, strike", wrōtan "root up"
data.pres23 = pref .. "ē" .. palatalize_final_cons(suf)
data.impsg = pref .. "ō" .. suf
data.pastsg = {} -- no preterite
data.pastpl = {}
data.pp = pref .. "ō" .. suf .. "en"
return
end
-- blōtan "sacrifice", blōwan "bloom, blossom", hrōpan "shout",
-- hwōpan "threaten", flōwan "flow", grōwan "grow", hlōwan "low, bellow",
-- spōwan "succeed"; also rōwan "row", which has alt pret pl rēon
data.pres23 = pref .. "ē" .. palatalize_final_cons(suf)
data.impsg = pref .. "ō" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ō" .. suf .. "en"
if (suf == "w" or suf == "ƿ") and pref:find("r$") and not pref:find("gr$") then
-- rōwan "row"
data.extraforms["pl_past_indc"] = {pref .. "ēon"}
end
return
end
local pref = rmatch(data.inf, "^(.-[wƿ])ēpan$")
if pref then
-- wēpan "weep"; j-present
data.jpres = true
data.pres23 = pref .. "ēp"
data.impsg = pref .. "ēp"
data.pastsg = pref .. "ēop"
data.pastpl = data.pastsg
data.pp = pref .. "ōpen"
return
end
end
local weak_verbs = {}
weak_verbs["1a"] = function(data)
data.stem_weight = "light"
local pref = rmatch(data.inf, "^(.-)ian$")
if pref then
data.pres23 = pref .. "e"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
local pref, last_cons = rmatch(data.inf, "^(.-)([dt])%2an$")
if pref then
data.pres23 = pref .. last_cons
data.impsg = data.pres23 .. "e"
data.past = data.pres23 .. last_cons
data.pp = {data.pres23 .. "ed", data.past, data.pres23}
return
end
local pref = rmatch(data.inf, "^(.-)ċġe?an$")
if pref then
data.pres23 = pref .. "ġ"
data.impsg = data.pres23 .. "e"
data.past = data.pres23 .. "d"
data.pp = {data.pres23 .. "ed", data.past}
return
end
local pref = rmatch(data.inf, "^(.-)bban$")
if pref then
-- swebban etc.
data.pres23 = pref .. "fe"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
local pref, last_cons = rmatch(data.inf, "^(.-)(.)%2an$")
if not pref then
pref, last_cons = rmatch(data.inf, "^(.-)(ċ)ċean$")
end
if pref then
data.pres23 = pref .. last_cons .. "e"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
end
weak_verbs["1b"] = function(data)
data.stem_weight = "heavy"
local pref, cons = rmatch(data.inf, "^(.-[rl])([wƿ])an$")
if pref then
-- ġierwan, hierwan, nierwan, sierwan, smierwan, wielwan (?)
data.pres23 = pref .. "e"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = {pref .. cons .. "ed", pref .. "ed"}
return
end
local pref = rmatch(data.inf, "^(.-" .. cons_c .. "[rlmnwƿ])an$")
if pref and not pref:find("[rl][mn]$") and not pref:find("rl$") and not rfind(pref, "(" .. cons_c .. ")%1$") then
-- hyngran, dīeglan, bīecnan, þrysman, etc.
data.pres23 = pref .. "e"
data.impsg = data.pres23
local vowel = rmatch(pref, "^.-(" .. vowel_c .. "+)" .. single_cons_c .. "[rlmnwƿ]$")
if vowel and not ends_in_long_vowel(vowel) then
-- efnan, bytlan, eġlan, ræfnan, seġlan, þrysman; form without -ed is older
data.past = {pref .. "d", pref .. "ed"}
else
-- dīeglan, forglendran, wrixlan, frēfran, timbran, symblan, etc.
data.past = pref .. "ed"
end
data.pp = pref .. "ed"
return
end
if data.inf:find("ēan$") or rfind(data.inf, vowel_c .. "n$") and not data.inf:find("an$") then
-- contracted verb, e.g. hēan, þēon, tȳn, rȳn, þȳn
-- FIXME, verify in Campbell that all of the following are correct
data.pres23 = data.presa
data.impsg = data.presa
data.past = data.presa .. "d"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)an$")
if pref then
data.pres23 = {pref .. "e", pref}
data.impsg = pref
data.past = construct_cons_stem_ending(pref, "d")
data.pp = pref .. "ed"
return
end
end
weak_verbs["1"] = function(data)
local weaktype
if data.inf:find("ian$") then
weaktype = "1a"
elseif rfind(data.inf, "(" .. cons_c .. ")%1an$") or data.inf:find("ċċean$") or data.inf:find("cgan$") or data.inf:find("ċġan$") then
local prev = rmatch(data.inf, "^(.-)....$")
if rfind(prev, vowel_c .. "$") and not ends_in_long_vowel(prev) then
weaktype = "1a"
else
weaktype = "1b"
end
else
weaktype = "1b"
end
weak_verbs[weaktype](data)
end
weak_verbs["2"] = function(data)
-- lufian
local pref, suf = rmatch(data.inf, "^(.-)(ian)$")
if not pref then
-- lufiġan, lufeġan, lufiġean, lufeġean (alternative spellings)
pref, suf = rmatch(data.inf, "^(.-)([ei]ġe?an)$")
end
if pref then
data.pres23 = pref .. "a"
data.presenfin = data.prese
data.presefin = suf == "ian" and pref .. "iġe" or data.presenfin
data.impsg = data.pres23
data.past = pref .. "od"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)ġe?an$")
if pref then
-- twēoġan, smēaġ(e)an
data.pres23 = pref
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
end
weak_verbs["3"] = function(data)
local pref = rmatch(data.inf, "^(.-)abban$")
if pref then
data.prese = pref .. "æbbe"
data.pres23 = pref .. "æf"
data.impsg = pref .. "afa"
data.past = pref .. "æfd"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)libban$")
if pref then
-- libban, compounds
data.pres23 = pref .. "leofa"
data.impsg = data.pres23
data.past = pref .. "lifd"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)seċġe?an$")
if pref then
-- seċġan, compounds
data.pres23 = pref .. "sæġ"
data.impsg = pref .. "sæġe"
data.past = pref .. "sæġd"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)hyċġe?an$")
if pref then
-- hyċġan, compounds
data.pres23 = pref .. "hyġ"
data.impsg = pref .. "hyġe"
data.past = pref .. "hogd"
data.pp = data.past
return
end
end
local function make_irregular_non_past(args, inf, pref, pres1, pres2, pres3, prespl,
presp, subj, impsg, imppl, pp, with_ge)
add_ending(args, "infinitive", inf, "")
add_ending_with_prefix(args, "infinitive2", pref, presp, "ne")
add_ending_with_prefix(args, "1sg_pres_indc", pref, pres1, "")
add_ending_with_prefix(args, "2sg_pres_indc", pref, pres2, "")
add_ending_with_prefix(args, "3sg_pres_indc", pref, pres3, "")
add_ending_with_prefix(args, "pl_pres_indc", pref, prespl, "")
add_ending_with_prefix(args, "sg_pres_subj", pref, subj, "")
add_ending_with_prefix(args, "pl_pres_subj", pref, subj, "n")
add_ending_with_prefix(args, "sg_impr", pref, impsg, "")
add_ending_with_prefix(args, "pl_impr", pref, imppl, "")
add_ending_with_prefix(args, "pres_ptc", pref, presp, "de")
if with_ge then
add_ending_with_prefix(args, "past_ptc", pref, pp, "", construct_optional_ge_stem_ending)
else
add_ending_with_prefix(args, "past_ptc", pref, pp, "")
end
end
-- Construct all preterite-present forms. Each of the arguments can be a single string or list.
-- If a given argument is missing, supply an empty list {}.
-- Arguments:
-- INF: Infinitive.
-- PREF: Prefix to add to all forms other than the infinitive.
-- PRES13: 1st/3rd singular present form.
-- PRES2: 2nd singular present form.
-- PRESPL: Plural present form.
-- PRESP: Present participle stem (up through -en, missing final -de; also used to construct
-- second infinitive by adding -ne)
-- SUBJ: Singular present subjunctive form (also used to construct plural subjunctive by adding -n)
-- IMPSG: 2nd singular imperative form.
-- IMPPL: 2nd plural imperative form.
-- PAST: Stem of past tense.
-- PP: Past participle.
local function make_preterite_present_forms(inf, pref, pres13, pres2, prespl,
presp, subj, impsg, imppl, past, pp, with_ge)
local args = {}
make_irregular_non_past(args, inf, pref, pres13, pres2, pres13, prespl, presp, subj,
impsg, imppl, pp, with_ge)
make_weak_past(args, pref, past)
return args
end
local function make_preterite_present(inf, with_ge)
local pref, vowel = rmatch(inf, "^(.-[wƿn])([iy])[oe]?tan$")
if pref then
return make_preterite_present_forms(
inf, pref, "āt", "āst", vowel .. "ton", vowel .. "ten",
vowel .. "te", vowel .. "te", vowel .. "taþ", {vowel .. "ss", vowel .. "st"},
vowel .. "ten", with_ge)
end
local pref = rmatch(inf, "^(.-)dugan$")
if pref then
return make_preterite_present_forms(
inf, pref, "dēag", "dēaht", "dugon", "dugen", "dyġe", "dyġe", "dugaþ", "doht", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)cunnan$")
if pref then
return make_preterite_present_forms(
inf, pref, "cann", "canst", "cunnon", "cunnen", "cunne",
"cunne", "cunnaþ", "cūþ", "cunnen", with_ge)
end
local pref = rmatch(inf, "^(.-)unnan$")
if pref then
return make_preterite_present_forms(
inf, pref, "ann", "anst", "unnon", "unnen", "unne", "unne", "unnaþ", "ūþ", "unnen", with_ge)
end
local pref = rmatch(inf, "^(.-[þð])urfan$")
if pref then
return make_preterite_present_forms(
inf, pref, "earf", "earft", "urfon", "earfen", "yrfe", "yrfe", "urfaþ", "orft", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)durran$")
if pref then
return make_preterite_present_forms(
inf, pref, "dearr", "dearst", "durron", {}, "dyrre", "dyrre", "durfaþ",
"dorst", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)sċulan$")
if not pref then
pref = rmatch(inf, "^(.-)sċeolan$")
end
if pref then
return make_preterite_present_forms(
inf, pref, "sċeal", "sċealt", "sċulon", {}, "sċyle",
{}, {}, "sċeold", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)munan$")
if pref then
return make_preterite_present_forms(
inf, pref, "man", "manst", "munon", "munen", "myne",
{"mun", "myne"}, "munaþ", "mund", "munen", with_ge)
end
local pref = rmatch(inf, "^(.-)magan$")
if pref then
return make_preterite_present_forms(
inf, pref, "mæġ", "meaht", "magon", "magen", "mæġe", {}, {},
{"meaht", "meht"}, {}, with_ge)
end
local pref = rmatch(inf, "^(.-)nugan$")
if pref then
return make_preterite_present_forms(
inf, pref, "neah", {}, "nugon", {}, "nuge", {}, {}, "noht", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)mōtan$")
if pref then
return make_preterite_present_forms(
inf, pref, "mōt", "mōst", "mōton", {}, "mōte", {}, {}, "mōst", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)āgan$")
if pref then
return make_preterite_present_forms(
inf, pref, "āh", "āhst", "āgon", "āgen", "āge", "āge", "āgaþ", "āht", "āgen", with_ge)
end
error("Unrecognized preterite-present verb: " .. inf)
end
local function make_irregular(inf, with_ge)
local args = {}
local pref, cons = rmatch(inf, "^(.-)([wƿ])esan$")
if pref then
make_irregular_non_past(args, inf, pref, "eom", "eart", "is", {"sind", "sindon"},
cons .. "esen", "sīe", cons .. "es", cons .. "esaþ", {}, with_ge)
make_strong_past(args, pref, cons .. "æs", cons .. "ǣr")
return args
end
local pref = rmatch(inf, "^(.-)nesan$")
if pref then
make_irregular_non_past(args, inf, pref, "neom", "neart", "nis", {"ne sind", "ne sindon"},
"nesen", "ne sīe", "nes", "nesaþ", {}, with_ge)
make_strong_past(args, pref, "næs", "nǣr")
return args
end
local pref, vowel = rmatch(inf, "^(.-)b([īē]o)n$")
if pref then
make_irregular_non_past(args, inf, pref, "b" .. vowel, "bist", "biþ", "b" .. vowel .. "þ",
"b" .. vowel .. "n", "b" .. vowel, "b" .. vowel, "b" .. vowel .. "þ", "b" .. vowel .. "n", with_ge)
return args
end
local pref = rmatch(inf, "^(.-)dōn$")
if pref then
make_irregular_non_past(args, inf, pref, "dō", "dēst", "dēþ", "dōþ", "dōn",
"dō", "dō", "dōþ", "dōn", with_ge)
make_weak_past(args, pref, "dyd")
return args
end
local pref = rmatch(inf, "^(.-)gān$")
if pref then
make_irregular_non_past(args, inf, pref, "gā", "gǣst", "gǣþ", "gāþ", "gān",
"gā", "gā", "gāþ", "gān", with_ge)
make_weak_past(args, pref, "ēod")
return args
end
local pref = rmatch(inf, "^(.-[wƿ])illan$")
if pref then
make_irregular_non_past(args, inf, pref, "ille", "ilt", "ile", "illaþ", "illen",
"ille", {}, {}, {}, with_ge)
make_weak_past(args, pref, "old")
return args
end
local pref, vowel = rmatch(inf, "^(.-)n([eiy])llan$")
if pref then
make_irregular_non_past(args, inf, pref, "n" .. vowel .. "lle", "n" .. vowel .. "lt",
"n" .. vowel .. "le", "n" .. vowel .. "llaþ",
"n" .. vowel .. "llen", "n" .. vowel .. "lle",
{}, {}, {}, with_ge)
make_weak_past(args, pref, "nold")
return args
end
error("Unrecognized irregular verb: " .. inf)
end
local function set_categories(typ, class, jpres, stem_weight, contracted)
local cats = {}
local classtext = class and "class " .. class .. " " or ""
if typ == "strong" then
insert(cats, "Englisc " .. classtext .. "strang word")
if jpres then
insert(cats, "Englisc " .. classtext .. "strang j-andweard word")
elseif contracted then
insert(cats, "Englisc " .. classtext .. "strang scortod word")
end
elseif typ == "weak" then
insert(cats, "Englisc " .. classtext .. "unstrang word")
if jpres then
insert(cats, "Englisc " .. classtext .. "unstrang j-andweard word")
elseif stem_weight then
insert(cats, "Englisc " .. classtext .. "unstrang " .. stem_weight .. "-stefn word")
end
elseif typ == "pretpres" then
insert(cats, "Englisc forþgewiten-andweard word")
elseif typ == "irreg" or typ == "anomalous" then
insert(cats, "Englisc ungemǣne word")
elseif typ then
error("Unrecognized verb type: " .. typ)
end
return cats
end
function export.show(frame)
local parent_args = frame:getParent().args
local params = {
[1] = {required = true, list = true, default = "beran<s4>"},
}
for slot, _ in pairs(slots_and_accel) do
params[slot] = {}
end
local args = require("Module:parameters").process(parent_args, params)
local allforms
local allcats = {}
if #args[1] > 1 then
insert(allcats, "Old English verbs with multiple conjugations")
end
for _, infspec in ipairs(args[1]) do
local inf, spec = rmatch(infspec, "^(.-)<(.*)>$")
if not inf then
error("Verb spec should look like e.g. 'beran<s4>' or 'dēman<w1>': " .. infspec)
end
local specs = rsplit(spec, "/")
local class = specs[1]
local verner = rfind(class, "v")
class = gsub(class, "v", "")
local presa = gsub(inf, "n$", "")
data = {
inf = inf,
presa = presa,
prese = presa:find("ēa$") and presa or gsub(presa, "e?a$", "e"),
verner = verner,
with_ge = not begins_with_verbal_prefix(inf),
extraforms = {},
}
local typ
if class:find("^s") then
typ = "strong"
class = gsub(class, "^s", "")
if strong_verbs[class] then
strong_verbs[class](data)
else
error("Unrecognized strong class: " .. class)
end
elseif class:find("^w") then
typ = "weak"
class = gsub(class, "^w", "")
if weak_verbs[class] then
weak_verbs[class](data)
data.presenfin = data.presenfin or data.prese
data.presefin = data.presefin or data.prese
else
error("Unrecognized weak class: " .. class)
end
elseif class == "pp" then
typ = "pretpres"
elseif class == "i" then
typ = "irreg"
else
error("Unrecognized verb class: " .. class)
end
local overrides = {}
for i, spec in ipairs(specs) do
if i > 1 then
local parts = rsplit(spec, ":")
if #parts ~= 2 then
error("Verb modified spec must be of the form 'KEY:VALUE': " .. spec)
end
local k = parts[1]
local v = parts[2]
local splitv = rsplit(v, ", *")
local unrecognized = false
if slots_and_accel[k] then
overrides[k] = splitv
elseif k == "ge" then
data.with_ge = require("Module:yesno")(v)
elseif k == "impers" then
data.impers = require("Module:yesno")(v)
elseif typ == "weak" or typ == "strong" then
if k == "pres" then
data.presa = splitv
data.prese = splitv
data.presefin = splitv
data.presenfin = splitv
data.pres23 = splitv
data.impsg = splitv
elseif k == "pres1456" then
data.presa = splitv
data.prese = splitv
data.presefin = splitv
data.presenfin = splitv
elseif k == "pres23" then
data.pres23 = splitv
elseif k == "presa" then
data.presa = splitv
elseif k == "prese" then
data.prese = splitv
data.presefin = splitv
data.presenfin = splitv
elseif typ == "weak" and k == "presefin" then
data.presefin = splitv
elseif typ == "weak" and k == "presenfin" then
data.presenfin = splitv
elseif k == "past" then
data.past = splitv
data.pastsg = splitv
data.pastpl = splitv
elseif typ == "strong" and k == "pastsg" then
data.pastsg = splitv
elseif typ == "strong" and k == "pastpl" then
data.pastpl = splitv
elseif k == "impsg" then
data.impsg = splitv
elseif k == "pp" then
data.pp = splitv
elseif typ == "weak" and k == "papp" then
data.past = splitv
data.pp = splitv
else
unrecognized = true
end
else
unrecognized = true
end
if unrecognized then
error("Unrecognized spec key '" .. k .. "' (value '" .. v .. "')")
end
end
end
if typ == "weak" or typ == "strong" then
local missing_fields = {}
local fields_to_check =
typ == "weak" and {"presa", "presefin", "presenfin", "pres23", "impsg", "past", "pp"} or
{"presa", "prese", "pres23", "impsg", "pastsg", "pastpl", "pp"}
for _, field in ipairs(fields_to_check) do
if not data[field] then
insert(missing_fields, field)
end
end
if #missing_fields > 0 then
error("Required spec(s) " .. concat(missing_fields, ",") ..
" missing, i.e. the form of the infinitive '" .. inf ..
"' was not recognized as a " .. typ .. " class-" .. class .. " verb and the " ..
"overriding specs weren't (all) supplied")
end
end
local forms
if typ == "strong" then
forms = make_strong(data.presa, data.prese, data.pres23, data.impsg, data.pastsg,
data.pastpl, data.pp, data.with_ge)
elseif typ == "weak" then
forms = make_weak(data.presa, data.presefin, data.presenfin,
data.pres23, data.impsg, data.past, data.pp, data.with_ge)
elseif typ == "pretpres" then
forms = make_preterite_present(inf, data.with_ge)
elseif typ == "irreg" then
forms = make_irregular(inf, data.with_ge)
else
error("Internal error: Unrecognized verb type: " .. typ)
end
for k, v in pairs(data.extraforms) do
add_form_to_slot(forms, k, v)
end
for k, v in pairs(overrides) do
forms[k] = v
end
if data.impers then
-- e.g. mǣtan; clear personal non-3sg forms
forms["1sg_pres_indc"] = {}
forms["2sg_pres_indc"] = {}
forms["pl_pres_indc"] = {}
forms["pl_pres_subj"] = {}
forms["1sg_past_indc"] = {}
forms["2sg_past_indc"] = {}
forms["pl_past_indc"] = {}
forms["pl_past_subj"] = {}
forms["sg_impr"] = {}
forms["pl_impr"] = {}
end
class = rsub(class, "[a-z]", "")
if class == "" then
class = nil
end
if not allforms then
allforms = forms
allforms["type"] = typ
allforms["class"] = class
else
for k, v in pairs(forms) do
for _, form in ipairs(v) do
m_table.insertIfNot(allforms[k], form)
end
end
end
local cats = set_categories(typ, class, data.jpres, data.stem_weight, data.contracted)
for _, cat in ipairs(cats) do
m_table.insertIfNot(allcats, cat)
end
end
local table = make_table(allforms)
return table .. m_utilities.format_categories(allcats, lang)
end
return export
eqhocldhsa5nebvtvwbe8fpms7mnlov
55170
55169
2026-10-02T21:57:50Z
Deadend0914
7211
55170
Scribunto
text/plain
local m_links = require("Module:links")
local m_utilities = require("Module:utilities")
local strutils = require("Module:string utilities")
local m_table = require("Module:table")
local com = require("Module:ang-common")
local lang = require("Module:languages").getByCode("ang")
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rsplit = mw.text.split
local rsubn = mw.ustring.gsub
local insert = table.insert
local concat = table.concat
-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar, n)
local retval = rsubn(term, foo, bar, n)
return retval
end
-- like str:gsub() but discards all but the first return value
local function gsub(term, foo, bar, n)
local retval = term:gsub(foo, bar, n)
return retval
end
local function track(page)
require("Module:debug").track("ang-verb/" .. page)
return true
end
local export = {}
local long_vowel = "āēīōūȳǣ" .. com.MACRON -- No precomposed œ + macron
local short_vowel = "aeiouyæœ"
local short_vowel_c = "[" .. short_vowel .. "]"
local vowel = long_vowel .. short_vowel
local vowel_c = "[" .. vowel .. "]"
local long_vowel_c = "[" .. long_vowel .. "]"
local non_vowel_c = "[^" .. vowel .. "]"
local always_unvoiced_cons = "cċkptxz"
local always_unvoiced_cons_c = "[" .. always_unvoiced_cons .. "]"
local unvoiced_cons = always_unvoiced_cons .. "fsþð"
local unvoiced_cons_c = "[" .. unvoiced_cons .. "]"
local single_cons = "bcċdfgġhklmnprstwþðƿ"
local single_cons_c = "[" .. single_cons .. "]"
local cons = single_cons .. "xz"
local cons_c = "[" .. cons .. "]"
local slots_and_accel = {
["infinitive"] = "inf",
["infinitive2"] = "inflected|inf",
["1sg_pres_indc"] = "1|s|pres|ind",
["2sg_pres_indc"] = "2|s|pres|ind",
["3sg_pres_indc"] = "3|s|pres|ind",
["pl_pres_indc"] = "p|pres|ind",
["sg_pres_subj"] = "s|pres|sub",
["pl_pres_subj"] = "p|pres|sub",
["1sg_past_indc"] = "1|s|pret|ind",
["2sg_past_indc"] = "2|s|pret|ind",
["3sg_past_indc"] = "3|s|pret|ind",
["pl_past_indc"] = "p|pret|ind",
["sg_past_subj"] = "s|pret|sub",
["pl_past_subj"] = "p|pret|sub",
["sg_impr"] = "s|imp",
["pl_impr"] = "p|imp",
["pres_ptc"] = "pres|part",
["past_ptc"] = "past|part",
}
local function ends_in_long_vowel(word)
if rfind(word, long_vowel_c .. "$") then
return true
elseif rfind(word, "ē[ao]$") then
return true
elseif rfind(word, "ī[eo]$") then
return true
else
return false
end
end
local function begins_with_verbal_prefix(word)
word = com.decompose(word)
for _, prefixspec in ipairs(com.prefixes) do
local prefix = prefixspec[1]
local specs = prefixspec[2]
if specs.verb then
local main = rmatch(word, "^" .. prefix .. "(.-)$")
if main and (not specs.restriction or rfind(main, specs.restriction)) then
return true
end
end
end
return false
end
local function make_table(forms)
local title = forms.title
local accel_lemma = m_links.remove_links(forms.infinitive[1] or mw.loadData("Module:headword/data").pagename)
local function typetext()
local typ = forms["type"]
local class = (forms["class"] and tonumber(forms["class"])) or nil
local id
if typ == "strong" then
local class_roman = {"I", "II", "III", "IV", "V", "VI", "VII"}
class = class_roman[class]
id = (class and "Class_" .. class) or "Strong_verbs"
return "[[Appendix:Old English verbs#Strong_verbs|strang]]" .. (class and ", " .. "[[Appendix:Old English verbs#" .. id .. "|class " .. class .. "]]" or "")
elseif typ == "weak" then
id = (class and class>=1 and class<=3 and "Class_" .. class) or "Weak_verbs"
return "[[Appendix:Old English verbs#Weak_verbs|unstrang]]" .. (class and ", " .. "[[Appendix:Old English verbs#" .. id .. "|class " .. class .. "]]" or "")
elseif typ == "pretpres" then
return "[[Appendix:Old English verbs#Preterite-present_verbs|forþgewiten-anweard]]"
elseif typ == "irreg" or typ == "anomalous" then
return "[[Appendix:Old English verbs#Anomalous_verbs|ungemǣne]]"
else
error("Unrecognized verb type: " .. typ)
end
end
if not title then
title = "Fēgung of " .. m_links.full_link({lang = lang, alt = accel_lemma}, "term")
if forms["type"] then
title = title .. " (" .. typetext() .. ")"
end
end
local table_args = {
title = title,
style = forms.style == "right" and "float:right; clear:right;" or "",
width = forms.width or "30",
}
for slot, accel_form in pairs(slots_and_accel) do
local table_arg = {}
local slotforms = forms[slot] and #forms[slot] > 0 and forms[slot] or {"—"}
for _, form in ipairs(slotforms) do
insert(table_arg, form == "—" and form or m_links.full_link{
lang = lang, term = form, accel = {
form = accel_form ~= "" and accel_form or nil,
lemma = accel_lemma,
}
})
table_args[slot] = concat(table_arg, ", ")
end
end
local table = [=[
<div class="NavFrame" style="{style}max-width:{width}em">
<div class="NavHead" style="background: var(--wikt-palette-grey-blue-1,#EFF7FF)" >{title}
</div>
<div class="NavContent">
{\op}| style="background:var(--wikt-palette-grey-0,#F9F9F9);text-align:center;width:100%" class="inflection-table"
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | infinitive
| {infinitive}
| {infinitive2}
|-
! style="font-size:80%;" | bēacniendlīc
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | present tense
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | past tense
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | forma hād ānfealdlic
| {1sg_pres_indc}
| {1sg_past_indc}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | ōþer hād ānfealdlic
| {2sg_pres_indc}
| {2sg_past_indc}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | þridda hād ānfealdlic
| {3sg_pres_indc}
| {3sg_past_indc}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | manigfealdlic
| {pl_pres_indc}
| {pl_past_indc}
|-
! style="font-size:80%;" | underþēodendlic
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | andweardnes tīd
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | forþgewiten tīd
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | ānfealdlic
| {sg_pres_subj}
| {sg_past_subj}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | manigfealdlic
| {pl_pres_subj}
| {pl_past_subj}
|-
! style="font-size:80%;" | bebēodendlic
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" colspan="2" |
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | ānfealdlic
| colspan="2" | {sg_impr}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | manigfealdlic
| colspan="2" | {pl_impr}
|-
! style="font-size:80%;" | dǣlnimend
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | andweardnes
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | forþgewiten
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" |
| {pres_ptc}
| {past_ptc}
|{\cl}</div></div>]=]
return strutils.format(table, table_args)
end
function export.make_table(frame)
local parent_args = frame:getParent().args
local params = {
["title"] = {default = "—"},
["type"] = {},
["width"] = {},
["style"] = {},
}
for slot, _ in pairs(slots_and_accel) do
params[slot] = {}
end
local args = require("Module:parameters").process(parent_args, params)
return make_table(args)
end
local function vernerize_cons(suf, verner)
if not verner then
return suf
end
local first_cons, cons = rmatch(suf, "^(.*)([sþðh])$")
if not first_cons then
return suf
end
if cons == "s" then
cons = "r"
elseif cons == "þ" or cons == "ð" then
cons = "d"
elseif cons == "h" then
cons = "g"
else
error("Internal error in vernerize_cons(): Unexpected suffix " .. suf)
end
return first_cons .. cons
end
local function depalatalize_final_cons_before_cons(word)
if word:find("sċ$") then
return word
elseif word:find("nċġ$") then
-- crinċġan etc.
return gsub(word, "nċġ$", "ng")
else
return rsub(word, "([nċġ]?[ċġ])$", {
["ċ"] = "c",
["nċ"] = "nc",
["ċċ"] = "cc",
["ġċ"] = "ġc",
["nġ"] = "ng",
["ċġ"] = "cg",
-- ġ and ġġ stay as-is
})
end
end
local function depalatalize_final_cons_before_back_vowel(word)
local word = depalatalize_final_cons_before_cons(word)
return gsub(word, "ġ$", "g")
end
local function palatalize_final_cons(word)
return rsub(word, "([cg]?[cg])$", {
["c"] = "ċ",
["cc"] = "ċċ",
["cg"] = "ċġ",
["g"] = "ġ",
["gc"] = "gċ", -- ??
["gg"] = "ċġ",
})
end
-- Add an ending that begins with a consonant onto a stem, making adjustments
-- as necessary when two consonants come together. Currently recognizes only
-- the three endings "st", "þ" and "d".
local function construct_cons_stem_ending(stem, ending)
-- If the stem ends in a geminate, reduce to single consonant
-- (e.g. fyll-, sett-).
local origstem = stem
local base, final_geminated = rmatch(stem, "^(.-)(" .. non_vowel_c .. ")%2$")
if base then
stem = base .. final_geminated
end
stem = depalatalize_final_cons_before_cons(stem)
if ending == "st" then
-- For 2sg:
-- cyssan + -st -> cyst, tǣsan + -st -> tǣst
-- settan + -st -> setst, myntan + -st -> myn(t)st (?), restan + -st -> restst/rest (?)
-- bǣdan + -st -> bǣtst, sendan + -st -> sen(t)st
-- cȳþan + -st -> cȳst, cwiþ- + -st -> cwist
-- wiex- + -st -> wiext
-- drenċan + -st -> drencst
-- senġan + -st -> sengst
if stem:find("s$") then
return stem .. "t"
elseif stem:find("[dt]$") then
if rfind(stem, vowel_c .. "[dt]$") then
return gsub(stem, "[dt]$", "tst")
elseif rfind(stem, "s[dt]$") then
return gsub(stem, "s[dt]$", "st")
else
return {gsub(stem, "[dt]$", "st"), gsub(stem, "[dt]$", "tst")}
end
elseif rfind(stem, "[þð]$") then
return rsub(stem, "[þð]$", "st")
elseif stem:find("x$") then
return stem .. "t"
else
return stem .. "st"
end
elseif ending == "þ" then
-- For 3sg:
-- cyssan + -þ -> cyst, tǣsan + -þ -> tǣst
-- settan + -þ -> set(t), myntan + -þ -> mynt, restan + -þ -> rest
-- bǣdan + -þ -> bǣt(t), sendan + -þ -> sent
-- cȳþan + -þ -> cȳþ(þ), cwiþ- + -þ -> cwiþ(þ)
-- wiex- + -þ -> wiext
-- drenċan + -þ -> drencþ
-- senġan + -þ -> sengþ
if rfind(stem, vowel_c .. "[dt]$") then
return {gsub(stem, "[dt]$", "tt"), gsub(stem, "[dt]$", "t")}
elseif stem:find("[dt]$") then
return gsub(stem, "[dt]$", "t")
elseif stem:find("[sx]$") then
return stem .. "t"
elseif rfind(stem, "[þð]$") then
return {rsub(stem, "[þð]$", "þþ"), stem}
else
return stem .. "þ"
end
elseif ending == "d" then
-- For past:
-- cyssan + -de -> cyste, tǣsan + -de -> tǣsde
-- settan + -de -> sette, myntan + -de -> mynte, restan + -de -> reste, mētan + -de -> mētte
-- bǣdan + -de -> bǣdde, sendan + -de -> sende, hreddan + -de -> hredde
-- cȳþan + -de -> cȳþde (later cȳdde), ġeorwirþan + -de -> ġeorwirþde, sċeþþan + -de -> sċeþte
-- (? Bosworth-Toller has only sċeþede, and has pæþde for *pæþte from pæþþan)
-- līexan + -de -> līexte
-- pyffan + -de -> pyfte, ġelīefan + -de -> ġelīefde
-- drenċan + -de -> drencte
-- senġan + -de -> sengde
-- cīepan + -de -> cīepte, clyppan + -de -> clypte
-- spillan + -de -> spilde, cierran + -de -> cierde, wemman + -de -> wemde, etc.
if rfind(stem, vowel_c .. "t$") then
return stem .. "t"
elseif rfind(stem, vowel_c .. "d$") then
return stem .. "d"
elseif stem:find("[dt]$") then
return stem
elseif rfind(stem, always_unvoiced_cons_c .. "$") or rfind(origstem, unvoiced_cons_c .. "[sfþð]$") then
return stem .. "t"
else
return stem .. "d"
end
else
error("Unrecognized ending: '" .. ending .. "'")
end
end
-- Default function for combining a stem and an ending. This makes no adjustments
-- to the result other than returning an optional variant ending in -h if the result
-- ends in -g. Example: stīgan preterite stāg or stāh. (Does not apply to a form
-- ending in -ġ.) If adjustments are necessary at the stem/ending boundary, use e.g.
-- construct_cons_stem_ending.
local function default_construct_stem_ending(stem, ending)
local form = stem .. ending
if form:find("g$") and not form:find("[ncg]g$") then
return {form, gsub(form, "g$", "h")}
else
return form
end
end
local function add_form_to_slot(args, slot, form)
if not args[slot] then
args[slot] = {}
end
if type(form) == "string" then
m_table.insertIfNot(args[slot], form)
else
for _, f in ipairs(form) do
m_table.insertIfNot(args[slot], f)
end
end
end
local function add_ending_with_prefix(args, slot, pref, stems, ending, construct_stem_ending)
construct_stem_ending = construct_stem_ending or default_construct_stem_ending
if type(stems) ~= "table" then
stems = {stems}
end
for _, stem in ipairs(stems) do
local form = construct_stem_ending(pref and pref .. stem or stem, ending)
add_form_to_slot(args, slot, form)
end
end
local function add_ending(args, slot, stems, ending, construct_stem_ending)
add_ending_with_prefix(args, slot, nil, stems, ending, construct_stem_ending)
end
local function construct_optional_ge_stem_ending(stem, ending)
return "([[ge" .. stem .. ending .. "|ġe]])[[" .. stem .. ending .. "]]"
end
local function make_non_past(args, presa, presefin, presenfin, pres23, impsg, pp, with_ge)
add_ending(args, "infinitive", presa, "n")
add_ending(args, "infinitive2", presenfin, "nne")
add_ending(args, "1sg_pres_indc", presefin, "")
add_ending(args, "2sg_pres_indc", pres23, "st", construct_cons_stem_ending)
add_ending(args, "3sg_pres_indc", pres23, "þ", construct_cons_stem_ending)
add_ending(args, "pl_pres_indc", presa, "þ")
add_ending(args, "sg_pres_subj", presefin, "")
add_ending(args, "pl_pres_subj", presefin, "n")
add_ending(args, "sg_impr", impsg, "")
add_ending(args, "pl_impr", presa, "þ")
add_ending(args, "pres_ptc", presenfin, "nde")
if with_ge then
add_ending(args, "past_ptc", pp, "", construct_optional_ge_stem_ending)
else
add_ending(args, "past_ptc", pp, "")
end
end
local function make_strong_past(args, pref, pastsg, pastpl)
add_ending_with_prefix(args, "1sg_past_indc", pref, pastsg, "")
add_ending_with_prefix(args, "2sg_past_indc", pref, pastpl, "e")
add_ending_with_prefix(args, "3sg_past_indc", pref, pastsg, "")
add_ending_with_prefix(args, "pl_past_indc", pref, pastpl, "on")
add_ending_with_prefix(args, "sg_past_subj", pref, pastpl, "e")
add_ending_with_prefix(args, "pl_past_subj", pref, pastpl, "en")
end
local function make_strong(presa, prese, pres23, impsg, pastsg, pastpl, pp, with_ge)
local args = {}
make_non_past(args, presa, prese, prese, pres23, impsg, pp, with_ge)
make_strong_past(args, nil, pastsg, pastpl)
return args
end
local function make_weak_past(args, pref, past)
add_ending_with_prefix(args, "1sg_past_indc", pref, past, "e")
add_ending_with_prefix(args, "2sg_past_indc", pref, past, "est")
add_ending_with_prefix(args, "3sg_past_indc", pref, past, "e")
add_ending_with_prefix(args, "pl_past_indc", pref, past, "on")
add_ending_with_prefix(args, "sg_past_subj", pref, past, "e")
add_ending_with_prefix(args, "pl_past_subj", pref, past, "en")
end
local function make_weak(presa, presefin, presenfin, pres23, impsg, past, pp, with_ge)
local args = {}
make_non_past(args, presa, presefin, presenfin, pres23, impsg, pp, with_ge)
make_weak_past(args, nil, past)
return args
end
local strong_verbs = {}
strong_verbs["1"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ī(" .. cons_c .. "+)an$")
if pref then
-- bīdan "await", ācwīnan "dwindle away", sċīnan "shine", spīwan "spew, spit", etc.;
-- stīgan "ascend" (þū stīġst, stāg/stāh [handled by default_construct_stem_ending],
-- stigon, stiġen); blīcan "shine" (þū blīcst/blīċest)
data.pres23 = pref .. "ī" .. palatalize_final_cons(suf)
if suf == "g" then
data.impsg = pref .. "īġ"
else
data.impsg = pref .. "ī" .. suf
end
-- ġīnan "yawn" (gān, ġinon, ġinen)
data.pastsg = depalatalize_final_cons_before_back_vowel(pref) .. "ā" .. suf
-- snīþan "cut" -> snidon; sċrīþan "go, proceed" -> sċridon
-- (but not mīþan "avoid", wrīþan "twist")
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pref .. "i" .. pastsuf
if pastsuf == "g" then
data.pp = pref .. "iġen"
else
data.pp = data.pastpl .. "en"
end
return
end
pref = rmatch(data.inf, "^(.-)[ēī]on$")
if pref then
-- tēon/tīon "accuse" < *tīhanan, similarly lēon "lend" < *līhwanan,
-- sēon "strain" < *sīhwanan, þēon "thrive" < *þinhanan (originally strong 3),
-- wrēon < *wrīhanan. Beware of homonyms e.g. tēon "pull, draw" (strong 2) < *teuhanan,
-- tēon "make, create" (weak) ?< *tīhanan (strong);
-- þēon/þēowan/þȳ(g)(a)n "press" (weak) < *þunhijanan;
-- sēon "see" (strong 5) < *sehwanan
data.contracted = true
data.pres23 = pref .. "īeh"
data.impsg = gsub(data.inf, "n$", "h")
data.pastsg = pref .. "āh"
if rfind(pref, "[þð]$") then
-- þēon "thrive", has remnant strong 3 parts
data.pastpl = {pref .. "ig", pref .. "ung"}
data.pp = {pref .. "iġen", pref .. "ungen"}
else
data.pastpl = pref .. "ig"
if pref:find("s$") then
-- sēon "strain" alt past part siwen
data.pp = {pref .. "iġen", pref .. "iwen"}
else
data.pp = pref .. "iġen"
end
end
return
end
end
strong_verbs["2"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ēo(" .. cons_c .. "+)an$")
if pref then
-- bēodan "command", crēopan "creep"; rēocan "smoke, reek" (þū rīecst/rīeċest);
-- drēogan "endure" (þū drīeġst, drēag/drēah [handled by default_construct_stem_ending],
-- drugon, drogen)
data.pres23 = pref .. "īe" .. palatalize_final_cons(suf)
data.impsg = pref .. "ēo" .. suf
data.pastsg = pref .. "ēa" .. suf
-- ġēotan "pour" (ġēat, guton, goten); ċēosan "choose" (ċēas, curon, coren)
local pastpref = depalatalize_final_cons_before_back_vowel(pref)
-- ċēosan "choose" -> curon; forlēosan "lose" -> forluron; sēoþan "boil" -> sudon
-- (but not ābrēoþan "perish, ruin")
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pastpref .. "u" .. pastsuf
data.pp = pastpref .. "o" .. pastsuf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ū(" .. cons_c .. "+)an$")
if pref then
-- sċūfan "shove"; brūcan "use" (þū brīecst/brīeċest);
-- būgan "bend" (þū bīeġst, bēag/bēah [handled by default_construct_stem_ending],
-- bugon, bogen)
data.pres23 = pref .. "ȳ" .. palatalize_final_cons(suf)
data.impsg = pref .. "ū" .. suf
-- could have palatalization here, but no known examples
data.pastsg = pref .. "ēa" .. suf
-- no known examples of Vernerization, but just in case
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pref .. "u" .. pastsuf
data.pp = pref .. "o" .. pastsuf .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)ēon$")
if pref then
-- tēon "pull, draw" < *teuhanan, flēon "flee"
-- Beware of homonyms, e.g. tēon/tīon "accuse" (strong 1) < *tīhanan,
-- tēon "make, create" (weak) ?< *tīhan (strong)
data.contracted = true
data.pres23 = pref .. "īeh"
data.impsg = gsub(data.inf, "n$", "h")
data.pastsg = pref .. "ēah"
-- no examples where depalatalization is needed
data.pastpl = pref .. "ug"
data.pp = pref .. "ogen"
return
end
end
strong_verbs["3"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)i([mn]" .. cons_c .. "+)an$")
if pref then
-- bindan "bind", climban "climb", ġelimpan "happen", winnan "win",
-- swimman "swim", etc.; ācwincan "vanish" (þū ācwincst/ācwinċest);
-- cringan (þū cringst/crinġest), variant crinċġan (þū cringst/crinċġest)
data.pres23 = pref .. "i" .. palatalize_final_cons(suf)
data.impsg = pref .. "i" .. suf
-- onġinnan "begin" (ongann, ongunnon, ongunnen), ċimban "join"
local pastpref = depalatalize_final_cons_before_back_vowel(pref)
-- no Verner alternation here; expected #fīþan, #fōþ, #fundon <
-- *finþanan, *fanþ, *fundund regularized into findan, fand, fundon;
-- but depalatalize to handle crin(ċ)ġan past crang/crungon/crungen
-- and (maybe?) variant crinċan past cranc/cruncon/cruncen
local pastsuf = depalatalize_final_cons_before_cons(suf)
data.pastsg = pastpref .. "a" .. pastsuf
data.pastpl = pastpref .. "u" .. pastsuf
data.pp = pastpref .. "u" .. pastsuf .. "en"
return
end
local pref, vowel, suf = rmatch(data.inf, "^(.-)(ie)(l" .. cons_c .. "+)an$")
if not pref then
-- ġeldan/ġildan/ġyldan variants of ġieldan; helpan/bellan/delfan etc.
pref, vowel, suf = rmatch(data.inf, "^(.-)([eiy])(l" .. cons_c .. "+)an$")
end
if not pref then
pref, vowel, suf = rmatch(data.inf, "^(.-)(eo)(" .. cons_c .. "+)an$")
end
if pref then
-- helpan "help" (þū hilpst), bellan "bellow", beteldan "cover", delfan "dig",
-- sweltan "die", etc.; belgan "swell with anger" (þū bielġst, bealg/bealh
-- [handled by default_construct_stem_ending])
--
-- ġieldan "yield, pay" (þū ġiel(t)st, hē ġieldeþ/ġielt, ġeald, guldon, golden),
-- ġiellan "yell", ġielpan "boast"
--
-- weorpan "throw" (þū wierpst), feohtan "fight", sċeorfan "gnaw";
-- āseolcan "languish" (þū āsielcst/āsielċest), beorgan "protect"
-- (þū bierġst, bearg/bearh [handled by default_construct_stem_ending])
data.pres23 = pref .. (vowel == "e" and "i" or vowel == "eo" and "ie" or vowel) .. palatalize_final_cons(suf)
data.impsg = pref .. vowel .. suf
data.pastsg = pref .. "ea" .. suf
-- ġieldan etc. (see above)
local pastpref = depalatalize_final_cons_before_back_vowel(pref)
-- weorþan -> wurdon
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pastpref .. "u" .. pastsuf
data.pp = pastpref .. "o" .. pastsuf .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)eġdan$")
if pref then
-- breġdan "brandish" (þū breġdest, hē breġdeþ, bræġd/brǣd, brugdon, brogden)
-- streġdan "strew" (like breġdan)
data.pres23 = pref .. "eġde"
data.impsg = pref .. "eġd"
data.pastsg = {pref .. "æġd", pref .. "ǣd"}
data.pastpl = pref .. "ugd"
data.pp = pref .. "ogden"
return
end
local pref, suf = rmatch(data.inf, "^(.-)(ie?rn)an$")
if not pref then
pref, suf = rmatch(data.inf, "^(.-)(yrn)an$")
end
if pref then
-- biernan/birnan/byrnan "burn" < *brinnanan (þū biernst, barn/born/bearn, burnon, burnen)
-- iernan/irnan/yrnan "run" < *rinnan (like biernan)
data.pres23 = pref .. suf
data.impsg = data.pres23
data.pastsg = {pref .. "arn", pref .. "orn", pref .. "earn"}
data.pastpl = pref .. "urn"
data.pp = pref .. "urnen"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)([ou])rnan$")
if pref then
-- murnan "mourn" (þū myrnst, mearn, murnon, — but BT documents mornen)
-- spurnan/spornan "spurn" (þū spyrnst, spearn, spurnon, spornen)
data.pres23 = pref .. "yrn"
data.impsg = pref .. vowel .. "rn"
data.pastsg = pref .. "earn"
data.pastpl = pref .. "urn"
data.pp = pref .. "ornen"
return
end
local pref, suf = rmatch(data.inf, "^(.-)e(r" .. cons_c .. "+)an$")
if pref then
-- berstan "burst" < *brestanan (þū birst, hē birsteþ/birst, bærst, burston, borsten)
-- þersċan "thrash, thresh" < *þreskanan (þū þirsċst, hē þirsċeþ, þærsċ, þursċon, þorsċen)
data.pres23 = pref .. "i" .. suf
data.impsg = pref .. "e" .. suf
data.pastsg = pref .. "æ" .. suf
data.pastpl = pref .. "u" .. suf
data.pp = pref .. "o" .. suf .. "en"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)fr([ei])ġnan$")
if pref then
-- friġnan "ask", variant freġnan
data.pres23 = {pref .. "friġne", pref .. "friġn"}
data.impsg = pref .. "fr" .. vowel .. "ġn"
data.pastsg = pref .. "fræġn"
data.pastpl = pref .. "frugn"
data.pp = pref .. "frugnen"
return
end
local pref = rmatch(data.inf, "^(.-)frīnan$")
if pref then
-- frīnan "ask" variant of friġnan
data.pres23 = {pref .. "frīne", pref .. "frīn"}
data.impsg = pref .. "frīn"
data.pastsg = pref .. "frān"
data.pastpl = pref .. "frūn"
data.pp = pref .. "frūnen"
return
end
local pref = rmatch(data.inf, "^(.-)fēolan$")
if pref then
-- fēolan "enter, penetrate"
data.pres23 = {pref .. "fielh", pref .. "filh"}
data.impsg = pref .. "feolh"
data.pastsg = pref .. "fealh"
data.pastpl = {pref .. "fǣl", pref .. "fulg", pref .. "fūl"}
data.pp = {pref .. "folgen", pref .. "fōlen"}
return
end
end
strong_verbs["4"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ie(" .. cons_c .. ")an$")
if pref then
-- sċieran "shear"
data.pres23 = {pref .. "ie" .. suf .. "e", pref .. "ie" .. suf}
data.impsg = pref .. "ie" .. suf
-- no Verner alternation or depalatalization here
data.pastsg = pref .. "ea" .. suf
data.pastpl = pref .. "ēa" .. suf
data.pp = pref .. "o" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)e(" .. cons_c .. ")an$")
if pref then
-- beran "bear, carry", cwelan "die", brecan "break" (þū bricst/briċest), etc.
if suf == "r" or suf == "l" then
data.pres23 = {pref .. "i" .. suf .. "e", pref .. "i" .. suf}
else
data.pres23 = pref .. "i" .. palatalize_final_cons(suf)
end
data.impsg = pref .. "e" .. suf
-- no Verner alternation or depalatalization here
data.pastsg = pref .. "æ" .. suf
data.pastpl = pref .. "ǣ" .. suf
data.pp = pref .. "o" .. suf .. "en"
return
end
-- Next two are irregular but occur with so many prefixes that we special-case them here.
local pref = rmatch(data.inf, "^(.-)cuman$")
if pref then
-- cuman "come"
data.pres23 = {pref .. "cyme", pref .. "cym"}
data.impsg = pref .. "cum"
data.pastsg = {pref .. "cōm", pref .. "cwōm"}
data.pastpl = data.pastsg
data.pp = {pref .. "cumen", pref .. "cymen"}
return
end
local pref = rmatch(data.inf, "^(.-)niman$")
if pref then
-- niman "take"
data.pres23 = {pref .. "nime", pref .. "nim"}
data.impsg = pref .. "nim"
data.pastsg = pref .. "nōm"
data.pastpl = data.pastsg
data.pp = pref .. "numen"
return
end
end
strong_verbs["5"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ie(" .. cons_c .. ")an$")
if not pref then
pref, suf = rmatch(data.inf, "^(.-ġ)[eiy](" .. cons_c .. ")an$")
end
if pref then
-- ġiefan "give", forġietan "forget"
data.pres23 = pref .. "ie" .. suf
data.impsg = data.pres23
data.pastsg = pref .. "ea" .. suf
data.pastpl = pref .. "ēa" .. suf
data.pp = pref .. "e" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)e(" .. cons_c .. ")an$")
if suf == "g" then
-- wegan "carry"; special-case
data.pres23 = pref .. "iġ"
data.impsg = pref .. "eġ"
data.pastsg = pref .. "æġ"
data.pastpl = {pref .. "ǣg", pref .. "āg"}
data.pp = pref .. "eġen"
return
elseif pref then
-- metan "measure", sprecan "speak", cnedan "knead", wefan "weave", etc.
data.pres23 = pref .. "i" .. palatalize_final_cons(suf)
data.impsg = pref .. "e" .. suf
if suf == "t" and not pref:find("m$") and not pref:find("ġ$") then
-- etan "eat", fretan "devour", compounds; exclude metan "measure",
-- ġetan (potential variant of ġietan)
data.pastsg = pref .. "ǣ" .. suf
else
data.pastsg = pref .. "æ" .. suf
end
-- cweþan "say" -> cwǣdon, wesan "be" -> wǣron
-- (but not ġenesan "be saved", lesan "collect, gather")
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pref .. "ǣ" .. pastsuf
if data.inf:find("drepan$") then
-- Special-case drepan "strike, slay"; Wright lists brecan here with
-- pp only brocen, but that just makes it a strong-4 verb and that's
-- where it's normally listed in dictionaries
data.pp = {pref .. "epen", pref .. "open"}
else
data.pp = pref .. "e" .. pastsuf .. "en"
end
return
end
local pref, last_cons = rmatch(data.inf, "^(.-)i([dt])%2an$")
if pref then
-- biddan "pray", sittan "sit"
data.jpres = true
data.pres23 = pref .. "i" .. last_cons
data.impsg = data.pres23 .. "e"
data.pastsg = pref .. "æ" .. last_cons
data.pastpl = pref .. "ǣ" .. last_cons
data.pp = pref .. "e" .. last_cons .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)iċġe?an$")
if pref then
-- liċġan "lie down", þiċġan "receive", friċġan "ask, inquire"
data.jpres = true
data.pres23 = pref .. "iġ"
data.impsg = data.pres23 .. "e"
if rfind(data.inf, "[þð]iċġe?an$") then
data.pastsg = {pref .. "eah", pref .. "ah"}
else
data.pastsg = pref .. "æġ"
end
data.pastpl = {pref .. "ǣg", pref .. "āg"}
if data.inf:find("friċġe?an$") then
data.pp = {pref .. "iġen", pref .. "ugen"}
else
data.pp = pref .. "eġen"
end
return
end
local pref = rmatch(data.inf, "^(.-)ēon$")
if pref then
-- sēon "see" < *sehwanan, ġefēon "rejoice" < *gafehanan, plēon "risk" < *plehanan
data.contracted = true
data.pres23 = pref .. "ieh"
data.impsg = pref .. "eoh"
data.pastsg = pref .. "eah"
if pref:find("s$") then
-- sēon "see"
data.pastpl = pref .. "āw"
data.pp = pref .. "ewen"
else
data.pastpl = pref .. "ǣg"
data.pp = pref .. "eġen"
end
return
end
end
strong_verbs["6"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ea(" .. cons_c .. "+)an$")
if pref then
-- sċ(e)acan "shake", sċ(e)afan "shave, scrape"
data.pres23 = pref .. "ea" .. suf
data.impsg = {pref .. "a" .. suf, data.pres23}
data.pastsg = {pref .. "ō" .. suf, pref .. "eō" .. suf}
data.pastpl = data.pastsg
data.pp = {pref .. "a" .. suf .. "en", pref .. "ea" .. suf .. "en"}
return
end
local pref, vowel, suf = rmatch(data.inf, "^(.-)(a)(" .. cons_c .. "+)an$")
if not pref then
-- stondan variant of standan, sponan variant of spanan
pref, vowel, suf = rmatch(data.inf, "^(.-)(o)(n" .. cons_c .. "*)an$")
end
if not pref then
-- wæsċan/wasċean/wæsċean variant of wasċan
pref, vowel, suf = rmatch(data.inf, "^(.-)([aæ])(sċ" .. cons_c .. "*)e?an$")
end
if suf == "g" then
-- gnagan "gnaw", dragan "draw"
data.pres23 = pref .. "æġ"
data.impsg = pref .. "ag"
data.pastsg = pref .. "ōg"
data.pastpl = data.pastsg
data.pp = {pref .. "æġen", pref .. "agen"}
return
elseif suf == "nd" and pref:find("st$") then
-- standan/stondan "stand"
data.pres23 = pref .. "end"
data.impsg = pref .. vowel .. "nd"
data.pastsg = pref .. "ōd"
data.pastpl = data.pastsg
data.pp = pref .. vowel .. "nden"
return
elseif suf == "n" and pref:find("sp$") then
-- spanon/sponan "allure"
data.pres23 = {pref .. "ene", pref .. "en"}
data.impsg = pref .. vowel .. "n"
data.pastsg = {pref .. "ōn", pref .. "ēon"} -- has alt class VII past
data.pastpl = data.pastsg
data.pp = pref .. vowel .. "nen"
return
elseif pref then
-- faran "go", alan "grow", bacan "bake", hladan "lade", wasċan "wash", etc.
if suf == "r" or suf == "l" or suf == "sċ" then
data.pres23 = {pref .. "æ" .. suf .. "e", pref .. "æ" .. suf}
else
data.pres23 = pref .. "æ" .. palatalize_final_cons(suf)
end
data.impsg = pref .. "a" .. suf
data.pastsg = pref .. "ō" .. suf
-- Apparently no Verner variation here
data.pastpl = data.pastsg
data.pp = {pref .. "æ" .. suf .. "en", pref .. "a" .. suf .. "en"}
return
end
local pref = rmatch(data.inf, "^(.-)ēan$")
if pref then
-- slēan "strike", flēan "flay", lēan "blame", þwēan "wash"
data.contracted = true
data.pres23 = pref .. "ieh"
data.impsg = pref .. "eah"
data.pastsg = pref .. "ōg" -- also slōh etc., which will get automatically added
data.pastpl = data.pastsg
data.pp = {pref .. "æġen", pref .. "agen", pref .. "eġen"}
return
end
-- All the j-present verbs have to be handled individually as each has
-- idiosyncrasies.
local pref, last_cons = rmatch(data.inf, "^(.-)hebban$")
if pref then
-- hebban "raise"
data.jpres = true
data.pres23 = pref .. "hefe"
data.impsg = data.pres23
data.pastsg = pref .. "hōf"
data.pastpl = data.pastsg
data.pp = {pref .. "hæfen", pref .. "hafen", pref .. "hefen"}
return
end
local pref, vowel = rmatch(data.inf, "^(.-)hl([iy]?e?)hhan$")
if pref then
-- hliehhan "laugh"
data.jpres = true
data.pres23 = pref .. "hl" .. vowel .. "h"
data.impsg = data.pres23
data.pastsg = pref .. "hlōg"
data.pastpl = data.pastsg
data.pp = pref .. "hlæġen"
return
end
local pref, cons = rmatch(data.inf, "^(.-)sċe([þð])%2an$")
if pref then
-- sċeþþan "injure" (for some reason, expected #sċieþþan doesn't occur)
data.jpres = true
data.pres23 = pref .. "sċe" .. cons .. "e"
data.impsg = data.pres23
data.pastsg = "sċōd"
data.pastpl = data.pastsg
data.pp = "sċeaþen"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)sċ([iy]?e?)ppan$")
if pref then
-- sċieppan "create"
data.jpres = true
data.pres23 = pref .. "sċ" .. vowel .. "pe"
data.impsg = data.pres23
data.pastsg = {pref .. "sċōp", pref .. "sċeōp"}
data.pastpl = data.pastsg
data.pp = {pref .. "sċeapen", pref .. "sċapen"}
return
end
local pref, vowel = rmatch(data.inf, "^(.-)st([æe])ppan$")
if pref then
-- stæppan "step, go"
data.jpres = true
data.pres23 = pref .. "st" .. vowel .. "pe"
data.impsg = data.pres23
data.pastsg = pref .. "stōp"
data.pastpl = data.pastsg
data.pp = {pref .. "stæpen", pref .. "stapen"}
return
end
local pref = rmatch(data.inf, "^(.-s[wƿ])erian$")
if pref then
-- swerian "swear"
data.jpres = true
data.pres23 = pref .. "ere"
data.impsg = data.pres23
data.pastsg = pref .. "ōr"
data.pastpl = data.pastsg
data.pp = pref .. "oren" -- on the analogy of class IV verbs like beran
return
end
end
strong_verbs["7"] = function(data)
-- Type (7a) verbs
local pref = rmatch(data.inf, "^(.-)hātan$")
if pref then
-- hātan "call"
data.pres23 = pref .. "hǣt"
data.impsg = pref .. "hāt"
data.pastsg = {pref .. "hēt", pref .. "hēht"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "hāten"
return
end
local pref = rmatch(data.inf, "^(.-)lācan$")
if pref then
-- lācan "play"
data.pres23 = pref .. "lǣċ"
data.impsg = pref .. "lāc"
data.pastsg = {pref .. "lēc", pref .. "leolc"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "lācen"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)sċ(e?ā)dan$")
if not pref then
pref, vowel = rmatch(data.inf, "^(.-)sċ(ēa)dan$")
end
if pref then
-- sċ(e)ādan or sċēadan "separate"
data.pres23 = pref .. "sċēad"
data.impsg = pref .. "sċ" .. vowel .. "d"
data.pastsg = {pref .. "sċēd", pref .. "sċēad"}
data.pastpl = data.pastsg
data.pp = pref .. "sċ" .. vowel .. "den"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)lǣtan$")
if pref then
-- lǣtan "let, allow"
data.pres23 = pref .. "lǣt"
data.impsg = pref .. "lǣt"
data.pastsg = {pref .. "lēt", pref .. "leort"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "lǣten"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)ondrǣdan$")
if pref then
-- ondrǣdan "dread, fear"
data.pres23 = pref .. "ondrǣd"
data.impsg = pref .. "ondrǣd"
data.pastsg = {pref .. "ondrēd", pref .. "ondreord"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
make_weak_past(data.extraforms, pref, "ondrǣdd")
data.pp = pref .. "ondrǣden"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)rǣdan$")
if pref then
-- rǣdan "advise"
data.pres23 = pref .. "rǣd"
data.impsg = pref .. "rǣd"
-- NOTE: Also (mostly) has weak past rǣdde and pp (ġe)rǣdd; can be handled
-- by declaring the verb as both weak 1b and strong 7.
data.pastsg = {pref .. "rēd", pref .. "reord"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "rǣden"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)slǣpan$")
if pref then
-- slǣpan "sleep"
data.pres23 = pref .. "slǣp"
data.impsg = pref .. "slǣp"
data.pastsg = pref .. "slēp"
data.pastpl = data.pastsg
make_weak_past(data.extraforms, pref, "slǣpt")
data.pp = pref .. "slǣpen"
return
end
local pref, main = rmatch(data.inf, "^(.-)(gr[ǣē]t)an$")
if pref then
-- grǣtan "wail"
data.pres23 = pref .. main
data.impsg = pref .. main
data.pastsg = pref .. "grēt"
data.pastpl = data.pastsg
data.pp = pref .. main .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)blandan$")
if pref then
-- blandan "mix"
data.pres23 = pref .. "blend"
data.impsg = pref .. "bland"
data.pastsg = pref .. "blēnd"
data.pastpl = data.pastsg
data.pp = pref .. "blanden"
return
end
local pref = rmatch(data.inf, "^(.-)ōn$")
if pref then
-- fōn "seize", hōn "hang"
data.contracted = true
data.pres23 = pref .. "ēh"
data.impsg = pref .. "ōh"
data.pastsg = pref .. "ēng"
data.pastpl = data.pastsg
data.pp = {pref .. "angen"}
return
end
-- Type (7b) verbs
local pref = rmatch(data.inf, "^(.-)annan$")
if pref then
-- bannan "summon", spannan "join, clasp"
data.pres23 = pref .. "enn"
data.impsg = pref .. "ann"
data.pastsg = {pref .. "ēonn", pref .. "ēon"}
data.pastpl = data.pastsg
data.pp = pref .. "annen"
return
end
local pref = rmatch(data.inf, "^(.-)gangan$")
if pref then
-- gangan "go"
data.pres23 = pref .. "geng"
data.impsg = pref .. "gang"
data.pastsg = {pref .. "ġēng", pref .. "ġīeng"}
data.pastpl = data.pastsg
data.pp = pref .. "gangen"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ea(" .. cons_c .. "+)an$")
if pref then
-- fealdan "fold", feallan "fall", healdan "hold", stealdan "possess",
-- wealcan "roll", wealdan "rule", weallan "boil", weaxan "grow"
data.pres23 = pref .. "ie" .. palatalize_final_cons(suf)
data.impsg = pref .. "ea" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ea" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ā(" .. cons_c .. "+)an$")
if pref then
-- blāwan "blow", cnāwan "know", crāwan "crow", māwan "mow", sāwan "sow",
-- swāpan "sweep", þrāwan "turn, twist", wāwan "blow"
data.pres23 = pref .. "ǣ" .. palatalize_final_cons(suf)
data.impsg = pref .. "ā" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ā" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ēa(" .. cons_c .. "+)an$")
if pref then
-- bēatan "beat", āhnēapan "pluck off", hēawan "hew", hlēapan "leap"
data.pres23 = pref .. "īe" .. palatalize_final_cons(suf)
data.impsg = pref .. "ēa" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ēa" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ō(" .. cons_c .. "+)an$")
if pref then
if suf == "g" and pref:find("sw$") then
-- swōgan "sound"
data.pres23 = pref .. "ēġ"
data.impsg = pref .. "ōg"
data.pastsg = {} -- no preterite
data.pastpl = {}
data.pp = pref .. "ōgen"
return
end
if suf == "c" and pref:find("fl$") or suf == "t" and rfind(pref, "[wƿ]r$") then
-- flōcan "clap, strike", wrōtan "root up"
data.pres23 = pref .. "ē" .. palatalize_final_cons(suf)
data.impsg = pref .. "ō" .. suf
data.pastsg = {} -- no preterite
data.pastpl = {}
data.pp = pref .. "ō" .. suf .. "en"
return
end
-- blōtan "sacrifice", blōwan "bloom, blossom", hrōpan "shout",
-- hwōpan "threaten", flōwan "flow", grōwan "grow", hlōwan "low, bellow",
-- spōwan "succeed"; also rōwan "row", which has alt pret pl rēon
data.pres23 = pref .. "ē" .. palatalize_final_cons(suf)
data.impsg = pref .. "ō" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ō" .. suf .. "en"
if (suf == "w" or suf == "ƿ") and pref:find("r$") and not pref:find("gr$") then
-- rōwan "row"
data.extraforms["pl_past_indc"] = {pref .. "ēon"}
end
return
end
local pref = rmatch(data.inf, "^(.-[wƿ])ēpan$")
if pref then
-- wēpan "weep"; j-present
data.jpres = true
data.pres23 = pref .. "ēp"
data.impsg = pref .. "ēp"
data.pastsg = pref .. "ēop"
data.pastpl = data.pastsg
data.pp = pref .. "ōpen"
return
end
end
local weak_verbs = {}
weak_verbs["1a"] = function(data)
data.stem_weight = "light"
local pref = rmatch(data.inf, "^(.-)ian$")
if pref then
data.pres23 = pref .. "e"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
local pref, last_cons = rmatch(data.inf, "^(.-)([dt])%2an$")
if pref then
data.pres23 = pref .. last_cons
data.impsg = data.pres23 .. "e"
data.past = data.pres23 .. last_cons
data.pp = {data.pres23 .. "ed", data.past, data.pres23}
return
end
local pref = rmatch(data.inf, "^(.-)ċġe?an$")
if pref then
data.pres23 = pref .. "ġ"
data.impsg = data.pres23 .. "e"
data.past = data.pres23 .. "d"
data.pp = {data.pres23 .. "ed", data.past}
return
end
local pref = rmatch(data.inf, "^(.-)bban$")
if pref then
-- swebban etc.
data.pres23 = pref .. "fe"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
local pref, last_cons = rmatch(data.inf, "^(.-)(.)%2an$")
if not pref then
pref, last_cons = rmatch(data.inf, "^(.-)(ċ)ċean$")
end
if pref then
data.pres23 = pref .. last_cons .. "e"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
end
weak_verbs["1b"] = function(data)
data.stem_weight = "heavy"
local pref, cons = rmatch(data.inf, "^(.-[rl])([wƿ])an$")
if pref then
-- ġierwan, hierwan, nierwan, sierwan, smierwan, wielwan (?)
data.pres23 = pref .. "e"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = {pref .. cons .. "ed", pref .. "ed"}
return
end
local pref = rmatch(data.inf, "^(.-" .. cons_c .. "[rlmnwƿ])an$")
if pref and not pref:find("[rl][mn]$") and not pref:find("rl$") and not rfind(pref, "(" .. cons_c .. ")%1$") then
-- hyngran, dīeglan, bīecnan, þrysman, etc.
data.pres23 = pref .. "e"
data.impsg = data.pres23
local vowel = rmatch(pref, "^.-(" .. vowel_c .. "+)" .. single_cons_c .. "[rlmnwƿ]$")
if vowel and not ends_in_long_vowel(vowel) then
-- efnan, bytlan, eġlan, ræfnan, seġlan, þrysman; form without -ed is older
data.past = {pref .. "d", pref .. "ed"}
else
-- dīeglan, forglendran, wrixlan, frēfran, timbran, symblan, etc.
data.past = pref .. "ed"
end
data.pp = pref .. "ed"
return
end
if data.inf:find("ēan$") or rfind(data.inf, vowel_c .. "n$") and not data.inf:find("an$") then
-- contracted verb, e.g. hēan, þēon, tȳn, rȳn, þȳn
-- FIXME, verify in Campbell that all of the following are correct
data.pres23 = data.presa
data.impsg = data.presa
data.past = data.presa .. "d"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)an$")
if pref then
data.pres23 = {pref .. "e", pref}
data.impsg = pref
data.past = construct_cons_stem_ending(pref, "d")
data.pp = pref .. "ed"
return
end
end
weak_verbs["1"] = function(data)
local weaktype
if data.inf:find("ian$") then
weaktype = "1a"
elseif rfind(data.inf, "(" .. cons_c .. ")%1an$") or data.inf:find("ċċean$") or data.inf:find("cgan$") or data.inf:find("ċġan$") then
local prev = rmatch(data.inf, "^(.-)....$")
if rfind(prev, vowel_c .. "$") and not ends_in_long_vowel(prev) then
weaktype = "1a"
else
weaktype = "1b"
end
else
weaktype = "1b"
end
weak_verbs[weaktype](data)
end
weak_verbs["2"] = function(data)
-- lufian
local pref, suf = rmatch(data.inf, "^(.-)(ian)$")
if not pref then
-- lufiġan, lufeġan, lufiġean, lufeġean (alternative spellings)
pref, suf = rmatch(data.inf, "^(.-)([ei]ġe?an)$")
end
if pref then
data.pres23 = pref .. "a"
data.presenfin = data.prese
data.presefin = suf == "ian" and pref .. "iġe" or data.presenfin
data.impsg = data.pres23
data.past = pref .. "od"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)ġe?an$")
if pref then
-- twēoġan, smēaġ(e)an
data.pres23 = pref
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
end
weak_verbs["3"] = function(data)
local pref = rmatch(data.inf, "^(.-)abban$")
if pref then
data.prese = pref .. "æbbe"
data.pres23 = pref .. "æf"
data.impsg = pref .. "afa"
data.past = pref .. "æfd"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)libban$")
if pref then
-- libban, compounds
data.pres23 = pref .. "leofa"
data.impsg = data.pres23
data.past = pref .. "lifd"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)seċġe?an$")
if pref then
-- seċġan, compounds
data.pres23 = pref .. "sæġ"
data.impsg = pref .. "sæġe"
data.past = pref .. "sæġd"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)hyċġe?an$")
if pref then
-- hyċġan, compounds
data.pres23 = pref .. "hyġ"
data.impsg = pref .. "hyġe"
data.past = pref .. "hogd"
data.pp = data.past
return
end
end
local function make_irregular_non_past(args, inf, pref, pres1, pres2, pres3, prespl,
presp, subj, impsg, imppl, pp, with_ge)
add_ending(args, "infinitive", inf, "")
add_ending_with_prefix(args, "infinitive2", pref, presp, "ne")
add_ending_with_prefix(args, "1sg_pres_indc", pref, pres1, "")
add_ending_with_prefix(args, "2sg_pres_indc", pref, pres2, "")
add_ending_with_prefix(args, "3sg_pres_indc", pref, pres3, "")
add_ending_with_prefix(args, "pl_pres_indc", pref, prespl, "")
add_ending_with_prefix(args, "sg_pres_subj", pref, subj, "")
add_ending_with_prefix(args, "pl_pres_subj", pref, subj, "n")
add_ending_with_prefix(args, "sg_impr", pref, impsg, "")
add_ending_with_prefix(args, "pl_impr", pref, imppl, "")
add_ending_with_prefix(args, "pres_ptc", pref, presp, "de")
if with_ge then
add_ending_with_prefix(args, "past_ptc", pref, pp, "", construct_optional_ge_stem_ending)
else
add_ending_with_prefix(args, "past_ptc", pref, pp, "")
end
end
-- Construct all preterite-present forms. Each of the arguments can be a single string or list.
-- If a given argument is missing, supply an empty list {}.
-- Arguments:
-- INF: Infinitive.
-- PREF: Prefix to add to all forms other than the infinitive.
-- PRES13: 1st/3rd singular present form.
-- PRES2: 2nd singular present form.
-- PRESPL: Plural present form.
-- PRESP: Present participle stem (up through -en, missing final -de; also used to construct
-- second infinitive by adding -ne)
-- SUBJ: Singular present subjunctive form (also used to construct plural subjunctive by adding -n)
-- IMPSG: 2nd singular imperative form.
-- IMPPL: 2nd plural imperative form.
-- PAST: Stem of past tense.
-- PP: Past participle.
local function make_preterite_present_forms(inf, pref, pres13, pres2, prespl,
presp, subj, impsg, imppl, past, pp, with_ge)
local args = {}
make_irregular_non_past(args, inf, pref, pres13, pres2, pres13, prespl, presp, subj,
impsg, imppl, pp, with_ge)
make_weak_past(args, pref, past)
return args
end
local function make_preterite_present(inf, with_ge)
local pref, vowel = rmatch(inf, "^(.-[wƿn])([iy])[oe]?tan$")
if pref then
return make_preterite_present_forms(
inf, pref, "āt", "āst", vowel .. "ton", vowel .. "ten",
vowel .. "te", vowel .. "te", vowel .. "taþ", {vowel .. "ss", vowel .. "st"},
vowel .. "ten", with_ge)
end
local pref = rmatch(inf, "^(.-)dugan$")
if pref then
return make_preterite_present_forms(
inf, pref, "dēag", "dēaht", "dugon", "dugen", "dyġe", "dyġe", "dugaþ", "doht", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)cunnan$")
if pref then
return make_preterite_present_forms(
inf, pref, "cann", "canst", "cunnon", "cunnen", "cunne",
"cunne", "cunnaþ", "cūþ", "cunnen", with_ge)
end
local pref = rmatch(inf, "^(.-)unnan$")
if pref then
return make_preterite_present_forms(
inf, pref, "ann", "anst", "unnon", "unnen", "unne", "unne", "unnaþ", "ūþ", "unnen", with_ge)
end
local pref = rmatch(inf, "^(.-[þð])urfan$")
if pref then
return make_preterite_present_forms(
inf, pref, "earf", "earft", "urfon", "earfen", "yrfe", "yrfe", "urfaþ", "orft", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)durran$")
if pref then
return make_preterite_present_forms(
inf, pref, "dearr", "dearst", "durron", {}, "dyrre", "dyrre", "durfaþ",
"dorst", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)sċulan$")
if not pref then
pref = rmatch(inf, "^(.-)sċeolan$")
end
if pref then
return make_preterite_present_forms(
inf, pref, "sċeal", "sċealt", "sċulon", {}, "sċyle",
{}, {}, "sċeold", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)munan$")
if pref then
return make_preterite_present_forms(
inf, pref, "man", "manst", "munon", "munen", "myne",
{"mun", "myne"}, "munaþ", "mund", "munen", with_ge)
end
local pref = rmatch(inf, "^(.-)magan$")
if pref then
return make_preterite_present_forms(
inf, pref, "mæġ", "meaht", "magon", "magen", "mæġe", {}, {},
{"meaht", "meht"}, {}, with_ge)
end
local pref = rmatch(inf, "^(.-)nugan$")
if pref then
return make_preterite_present_forms(
inf, pref, "neah", {}, "nugon", {}, "nuge", {}, {}, "noht", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)mōtan$")
if pref then
return make_preterite_present_forms(
inf, pref, "mōt", "mōst", "mōton", {}, "mōte", {}, {}, "mōst", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)āgan$")
if pref then
return make_preterite_present_forms(
inf, pref, "āh", "āhst", "āgon", "āgen", "āge", "āge", "āgaþ", "āht", "āgen", with_ge)
end
error("Unrecognized preterite-present verb: " .. inf)
end
local function make_irregular(inf, with_ge)
local args = {}
local pref, cons = rmatch(inf, "^(.-)([wƿ])esan$")
if pref then
make_irregular_non_past(args, inf, pref, "eom", "eart", "is", {"sind", "sindon"},
cons .. "esen", "sīe", cons .. "es", cons .. "esaþ", {}, with_ge)
make_strong_past(args, pref, cons .. "æs", cons .. "ǣr")
return args
end
local pref = rmatch(inf, "^(.-)nesan$")
if pref then
make_irregular_non_past(args, inf, pref, "neom", "neart", "nis", {"ne sind", "ne sindon"},
"nesen", "ne sīe", "nes", "nesaþ", {}, with_ge)
make_strong_past(args, pref, "næs", "nǣr")
return args
end
local pref, vowel = rmatch(inf, "^(.-)b([īē]o)n$")
if pref then
make_irregular_non_past(args, inf, pref, "b" .. vowel, "bist", "biþ", "b" .. vowel .. "þ",
"b" .. vowel .. "n", "b" .. vowel, "b" .. vowel, "b" .. vowel .. "þ", "b" .. vowel .. "n", with_ge)
return args
end
local pref = rmatch(inf, "^(.-)dōn$")
if pref then
make_irregular_non_past(args, inf, pref, "dō", "dēst", "dēþ", "dōþ", "dōn",
"dō", "dō", "dōþ", "dōn", with_ge)
make_weak_past(args, pref, "dyd")
return args
end
local pref = rmatch(inf, "^(.-)gān$")
if pref then
make_irregular_non_past(args, inf, pref, "gā", "gǣst", "gǣþ", "gāþ", "gān",
"gā", "gā", "gāþ", "gān", with_ge)
make_weak_past(args, pref, "ēod")
return args
end
local pref = rmatch(inf, "^(.-[wƿ])illan$")
if pref then
make_irregular_non_past(args, inf, pref, "ille", "ilt", "ile", "illaþ", "illen",
"ille", {}, {}, {}, with_ge)
make_weak_past(args, pref, "old")
return args
end
local pref, vowel = rmatch(inf, "^(.-)n([eiy])llan$")
if pref then
make_irregular_non_past(args, inf, pref, "n" .. vowel .. "lle", "n" .. vowel .. "lt",
"n" .. vowel .. "le", "n" .. vowel .. "llaþ",
"n" .. vowel .. "llen", "n" .. vowel .. "lle",
{}, {}, {}, with_ge)
make_weak_past(args, pref, "nold")
return args
end
error("Unrecognized irregular verb: " .. inf)
end
local function set_categories(typ, class, jpres, stem_weight, contracted)
local cats = {}
local classtext = class and "class " .. class .. " " or ""
if typ == "strong" then
insert(cats, "Englisc " .. classtext .. "strang word")
if jpres then
insert(cats, "Englisc " .. classtext .. "strang j-andweard word")
elseif contracted then
insert(cats, "Englisc " .. classtext .. "strang scortod word")
end
elseif typ == "weak" then
insert(cats, "Englisc " .. classtext .. "unstrang word")
if jpres then
insert(cats, "Englisc " .. classtext .. "unstrang j-andweard word")
elseif stem_weight then
insert(cats, "Englisc " .. classtext .. "unstrang " .. stem_weight .. "-stefn word")
end
elseif typ == "pretpres" then
insert(cats, "Englisc forþgewiten-andweard word")
elseif typ == "irreg" or typ == "anomalous" then
insert(cats, "Englisc ungemǣne word")
elseif typ then
error("Unrecognized verb type: " .. typ)
end
return cats
end
function export.show(frame)
local parent_args = frame:getParent().args
local params = {
[1] = {required = true, list = true, default = "beran<s4>"},
}
for slot, _ in pairs(slots_and_accel) do
params[slot] = {}
end
local args = require("Module:parameters").process(parent_args, params)
local allforms
local allcats = {}
if #args[1] > 1 then
insert(allcats, "Old English verbs with multiple conjugations")
end
for _, infspec in ipairs(args[1]) do
local inf, spec = rmatch(infspec, "^(.-)<(.*)>$")
if not inf then
error("Verb spec should look like e.g. 'beran<s4>' or 'dēman<w1>': " .. infspec)
end
local specs = rsplit(spec, "/")
local class = specs[1]
local verner = rfind(class, "v")
class = gsub(class, "v", "")
local presa = gsub(inf, "n$", "")
data = {
inf = inf,
presa = presa,
prese = presa:find("ēa$") and presa or gsub(presa, "e?a$", "e"),
verner = verner,
with_ge = not begins_with_verbal_prefix(inf),
extraforms = {},
}
local typ
if class:find("^s") then
typ = "strong"
class = gsub(class, "^s", "")
if strong_verbs[class] then
strong_verbs[class](data)
else
error("Unrecognized strong class: " .. class)
end
elseif class:find("^w") then
typ = "weak"
class = gsub(class, "^w", "")
if weak_verbs[class] then
weak_verbs[class](data)
data.presenfin = data.presenfin or data.prese
data.presefin = data.presefin or data.prese
else
error("Unrecognized weak class: " .. class)
end
elseif class == "pp" then
typ = "pretpres"
elseif class == "i" then
typ = "irreg"
else
error("Unrecognized verb class: " .. class)
end
local overrides = {}
for i, spec in ipairs(specs) do
if i > 1 then
local parts = rsplit(spec, ":")
if #parts ~= 2 then
error("Verb modified spec must be of the form 'KEY:VALUE': " .. spec)
end
local k = parts[1]
local v = parts[2]
local splitv = rsplit(v, ", *")
local unrecognized = false
if slots_and_accel[k] then
overrides[k] = splitv
elseif k == "ge" then
data.with_ge = require("Module:yesno")(v)
elseif k == "impers" then
data.impers = require("Module:yesno")(v)
elseif typ == "weak" or typ == "strong" then
if k == "pres" then
data.presa = splitv
data.prese = splitv
data.presefin = splitv
data.presenfin = splitv
data.pres23 = splitv
data.impsg = splitv
elseif k == "pres1456" then
data.presa = splitv
data.prese = splitv
data.presefin = splitv
data.presenfin = splitv
elseif k == "pres23" then
data.pres23 = splitv
elseif k == "presa" then
data.presa = splitv
elseif k == "prese" then
data.prese = splitv
data.presefin = splitv
data.presenfin = splitv
elseif typ == "weak" and k == "presefin" then
data.presefin = splitv
elseif typ == "weak" and k == "presenfin" then
data.presenfin = splitv
elseif k == "past" then
data.past = splitv
data.pastsg = splitv
data.pastpl = splitv
elseif typ == "strong" and k == "pastsg" then
data.pastsg = splitv
elseif typ == "strong" and k == "pastpl" then
data.pastpl = splitv
elseif k == "impsg" then
data.impsg = splitv
elseif k == "pp" then
data.pp = splitv
elseif typ == "weak" and k == "papp" then
data.past = splitv
data.pp = splitv
else
unrecognized = true
end
else
unrecognized = true
end
if unrecognized then
error("Unrecognized spec key '" .. k .. "' (value '" .. v .. "')")
end
end
end
if typ == "weak" or typ == "strong" then
local missing_fields = {}
local fields_to_check =
typ == "weak" and {"presa", "presefin", "presenfin", "pres23", "impsg", "past", "pp"} or
{"presa", "prese", "pres23", "impsg", "pastsg", "pastpl", "pp"}
for _, field in ipairs(fields_to_check) do
if not data[field] then
insert(missing_fields, field)
end
end
if #missing_fields > 0 then
error("Required spec(s) " .. concat(missing_fields, ",") ..
" missing, i.e. the form of the infinitive '" .. inf ..
"' was not recognized as a " .. typ .. " class-" .. class .. " verb and the " ..
"overriding specs weren't (all) supplied")
end
end
local forms
if typ == "strong" then
forms = make_strong(data.presa, data.prese, data.pres23, data.impsg, data.pastsg,
data.pastpl, data.pp, data.with_ge)
elseif typ == "weak" then
forms = make_weak(data.presa, data.presefin, data.presenfin,
data.pres23, data.impsg, data.past, data.pp, data.with_ge)
elseif typ == "pretpres" then
forms = make_preterite_present(inf, data.with_ge)
elseif typ == "irreg" then
forms = make_irregular(inf, data.with_ge)
else
error("Internal error: Unrecognized verb type: " .. typ)
end
for k, v in pairs(data.extraforms) do
add_form_to_slot(forms, k, v)
end
for k, v in pairs(overrides) do
forms[k] = v
end
if data.impers then
-- e.g. mǣtan; clear personal non-3sg forms
forms["1sg_pres_indc"] = {}
forms["2sg_pres_indc"] = {}
forms["pl_pres_indc"] = {}
forms["pl_pres_subj"] = {}
forms["1sg_past_indc"] = {}
forms["2sg_past_indc"] = {}
forms["pl_past_indc"] = {}
forms["pl_past_subj"] = {}
forms["sg_impr"] = {}
forms["pl_impr"] = {}
end
class = rsub(class, "[a-z]", "")
if class == "" then
class = nil
end
if not allforms then
allforms = forms
allforms["type"] = typ
allforms["class"] = class
else
for k, v in pairs(forms) do
for _, form in ipairs(v) do
m_table.insertIfNot(allforms[k], form)
end
end
end
local cats = set_categories(typ, class, data.jpres, data.stem_weight, data.contracted)
for _, cat in ipairs(cats) do
m_table.insertIfNot(allcats, cat)
end
end
local table = make_table(allforms)
return table .. m_utilities.format_categories(allcats, lang)
end
return export
g6069dzqk92j78enboveafrwfhz7ztc
55171
55170
2026-10-02T21:58:37Z
Deadend0914
7211
55171
Scribunto
text/plain
local m_links = require("Module:links")
local m_utilities = require("Module:utilities")
local strutils = require("Module:string utilities")
local m_table = require("Module:table")
local com = require("Module:ang-common")
local lang = require("Module:languages").getByCode("ang")
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rsplit = mw.text.split
local rsubn = mw.ustring.gsub
local insert = table.insert
local concat = table.concat
-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar, n)
local retval = rsubn(term, foo, bar, n)
return retval
end
-- like str:gsub() but discards all but the first return value
local function gsub(term, foo, bar, n)
local retval = term:gsub(foo, bar, n)
return retval
end
local function track(page)
require("Module:debug").track("ang-verb/" .. page)
return true
end
local export = {}
local long_vowel = "āēīōūȳǣ" .. com.MACRON -- No precomposed œ + macron
local short_vowel = "aeiouyæœ"
local short_vowel_c = "[" .. short_vowel .. "]"
local vowel = long_vowel .. short_vowel
local vowel_c = "[" .. vowel .. "]"
local long_vowel_c = "[" .. long_vowel .. "]"
local non_vowel_c = "[^" .. vowel .. "]"
local always_unvoiced_cons = "cċkptxz"
local always_unvoiced_cons_c = "[" .. always_unvoiced_cons .. "]"
local unvoiced_cons = always_unvoiced_cons .. "fsþð"
local unvoiced_cons_c = "[" .. unvoiced_cons .. "]"
local single_cons = "bcċdfgġhklmnprstwþðƿ"
local single_cons_c = "[" .. single_cons .. "]"
local cons = single_cons .. "xz"
local cons_c = "[" .. cons .. "]"
local slots_and_accel = {
["infinitive"] = "inf",
["infinitive2"] = "inflected|inf",
["1sg_pres_indc"] = "1|s|pres|ind",
["2sg_pres_indc"] = "2|s|pres|ind",
["3sg_pres_indc"] = "3|s|pres|ind",
["pl_pres_indc"] = "p|pres|ind",
["sg_pres_subj"] = "s|pres|sub",
["pl_pres_subj"] = "p|pres|sub",
["1sg_past_indc"] = "1|s|pret|ind",
["2sg_past_indc"] = "2|s|pret|ind",
["3sg_past_indc"] = "3|s|pret|ind",
["pl_past_indc"] = "p|pret|ind",
["sg_past_subj"] = "s|pret|sub",
["pl_past_subj"] = "p|pret|sub",
["sg_impr"] = "s|imp",
["pl_impr"] = "p|imp",
["pres_ptc"] = "pres|part",
["past_ptc"] = "past|part",
}
local function ends_in_long_vowel(word)
if rfind(word, long_vowel_c .. "$") then
return true
elseif rfind(word, "ē[ao]$") then
return true
elseif rfind(word, "ī[eo]$") then
return true
else
return false
end
end
local function begins_with_verbal_prefix(word)
word = com.decompose(word)
for _, prefixspec in ipairs(com.prefixes) do
local prefix = prefixspec[1]
local specs = prefixspec[2]
if specs.verb then
local main = rmatch(word, "^" .. prefix .. "(.-)$")
if main and (not specs.restriction or rfind(main, specs.restriction)) then
return true
end
end
end
return false
end
local function make_table(forms)
local title = forms.title
local accel_lemma = m_links.remove_links(forms.infinitive[1] or mw.loadData("Module:headword/data").pagename)
local function typetext()
local typ = forms["type"]
local class = (forms["class"] and tonumber(forms["class"])) or nil
local id
if typ == "strong" then
local class_roman = {"I", "II", "III", "IV", "V", "VI", "VII"}
class = class_roman[class]
id = (class and "Class_" .. class) or "Strong_verbs"
return "[[Appendix:Old English verbs#Strong_verbs|strang]]" .. (class and ", " .. "[[Appendix:Old English verbs#" .. id .. "|class " .. class .. "]]" or "")
elseif typ == "weak" then
id = (class and class>=1 and class<=3 and "Class_" .. class) or "Weak_verbs"
return "[[Appendix:Old English verbs#Weak_verbs|unstrang]]" .. (class and ", " .. "[[Appendix:Old English verbs#" .. id .. "|class " .. class .. "]]" or "")
elseif typ == "pretpres" then
return "[[Appendix:Old English verbs#Preterite-present_verbs|forþgewiten-anweard]]"
elseif typ == "irreg" or typ == "anomalous" then
return "[[Appendix:Old English verbs#Anomalous_verbs|ungemǣne]]"
else
error("Unrecognized verb type: " .. typ)
end
end
if not title then
title = "Fēgung of " .. m_links.full_link({lang = lang, alt = accel_lemma}, "term")
if forms["type"] then
title = title .. " (" .. typetext() .. ")"
end
end
local table_args = {
title = title,
style = forms.style == "right" and "float:right; clear:right;" or "",
width = forms.width or "30",
}
for slot, accel_form in pairs(slots_and_accel) do
local table_arg = {}
local slotforms = forms[slot] and #forms[slot] > 0 and forms[slot] or {"—"}
for _, form in ipairs(slotforms) do
insert(table_arg, form == "—" and form or m_links.full_link{
lang = lang, term = form, accel = {
form = accel_form ~= "" and accel_form or nil,
lemma = accel_lemma,
}
})
table_args[slot] = concat(table_arg, ", ")
end
end
local table = [=[
<div class="NavFrame" style="{style}max-width:{width}em">
<div class="NavHead" style="background: var(--wikt-palette-grey-blue-1,#EFF7FF)" >{title}
</div>
<div class="NavContent">
{\op}| style="background:var(--wikt-palette-grey-0,#F9F9F9);text-align:center;width:100%" class="inflection-table"
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | infinitive
| {infinitive}
| {infinitive2}
|-
! style="font-size:80%;" | bēacniendlīc
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | andweardnes tīd
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | forþgewiten tīd
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | forma hād ānfealdlic
| {1sg_pres_indc}
| {1sg_past_indc}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | ōþer hād ānfealdlic
| {2sg_pres_indc}
| {2sg_past_indc}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | þridda hād ānfealdlic
| {3sg_pres_indc}
| {3sg_past_indc}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | manigfealdlic
| {pl_pres_indc}
| {pl_past_indc}
|-
! style="font-size:80%;" | underþēodendlic
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | andweardnes tīd
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | forþgewiten tīd
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | ānfealdlic
| {sg_pres_subj}
| {sg_past_subj}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | manigfealdlic
| {pl_pres_subj}
| {pl_past_subj}
|-
! style="font-size:80%;" | bebēodendlic
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" colspan="2" |
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | ānfealdlic
| colspan="2" | {sg_impr}
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" | manigfealdlic
| colspan="2" | {pl_impr}
|-
! style="font-size:80%;" | dǣlnimend
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | andweardnes
! style="font-size:80%; background-color:var(--wikt-palette-grey-indigo-2,#EFEFFF)" | forþgewiten
|-
! style="font-size:90%; background-color:var(--wikt-palette-yellow-2,#FFFFE0); text-align: left" |
| {pres_ptc}
| {past_ptc}
|{\cl}</div></div>]=]
return strutils.format(table, table_args)
end
function export.make_table(frame)
local parent_args = frame:getParent().args
local params = {
["title"] = {default = "—"},
["type"] = {},
["width"] = {},
["style"] = {},
}
for slot, _ in pairs(slots_and_accel) do
params[slot] = {}
end
local args = require("Module:parameters").process(parent_args, params)
return make_table(args)
end
local function vernerize_cons(suf, verner)
if not verner then
return suf
end
local first_cons, cons = rmatch(suf, "^(.*)([sþðh])$")
if not first_cons then
return suf
end
if cons == "s" then
cons = "r"
elseif cons == "þ" or cons == "ð" then
cons = "d"
elseif cons == "h" then
cons = "g"
else
error("Internal error in vernerize_cons(): Unexpected suffix " .. suf)
end
return first_cons .. cons
end
local function depalatalize_final_cons_before_cons(word)
if word:find("sċ$") then
return word
elseif word:find("nċġ$") then
-- crinċġan etc.
return gsub(word, "nċġ$", "ng")
else
return rsub(word, "([nċġ]?[ċġ])$", {
["ċ"] = "c",
["nċ"] = "nc",
["ċċ"] = "cc",
["ġċ"] = "ġc",
["nġ"] = "ng",
["ċġ"] = "cg",
-- ġ and ġġ stay as-is
})
end
end
local function depalatalize_final_cons_before_back_vowel(word)
local word = depalatalize_final_cons_before_cons(word)
return gsub(word, "ġ$", "g")
end
local function palatalize_final_cons(word)
return rsub(word, "([cg]?[cg])$", {
["c"] = "ċ",
["cc"] = "ċċ",
["cg"] = "ċġ",
["g"] = "ġ",
["gc"] = "gċ", -- ??
["gg"] = "ċġ",
})
end
-- Add an ending that begins with a consonant onto a stem, making adjustments
-- as necessary when two consonants come together. Currently recognizes only
-- the three endings "st", "þ" and "d".
local function construct_cons_stem_ending(stem, ending)
-- If the stem ends in a geminate, reduce to single consonant
-- (e.g. fyll-, sett-).
local origstem = stem
local base, final_geminated = rmatch(stem, "^(.-)(" .. non_vowel_c .. ")%2$")
if base then
stem = base .. final_geminated
end
stem = depalatalize_final_cons_before_cons(stem)
if ending == "st" then
-- For 2sg:
-- cyssan + -st -> cyst, tǣsan + -st -> tǣst
-- settan + -st -> setst, myntan + -st -> myn(t)st (?), restan + -st -> restst/rest (?)
-- bǣdan + -st -> bǣtst, sendan + -st -> sen(t)st
-- cȳþan + -st -> cȳst, cwiþ- + -st -> cwist
-- wiex- + -st -> wiext
-- drenċan + -st -> drencst
-- senġan + -st -> sengst
if stem:find("s$") then
return stem .. "t"
elseif stem:find("[dt]$") then
if rfind(stem, vowel_c .. "[dt]$") then
return gsub(stem, "[dt]$", "tst")
elseif rfind(stem, "s[dt]$") then
return gsub(stem, "s[dt]$", "st")
else
return {gsub(stem, "[dt]$", "st"), gsub(stem, "[dt]$", "tst")}
end
elseif rfind(stem, "[þð]$") then
return rsub(stem, "[þð]$", "st")
elseif stem:find("x$") then
return stem .. "t"
else
return stem .. "st"
end
elseif ending == "þ" then
-- For 3sg:
-- cyssan + -þ -> cyst, tǣsan + -þ -> tǣst
-- settan + -þ -> set(t), myntan + -þ -> mynt, restan + -þ -> rest
-- bǣdan + -þ -> bǣt(t), sendan + -þ -> sent
-- cȳþan + -þ -> cȳþ(þ), cwiþ- + -þ -> cwiþ(þ)
-- wiex- + -þ -> wiext
-- drenċan + -þ -> drencþ
-- senġan + -þ -> sengþ
if rfind(stem, vowel_c .. "[dt]$") then
return {gsub(stem, "[dt]$", "tt"), gsub(stem, "[dt]$", "t")}
elseif stem:find("[dt]$") then
return gsub(stem, "[dt]$", "t")
elseif stem:find("[sx]$") then
return stem .. "t"
elseif rfind(stem, "[þð]$") then
return {rsub(stem, "[þð]$", "þþ"), stem}
else
return stem .. "þ"
end
elseif ending == "d" then
-- For past:
-- cyssan + -de -> cyste, tǣsan + -de -> tǣsde
-- settan + -de -> sette, myntan + -de -> mynte, restan + -de -> reste, mētan + -de -> mētte
-- bǣdan + -de -> bǣdde, sendan + -de -> sende, hreddan + -de -> hredde
-- cȳþan + -de -> cȳþde (later cȳdde), ġeorwirþan + -de -> ġeorwirþde, sċeþþan + -de -> sċeþte
-- (? Bosworth-Toller has only sċeþede, and has pæþde for *pæþte from pæþþan)
-- līexan + -de -> līexte
-- pyffan + -de -> pyfte, ġelīefan + -de -> ġelīefde
-- drenċan + -de -> drencte
-- senġan + -de -> sengde
-- cīepan + -de -> cīepte, clyppan + -de -> clypte
-- spillan + -de -> spilde, cierran + -de -> cierde, wemman + -de -> wemde, etc.
if rfind(stem, vowel_c .. "t$") then
return stem .. "t"
elseif rfind(stem, vowel_c .. "d$") then
return stem .. "d"
elseif stem:find("[dt]$") then
return stem
elseif rfind(stem, always_unvoiced_cons_c .. "$") or rfind(origstem, unvoiced_cons_c .. "[sfþð]$") then
return stem .. "t"
else
return stem .. "d"
end
else
error("Unrecognized ending: '" .. ending .. "'")
end
end
-- Default function for combining a stem and an ending. This makes no adjustments
-- to the result other than returning an optional variant ending in -h if the result
-- ends in -g. Example: stīgan preterite stāg or stāh. (Does not apply to a form
-- ending in -ġ.) If adjustments are necessary at the stem/ending boundary, use e.g.
-- construct_cons_stem_ending.
local function default_construct_stem_ending(stem, ending)
local form = stem .. ending
if form:find("g$") and not form:find("[ncg]g$") then
return {form, gsub(form, "g$", "h")}
else
return form
end
end
local function add_form_to_slot(args, slot, form)
if not args[slot] then
args[slot] = {}
end
if type(form) == "string" then
m_table.insertIfNot(args[slot], form)
else
for _, f in ipairs(form) do
m_table.insertIfNot(args[slot], f)
end
end
end
local function add_ending_with_prefix(args, slot, pref, stems, ending, construct_stem_ending)
construct_stem_ending = construct_stem_ending or default_construct_stem_ending
if type(stems) ~= "table" then
stems = {stems}
end
for _, stem in ipairs(stems) do
local form = construct_stem_ending(pref and pref .. stem or stem, ending)
add_form_to_slot(args, slot, form)
end
end
local function add_ending(args, slot, stems, ending, construct_stem_ending)
add_ending_with_prefix(args, slot, nil, stems, ending, construct_stem_ending)
end
local function construct_optional_ge_stem_ending(stem, ending)
return "([[ge" .. stem .. ending .. "|ġe]])[[" .. stem .. ending .. "]]"
end
local function make_non_past(args, presa, presefin, presenfin, pres23, impsg, pp, with_ge)
add_ending(args, "infinitive", presa, "n")
add_ending(args, "infinitive2", presenfin, "nne")
add_ending(args, "1sg_pres_indc", presefin, "")
add_ending(args, "2sg_pres_indc", pres23, "st", construct_cons_stem_ending)
add_ending(args, "3sg_pres_indc", pres23, "þ", construct_cons_stem_ending)
add_ending(args, "pl_pres_indc", presa, "þ")
add_ending(args, "sg_pres_subj", presefin, "")
add_ending(args, "pl_pres_subj", presefin, "n")
add_ending(args, "sg_impr", impsg, "")
add_ending(args, "pl_impr", presa, "þ")
add_ending(args, "pres_ptc", presenfin, "nde")
if with_ge then
add_ending(args, "past_ptc", pp, "", construct_optional_ge_stem_ending)
else
add_ending(args, "past_ptc", pp, "")
end
end
local function make_strong_past(args, pref, pastsg, pastpl)
add_ending_with_prefix(args, "1sg_past_indc", pref, pastsg, "")
add_ending_with_prefix(args, "2sg_past_indc", pref, pastpl, "e")
add_ending_with_prefix(args, "3sg_past_indc", pref, pastsg, "")
add_ending_with_prefix(args, "pl_past_indc", pref, pastpl, "on")
add_ending_with_prefix(args, "sg_past_subj", pref, pastpl, "e")
add_ending_with_prefix(args, "pl_past_subj", pref, pastpl, "en")
end
local function make_strong(presa, prese, pres23, impsg, pastsg, pastpl, pp, with_ge)
local args = {}
make_non_past(args, presa, prese, prese, pres23, impsg, pp, with_ge)
make_strong_past(args, nil, pastsg, pastpl)
return args
end
local function make_weak_past(args, pref, past)
add_ending_with_prefix(args, "1sg_past_indc", pref, past, "e")
add_ending_with_prefix(args, "2sg_past_indc", pref, past, "est")
add_ending_with_prefix(args, "3sg_past_indc", pref, past, "e")
add_ending_with_prefix(args, "pl_past_indc", pref, past, "on")
add_ending_with_prefix(args, "sg_past_subj", pref, past, "e")
add_ending_with_prefix(args, "pl_past_subj", pref, past, "en")
end
local function make_weak(presa, presefin, presenfin, pres23, impsg, past, pp, with_ge)
local args = {}
make_non_past(args, presa, presefin, presenfin, pres23, impsg, pp, with_ge)
make_weak_past(args, nil, past)
return args
end
local strong_verbs = {}
strong_verbs["1"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ī(" .. cons_c .. "+)an$")
if pref then
-- bīdan "await", ācwīnan "dwindle away", sċīnan "shine", spīwan "spew, spit", etc.;
-- stīgan "ascend" (þū stīġst, stāg/stāh [handled by default_construct_stem_ending],
-- stigon, stiġen); blīcan "shine" (þū blīcst/blīċest)
data.pres23 = pref .. "ī" .. palatalize_final_cons(suf)
if suf == "g" then
data.impsg = pref .. "īġ"
else
data.impsg = pref .. "ī" .. suf
end
-- ġīnan "yawn" (gān, ġinon, ġinen)
data.pastsg = depalatalize_final_cons_before_back_vowel(pref) .. "ā" .. suf
-- snīþan "cut" -> snidon; sċrīþan "go, proceed" -> sċridon
-- (but not mīþan "avoid", wrīþan "twist")
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pref .. "i" .. pastsuf
if pastsuf == "g" then
data.pp = pref .. "iġen"
else
data.pp = data.pastpl .. "en"
end
return
end
pref = rmatch(data.inf, "^(.-)[ēī]on$")
if pref then
-- tēon/tīon "accuse" < *tīhanan, similarly lēon "lend" < *līhwanan,
-- sēon "strain" < *sīhwanan, þēon "thrive" < *þinhanan (originally strong 3),
-- wrēon < *wrīhanan. Beware of homonyms e.g. tēon "pull, draw" (strong 2) < *teuhanan,
-- tēon "make, create" (weak) ?< *tīhanan (strong);
-- þēon/þēowan/þȳ(g)(a)n "press" (weak) < *þunhijanan;
-- sēon "see" (strong 5) < *sehwanan
data.contracted = true
data.pres23 = pref .. "īeh"
data.impsg = gsub(data.inf, "n$", "h")
data.pastsg = pref .. "āh"
if rfind(pref, "[þð]$") then
-- þēon "thrive", has remnant strong 3 parts
data.pastpl = {pref .. "ig", pref .. "ung"}
data.pp = {pref .. "iġen", pref .. "ungen"}
else
data.pastpl = pref .. "ig"
if pref:find("s$") then
-- sēon "strain" alt past part siwen
data.pp = {pref .. "iġen", pref .. "iwen"}
else
data.pp = pref .. "iġen"
end
end
return
end
end
strong_verbs["2"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ēo(" .. cons_c .. "+)an$")
if pref then
-- bēodan "command", crēopan "creep"; rēocan "smoke, reek" (þū rīecst/rīeċest);
-- drēogan "endure" (þū drīeġst, drēag/drēah [handled by default_construct_stem_ending],
-- drugon, drogen)
data.pres23 = pref .. "īe" .. palatalize_final_cons(suf)
data.impsg = pref .. "ēo" .. suf
data.pastsg = pref .. "ēa" .. suf
-- ġēotan "pour" (ġēat, guton, goten); ċēosan "choose" (ċēas, curon, coren)
local pastpref = depalatalize_final_cons_before_back_vowel(pref)
-- ċēosan "choose" -> curon; forlēosan "lose" -> forluron; sēoþan "boil" -> sudon
-- (but not ābrēoþan "perish, ruin")
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pastpref .. "u" .. pastsuf
data.pp = pastpref .. "o" .. pastsuf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ū(" .. cons_c .. "+)an$")
if pref then
-- sċūfan "shove"; brūcan "use" (þū brīecst/brīeċest);
-- būgan "bend" (þū bīeġst, bēag/bēah [handled by default_construct_stem_ending],
-- bugon, bogen)
data.pres23 = pref .. "ȳ" .. palatalize_final_cons(suf)
data.impsg = pref .. "ū" .. suf
-- could have palatalization here, but no known examples
data.pastsg = pref .. "ēa" .. suf
-- no known examples of Vernerization, but just in case
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pref .. "u" .. pastsuf
data.pp = pref .. "o" .. pastsuf .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)ēon$")
if pref then
-- tēon "pull, draw" < *teuhanan, flēon "flee"
-- Beware of homonyms, e.g. tēon/tīon "accuse" (strong 1) < *tīhanan,
-- tēon "make, create" (weak) ?< *tīhan (strong)
data.contracted = true
data.pres23 = pref .. "īeh"
data.impsg = gsub(data.inf, "n$", "h")
data.pastsg = pref .. "ēah"
-- no examples where depalatalization is needed
data.pastpl = pref .. "ug"
data.pp = pref .. "ogen"
return
end
end
strong_verbs["3"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)i([mn]" .. cons_c .. "+)an$")
if pref then
-- bindan "bind", climban "climb", ġelimpan "happen", winnan "win",
-- swimman "swim", etc.; ācwincan "vanish" (þū ācwincst/ācwinċest);
-- cringan (þū cringst/crinġest), variant crinċġan (þū cringst/crinċġest)
data.pres23 = pref .. "i" .. palatalize_final_cons(suf)
data.impsg = pref .. "i" .. suf
-- onġinnan "begin" (ongann, ongunnon, ongunnen), ċimban "join"
local pastpref = depalatalize_final_cons_before_back_vowel(pref)
-- no Verner alternation here; expected #fīþan, #fōþ, #fundon <
-- *finþanan, *fanþ, *fundund regularized into findan, fand, fundon;
-- but depalatalize to handle crin(ċ)ġan past crang/crungon/crungen
-- and (maybe?) variant crinċan past cranc/cruncon/cruncen
local pastsuf = depalatalize_final_cons_before_cons(suf)
data.pastsg = pastpref .. "a" .. pastsuf
data.pastpl = pastpref .. "u" .. pastsuf
data.pp = pastpref .. "u" .. pastsuf .. "en"
return
end
local pref, vowel, suf = rmatch(data.inf, "^(.-)(ie)(l" .. cons_c .. "+)an$")
if not pref then
-- ġeldan/ġildan/ġyldan variants of ġieldan; helpan/bellan/delfan etc.
pref, vowel, suf = rmatch(data.inf, "^(.-)([eiy])(l" .. cons_c .. "+)an$")
end
if not pref then
pref, vowel, suf = rmatch(data.inf, "^(.-)(eo)(" .. cons_c .. "+)an$")
end
if pref then
-- helpan "help" (þū hilpst), bellan "bellow", beteldan "cover", delfan "dig",
-- sweltan "die", etc.; belgan "swell with anger" (þū bielġst, bealg/bealh
-- [handled by default_construct_stem_ending])
--
-- ġieldan "yield, pay" (þū ġiel(t)st, hē ġieldeþ/ġielt, ġeald, guldon, golden),
-- ġiellan "yell", ġielpan "boast"
--
-- weorpan "throw" (þū wierpst), feohtan "fight", sċeorfan "gnaw";
-- āseolcan "languish" (þū āsielcst/āsielċest), beorgan "protect"
-- (þū bierġst, bearg/bearh [handled by default_construct_stem_ending])
data.pres23 = pref .. (vowel == "e" and "i" or vowel == "eo" and "ie" or vowel) .. palatalize_final_cons(suf)
data.impsg = pref .. vowel .. suf
data.pastsg = pref .. "ea" .. suf
-- ġieldan etc. (see above)
local pastpref = depalatalize_final_cons_before_back_vowel(pref)
-- weorþan -> wurdon
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pastpref .. "u" .. pastsuf
data.pp = pastpref .. "o" .. pastsuf .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)eġdan$")
if pref then
-- breġdan "brandish" (þū breġdest, hē breġdeþ, bræġd/brǣd, brugdon, brogden)
-- streġdan "strew" (like breġdan)
data.pres23 = pref .. "eġde"
data.impsg = pref .. "eġd"
data.pastsg = {pref .. "æġd", pref .. "ǣd"}
data.pastpl = pref .. "ugd"
data.pp = pref .. "ogden"
return
end
local pref, suf = rmatch(data.inf, "^(.-)(ie?rn)an$")
if not pref then
pref, suf = rmatch(data.inf, "^(.-)(yrn)an$")
end
if pref then
-- biernan/birnan/byrnan "burn" < *brinnanan (þū biernst, barn/born/bearn, burnon, burnen)
-- iernan/irnan/yrnan "run" < *rinnan (like biernan)
data.pres23 = pref .. suf
data.impsg = data.pres23
data.pastsg = {pref .. "arn", pref .. "orn", pref .. "earn"}
data.pastpl = pref .. "urn"
data.pp = pref .. "urnen"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)([ou])rnan$")
if pref then
-- murnan "mourn" (þū myrnst, mearn, murnon, — but BT documents mornen)
-- spurnan/spornan "spurn" (þū spyrnst, spearn, spurnon, spornen)
data.pres23 = pref .. "yrn"
data.impsg = pref .. vowel .. "rn"
data.pastsg = pref .. "earn"
data.pastpl = pref .. "urn"
data.pp = pref .. "ornen"
return
end
local pref, suf = rmatch(data.inf, "^(.-)e(r" .. cons_c .. "+)an$")
if pref then
-- berstan "burst" < *brestanan (þū birst, hē birsteþ/birst, bærst, burston, borsten)
-- þersċan "thrash, thresh" < *þreskanan (þū þirsċst, hē þirsċeþ, þærsċ, þursċon, þorsċen)
data.pres23 = pref .. "i" .. suf
data.impsg = pref .. "e" .. suf
data.pastsg = pref .. "æ" .. suf
data.pastpl = pref .. "u" .. suf
data.pp = pref .. "o" .. suf .. "en"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)fr([ei])ġnan$")
if pref then
-- friġnan "ask", variant freġnan
data.pres23 = {pref .. "friġne", pref .. "friġn"}
data.impsg = pref .. "fr" .. vowel .. "ġn"
data.pastsg = pref .. "fræġn"
data.pastpl = pref .. "frugn"
data.pp = pref .. "frugnen"
return
end
local pref = rmatch(data.inf, "^(.-)frīnan$")
if pref then
-- frīnan "ask" variant of friġnan
data.pres23 = {pref .. "frīne", pref .. "frīn"}
data.impsg = pref .. "frīn"
data.pastsg = pref .. "frān"
data.pastpl = pref .. "frūn"
data.pp = pref .. "frūnen"
return
end
local pref = rmatch(data.inf, "^(.-)fēolan$")
if pref then
-- fēolan "enter, penetrate"
data.pres23 = {pref .. "fielh", pref .. "filh"}
data.impsg = pref .. "feolh"
data.pastsg = pref .. "fealh"
data.pastpl = {pref .. "fǣl", pref .. "fulg", pref .. "fūl"}
data.pp = {pref .. "folgen", pref .. "fōlen"}
return
end
end
strong_verbs["4"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ie(" .. cons_c .. ")an$")
if pref then
-- sċieran "shear"
data.pres23 = {pref .. "ie" .. suf .. "e", pref .. "ie" .. suf}
data.impsg = pref .. "ie" .. suf
-- no Verner alternation or depalatalization here
data.pastsg = pref .. "ea" .. suf
data.pastpl = pref .. "ēa" .. suf
data.pp = pref .. "o" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)e(" .. cons_c .. ")an$")
if pref then
-- beran "bear, carry", cwelan "die", brecan "break" (þū bricst/briċest), etc.
if suf == "r" or suf == "l" then
data.pres23 = {pref .. "i" .. suf .. "e", pref .. "i" .. suf}
else
data.pres23 = pref .. "i" .. palatalize_final_cons(suf)
end
data.impsg = pref .. "e" .. suf
-- no Verner alternation or depalatalization here
data.pastsg = pref .. "æ" .. suf
data.pastpl = pref .. "ǣ" .. suf
data.pp = pref .. "o" .. suf .. "en"
return
end
-- Next two are irregular but occur with so many prefixes that we special-case them here.
local pref = rmatch(data.inf, "^(.-)cuman$")
if pref then
-- cuman "come"
data.pres23 = {pref .. "cyme", pref .. "cym"}
data.impsg = pref .. "cum"
data.pastsg = {pref .. "cōm", pref .. "cwōm"}
data.pastpl = data.pastsg
data.pp = {pref .. "cumen", pref .. "cymen"}
return
end
local pref = rmatch(data.inf, "^(.-)niman$")
if pref then
-- niman "take"
data.pres23 = {pref .. "nime", pref .. "nim"}
data.impsg = pref .. "nim"
data.pastsg = pref .. "nōm"
data.pastpl = data.pastsg
data.pp = pref .. "numen"
return
end
end
strong_verbs["5"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ie(" .. cons_c .. ")an$")
if not pref then
pref, suf = rmatch(data.inf, "^(.-ġ)[eiy](" .. cons_c .. ")an$")
end
if pref then
-- ġiefan "give", forġietan "forget"
data.pres23 = pref .. "ie" .. suf
data.impsg = data.pres23
data.pastsg = pref .. "ea" .. suf
data.pastpl = pref .. "ēa" .. suf
data.pp = pref .. "e" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)e(" .. cons_c .. ")an$")
if suf == "g" then
-- wegan "carry"; special-case
data.pres23 = pref .. "iġ"
data.impsg = pref .. "eġ"
data.pastsg = pref .. "æġ"
data.pastpl = {pref .. "ǣg", pref .. "āg"}
data.pp = pref .. "eġen"
return
elseif pref then
-- metan "measure", sprecan "speak", cnedan "knead", wefan "weave", etc.
data.pres23 = pref .. "i" .. palatalize_final_cons(suf)
data.impsg = pref .. "e" .. suf
if suf == "t" and not pref:find("m$") and not pref:find("ġ$") then
-- etan "eat", fretan "devour", compounds; exclude metan "measure",
-- ġetan (potential variant of ġietan)
data.pastsg = pref .. "ǣ" .. suf
else
data.pastsg = pref .. "æ" .. suf
end
-- cweþan "say" -> cwǣdon, wesan "be" -> wǣron
-- (but not ġenesan "be saved", lesan "collect, gather")
local pastsuf = vernerize_cons(suf, data.verner)
data.pastpl = pref .. "ǣ" .. pastsuf
if data.inf:find("drepan$") then
-- Special-case drepan "strike, slay"; Wright lists brecan here with
-- pp only brocen, but that just makes it a strong-4 verb and that's
-- where it's normally listed in dictionaries
data.pp = {pref .. "epen", pref .. "open"}
else
data.pp = pref .. "e" .. pastsuf .. "en"
end
return
end
local pref, last_cons = rmatch(data.inf, "^(.-)i([dt])%2an$")
if pref then
-- biddan "pray", sittan "sit"
data.jpres = true
data.pres23 = pref .. "i" .. last_cons
data.impsg = data.pres23 .. "e"
data.pastsg = pref .. "æ" .. last_cons
data.pastpl = pref .. "ǣ" .. last_cons
data.pp = pref .. "e" .. last_cons .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)iċġe?an$")
if pref then
-- liċġan "lie down", þiċġan "receive", friċġan "ask, inquire"
data.jpres = true
data.pres23 = pref .. "iġ"
data.impsg = data.pres23 .. "e"
if rfind(data.inf, "[þð]iċġe?an$") then
data.pastsg = {pref .. "eah", pref .. "ah"}
else
data.pastsg = pref .. "æġ"
end
data.pastpl = {pref .. "ǣg", pref .. "āg"}
if data.inf:find("friċġe?an$") then
data.pp = {pref .. "iġen", pref .. "ugen"}
else
data.pp = pref .. "eġen"
end
return
end
local pref = rmatch(data.inf, "^(.-)ēon$")
if pref then
-- sēon "see" < *sehwanan, ġefēon "rejoice" < *gafehanan, plēon "risk" < *plehanan
data.contracted = true
data.pres23 = pref .. "ieh"
data.impsg = pref .. "eoh"
data.pastsg = pref .. "eah"
if pref:find("s$") then
-- sēon "see"
data.pastpl = pref .. "āw"
data.pp = pref .. "ewen"
else
data.pastpl = pref .. "ǣg"
data.pp = pref .. "eġen"
end
return
end
end
strong_verbs["6"] = function(data)
local pref, suf = rmatch(data.inf, "^(.-)ea(" .. cons_c .. "+)an$")
if pref then
-- sċ(e)acan "shake", sċ(e)afan "shave, scrape"
data.pres23 = pref .. "ea" .. suf
data.impsg = {pref .. "a" .. suf, data.pres23}
data.pastsg = {pref .. "ō" .. suf, pref .. "eō" .. suf}
data.pastpl = data.pastsg
data.pp = {pref .. "a" .. suf .. "en", pref .. "ea" .. suf .. "en"}
return
end
local pref, vowel, suf = rmatch(data.inf, "^(.-)(a)(" .. cons_c .. "+)an$")
if not pref then
-- stondan variant of standan, sponan variant of spanan
pref, vowel, suf = rmatch(data.inf, "^(.-)(o)(n" .. cons_c .. "*)an$")
end
if not pref then
-- wæsċan/wasċean/wæsċean variant of wasċan
pref, vowel, suf = rmatch(data.inf, "^(.-)([aæ])(sċ" .. cons_c .. "*)e?an$")
end
if suf == "g" then
-- gnagan "gnaw", dragan "draw"
data.pres23 = pref .. "æġ"
data.impsg = pref .. "ag"
data.pastsg = pref .. "ōg"
data.pastpl = data.pastsg
data.pp = {pref .. "æġen", pref .. "agen"}
return
elseif suf == "nd" and pref:find("st$") then
-- standan/stondan "stand"
data.pres23 = pref .. "end"
data.impsg = pref .. vowel .. "nd"
data.pastsg = pref .. "ōd"
data.pastpl = data.pastsg
data.pp = pref .. vowel .. "nden"
return
elseif suf == "n" and pref:find("sp$") then
-- spanon/sponan "allure"
data.pres23 = {pref .. "ene", pref .. "en"}
data.impsg = pref .. vowel .. "n"
data.pastsg = {pref .. "ōn", pref .. "ēon"} -- has alt class VII past
data.pastpl = data.pastsg
data.pp = pref .. vowel .. "nen"
return
elseif pref then
-- faran "go", alan "grow", bacan "bake", hladan "lade", wasċan "wash", etc.
if suf == "r" or suf == "l" or suf == "sċ" then
data.pres23 = {pref .. "æ" .. suf .. "e", pref .. "æ" .. suf}
else
data.pres23 = pref .. "æ" .. palatalize_final_cons(suf)
end
data.impsg = pref .. "a" .. suf
data.pastsg = pref .. "ō" .. suf
-- Apparently no Verner variation here
data.pastpl = data.pastsg
data.pp = {pref .. "æ" .. suf .. "en", pref .. "a" .. suf .. "en"}
return
end
local pref = rmatch(data.inf, "^(.-)ēan$")
if pref then
-- slēan "strike", flēan "flay", lēan "blame", þwēan "wash"
data.contracted = true
data.pres23 = pref .. "ieh"
data.impsg = pref .. "eah"
data.pastsg = pref .. "ōg" -- also slōh etc., which will get automatically added
data.pastpl = data.pastsg
data.pp = {pref .. "æġen", pref .. "agen", pref .. "eġen"}
return
end
-- All the j-present verbs have to be handled individually as each has
-- idiosyncrasies.
local pref, last_cons = rmatch(data.inf, "^(.-)hebban$")
if pref then
-- hebban "raise"
data.jpres = true
data.pres23 = pref .. "hefe"
data.impsg = data.pres23
data.pastsg = pref .. "hōf"
data.pastpl = data.pastsg
data.pp = {pref .. "hæfen", pref .. "hafen", pref .. "hefen"}
return
end
local pref, vowel = rmatch(data.inf, "^(.-)hl([iy]?e?)hhan$")
if pref then
-- hliehhan "laugh"
data.jpres = true
data.pres23 = pref .. "hl" .. vowel .. "h"
data.impsg = data.pres23
data.pastsg = pref .. "hlōg"
data.pastpl = data.pastsg
data.pp = pref .. "hlæġen"
return
end
local pref, cons = rmatch(data.inf, "^(.-)sċe([þð])%2an$")
if pref then
-- sċeþþan "injure" (for some reason, expected #sċieþþan doesn't occur)
data.jpres = true
data.pres23 = pref .. "sċe" .. cons .. "e"
data.impsg = data.pres23
data.pastsg = "sċōd"
data.pastpl = data.pastsg
data.pp = "sċeaþen"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)sċ([iy]?e?)ppan$")
if pref then
-- sċieppan "create"
data.jpres = true
data.pres23 = pref .. "sċ" .. vowel .. "pe"
data.impsg = data.pres23
data.pastsg = {pref .. "sċōp", pref .. "sċeōp"}
data.pastpl = data.pastsg
data.pp = {pref .. "sċeapen", pref .. "sċapen"}
return
end
local pref, vowel = rmatch(data.inf, "^(.-)st([æe])ppan$")
if pref then
-- stæppan "step, go"
data.jpres = true
data.pres23 = pref .. "st" .. vowel .. "pe"
data.impsg = data.pres23
data.pastsg = pref .. "stōp"
data.pastpl = data.pastsg
data.pp = {pref .. "stæpen", pref .. "stapen"}
return
end
local pref = rmatch(data.inf, "^(.-s[wƿ])erian$")
if pref then
-- swerian "swear"
data.jpres = true
data.pres23 = pref .. "ere"
data.impsg = data.pres23
data.pastsg = pref .. "ōr"
data.pastpl = data.pastsg
data.pp = pref .. "oren" -- on the analogy of class IV verbs like beran
return
end
end
strong_verbs["7"] = function(data)
-- Type (7a) verbs
local pref = rmatch(data.inf, "^(.-)hātan$")
if pref then
-- hātan "call"
data.pres23 = pref .. "hǣt"
data.impsg = pref .. "hāt"
data.pastsg = {pref .. "hēt", pref .. "hēht"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "hāten"
return
end
local pref = rmatch(data.inf, "^(.-)lācan$")
if pref then
-- lācan "play"
data.pres23 = pref .. "lǣċ"
data.impsg = pref .. "lāc"
data.pastsg = {pref .. "lēc", pref .. "leolc"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "lācen"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)sċ(e?ā)dan$")
if not pref then
pref, vowel = rmatch(data.inf, "^(.-)sċ(ēa)dan$")
end
if pref then
-- sċ(e)ādan or sċēadan "separate"
data.pres23 = pref .. "sċēad"
data.impsg = pref .. "sċ" .. vowel .. "d"
data.pastsg = {pref .. "sċēd", pref .. "sċēad"}
data.pastpl = data.pastsg
data.pp = pref .. "sċ" .. vowel .. "den"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)lǣtan$")
if pref then
-- lǣtan "let, allow"
data.pres23 = pref .. "lǣt"
data.impsg = pref .. "lǣt"
data.pastsg = {pref .. "lēt", pref .. "leort"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "lǣten"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)ondrǣdan$")
if pref then
-- ondrǣdan "dread, fear"
data.pres23 = pref .. "ondrǣd"
data.impsg = pref .. "ondrǣd"
data.pastsg = {pref .. "ondrēd", pref .. "ondreord"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
make_weak_past(data.extraforms, pref, "ondrǣdd")
data.pp = pref .. "ondrǣden"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)rǣdan$")
if pref then
-- rǣdan "advise"
data.pres23 = pref .. "rǣd"
data.impsg = pref .. "rǣd"
-- NOTE: Also (mostly) has weak past rǣdde and pp (ġe)rǣdd; can be handled
-- by declaring the verb as both weak 1b and strong 7.
data.pastsg = {pref .. "rēd", pref .. "reord"} -- FIXME, indicate latter as poetic
data.pastpl = data.pastsg
data.pp = pref .. "rǣden"
return
end
local pref, vowel = rmatch(data.inf, "^(.-)slǣpan$")
if pref then
-- slǣpan "sleep"
data.pres23 = pref .. "slǣp"
data.impsg = pref .. "slǣp"
data.pastsg = pref .. "slēp"
data.pastpl = data.pastsg
make_weak_past(data.extraforms, pref, "slǣpt")
data.pp = pref .. "slǣpen"
return
end
local pref, main = rmatch(data.inf, "^(.-)(gr[ǣē]t)an$")
if pref then
-- grǣtan "wail"
data.pres23 = pref .. main
data.impsg = pref .. main
data.pastsg = pref .. "grēt"
data.pastpl = data.pastsg
data.pp = pref .. main .. "en"
return
end
local pref = rmatch(data.inf, "^(.-)blandan$")
if pref then
-- blandan "mix"
data.pres23 = pref .. "blend"
data.impsg = pref .. "bland"
data.pastsg = pref .. "blēnd"
data.pastpl = data.pastsg
data.pp = pref .. "blanden"
return
end
local pref = rmatch(data.inf, "^(.-)ōn$")
if pref then
-- fōn "seize", hōn "hang"
data.contracted = true
data.pres23 = pref .. "ēh"
data.impsg = pref .. "ōh"
data.pastsg = pref .. "ēng"
data.pastpl = data.pastsg
data.pp = {pref .. "angen"}
return
end
-- Type (7b) verbs
local pref = rmatch(data.inf, "^(.-)annan$")
if pref then
-- bannan "summon", spannan "join, clasp"
data.pres23 = pref .. "enn"
data.impsg = pref .. "ann"
data.pastsg = {pref .. "ēonn", pref .. "ēon"}
data.pastpl = data.pastsg
data.pp = pref .. "annen"
return
end
local pref = rmatch(data.inf, "^(.-)gangan$")
if pref then
-- gangan "go"
data.pres23 = pref .. "geng"
data.impsg = pref .. "gang"
data.pastsg = {pref .. "ġēng", pref .. "ġīeng"}
data.pastpl = data.pastsg
data.pp = pref .. "gangen"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ea(" .. cons_c .. "+)an$")
if pref then
-- fealdan "fold", feallan "fall", healdan "hold", stealdan "possess",
-- wealcan "roll", wealdan "rule", weallan "boil", weaxan "grow"
data.pres23 = pref .. "ie" .. palatalize_final_cons(suf)
data.impsg = pref .. "ea" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ea" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ā(" .. cons_c .. "+)an$")
if pref then
-- blāwan "blow", cnāwan "know", crāwan "crow", māwan "mow", sāwan "sow",
-- swāpan "sweep", þrāwan "turn, twist", wāwan "blow"
data.pres23 = pref .. "ǣ" .. palatalize_final_cons(suf)
data.impsg = pref .. "ā" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ā" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ēa(" .. cons_c .. "+)an$")
if pref then
-- bēatan "beat", āhnēapan "pluck off", hēawan "hew", hlēapan "leap"
data.pres23 = pref .. "īe" .. palatalize_final_cons(suf)
data.impsg = pref .. "ēa" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ēa" .. suf .. "en"
return
end
local pref, suf = rmatch(data.inf, "^(.-)ō(" .. cons_c .. "+)an$")
if pref then
if suf == "g" and pref:find("sw$") then
-- swōgan "sound"
data.pres23 = pref .. "ēġ"
data.impsg = pref .. "ōg"
data.pastsg = {} -- no preterite
data.pastpl = {}
data.pp = pref .. "ōgen"
return
end
if suf == "c" and pref:find("fl$") or suf == "t" and rfind(pref, "[wƿ]r$") then
-- flōcan "clap, strike", wrōtan "root up"
data.pres23 = pref .. "ē" .. palatalize_final_cons(suf)
data.impsg = pref .. "ō" .. suf
data.pastsg = {} -- no preterite
data.pastpl = {}
data.pp = pref .. "ō" .. suf .. "en"
return
end
-- blōtan "sacrifice", blōwan "bloom, blossom", hrōpan "shout",
-- hwōpan "threaten", flōwan "flow", grōwan "grow", hlōwan "low, bellow",
-- spōwan "succeed"; also rōwan "row", which has alt pret pl rēon
data.pres23 = pref .. "ē" .. palatalize_final_cons(suf)
data.impsg = pref .. "ō" .. suf
data.pastsg = pref .. "ēo" .. suf
data.pastpl = data.pastsg
data.pp = pref .. "ō" .. suf .. "en"
if (suf == "w" or suf == "ƿ") and pref:find("r$") and not pref:find("gr$") then
-- rōwan "row"
data.extraforms["pl_past_indc"] = {pref .. "ēon"}
end
return
end
local pref = rmatch(data.inf, "^(.-[wƿ])ēpan$")
if pref then
-- wēpan "weep"; j-present
data.jpres = true
data.pres23 = pref .. "ēp"
data.impsg = pref .. "ēp"
data.pastsg = pref .. "ēop"
data.pastpl = data.pastsg
data.pp = pref .. "ōpen"
return
end
end
local weak_verbs = {}
weak_verbs["1a"] = function(data)
data.stem_weight = "light"
local pref = rmatch(data.inf, "^(.-)ian$")
if pref then
data.pres23 = pref .. "e"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
local pref, last_cons = rmatch(data.inf, "^(.-)([dt])%2an$")
if pref then
data.pres23 = pref .. last_cons
data.impsg = data.pres23 .. "e"
data.past = data.pres23 .. last_cons
data.pp = {data.pres23 .. "ed", data.past, data.pres23}
return
end
local pref = rmatch(data.inf, "^(.-)ċġe?an$")
if pref then
data.pres23 = pref .. "ġ"
data.impsg = data.pres23 .. "e"
data.past = data.pres23 .. "d"
data.pp = {data.pres23 .. "ed", data.past}
return
end
local pref = rmatch(data.inf, "^(.-)bban$")
if pref then
-- swebban etc.
data.pres23 = pref .. "fe"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
local pref, last_cons = rmatch(data.inf, "^(.-)(.)%2an$")
if not pref then
pref, last_cons = rmatch(data.inf, "^(.-)(ċ)ċean$")
end
if pref then
data.pres23 = pref .. last_cons .. "e"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
end
weak_verbs["1b"] = function(data)
data.stem_weight = "heavy"
local pref, cons = rmatch(data.inf, "^(.-[rl])([wƿ])an$")
if pref then
-- ġierwan, hierwan, nierwan, sierwan, smierwan, wielwan (?)
data.pres23 = pref .. "e"
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = {pref .. cons .. "ed", pref .. "ed"}
return
end
local pref = rmatch(data.inf, "^(.-" .. cons_c .. "[rlmnwƿ])an$")
if pref and not pref:find("[rl][mn]$") and not pref:find("rl$") and not rfind(pref, "(" .. cons_c .. ")%1$") then
-- hyngran, dīeglan, bīecnan, þrysman, etc.
data.pres23 = pref .. "e"
data.impsg = data.pres23
local vowel = rmatch(pref, "^.-(" .. vowel_c .. "+)" .. single_cons_c .. "[rlmnwƿ]$")
if vowel and not ends_in_long_vowel(vowel) then
-- efnan, bytlan, eġlan, ræfnan, seġlan, þrysman; form without -ed is older
data.past = {pref .. "d", pref .. "ed"}
else
-- dīeglan, forglendran, wrixlan, frēfran, timbran, symblan, etc.
data.past = pref .. "ed"
end
data.pp = pref .. "ed"
return
end
if data.inf:find("ēan$") or rfind(data.inf, vowel_c .. "n$") and not data.inf:find("an$") then
-- contracted verb, e.g. hēan, þēon, tȳn, rȳn, þȳn
-- FIXME, verify in Campbell that all of the following are correct
data.pres23 = data.presa
data.impsg = data.presa
data.past = data.presa .. "d"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)an$")
if pref then
data.pres23 = {pref .. "e", pref}
data.impsg = pref
data.past = construct_cons_stem_ending(pref, "d")
data.pp = pref .. "ed"
return
end
end
weak_verbs["1"] = function(data)
local weaktype
if data.inf:find("ian$") then
weaktype = "1a"
elseif rfind(data.inf, "(" .. cons_c .. ")%1an$") or data.inf:find("ċċean$") or data.inf:find("cgan$") or data.inf:find("ċġan$") then
local prev = rmatch(data.inf, "^(.-)....$")
if rfind(prev, vowel_c .. "$") and not ends_in_long_vowel(prev) then
weaktype = "1a"
else
weaktype = "1b"
end
else
weaktype = "1b"
end
weak_verbs[weaktype](data)
end
weak_verbs["2"] = function(data)
-- lufian
local pref, suf = rmatch(data.inf, "^(.-)(ian)$")
if not pref then
-- lufiġan, lufeġan, lufiġean, lufeġean (alternative spellings)
pref, suf = rmatch(data.inf, "^(.-)([ei]ġe?an)$")
end
if pref then
data.pres23 = pref .. "a"
data.presenfin = data.prese
data.presefin = suf == "ian" and pref .. "iġe" or data.presenfin
data.impsg = data.pres23
data.past = pref .. "od"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)ġe?an$")
if pref then
-- twēoġan, smēaġ(e)an
data.pres23 = pref
data.impsg = data.pres23
data.past = data.pres23 .. "d"
data.pp = data.past
return
end
end
weak_verbs["3"] = function(data)
local pref = rmatch(data.inf, "^(.-)abban$")
if pref then
data.prese = pref .. "æbbe"
data.pres23 = pref .. "æf"
data.impsg = pref .. "afa"
data.past = pref .. "æfd"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)libban$")
if pref then
-- libban, compounds
data.pres23 = pref .. "leofa"
data.impsg = data.pres23
data.past = pref .. "lifd"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)seċġe?an$")
if pref then
-- seċġan, compounds
data.pres23 = pref .. "sæġ"
data.impsg = pref .. "sæġe"
data.past = pref .. "sæġd"
data.pp = data.past
return
end
local pref = rmatch(data.inf, "^(.-)hyċġe?an$")
if pref then
-- hyċġan, compounds
data.pres23 = pref .. "hyġ"
data.impsg = pref .. "hyġe"
data.past = pref .. "hogd"
data.pp = data.past
return
end
end
local function make_irregular_non_past(args, inf, pref, pres1, pres2, pres3, prespl,
presp, subj, impsg, imppl, pp, with_ge)
add_ending(args, "infinitive", inf, "")
add_ending_with_prefix(args, "infinitive2", pref, presp, "ne")
add_ending_with_prefix(args, "1sg_pres_indc", pref, pres1, "")
add_ending_with_prefix(args, "2sg_pres_indc", pref, pres2, "")
add_ending_with_prefix(args, "3sg_pres_indc", pref, pres3, "")
add_ending_with_prefix(args, "pl_pres_indc", pref, prespl, "")
add_ending_with_prefix(args, "sg_pres_subj", pref, subj, "")
add_ending_with_prefix(args, "pl_pres_subj", pref, subj, "n")
add_ending_with_prefix(args, "sg_impr", pref, impsg, "")
add_ending_with_prefix(args, "pl_impr", pref, imppl, "")
add_ending_with_prefix(args, "pres_ptc", pref, presp, "de")
if with_ge then
add_ending_with_prefix(args, "past_ptc", pref, pp, "", construct_optional_ge_stem_ending)
else
add_ending_with_prefix(args, "past_ptc", pref, pp, "")
end
end
-- Construct all preterite-present forms. Each of the arguments can be a single string or list.
-- If a given argument is missing, supply an empty list {}.
-- Arguments:
-- INF: Infinitive.
-- PREF: Prefix to add to all forms other than the infinitive.
-- PRES13: 1st/3rd singular present form.
-- PRES2: 2nd singular present form.
-- PRESPL: Plural present form.
-- PRESP: Present participle stem (up through -en, missing final -de; also used to construct
-- second infinitive by adding -ne)
-- SUBJ: Singular present subjunctive form (also used to construct plural subjunctive by adding -n)
-- IMPSG: 2nd singular imperative form.
-- IMPPL: 2nd plural imperative form.
-- PAST: Stem of past tense.
-- PP: Past participle.
local function make_preterite_present_forms(inf, pref, pres13, pres2, prespl,
presp, subj, impsg, imppl, past, pp, with_ge)
local args = {}
make_irregular_non_past(args, inf, pref, pres13, pres2, pres13, prespl, presp, subj,
impsg, imppl, pp, with_ge)
make_weak_past(args, pref, past)
return args
end
local function make_preterite_present(inf, with_ge)
local pref, vowel = rmatch(inf, "^(.-[wƿn])([iy])[oe]?tan$")
if pref then
return make_preterite_present_forms(
inf, pref, "āt", "āst", vowel .. "ton", vowel .. "ten",
vowel .. "te", vowel .. "te", vowel .. "taþ", {vowel .. "ss", vowel .. "st"},
vowel .. "ten", with_ge)
end
local pref = rmatch(inf, "^(.-)dugan$")
if pref then
return make_preterite_present_forms(
inf, pref, "dēag", "dēaht", "dugon", "dugen", "dyġe", "dyġe", "dugaþ", "doht", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)cunnan$")
if pref then
return make_preterite_present_forms(
inf, pref, "cann", "canst", "cunnon", "cunnen", "cunne",
"cunne", "cunnaþ", "cūþ", "cunnen", with_ge)
end
local pref = rmatch(inf, "^(.-)unnan$")
if pref then
return make_preterite_present_forms(
inf, pref, "ann", "anst", "unnon", "unnen", "unne", "unne", "unnaþ", "ūþ", "unnen", with_ge)
end
local pref = rmatch(inf, "^(.-[þð])urfan$")
if pref then
return make_preterite_present_forms(
inf, pref, "earf", "earft", "urfon", "earfen", "yrfe", "yrfe", "urfaþ", "orft", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)durran$")
if pref then
return make_preterite_present_forms(
inf, pref, "dearr", "dearst", "durron", {}, "dyrre", "dyrre", "durfaþ",
"dorst", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)sċulan$")
if not pref then
pref = rmatch(inf, "^(.-)sċeolan$")
end
if pref then
return make_preterite_present_forms(
inf, pref, "sċeal", "sċealt", "sċulon", {}, "sċyle",
{}, {}, "sċeold", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)munan$")
if pref then
return make_preterite_present_forms(
inf, pref, "man", "manst", "munon", "munen", "myne",
{"mun", "myne"}, "munaþ", "mund", "munen", with_ge)
end
local pref = rmatch(inf, "^(.-)magan$")
if pref then
return make_preterite_present_forms(
inf, pref, "mæġ", "meaht", "magon", "magen", "mæġe", {}, {},
{"meaht", "meht"}, {}, with_ge)
end
local pref = rmatch(inf, "^(.-)nugan$")
if pref then
return make_preterite_present_forms(
inf, pref, "neah", {}, "nugon", {}, "nuge", {}, {}, "noht", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)mōtan$")
if pref then
return make_preterite_present_forms(
inf, pref, "mōt", "mōst", "mōton", {}, "mōte", {}, {}, "mōst", {}, with_ge)
end
local pref = rmatch(inf, "^(.-)āgan$")
if pref then
return make_preterite_present_forms(
inf, pref, "āh", "āhst", "āgon", "āgen", "āge", "āge", "āgaþ", "āht", "āgen", with_ge)
end
error("Unrecognized preterite-present verb: " .. inf)
end
local function make_irregular(inf, with_ge)
local args = {}
local pref, cons = rmatch(inf, "^(.-)([wƿ])esan$")
if pref then
make_irregular_non_past(args, inf, pref, "eom", "eart", "is", {"sind", "sindon"},
cons .. "esen", "sīe", cons .. "es", cons .. "esaþ", {}, with_ge)
make_strong_past(args, pref, cons .. "æs", cons .. "ǣr")
return args
end
local pref = rmatch(inf, "^(.-)nesan$")
if pref then
make_irregular_non_past(args, inf, pref, "neom", "neart", "nis", {"ne sind", "ne sindon"},
"nesen", "ne sīe", "nes", "nesaþ", {}, with_ge)
make_strong_past(args, pref, "næs", "nǣr")
return args
end
local pref, vowel = rmatch(inf, "^(.-)b([īē]o)n$")
if pref then
make_irregular_non_past(args, inf, pref, "b" .. vowel, "bist", "biþ", "b" .. vowel .. "þ",
"b" .. vowel .. "n", "b" .. vowel, "b" .. vowel, "b" .. vowel .. "þ", "b" .. vowel .. "n", with_ge)
return args
end
local pref = rmatch(inf, "^(.-)dōn$")
if pref then
make_irregular_non_past(args, inf, pref, "dō", "dēst", "dēþ", "dōþ", "dōn",
"dō", "dō", "dōþ", "dōn", with_ge)
make_weak_past(args, pref, "dyd")
return args
end
local pref = rmatch(inf, "^(.-)gān$")
if pref then
make_irregular_non_past(args, inf, pref, "gā", "gǣst", "gǣþ", "gāþ", "gān",
"gā", "gā", "gāþ", "gān", with_ge)
make_weak_past(args, pref, "ēod")
return args
end
local pref = rmatch(inf, "^(.-[wƿ])illan$")
if pref then
make_irregular_non_past(args, inf, pref, "ille", "ilt", "ile", "illaþ", "illen",
"ille", {}, {}, {}, with_ge)
make_weak_past(args, pref, "old")
return args
end
local pref, vowel = rmatch(inf, "^(.-)n([eiy])llan$")
if pref then
make_irregular_non_past(args, inf, pref, "n" .. vowel .. "lle", "n" .. vowel .. "lt",
"n" .. vowel .. "le", "n" .. vowel .. "llaþ",
"n" .. vowel .. "llen", "n" .. vowel .. "lle",
{}, {}, {}, with_ge)
make_weak_past(args, pref, "nold")
return args
end
error("Unrecognized irregular verb: " .. inf)
end
local function set_categories(typ, class, jpres, stem_weight, contracted)
local cats = {}
local classtext = class and "class " .. class .. " " or ""
if typ == "strong" then
insert(cats, "Englisc " .. classtext .. "strang word")
if jpres then
insert(cats, "Englisc " .. classtext .. "strang j-andweard word")
elseif contracted then
insert(cats, "Englisc " .. classtext .. "strang scortod word")
end
elseif typ == "weak" then
insert(cats, "Englisc " .. classtext .. "unstrang word")
if jpres then
insert(cats, "Englisc " .. classtext .. "unstrang j-andweard word")
elseif stem_weight then
insert(cats, "Englisc " .. classtext .. "unstrang " .. stem_weight .. "-stefn word")
end
elseif typ == "pretpres" then
insert(cats, "Englisc forþgewiten-andweard word")
elseif typ == "irreg" or typ == "anomalous" then
insert(cats, "Englisc ungemǣne word")
elseif typ then
error("Unrecognized verb type: " .. typ)
end
return cats
end
function export.show(frame)
local parent_args = frame:getParent().args
local params = {
[1] = {required = true, list = true, default = "beran<s4>"},
}
for slot, _ in pairs(slots_and_accel) do
params[slot] = {}
end
local args = require("Module:parameters").process(parent_args, params)
local allforms
local allcats = {}
if #args[1] > 1 then
insert(allcats, "Old English verbs with multiple conjugations")
end
for _, infspec in ipairs(args[1]) do
local inf, spec = rmatch(infspec, "^(.-)<(.*)>$")
if not inf then
error("Verb spec should look like e.g. 'beran<s4>' or 'dēman<w1>': " .. infspec)
end
local specs = rsplit(spec, "/")
local class = specs[1]
local verner = rfind(class, "v")
class = gsub(class, "v", "")
local presa = gsub(inf, "n$", "")
data = {
inf = inf,
presa = presa,
prese = presa:find("ēa$") and presa or gsub(presa, "e?a$", "e"),
verner = verner,
with_ge = not begins_with_verbal_prefix(inf),
extraforms = {},
}
local typ
if class:find("^s") then
typ = "strong"
class = gsub(class, "^s", "")
if strong_verbs[class] then
strong_verbs[class](data)
else
error("Unrecognized strong class: " .. class)
end
elseif class:find("^w") then
typ = "weak"
class = gsub(class, "^w", "")
if weak_verbs[class] then
weak_verbs[class](data)
data.presenfin = data.presenfin or data.prese
data.presefin = data.presefin or data.prese
else
error("Unrecognized weak class: " .. class)
end
elseif class == "pp" then
typ = "pretpres"
elseif class == "i" then
typ = "irreg"
else
error("Unrecognized verb class: " .. class)
end
local overrides = {}
for i, spec in ipairs(specs) do
if i > 1 then
local parts = rsplit(spec, ":")
if #parts ~= 2 then
error("Verb modified spec must be of the form 'KEY:VALUE': " .. spec)
end
local k = parts[1]
local v = parts[2]
local splitv = rsplit(v, ", *")
local unrecognized = false
if slots_and_accel[k] then
overrides[k] = splitv
elseif k == "ge" then
data.with_ge = require("Module:yesno")(v)
elseif k == "impers" then
data.impers = require("Module:yesno")(v)
elseif typ == "weak" or typ == "strong" then
if k == "pres" then
data.presa = splitv
data.prese = splitv
data.presefin = splitv
data.presenfin = splitv
data.pres23 = splitv
data.impsg = splitv
elseif k == "pres1456" then
data.presa = splitv
data.prese = splitv
data.presefin = splitv
data.presenfin = splitv
elseif k == "pres23" then
data.pres23 = splitv
elseif k == "presa" then
data.presa = splitv
elseif k == "prese" then
data.prese = splitv
data.presefin = splitv
data.presenfin = splitv
elseif typ == "weak" and k == "presefin" then
data.presefin = splitv
elseif typ == "weak" and k == "presenfin" then
data.presenfin = splitv
elseif k == "past" then
data.past = splitv
data.pastsg = splitv
data.pastpl = splitv
elseif typ == "strong" and k == "pastsg" then
data.pastsg = splitv
elseif typ == "strong" and k == "pastpl" then
data.pastpl = splitv
elseif k == "impsg" then
data.impsg = splitv
elseif k == "pp" then
data.pp = splitv
elseif typ == "weak" and k == "papp" then
data.past = splitv
data.pp = splitv
else
unrecognized = true
end
else
unrecognized = true
end
if unrecognized then
error("Unrecognized spec key '" .. k .. "' (value '" .. v .. "')")
end
end
end
if typ == "weak" or typ == "strong" then
local missing_fields = {}
local fields_to_check =
typ == "weak" and {"presa", "presefin", "presenfin", "pres23", "impsg", "past", "pp"} or
{"presa", "prese", "pres23", "impsg", "pastsg", "pastpl", "pp"}
for _, field in ipairs(fields_to_check) do
if not data[field] then
insert(missing_fields, field)
end
end
if #missing_fields > 0 then
error("Required spec(s) " .. concat(missing_fields, ",") ..
" missing, i.e. the form of the infinitive '" .. inf ..
"' was not recognized as a " .. typ .. " class-" .. class .. " verb and the " ..
"overriding specs weren't (all) supplied")
end
end
local forms
if typ == "strong" then
forms = make_strong(data.presa, data.prese, data.pres23, data.impsg, data.pastsg,
data.pastpl, data.pp, data.with_ge)
elseif typ == "weak" then
forms = make_weak(data.presa, data.presefin, data.presenfin,
data.pres23, data.impsg, data.past, data.pp, data.with_ge)
elseif typ == "pretpres" then
forms = make_preterite_present(inf, data.with_ge)
elseif typ == "irreg" then
forms = make_irregular(inf, data.with_ge)
else
error("Internal error: Unrecognized verb type: " .. typ)
end
for k, v in pairs(data.extraforms) do
add_form_to_slot(forms, k, v)
end
for k, v in pairs(overrides) do
forms[k] = v
end
if data.impers then
-- e.g. mǣtan; clear personal non-3sg forms
forms["1sg_pres_indc"] = {}
forms["2sg_pres_indc"] = {}
forms["pl_pres_indc"] = {}
forms["pl_pres_subj"] = {}
forms["1sg_past_indc"] = {}
forms["2sg_past_indc"] = {}
forms["pl_past_indc"] = {}
forms["pl_past_subj"] = {}
forms["sg_impr"] = {}
forms["pl_impr"] = {}
end
class = rsub(class, "[a-z]", "")
if class == "" then
class = nil
end
if not allforms then
allforms = forms
allforms["type"] = typ
allforms["class"] = class
else
for k, v in pairs(forms) do
for _, form in ipairs(v) do
m_table.insertIfNot(allforms[k], form)
end
end
end
local cats = set_categories(typ, class, data.jpres, data.stem_weight, data.contracted)
for _, cat in ipairs(cats) do
m_table.insertIfNot(allcats, cat)
end
end
local table = make_table(allforms)
return table .. m_utilities.format_categories(allcats, lang)
end
return export
kny1wokdy23adpwk69gh624she6kq39
Module:ang-common
828
8215
55167
2026-10-02T21:40:33Z
Deadend0914
7211
Gesceop tramet þe hafaþ '--[=[ Common utilities and definitions used by various Old English modules. Author: Benwing ]=] local m_table = require("Module:table") local u = require("Module:string/char") local rsubn = mw.ustring.gsub -- version of rsubn() that discards all but the first return value local function rsub(term, foo, bar, n) local retval = rsubn(term, foo, bar, n) return retval end local export = {} export.ACUTE = u(0x0301) export.GRAVE = u(0x0300) export.CFLEX = u(0x0...'
55167
Scribunto
text/plain
--[=[
Common utilities and definitions used by various Old English modules.
Author: Benwing
]=]
local m_table = require("Module:table")
local u = require("Module:string/char")
local rsubn = mw.ustring.gsub
-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar, n)
local retval = rsubn(term, foo, bar, n)
return retval
end
local export = {}
export.ACUTE = u(0x0301)
export.GRAVE = u(0x0300)
export.CFLEX = u(0x0302)
export.MACRON = u(0x0304)
export.DOTABOVE = u(0x0307)
export.SYLLABIC = u(0x0329)
export.CEDILLA = u(0x0327)
export.DOUBLE_BREVE_BELOW = u(0x035C)
local accent = export.MACRON .. export.ACUTE .. export.GRAVE .. export.CFLEX
local recomposer = {
["g" .. export.DOTABOVE] = "ġ",
["G" .. export.DOTABOVE] = "Ġ",
["c" .. export.DOTABOVE] = "ċ",
["C" .. export.DOTABOVE] = "Ċ",
-- used in "explicit allophone" notation in [[Module:ang-pron]]
["c" .. export.CEDILLA] = "ç",
["C" .. export.CEDILLA] = "Ç",
}
-- Decompose macron, acute, grave, circumflex, but leave alone ġ, ċ and uppercase equiv
function export.decompose(text)
text = mw.ustring.toNFD(text)
text = rsub(text, ".[" .. export.DOTABOVE .. "]", recomposer)
return text
end
-- We use the following syllable-splitting algorithm.
-- (1) A single consonant goes with the following syllable.
-- (2) Two consonants are split down the middle.
-- (3) For three or more consonants, check for clusters ending in
-- onsets_3 then onsets_2, with at least one preceding consonant.
-- If so, split between the onset and the preceding consonant(s).
-- (4) Check similarly for secondary_onsets_2. If seen, then check
-- the preceding consonant; if it's not an l or r, split before
-- the onset.
-- (5) Otherwise, split before the last consonant (i.e. the last
-- consonant goes with the following syllable, and all preceding
-- consonants go with the preceding syllable).
export.onsets_2 = m_table.listToSet({
"pr", "pl",
"br", "bl",
"tr", "tw",
"dr", "dw",
"cr", "cl", "cw", --skip "cn"
"kr", "kl", "kw", --skip "kn"
"gr", "gl", -- skip "gn"
"sm", "sn", "sl", "sw",
"sp",
"st",
"sc", "sk", "sċ",
"fr", "fl", --skip "fn",
"þr", "þw",
"ðr", "ðw",
"hr", "hl", "hw", -- skip "hn"
"wr", "wl",
})
export.secondary_onsets_2 = m_table.listToSet({
"cn", "kn",
"gn",
"fn",
"hn",
})
export.onsets_3 = m_table.listToSet({
"spr", "spl",
"str",
"scr", "skr", "sċr",
})
export.diphthongs = m_table.listToSet({
"ea", export.decompose("ēa"), export.decompose("eā"),
"eo", export.decompose("ēo"), export.decompose("eō"),
"io", export.decompose("īo"), export.decompose("iō"),
"ie", export.decompose("īe"), export.decompose("iē"),
})
export.prefixes = {
{export.decompose("ā"), {verb = "unstressed", noun = "stressed"}},
{"æt", {verb = "unstressed"}},
{"æfter", {verb = "secstressed", noun = "stressed"}}, -- not very common
{"and", {verb = "unstressed", noun = "stressed"}},
{"an", {verb = "unstressed", noun = "stressed"}},
{"be", {verb = "unstressed", noun = "unstressed", restriction = "^[^" .. accent .. "ao]"}},
{export.decompose("bī"), {noun = "stressed"}},
{"ed", {verb = "unstressed", noun = "stressed"}}, -- not very common
{"fore", {verb = "unstressed", noun = "stressed", restriction = "^[^" .. accent .. "ao]"}},
{"for[þð]", {verb = "unstressed", noun = "stressed"}},
{"for", {verb = "unstressed", noun = "unstressed"}},
{"fram", {verb = "unstressed", noun = "stressed"}}, -- not very common
-- following is rare as a noun, mostly from verbal forms
{"ġeond", {verb = "unstressed"}},
{"ġe", {verb = "unstressed", noun = "unstressed", restriction = "^[^" .. accent .. "ao]"}},
{"in", {verb = "unstressed", noun = "stressed"}}, -- not very common
{"mis", {verb = "unstressed"}},
{"ofer", {verb = "secstressed", noun = "stressed"}},
{"of", {verb = "unstressed", noun = "stressed"}},
{"on", {verb = "unstressed", noun = "stressed"}},
{"or", {noun = "stressed"}},
{"o[þð]", {verb = "unstressed"}},
{export.decompose("stēop"), {noun = "stressed"}},
{export.decompose("tō"), {verb = "unstressed", noun = "stressed"}},
{"under", {verb = "secstressed", noun = "stressed"}},
{"un", {verb = "unstressed", noun = "stressed", verbal = "stressed"}}, -- uncommon as verb
{"up", {verb = "unstressed", noun = "stressed"}},
{export.decompose("ūt"), {verb = "unstressed", noun = "stressed"}},
{export.decompose("ū[þð]"), {noun = "stressed"}},
{"[wƿ]i[þð]er", {verb = "secstressed", noun = "stressed"}},
{"[wƿ]i[þð]", {verb = "unstressed"}},
{"ymb", {verb = "unstressed", noun = "stressed"}},
{"[þð]urh", {verb = "unstressed", noun = "stressed"}},
}
export.suffixes = {
{export.decompose("bǣre"), {noun = "secstressed"}},
{"fæst", {noun = "secstressed"}},
{"feald", {noun = "secstressed"}},
{"full?", {noun = "unstressed"}},
{export.decompose("lēas"), {noun = "secstressed"}},
-- These can be "verbal" if following a verbal past participle or similar
{export.decompose("līċe"), {noun = "secstressed", verb = "secstressed"}},
-- ī is decomposed into two chars so can't combine into [īi]
{export.decompose("li[ċc]"), {noun = "unstressed", verb = "unstressed"}},
{export.decompose("lī[ċc]"), {noun = "unstressed", verb = "unstressed"}},
{"n[eiy]ss?", {noun = "unstressed", verb = "unstressed"}},
{"sum", {noun = "unstressed"}},
}
return export
fc79ypblk4nipwsalhix5guv4evn5wg