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 = " +&lrm; ", 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("&#32;and&#32;") .. seq[2] else local comma = '<span class="serial-comma">,</span>' local conj = '<span class="serial-and">&#32;and&#32;</span>' return table.concat(seq, wrap_in_inflection_of_sep(",&#32;"), 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 &lrm; is what [[Module:affix]] has always done default_separator = data.allow_semicolon_separator and " +&lrm; " 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 = " +&lrm; ", 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 = " +&lrm; ", 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 = " +&lrm; ", 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 .. "&nbsp;(" .. 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 .. "&nbsp;(" .. 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 .. "&nbsp;(" .. 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 .. "&nbsp;(" .. 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