text:
Module:User:Benwing2/affix

local export = {}

local debug_force_cat = false -- if set to true, always display categories even on userspace pages

local m_links = require("Module:links") local m_str_utils = require("Module:string utilities") local m_table = require("Module:table") local etymology_module = "Module:etymology" local pron_qualifier_module = "Module:pron qualifier" local scripts_module = "Module:scripts" local utilities_module = "Module:utilities" -- Export this so the category code in Module:category tree/poscatboiler/data/terms by etymology can access it. export.affix_lang_data_module_prefix = "Module:affix/lang-data/"

local rsub = m_str_utils.gsub local usub = m_str_utils.sub local ulen = m_str_utils.len local rfind = m_str_utils.find local rmatch = m_str_utils.match local pluralize = m_str_utils.pluralize local u = m_str_utils.char local ucfirst = m_str_utils.ucfirst

-- Export this so the category code in Module:category tree/poscatboiler/data/terms by etymology can access it. export.langs_with_lang_specific_data = { ["az"] = true, ["fi"] = true, ["izh"] = true, ["la"] = true, ["tr"] = true, }

local default_pos = "term"

--[==[ intro:

About different types of hyphens ("template", "display" and "lookup"):
affix. This is always a single Unicode char, but there may be multiple possible hyphens for a given script. Normally this is just the regular hyphen character "-", but for some non-Latin-script languages (currently only right-to-left languages), it is different. to indicate that a term is an affix. Currently this is always either the same as the template hyphen or an empty string, but the code below is written generally enough to handle arbitrary display hyphens. Specifically: *# For East Asian languages, the display hyphen is always blank. *# For Arabic-script languages, either tatweel (ـ) or ZWNJ (zero-width non-joiner) are allowed as template hyphens, where ZWNJ is supported primarily for Farsi, because some suffixes have non-joining behavior. The display hyphen corresponding to tatweel is also tatweel, but the display hyphen corresponding to ZWNJ is blank (tatweel is also	 the default display hyphen, for calls to prefix/suffix/etc. that don't include an explicit hyphen). discussed in more detail below when discussing link affixes.) It depends only on the script of the affix in question. Most scripts (including East Asian scripts) use a regular hyphen "-" as the lookup hyphen, but Hebrew and Arabic  have their own lookup hyphens (respectively maqqef and tatweel). Note that for Arabic in particular, there are  three possible template hyphens that are recognized (tatweel, ZWNJ and regular hyphen), but mappings must use tatweel.
 * The "template hyphen" is the per-script hyphen character that is used in template calls to indicate that a term is an
 * The "display hyphen" is the string (which might be an empty string) that is added onto a term as displayed and linked,
 * The "lookup hyphen" is the hyphen that is used when looking up language-specific affix mappings. (These mappings are

About different types of affixes ("template", "display", "link", "lookup" and "category"):
an attached template hyphen (see above) to indicate that it is an affix and indicate what type of affix it is (prefix, suffix, interfix/infix or circumfix), but some of the older-style templates such as suffix, prefix, confix, etc. have "positional" affixes where the presence of the affix in a certain position (e.g. the second or third parameter) indicates that it is a certain type of affix, whether or not it has an attached template hyphen. from the template affix for various reasons: *# The display affix may be specified explicitly using the alt N parameter, the `` inline modifier or a piped link of the form e.g. ` -käs ` (here indicating that the affix should	 display as `-käs` but be linked as `-kas`). Here, the template affix is arguably the entire piped link, while the display affix is `-käs`. *# Even in the absence of alt N parameters, `` inline modifiers and piped links, certain languages have differences between the "template hyphen" specified in the template (which always needs to be	 specified somehow or other in templates like affix, to indicate that the term is an affix and what type of	 affix it is) and the display hyphen (see above), with corresponding differences between template and display affixes. the same as the display affix, but will differ in one of three circumstances: *# The display and link affixes are explicitly made different using alt N parameters, `` inline modifiers or piped links, as described above under "display affix". *# For certain languages, certain affixes are mapped to canonical form using language-specific mappings. For example, in Finnish, the adjective-forming suffix -kas appears as -käs after front vowels, but logically both forms are the same suffix and should be linked and categorized the same. Similarly, in Latin, the negative and intensive prefixes spelled in- (etymologically two distinct prefixes) appear variously as il-, im- or ir- before certain consonants. Mappings are supplied in Module:affix/lang-data/LANGCODE to convert Finnish -käs to -kas for linking and categorization purposes. Note that the affixes in the mappings use "lookup hyphens" to indicate the different types of affixes, which is usually the same as the template hyphen but differs for Arabic scripts, because there are multiple possible template hyphens recognized but only one lookup hyphen (tatweel). The form of the affix as used to look up in the mapping tables is called the "lookup affix"; see below. may strip certain diacritics: e.g. macrons in Latin and Old English (indicating length); acute and grave accents in Russian and various other Slavic languages (indicating stress); vowel diacritics in most Arabic-script languages; and also tatweel in some Arabic-script languages (currently, for example, Persian, Arabic and Urdu strip tatweel, but Ottoman Turkish does not). Stripped link affixes are currently what are used in category names. under link affixes. There are actually two lookup stages: *# First, the affix is looked up in a modified display form (specifically, the same as the display affix but using	 lookup hyphens). Note that this lookup does not occur if an explicit display form is given using alt N or an `` inline modifier, or if the template affix contains a piped or embedded link. *# If no entry is found, the affix is then looked up in a modified link form (specifically, the modified display	 form passed through the language's `makeEntryName` function, which strips out certain diacritics, but with the	 lookup hyphen re-added if it was stripped out, as in the case of tatweel in many Arabic-script languages). The reason for this double lookup procedure is to allow for mappings that are sensitive to the extra diacritics, but also allow for mappings that are not sensitive in this fashion (e.g. Russian -ливый occurs both stressed and unstressed, but is the same prefix either way). The category affix is currently always the same as the stripped link affix. This means that for Arabic-script languages, it may or may not have a tatweel, even if the correponding display affix and regular link affix have a tatweel. As mentioned above, makeEntryName strips tatweel for Arabic, Persian and Urdu, but not for Ottoman Turkish. Hence affix categories for Arabic, Persian and Urdu will be missing the tatweel, but affix categories for Ottoman Turkish will have it. An additional complication is that if the template affix contains a ZWNJ, the display (and hence the link and category affixes) will have no hyphen attached in any case. ]==]
 * A "template affix" is an affix in its source form as it appears in a template call. Generally, a template affix has
 * A "display affix" is the corresponding affix as it is actually displayed to the user. The display affix may differ
 * A (regular) "link affix" is the affix that is linked to when the affix is shown to the user. The link affix is usually
 * A "stripped link affix" is a link affix that has been passed through the language's `makeEntryName` function, which
 * A "lookup affix" is the form of the affix as it is looked up in the language-specific lookup mappings described above
 * A "category affix" is the affix as it appears in categories such as Category:Finnish terms suffixed with -kas.

- --                              Template and display hyphens                          -- -

--[=[ Per-script template hyphens. The template hyphen is what appears in the ///etc. template (in the wikicode). See above.

They key below is a script code, after removing a hyphen and anything preceding. Hence, script codes like 'fa-Arab' and 'ur-Arab' will match 'Arab'.

The value below is a string consisting of one or more hyphen characters. If there is more than one character, the default hyphen must come last and a non-default function must be specified for the script in display_hyphens[] so the correct display hyphen will be specified when no template hyphen is given (in //etc.).

Script detection is normally done when linking, but we need to do it earlier. However, under most circumstances we don't need to do script detection. Specifically, we only need to do script detection for a given language if

(a) the language has multiple scripts; and (b) at least one of those scripts is listed below or in display_hyphens. ]=]

local ZWNJ = u(0x200C) -- zero-width non-joiner local template_hyphens = { ["Arab"] = "ـ" .. ZWNJ .. "-", -- tatweel + zero-width non-joiner + regular hyphen ["Hebr"] = "־", -- Hebrew-specific hyphen termed "maqqef" -- This covers all Arabic scripts. See above. ["Mong"] = "᠊", ["mnc-Mong"] = "᠊", ["sjo-Mong"] = "᠊", ["xwo-Mong"] = "᠊", -- FIXME! What about the following right-to-left scripts? -- Adlm (Adlam) -- Armi (Imperial Aramaic) -- Avst (Avestan) -- Cprt (Cypriot) -- Khar (Kharoshthi) -- Mand (Mandaic/Mandaean) -- Mani (Manichaean) -- Mend (Mende/Mende Kikakui) -- Narb (Old North Arabian) -- Nbat (Nabataean/Nabatean) -- Nkoo (N'Ko) -- Orkh (Orkhon runes) -- Phli (Inscriptional Pahlavi) -- Phlp (Psalter Pahlavi) -- Phlv (Book Pahlavi) -- Phnx (Phoenician) -- Prti (Inscriptional Parthian) -- Rohg (Hanifi Rohingya) -- Samr (Samaritan) -- Sarb (Old South Arabian) -- Sogd (Sogdian) -- Sogo (Old Sogdian) -- Syrc (Syriac) -- Thaa (Thaana) }

-- Hyphens used when looking up an affix in a lang-specific affix mapping. Defaults to regular hyphen (-). The keys -- are script codes, after removing a hyphen and anything preceding. Hence, script codes like 'fa-Arab' and 'ur-Arab' -- will match 'Arab'. The value should be a single character. local lookup_hyphens = { ["Hebr"] = "־", -- This covers all Arabic scripts. See above. ["Arab"] = "ـ", }

-- Default display-hyphen function. local function default_display_hyphen(script, hyph) if not hyph then return template_hyphens[script] or "-" end return hyph end

local function arab_get_display_hyphen(script, hyph) if not hyph then return "ـ" -- tatweel elseif hyph == ZWNJ then return "" else return hyph end end

local function no_display_hyphen(script, hyph) return "" end

-- Per-script function to return the correct display hyphen given the script and template hyphen. The function should -- also handle the case where the passed-in template hyphen is nil, corresponding to the situation in -- //etc. where no template hyphen is specified. The key is the script code after removing a hyphen -- and anything preceding, so 'fa-Arab', 'ur-Arab' etc. will match 'Arab'. local display_hyphens = { -- This covers all Arabic scripts. See above. ["Arab"] = arab_get_display_hyphen, ["Bopo"] = no_display_hyphen, ["Hani"] = no_display_hyphen, ["Hans"] = no_display_hyphen, ["Hant"] = no_display_hyphen, -- The following is a mixture of several scripts. Hopefully the specs here are correct! ["Jpan"] = no_display_hyphen, ["Jurc"] = no_display_hyphen, ["Kitl"] = no_display_hyphen, ["Kits"] = no_display_hyphen, ["Laoo"] = no_display_hyphen, ["Nshu"] = no_display_hyphen, ["Shui"] = no_display_hyphen, ["Tang"] = no_display_hyphen, ["Thaa"] = no_display_hyphen, ["Thai"] = no_display_hyphen, }

- --                                Basic Utility functions                             -- -

local function glossary_link(entry, text) text = text or entry return "" .. text .. "" end

local function track(page) if type(page) == "table" then for i, pg in ipairs(page) do page[i] = "affix/" .. pg		end else page = "affix/" .. page end require("Module:debug/track")(page) end

local function ine(val) return val ~= "" and val or nil end

- --                                     Compound types                                 -- -

local function make_compound_type(typ, alttext) return { text = glossary_link(typ, alttext) .. " compound", cat = typ .. " compounds", } end

-- Make a compound type entry with a simple rather than glossary link. -- These should be replaced with a glossary link when the entry in the glossary -- is created. local function make_non_glossary_compound_type(typ, alttext) local link = alttext and "" .. alttext .. "" or "" .. typ .. "" return { text = link .. " compound", cat = typ .. " compounds", } end

local function make_raw_compound_type(typ, alttext) return { text = glossary_link(typ, alttext), cat = pluralize(typ), } end

export.compound_types = { ["alliterative"] = make_non_glossary_compound_type("alliterative"), ["allit"] = "alliterative", ["antonymous"] = make_non_glossary_compound_type("antonymous"), ["ant"] = "antonymous", ["bahuvrihi"] = make_compound_type("bahuvrihi", "bahuvrīhi"), ["bahu"] = "bahuvrihi", ["bv"] = "bahuvrihi", ["coordinative"] = make_compound_type("coordinative"), ["coord"] = "coordinative", ["descriptive"] = make_compound_type("descriptive"), ["desc"] = "descriptive", ["determinative"] = make_compound_type("determinative"), ["det"] = "determinative", ["dvandva"] = make_compound_type("dvandva"), ["dva"] = "dvandva", ["dvigu"] = make_compound_type("dvigu"), ["dvi"] = "dvigu", ["endocentric"] = make_compound_type("endocentric"), ["endo"] = "endocentric", ["exocentric"] = make_compound_type("exocentric"), ["exo"] = "exocentric", ["izafet I"] = make_compound_type("izafet I"), ["iz1"] = "izafet I", ["izafet II"] = make_compound_type("izafet II"), ["iz2"] = "izafet II", ["izafet III"] = make_compound_type("izafet III"), ["iz3"] = "izafet III", ["karmadharaya"] = make_compound_type("karmadharaya", "karmadhāraya"), ["karma"] = "karmadharaya", ["kd"] = "karmadharaya", ["kenning"] = make_raw_compound_type("kenning"), ["ken"] = "kenning", ["rhyming"] = make_non_glossary_compound_type("rhyming"), ["rhy"] = "rhyming", ["synonymous"] = make_non_glossary_compound_type("synonymous"), ["syn"] = "synonymous", ["tatpurusa"] = make_compound_type("tatpurusa", "tatpuruṣa"), ["tat"] = "tatpurusa", ["tp"] = "tatpurusa", }

local function process_compound_type(typ, nocap, notext, has_parts) local text_sections = {} local categories = {}

if typ then local typdata = export.compound_types[typ] if type(typdata) == "string" then typdata = export.compound_types[typdata] end if not typdata then error("Internal error: Unrecognized type '" .. typ .. "'") end local text = typdata.text if not nocap then text = ucfirst(text) end local cat = typdata.cat local oftext = typdata.oftext or " of"

if not notext then table.insert(text_sections, text) if has_parts then table.insert(text_sections, oftext) table.insert(text_sections, " ") end end table.insert(categories, cat) end

return text_sections, categories end

- --                                    Utility functions                               -- -

-- Iterate an array up to the greatest integer index found. local function ipairs_with_gaps(t) local indices = m_table.numKeys(t) local max_index = #indices > 0 and math.max(unpack(indices)) or 0 local i = 0 return function while i < max_index do			i = i + 1 return i, t[i] end end end

export.ipairs_with_gaps = ipairs_with_gaps

--[==[ Join formatted parts (in `parts_formatted`) together with any overall lit spec (in `lit`) plus categories, which are formatted by prepending the language name as found in `lang`. The value of an entry in `categories` can be either a string (which is formatted using `sort_key`) or a table of the form `{ {cat= category , sort_key= sort_key, sort_base= sort_base }`, specifying the sort key and sort base to use when formatting the category. If `nocat` is given, no categories are added; otherwise, `force_cat` causes categories to be added even on userspace pages. ]==] function export.join_formatted_parts(data) local cattext local lang = data.data.lang local force_cat = data.data.force_cat or debug_force_cat if data.data.nocat then cattext = "" else for i, cat in ipairs(data.categories) do			if type(cat) == "table" then data.categories[i] = require(utilities_module).format_categories({lang:getFullName .. " " .. cat.cat},					lang, cat.sort_key, cat.sort_base, force_cat) else data.categories[i] = require(utilities_module).format_categories({lang:getFullName .. " " .. cat}, lang,					data.data.sort_key, nil, force_cat) end end cattext = table.concat(data.categories) end local result = table.concat(data.parts_formatted, " + ") .. (data.data.lit and ", literally " ..		m_links.mark(data.data.lit, "gloss") or "") local q = data.data.q	local qq = data.data.qq	local l = data.data.l	local ll = data.data.ll	if q and q[1] or qq and qq[1] or l and l[1] or ll and ll[1] then result = require(pron_qualifier_module).format_qualifiers { lang = lang, text = result, q = q,			qq = qq, l = l,			ll = ll, }	end

return result .. cattext end

--[==[ Older entry point for calling `join_formatted_parts. FIXME: Convert callers. ]==] function export.concat_parts(lang, parts_formatted, categories, nocat, sort_key, lit, force_cat) return export.join_formatted_parts { data = { lang = lang, nocat = nocat, sort_key = sort_key, lit = lit, force_cat = force_cat, },		parts_formatted = parts_formatted, categories = categories, } end

local function pluralize(pos) if pos ~= "nouns" and usub(pos, -5) ~= "verbs" and usub(pos, -4) ~= "ives" then if pos:find("[sx]$") then pos = pos .. "es" else pos = pos .. "s" end end return pos end

-- Remove links and call lang:makeEntryName(term). local function make_entry_name_no_links(lang, term) -- Double parens because makeEntryName returns multiple values. Yuck. return (lang:makeEntryName(m_links.remove_links(term))) end

--[=[ Convert a raw part as passed into an entry point into a part ready for linking. `lang` and `sc` are the overall language and script objects. This uses the overall language and script objects as defaults for the part and parses off any fragment from the term. We need to do the latter so that fragments don't end up in categories and so that we correctly do affix mapping even in the presence of fragments. ]=] local function canonicalize_part(part, lang, sc) if not part then return end -- Save the original (user-specified, part-specific) value of `lang`. If such a value is specified, we don't insert -- a '*fixed with' category, and we format the part using format_derived in Module:etymology rather than -- full_link in Module:links. part.part_lang = part.lang part.lang = part.lang or lang part.sc = part.sc or sc	local term = part.term if not term then return elseif not part.fragment then part.term, part.fragment = m_links.get_fragment(term) else part.term = m_links.get_fragment(term) end end

--[==[ Construct a single linked part based on the information in `part`, for use by `show_affix` and other entry points. This should be called after `canonicalize_part` is called on the part. This is a thin wrapper around `full_link` in Module:links unless `part.part_lang` is specified (indicating that a part-specific language was given), in which case `format_derived` in Module:etymology is called to display a term in a language other than the language of the overall term (specified in `data.lang`). `data` contains the entire object passed into the entry point and is used to access information for constructing the categories added by `format_derived`. ]==] function export.link_term(part, data) local result

if part.part_lang then result = require(etymology_module).format_derived(data.lang, part, data.sort_key, data.nocat,			data.force_cat or debug_force_cat) else -- language (e.g. in a pseudo-loan). result = m_links.full_link(part, "term") end

if part.q and part.q[1] or part.qq and part.qq[1] or part.l and part.l[1] or part.ll and part.ll[1] or		part.refs and part.refs[1] then result = require(pron_qualifier_module).format_qualifiers { lang = part.lang, text = result, q = part.q,			qq = part.qq, l = part.l,			ll = part.ll, refs = part.refs, }	end

return result end

local function canonicalize_script_code(scode) -- Convert fa-Arab, ur-Arab etc. to Arab. return (scode:gsub("^.*%-", "")) end

- --                                 Affix-handling functions                           -- -

-- Figure out the appropriate script for the given affix and language (unless the script is explicitly passed in), and -- return the values of template_hyphens[], display_hyphens[] and lookup_hyphens[] for that script, substituting -- default values as appropriate. Four values are returned: --	DETECTED_SCRIPT, TEMPLATE_HYPHEN, DISPLAY_HYPHEN, LOOKUP_HYPHEN local function detect_script_and_hyphens(text, lang, sc) local scode -- 1. If the script is explicitly passed in, use it. if sc then scode = sc:getCode else local possible_script_codes = lang:getScriptCodes -- YUCK! `possible_script_codes` comes from loadData so #possible_scripts doesn't work (always returns 0). local num_possible_script_codes = m_table.length(possible_script_codes) if num_possible_script_codes == 0 then -- This shouldn't happen; if the language has no script codes, -- the list {"None"} should be returned. error("Something is majorly wrong! Language " .. lang:getCanonicalName .. " has no script codes.") end if num_possible_script_codes == 1 then -- 2. If the language has only one possible script, use it. scode = possible_script_codes[1] else -- 3. Check if any of the possible scripts for the language have non-default values for template_hyphens[] --   or display_hyphens[]. If so, we need to do script detection on the text. If not, just use "Latn", --   which may not be technically correct but produces the right results because Latn has all default --   values for template_hyphens[] and display_hyphens[]. local may_have_nondefault_hyphen = false for _, script_code in ipairs(possible_script_codes) do				script_code = canonicalize_script_code(script_code) if template_hyphens[script_code] or display_hyphens[script_code] then may_have_nondefault_hyphen = true break end end if not may_have_nondefault_hyphen then scode = "Latn" else scode = lang:findBestScript(text):getCode end end end scode = canonicalize_script_code(scode) local template_hyphen = template_hyphens[scode] or "-" local lookup_hyphen = lookup_hyphens[scode] or "-" local display_hyphen = display_hyphens[scode] or default_display_hyphen return scode, template_hyphen, display_hyphen, lookup_hyphen end

--[=[ Given a template affix `term` and an affix type `affix_type`, change the relevant template hyphen(s) in the affix to the display or lookup hyphen specified in `new_hyphen`, or add them if they are missing. `new_hyphen` can be a string, specifying a fixed hyphen, or a function of two arguments (the script code `scode` and the discovered template hyphen, or nil of no relevant template hyphen is present). `thyph_re` is a Lua pattern (which must be enclosed in parens) that matches the possible template hyphens. Note that not all template hyphens present in the affix are changed, but only the "relevant" ones (e.g. for a prefix, a relevant template hyphen is one coming at the end of the affix). ]=] local function reconstruct_term_per_hyphens(term, affix_type, scode, thyph_re, new_hyphen) local function get_hyphen(hyph) if type(new_hyphen) == "string" then return new_hyphen end return new_hyphen(scode, hyph) end

if not affix_type then return term elseif affix_type == "circumfix" then local before, before_hyphen, after_hyphen, after = rmatch(term, "^(.*)" .. thyph_re .. " " .. thyph_re			.. "(.*)$") if not before or ulen(term) <= 3 then -- Unlike with other types of affixes, don't try to add hyphens in the middle of the term to convert it to -- a circumfix. Also, if the term is just hyphen + space + hyphen, return it. return term end return before .. get_hyphen(before_hyphen) .. " " .. get_hyphen(after_hyphen) .. after elseif affix_type == "infix" or affix_type == "interfix" then local before_hyphen, middle, after_hyphen = rmatch(term, "^" .. thyph_re .. "(.*)" .. thyph_re .. "$") if before_hyphen and ulen(term) <= 1 then -- If the term is just a hyphen, return it. return term end return get_hyphen(before_hyphen) .. (middle or term) .. get_hyphen(after_hyphen) elseif affix_type == "prefix" then local middle, after_hyphen = rmatch(term, "^(.*)" .. thyph_re .. "$") if middle and ulen(term) <= 1 then -- If the term is just a hyphen, return it. return term end return (middle or term) .. get_hyphen(after_hyphen) elseif affix_type == "suffix" then local before_hyphen, middle = rmatch(term, "^" .. thyph_re .. "(.*)$") if before_hyphen and ulen(term) <= 1 then -- If the term is just a hyphen, return it. return term end return get_hyphen(before_hyphen) .. (middle or term) else error(("Internal error: Unrecognized affix type '%s'"):format(affix_type)) end end

--[=[ Look up a mapping from a given affix variant to the canonical form used in categories and links. The lookup tables are language-specific according to `lang`, and may be ID-specific according to `affix_id`. The affixes as they appear in the lookup tables (both the variant and the canonical form) are in "lookup affix" format (approximately speaking, they use a regular hyphen for most scripts, but a tatweel for Arabic-script entries and a maqqef for Hebrew-script entries), but the passed-in `affix` param is in "template affix" format (which differs from the lookup affix for Arabic-script entries, because more types of hyphens are allowed in template affixes; see the comments at the top of the file). The remaining parameters to this function are used to convert from template affixes to lookup affixes; see the reconstruct_term_per_hyphens function above.

If the affix contains brackets, no lookup is done. Otherwise, a two-stage process is used, first looking up the affix directly and then stripping diacritics and looking it up again. The reason for this is documented above in the comments at the top of the file (specifically, the comments describing lookup affixes).

The value of a mapping can either be a string (do the mapping regardless of affix ID) or a table indexed by affix ID (where the special value `false` indicates no affix ID). The values of entries in this table can also be strings, or tables with keys `affix` and `id` (again, use `false` to indicate no ID). This allows an affix mapping to map from one ID to another (for example, this is used in English to map the an- prefix with no ID to the a- prefix with the ID 'not').

The Given a template affix `term` and an affix type `affix_type`, change the relevant template hyphen(s) in the affix to the display or lookup hyphen specified in `new_hyphen`, or add them if they are missing. `new_hyphen` can be a string, specifying a fixed hyphen, or a function of two arguments (the script code `scode` and the discovered template hyphen, or nil of no relevant template hyphen is present). `thyph_re` is a Lua pattern (which must be enclosed in parens) that matches the possible template hyphens. Note that not all template hyphens present in the affix are changed, but only the "relevant" ones (e.g. for a prefix, a relevant template hyphen is one coming at the end of the affix). ]=] local function lookup_affix_mapping(affix, affix_type, lang, scode, thyph_re, lookup_hyph, affix_id) local function do_lookup(affix) -- Ensure that the affix uses lookup hyphens regardless of whether it used a different type of hyphens before -- or no hyphens. local lookup_affix = reconstruct_term_per_hyphens(affix, affix_type, scode, thyph_re, lookup_hyph) local function do_lookup_for_langcode(langcode) if export.langs_with_lang_specific_data[langcode] then local langdata = mw.loadData(export.affix_lang_data_module_prefix .. langcode) if langdata.affix_mappings then local mapping = langdata.affix_mappings[lookup_affix] if mapping then if type(mapping) == "table" then mapping = mapping[affix_id or false] if mapping then return mapping end else return mapping end end end end end

-- If `lang` is an etymology-only language, look for a mapping both for it and its full parent. local langcode = lang:getCode local mapping = do_lookup_for_langcode(langcode) if mapping then return mapping end local full_langcode = lang:getFullCode if full_langcode ~= langcode then mapping = do_lookup_for_langcode(full_langcode) if mapping then return mapping end end return nil end

if affix:find("%[%[") then return nil end

-- Double parens because makeEntryName returns multiple values. Yuck. return do_lookup(affix) or do_lookup((lang:makeEntryName(affix))) or nil end

--[==[ For a given template term in a given language (see the definition of "template affix" near the top of the file), possibly in an explicitly specified script `sc` (but usually nil), return the term's affix type ({"prefix"}, {"infix"}, {"suffix"}, {"circumfix"} or {nil} for non-affix) along with the corresponding link and display affixes (see definitions near the top of the file); also the corresponding lookup affix (if `return_lookup_affix` is specified). The term passed in should already have any fragment (after the # sign) parsed off of it. Four values are returned: `affix_type`, `link_term`, `display_term` and `lookup_term`. The affix type can be passed in instead of autodetected (pass in {false} if the term is not an affix); in this case, the template term need not have any attached hyphens, and the appropriate hyphens will be added in the appropriate places. If `do_affix_mapping` is specified, look up the affix in the lang-specific affix mappings, as described in the comment at the top of the file; otherwise, the link and display terms will always be the same. (They will be the same in any case if the template term has a bracketed link in it or is not an affix.) If `return_lookup_affix` is given, the fourth return value contains the term with appropriate lookup hyphens in the appropriate places; otherwise, it is the same as the display term. (This functionality is used in Module:category tree/poscatboiler/data/terms by etymology to convert link affixes into lookup affixes so that they can be looked up in the affix mapping tables.) ]==] function export.parse_term_for_affixes(term, lang, sc, affix_type, do_affix_mapping, return_lookup_affix, affix_id) if not term then return nil, nil, nil, nil end

if term:find("^%^") then -- If term begins with ^, it's not an affix no matter what. Strip off the ^ and return "no affix". term = usub(term, 2) return nil, term, term, term end

-- Remove an asterisk if the morpheme is reconstructed and add it back at the end. local reconstructed = "" if term:find("^%*") then reconstructed = "*" term = term:gsub("^%*", "") end

local scode, thyph, dhyph, lhyph = detect_script_and_hyphens(term, lang, sc) thyph = "([" .. thyph .. "])"

if affix_type == nil then if rfind(term, thyph .. " " .. thyph) then affix_type = "circumfix" else local has_beginning_hyphen = rfind(term, "^" .. thyph) local has_ending_hyphen = rfind(term, thyph .. "$") if has_beginning_hyphen and has_ending_hyphen then affix_type = "infix" elseif has_ending_hyphen then affix_type = "prefix" elseif has_beginning_hyphen then affix_type = "suffix" end end end

local link_term, display_term, lookup_term if affix_type then display_term = reconstruct_term_per_hyphens(term, affix_type, scode, thyph, dhyph) if do_affix_mapping then link_term = lookup_affix_mapping(term, affix_type, lang, scode, thyph, lhyph, affix_id) -- The return value of lookup_affix_mapping may be an affix mapping with lookup hyphens if a mapping -- was found, otherwise nil if a mapping was not found. We need to convert to display hyphens in -- either case, but in the latter case we can reuse the display term, which has already been converted. if link_term then link_term = reconstruct_term_per_hyphens(link_term, affix_type, scode, thyph, dhyph) else link_term = display_term end else link_term = display_term end if return_lookup_affix then lookup_term = reconstruct_term_per_hyphens(term, affix_type, scode, thyph, lhyph) else lookup_term = display_term end else link_term = term display_term = term lookup_term = term end

link_term = reconstructed .. link_term display_term = reconstructed .. display_term lookup_term = reconstructed .. lookup_term

return affix_type, link_term, display_term, lookup_term end

export.get_affix_type = export.parse_term_for_affixes

--[==[ Add a hyphen to a term in the appropriate place, based on the specified affix type, stripping off any existing hyphens in that place. For example, if `affix_type` == {"prefix"}, we'll add a hyphen onto the end if it's not already there (or is of the wrong type). Three values are returned: the link term, display term and lookup term. This function is a thin wrapper around `parse_term_for_affixes`; see the comments above that function for more information. ]==] function export.make_affix(term, lang, sc, affix_type, do_affix_mapping, return_lookup_affix, affix_id) if not (affix_type == "prefix" or affix_type == "suffix" or affix_type == "circumfix" or affix_type == "infix" or		affix_type == "interfix") then error("Internal error: Invalid affix type " .. (affix_type or "(nil)")) end

local _, link_term, display_term, lookup_term = export.parse_term_for_affixes(term, lang, sc, affix_type,		do_affix_mapping, return_lookup_affix, affix_id) return link_term, display_term, lookup_term end

- --                                    Main entry points                               -- -

--[==[ Implementation of affix and surface analysis. `data` contains all the information describing the affixes to be displayed, and contains the following:

be passed to `full_link`, except that the `.lang` field should be missing unless the term is of a language different from the overall `.lang` value (in such a case, the language name is shown along with the term and		  an additional "derived from" category is added). WARNING: The data in `.parts` will be destructively modified. compound type is displayed before the parts (normally capitalized, unless `.nocap` is given). `.surface_analysis` is given).
 * `.lang` (required): Overall language object. Different from term-specific language objects (see `.parts` below).
 * `.sc`: Overall script object (usually omitted). Different from term-specific script objects.
 * `.parts` (required): List of objects describing the affixes to show. The general format of each object is as would
 * `.pos`: Overall part of speech (used in categories, defaults to {"terms"}). Different from term-specific part of speech.
 * `.sort_key`: Overall sort key. Normally omitted except e.g. in Japanese.
 * `.type`: Type of compound, if the parts in `.parts` describe a compound. Strictly optional, and if supplied, the
 * `.nocap`: Don't capitalize the first letter of text displayed before the parts (relevant only if `.type` or
 * `.notext`: Don't display any text before the parts (relevant only if `.type` or `.surface_analysis` is given).
 * `.nocat`: Disable all categorization.
 * `.lit`: Overall literal definition. Different from term-specific literal definitions.
 * `.force_cat`: Always display categories, even on userspace pages.
 * `.surface_analysis`: Implement ; adds `By surface analysis, ` before the parts.

WARNING: This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.show_affix(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos)

local text_sections, categories = process_compound_type(data.type, data.surface_analysis or data.nocap, data.notext,		#data.parts > 0)

-- Process each part local parts_formatted = {} local whole_words = 0 local is_affix_or_compound = false

-- Canonicalize and generate links for all the parts first; then do categorization in a separate step, because when -- processing the first part for categorization, we may access the second part and need it already canonicalized. for i, part in ipairs_with_gaps(data.parts) do		part = part or {} data.parts[i] = part canonicalize_part(part, data.lang, data.sc)

-- Determine affix type and get link and display terms (see text at top of file). Store them in the part -- (in fields that won't clash with fields used by full_link in Module:links or link_term), so they -- can be used in the loop below when categorizing. part.affix_type, part.affix_link_term, part.affix_display_term = export.parse_term_for_affixes(part.term,			part.lang, part.sc, nil, not part.alt, nil, part.id)

-- If link_term is an empty string, either a bare ^ was specified or an empty term was used along with inline -- modifiers. The intention in either case is not to link the term. part.term = ine(part.affix_link_term) -- If part.alt would be the same as part.term, make it nil, so that it isn't erroneously tracked as being -- redundant alt text. part.alt = part.alt or (part.affix_display_term ~= part.affix_link_term and part.affix_display_term) or nil

-- Make a link for the part. table.insert(parts_formatted, export.link_term(part, data)) end

-- Now do categorization. for i, part in ipairs_with_gaps(data.parts) do		local affix_type = part.affix_type if affix_type then is_affix_or_compound = true -- We cannot distinguish interfixes from infixes by appearance. Prefer interfixes; infixes will need to -- use ⟨⟩. if affix_type == "infix" then affix_type = "interfix" end

-- Make a sort key. For the first part, use the second part as the sort key; the intention is that if the -- term has a prefix, sorting by the prefix won't be very useful so we sort by what follows, which is -- presumably the root. local part_sort_base = nil local part_sort = part.sort or data.sort_key

if i == 1 and data.parts[2] and data.parts[2].term then local part2 = data.parts[2] -- If the second-part link term is empty, the user requested an unlinked term; avoid a wikitext error -- by using the alt value if available. part_sort_base = ine(part2.affix_link_term) or ine(part2.alt) if part_sort_base then part_sort_base = make_entry_name_no_links(part2.lang, part_sort_base) end end

if part.pos and rfind(part.pos, "patronym") then table.insert(categories, {cat = "patronymics", sort_key = part_sort, sort_base = part_sort_base}) end

if data.pos ~= "terms" and part.pos and rfind(part.pos, "diminutive") then table.insert(categories, {cat = "diminutive " .. data.pos, sort_key = part_sort,					sort_base = part_sort_base}) end

-- Don't add a '*fixed with' category if the link term is empty or is in a different language. if ine(part.affix_link_term) and not part.part_lang then table.insert(categories, {cat = data.pos .. " " .. affix_type .. "ed with " ..					make_entry_name_no_links(part.lang, part.affix_link_term) ..						(part.id and " (" .. part.id .. ")" or ""),					sort_key = part_sort, sort_base = part_sort_base}) end else whole_words = whole_words + 1

if whole_words == 2 then is_affix_or_compound = true table.insert(categories, "compound " .. data.pos) end end end

-- Make sure there was either an affix or a compound (two or more regular terms). if not is_affix_or_compound then error("The parameters did not include any affixes, and the term is not a compound. Please provide at least one affix.") end

if data.surface_analysis then local text = "by " .. glossary_link("surface analysis") .. ", "		if not data.nocap then text = ucfirst(text) end

table.insert(text_sections, 1, text) end

table.insert(text_sections, export.join_formatted_parts { data = data, parts_formatted = parts_formatted,		categories = categories }) return table.concat(text_sections) end

function export.show_surface_analysis(data) data.surface_analysis = true return export.show_affix(data) end

--[==[ Implementation of compound.

WARNING: This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.show_compound(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos)

local text_sections, categories = process_compound_type(data.type, data.nocap, data.notext, #data.parts > 0)

local parts_formatted = {} table.insert(categories, "compound " .. data.pos)

-- Make links out of all the parts local whole_words = 0 for i, part in ipairs(data.parts) do		canonicalize_part(part, data.lang, data.sc) -- Determine affix type and get link and display terms (see text at top of file). local affix_type, link_term, display_term = export.parse_term_for_affixes(part.term, part.lang, part.sc,			nil, not part.alt, nil, part.id)

-- If the term is an infix, recognize it as such (which means e.g. that we will display the term without		-- hyphens for East Asian languages). Otherwise, ignore the fact that it looks like an affix and display as -- specified in the template (but pay attention to the detected affix type for certain tracking purposes). if affix_type == "infix" then -- If link_term is an empty string, either a bare ^ was specified or an empty term was used along with -- inline modifiers. The intention in either case is not to link the term. Don't add a '*fixed with' -- category in this case, or if the term is in a different language. -- If part.alt would be the same as part.term, make it nil, so that it isn't erroneously tracked as being -- redundant alt text. if link_term and link_term ~= "" and not part.part_lang then table.insert(categories, {cat = data.pos .. " interfixed with " .. make_entry_name_no_links(part.lang, link_term), sort_key = part.sort or data.sort_key}) end part.term = link_term ~= "" and link_term or nil part.alt = part.alt or (display_term ~= link_term and display_term) or nil else if affix_type then local langcode = data.lang:getCode -- If `data.lang` is an etymology-only language, track both using its code and its full parent's code. track { affix_type, affix_type .. "/lang/" .. langcode } local full_langcode = data.lang:getFullCode if langcode ~= full_langcode then track(affix_type .. "/lang/" .. full_langcode) end else whole_words = whole_words + 1 end end table.insert(parts_formatted, export.link_term(part, data)) end

if whole_words == 1 then track("one whole word") elseif whole_words == 0 then track("looks like confix") end

table.insert(text_sections, export.join_formatted_parts { data = data, parts_formatted = parts_formatted,		categories = categories }) return table.concat(text_sections) end

--[==[ Implementation of blend, univerbation and similar "compound-like" templates.

WARNING: This destructively modifies both `data` and the individual structures within `.parts`. ]==] function export.show_compound_like(data) local parts_formatted = {} local categories = {}

if data.cat then table.insert(categories, data.cat) end

-- Make links out of all the parts for i, part in ipairs(data.parts) do		canonicalize_part(part, data.lang, data.sc) table.insert(parts_formatted, export.link_term(part, data)) end

local text_sections = {} if data.text then table.insert(text_sections, data.text) end if #data.parts > 0 and data.oftext then table.insert(text_sections, " ") table.insert(text_sections, data.oftext) table.insert(text_sections, " ") end table.insert(text_sections, export.join_formatted_parts { data = data, parts_formatted = parts_formatted,		categories = categories }) return table.concat(text_sections) end

--[==[ Make `part` (a structure holding information on an affix part) into an affix of type `affix_type`, and apply any relevant affix mappings. For example, if the desired affix type is "suffix", this will (in general) add a hyphen onto the beginning of the term, alt, tr and ts components of the part if not already present. The hyphen that's added is the "display hyphen" (see above) and may be script-specific. (In the case of East Asian scripts, the display hyphen is an empty string whereas the template hyphen is the regular hyphen, meaning that any regular hyphen at the beginning of the part will be effectively removed.) `lang` and `sc` hold overall language and script objects.

Note that this also applies any language-specific affix mappings, so that e.g. if the language is Finnish and the user specified -käs in the affix and didn't specify an `.alt` value, `part.term` will contain -kas and `part.alt` will contain -käs.

This function is used by the "legacy" templates (prefix, suffix, confix, etc.) where the nature of the affix is specified by the template itself rather than auto-determined from the affix, as is the case with affix.

WARNING: This destructively modifies `part`. ]==] local function make_part_into_affix(part, lang, sc, affix_type) canonicalize_part(part, lang, sc) local link_term, display_term = export.make_affix(part.term, part.lang, part.sc, affix_type, not part.alt, nil, part.id) part.term = link_term -- When we don't specify `do_affix_mapping` to make_affix, link and display terms (first and second retvals of	-- make_affix) are the same. -- If part.alt would be the same as part.term, make it nil, so that it isn't erroneously tracked as being -- redundant alt text. part.alt = part.alt and export.make_affix(part.alt, part.lang, part.sc, affix_type) or (display_term ~= link_term and display_term) or nil local Latn = require(scripts_module).getByCode("Latn") part.tr = export.make_affix(part.tr, part.lang, Latn, affix_type) part.ts = export.make_affix(part.ts, part.lang, Latn, affix_type) end

local function track_wrong_affix_type(template, part, expected_affix_type) if part then local affix_type = export.parse_term_for_affixes(part.term, part.lang, part.sc) if affix_type ~= expected_affix_type then local part_name = expected_affix_type or "base" local langcode = part.lang:getCode local full_langcode = part.lang:getFullCode require("Module:debug/track") { template, template .. "/" .. part_name, template .. "/" .. part_name .. "/" .. (affix_type or "none"), template .. "/" .. part_name .. "/" .. (affix_type or "none") .. "/lang/" .. langcode }			-- If `part.lang` is an etymology-only language, track both using its code and its full parent's code. if full_langcode ~= langcode then require("Module:debug/track")(					template .. "/" .. part_name .. "/" .. (affix_type or "none") .. "/lang/" .. full_langcode				) end end end end

local function insert_affix_category(categories, pos, affix_type, part, sort_key, sort_base) -- Don't add a '*fixed with' category if the link term is empty or is in a different language. if part.term and not part.part_lang then local cat = pos .. " " .. affix_type .. "ed with " .. make_entry_name_no_links(part.lang, part.term) .. (part.id and " (" .. part.id .. ")" or "") if sort_key or sort_base then table.insert(categories, {cat = cat, sort_key = sort_key, sort_base = sort_base}) else table.insert(categories, cat) end end end

--[==[ Implementation of circumfix.

WARNING: This destructively modifies both `data` and `.prefix`, `.base` and `.suffix`. ]==] function export.show_circumfix(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos)

canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. make_part_into_affix(data.prefix, data.lang, data.sc, "prefix") make_part_into_affix(data.suffix, data.lang, data.sc, "suffix")

track_wrong_affix_type("circumfix", data.prefix, "prefix") track_wrong_affix_type("circumfix", data.base, nil) track_wrong_affix_type("circumfix", data.suffix, "suffix")

-- Create circumfix term. local circumfix = nil

if data.prefix.term and data.suffix.term then circumfix = data.prefix.term .. " " .. data.suffix.term data.prefix.alt = data.prefix.alt or data.prefix.term data.suffix.alt = data.suffix.alt or data.suffix.term data.prefix.term = circumfix data.suffix.term = circumfix end

-- Make links out of all the parts. local parts_formatted = {} local categories = {} local sort_base if data.base.term then sort_base = make_entry_name_no_links(data.base.lang, data.base.term) end

table.insert(parts_formatted, export.link_term(data.prefix, data)) table.insert(parts_formatted, export.link_term(data.base, data)) table.insert(parts_formatted, export.link_term(data.suffix, data))

-- Insert the categories, but don't add a '*fixed with' category if the link term is in a different language. if not data.prefix.part_lang then table.insert(categories, {cat=data.pos .. " circumfixed with " .. make_entry_name_no_links(data.prefix.lang, circumfix), sort_key=data.sort_key, sort_base=sort_base}) end

return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end

--[==[ Implementation of confix.

WARNING: This destructively modifies both `data` and `.prefix`, `.base` and `.suffix`. ]==] function export.show_confix(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos)

canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. make_part_into_affix(data.prefix, data.lang, data.sc, "prefix") make_part_into_affix(data.suffix, data.lang, data.sc, "suffix")

track_wrong_affix_type("confix", data.prefix, "prefix") track_wrong_affix_type("confix", data.base, nil) track_wrong_affix_type("confix", data.suffix, "suffix")

-- Make links out of all the parts. local parts_formatted = {} local prefix_sort_base if data.base and data.base.term then prefix_sort_base = make_entry_name_no_links(data.base.lang, data.base.term) elseif data.suffix.term then prefix_sort_base = make_entry_name_no_links(data.suffix.lang, data.suffix.term) end

-- Insert the categories and parts. local categories = {}

table.insert(parts_formatted, export.link_term(data.prefix, data)) insert_affix_category(categories, data.pos, "prefix", data.prefix, data.sort_key, prefix_sort_base)

if data.base then table.insert(parts_formatted, export.link_term(data.base, data)) end

table.insert(parts_formatted, export.link_term(data.suffix, data)) -- FIXME, should we be specifying a sort base here? insert_affix_category(categories, data.pos, "suffix", data.suffix)

return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end

--[==[ Implementation of infix.

WARNING: This destructively modifies both `data` and `.base` and `.infix`. ]==] function export.show_infix(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos)

canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. make_part_into_affix(data.infix, data.lang, data.sc, "infix")

track_wrong_affix_type("infix", data.base, nil) track_wrong_affix_type("infix", data.infix, "infix")

-- Make links out of all the parts. local parts_formatted = {} local categories = {}

table.insert(parts_formatted, export.link_term(data.base, data)) table.insert(parts_formatted, export.link_term(data.infix, data))

-- Insert the categories. -- FIXME, should we be specifying a sort base here? insert_affix_category(categories, data.pos, "infix", data.infix)

return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end

--[==[ Implementation of prefix.

WARNING: This destructively modifies both `data` and the structures within `.prefixes`, as well as `.base`. ]==] function export.show_prefix(data) data.pos = data.pos or default_pos data.pos = pluralize(data.pos)

canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. for i, prefix in ipairs(data.prefixes) do		make_part_into_affix(prefix, data.lang, data.sc, "prefix") end

for i, prefix in ipairs(data.prefixes) do		track_wrong_affix_type("prefix", prefix, "prefix") end

track_wrong_affix_type("prefix", data.base, nil)

-- Make links out of all the parts. local parts_formatted = {} local first_sort_base = nil local categories = {}

if data.prefixes[2] then first_sort_base = ine(data.prefixes[2].term) or ine(data.prefixes[2].alt) if first_sort_base then first_sort_base = make_entry_name_no_links(data.prefixes[2].lang, first_sort_base) end elseif data.base then first_sort_base = ine(data.base.term) or ine(data.base.alt) if first_sort_base then first_sort_base = make_entry_name_no_links(data.base.lang, first_sort_base) end end

for i, prefix in ipairs(data.prefixes) do		table.insert(parts_formatted, export.link_term(prefix, data)) insert_affix_category(categories, data.pos, "prefix", prefix, data.sort_key, i == 1 and first_sort_base or nil) end

if data.base then table.insert(parts_formatted, export.link_term(data.base, data)) else table.insert(parts_formatted, "") end

return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end

--[==[ Implementation of suffix.

WARNING: This destructively modifies both `data` and the structures within `.suffixes`, as well as `.base`. ]==] function export.show_suffix(data) local categories = {}

data.pos = data.pos or default_pos data.pos = pluralize(data.pos)

canonicalize_part(data.base, data.lang, data.sc) -- Hyphenate the affixes and apply any affix mappings. for i, suffix in ipairs(data.suffixes) do		make_part_into_affix(suffix, data.lang, data.sc, "suffix") end

track_wrong_affix_type("suffix", data.base, nil) for i, suffix in ipairs(data.suffixes) do		track_wrong_affix_type("suffix", suffix, "suffix") end

-- Make links out of all the parts. local parts_formatted = {}

if data.base then table.insert(parts_formatted, export.link_term(data.base, data)) else table.insert(parts_formatted, "") end

for i, suffix in ipairs(data.suffixes) do		table.insert(parts_formatted, export.link_term(suffix, data)) end

-- Insert the categories. for i, suffix in ipairs(data.suffixes) do -- FIXME, should we be specifying a sort base here? insert_affix_category(categories, data.pos, "suffix", suffix)

if suffix.pos and rfind(suffix.pos, "patronym") then table.insert(categories, "patronymics") end end

return export.join_formatted_parts { data = data, parts_formatted = parts_formatted, categories = categories } end

return export

title: Module:User:Benwing2/affix


text:
Module:User:Benwing2/affix/templates

local export = {}

local m_affix = require("Module:affix") local parameter_utilities_module = "Module:User:Benwing2/parameter utilities" local pseudo_loan_module = "Module:affix/pseudo-loan"

local function is_property_key(k) return require(parameter_utilities_module).item_key_is_property(k) 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. -- * `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. -- -- 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"] = {type = "boolean"}, -- always allow this even if not used, for use with, which adds it	}

if not ilang then params[1] = {required = true, type = "language", etym_lang = true, default = "und"} end

local source_index if has_source then source_index = term_index - 1 params[source_index] = {required = true, type = "language", etym_lang = true, default = "und"} end

local m_param_utils = require(parameter_utilities_module) local param_mods = m_param_utils.construct_param_mods { -- 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}, {group = {"link", "ref", "lang", "q", "l"}}, -- Override these two to have separate_no_index, unless `data.require_index_for_pos` is specified. {param = "lit", separate_no_index = true}, {param = "pos", separate_no_index = not data.require_index_for_pos, require_index = data.require_index_for_pos}, }	if data.extra_params then data.extra_params(params) end

local items, args = m_param_utils.process_list_arguments { params = params, param_mods = param_mods, raw_args = raw_args, termarg = term_index, parse_lang_prefix = true, track_module = "homophones", disallow_custom_separators = true, -- For compatibility, we need to not skip completely unspecified items. It is common, for example, to do -- to generate "+ -foo". dont_skip_items = true, -- 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 end 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 = args.sort data.type = args.type 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 return data end

function export.affix(frame) local function extra_params(params) params.type = {} params.notext = {type = "boolean"} params.nocat = {type = "boolean"} params.force_cat = {type = "boolean"} end

local args, parts, lang, sc = parse_args { raw_args = frame:getParent.args, extra_params = extra_params, }

if args.type and not m_affix.compound_types[args.type] then error("Unrecognized compound type: '" .. args.type .. "'") end

-- 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 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.type = {} params.notext = {type = "boolean"} params.nocat = {type = "boolean"} params.force_cat = {type = "boolean"} end

local args, parts, lang, sc = parse_args { raw_args = frame:getParent.args, extra_params = extra_params, }

if args.type and not m_affix.compound_types[args.type] then error("Unrecognized compound type: '" .. args.type .. "'") end

-- 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 then if mw.title.getCurrentTitle.nsText == "Template" then parts = { {term = "first"}, {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", etym_lang = true}, ["template"] = {}, ["text"] = {}, ["oftext"] = {}, ["cat"] = {}, }

local iargs = require("Module:parameters").process(frame.args, iparams)

local function extra_params(params) params.notext = {type = "boolean"} params.nocat = {type = "boolean"} params.force_cat = {type = "boolean"} end

local args, parts, lang, sc = parse_args { raw_args = frame:getParent.args, extra_params = extra_params, ilang = iargs.lang, -- 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, }

local template = iargs.template 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

if not next(parts) then if mw.title.getCurrentTitle.nsText == "Template" then parts = { {term = "first"}, {term = "second"} } end end

return m_affix.show_compound_like(augment_affix_data({ parts = parts, text = text, oftext = oftext, cat = cat }, 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 surface analysis" .. etymtext end

local function extra_params(params) params.type = {} params.notext = {type = "boolean"} params.nocat = {type = "boolean"} params.force_cat = {type = "boolean"} end

local args, parts, lang, sc = parse_args { raw_args = parent_args, extra_params = extra_params, }

if args.type and not m_affix.compound_types[args.type] then error("Unrecognized compound type: '" .. args.type .. "'") end

-- 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"}, {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 = {type = "boolean"} params.force_cat = {type = "boolean"} 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 = {type = "boolean"} params.force_cat = {type = "boolean"} 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 = {type = "boolean"} params.nocat = {type = "boolean"} params.force_cat = {type = "boolean"} end

local args, parts, lang, sc = 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, }

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 = {type = "boolean"} params.force_cat = {type = "boolean"} 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 = {type = "boolean"} params.force_cat = {type = "boolean"} 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 = {type = "boolean"} params.force_cat = {type = "boolean"} 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 iargs = frame.args local iparams = { ["derivtype"] = {}, ["mode"] = {}, }	local iargs = require("Module:parameters").process(frame.args, iparams)

local params = { ["head"] = {}, ["id"] = {}, ["sc"] = {type = "script"}, ["pos"] = {}, }	local derivtype = iargs.derivtype if derivtype == "PIE root" then params[1] = {} else params[1] = {required = "true", type = "language", etym_lang = true, default = "und"} params[2] = {} end

local args = require("Module:parameters").process(frame:getParent.args, params)

local lang local term

if derivtype == "PIE root" then lang = m_languages.getByCode("ine-pro", true) term = args[1] or args.head

if term then term = "*" .. term .. "-"		end else lang = args[1] term = args[2] or args.head end

local id = args.id	local sc = args.sc	local pos = require("Module:string utilities").pluralize(args.pos or "term")

if not term then local SUBPAGE = mw.title.getCurrentTitle.subpageText 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

if derivtype == "PIE root" then return frame:callParserFunction{ name = "#categorytree", args = { "Terms derived from the Proto-Indo-European root " .. term .. (id and " (" .. id .. ")" or ""), depth = 0, class = "\"derivedterms\"", mode = iargs.mode, }			}	end

local category = nil 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 frame:callParserFunction{ name = "#categorytree", args = { category, depth = 0, class = "\"derivedterms" .. (sc and " " .. sc:getCode or "") .. "\"", namespaces = "-" .. (mw.title.getCurrentTitle.nsText == "Reconstruction" and " Reconstruction" or ""), }		} end

return export

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

title: Module:User:Benwing2/affix/templates


title: User:Benwing2/affix


text: Thesaurus:美觀

title: Thesaurus:美觀


text: Gémǎlán

title: Gémǎlán


text: Gámǎlán

title: Gámǎlán


text: 趋缓

title: 趋缓


text:
趨緩

Verb

 * 1) to slow down; to ease up; to abate

title: 趨緩


text: Thesaurus:欺侮

title: Thesaurus:欺侮


text:
qığılcım

Noun

 * 1) spark

title: qığılcım


text: shēnjiāo

title: shēnjiāo


text: Zhānghuà

title: Zhānghuà


text:
知友

Noun

 * 1) intimate friend; bosom friend

title: 知友


text:
知交

Noun

 * 1) intimate friend; bosom friend

title: 知交


text: zhījiāo

title: zhījiāo


text: Thesaurus:知心朋友

title: Thesaurus:知心朋友


text:
camel rider

Noun

 * 1) Someone who rides a camel.

Translations

 * Danish: kamelrytter
 * Dutch: kameelrijder, kameelrijdster
 * French: ,
 * German:, Kamelreiterin
 * Norwegian:
 * Bokmål: kamelrytter
 * Nynorsk: kamelryttar
 * Swedish: kamelryttare

title: camel rider


text: zhīyǒu

title: zhīyǒu


text:
無薪假

Noun

 * 1) unpaid leave; furlough

title: 無薪假


text: 无薪假

title: 无薪假


text: tóngqīn

title: tóngqīn


text: Category:Proto-Germanic onomatopoeias

title: Category:Proto-Germanic onomatopoeias


text: 死灰复燃

title: 死灰复燃


text:
死灰復燃

Idiom

 * 1) renascent; to resurge

title: 死灰復燃


text: chénguī

title: chénguī


text: 成规

title: 成规


text:
成規

Noun

 * 1) established rules; set rules

title: 成規


text: chéngguī

title: chéngguī


text: yōuyǎ

title: yōuyǎ


text: yánzhěng

title: yánzhěng


text: zhíyí

title: zhíyí


text: zhōngshēng

title: zhōngshēng


text: quánshénguànzhù

title: quánshénguànzhù


text:
туэ

Etymology
From, compare 🇨🇬, 🇨🇬.

Noun

 * 1) winter

title: туэ


text: gāochàng

title: gāochàng


text:
сирму

Etymology
From, compare 🇨🇬, 🇨🇬.

Noun

 * 1) tongue

title: сирму


text:
วรรณคดี

Noun

 * 1) literature, literary work

title: วรรณคดี


text:
ดีเด่น

Adjective

 * 1) excellent

title: ดีเด่น


text:
dvimmsa

Verb

 * 1) to dwindle, diminish

title: dvimmsa


text:
grandori

Noun

 * 1) septennial court

title: grandori


text:
ศิษย์เก่า

Etymology
From 🇰🇲.

Noun

 * 1) alumnus

title: ศิษย์เก่า


text:
ยึดมั่น

Verb

 * 1) adhere, hold fast to

title: ยึดมั่น


text: shēngfān

title: shēngfān


text:
сиӈэрэ

Etymology
From, borrowed from.

Noun

 * 1) mouse, rat

title: сиӈэрэ


text:
စောင်း

Etymology
From.

Noun

 * 1)  harp
 * 2)  traditional Burmese curved harp

title: စောင်း


text:
гиан

Etymology 1
From.

Noun

 * 1) street

Etymology 2
.

Noun

 * 1) jaw

Etymology 3
From.

Noun

 * 1) order; law

title: гиан


text:
миаван

Etymology
From, compare 🇨🇬 and 🇨🇬.

Noun

 * 1) heart

title: миаван


text:
ကမန်

Etymology
From.

Noun

 * 1) Kaman, an ethnic group of Myanmar

title: ကမန်


text:
дуэ

Etymology
From, compare 🇨🇬.

Noun

 * 1) end
 * 2) death

title: дуэ


text:
ပွိုင့်

Etymology
From.

Noun

 * 1) point

title: ပွိုင့်


text:
дякпон

Etymology
From.

Numeral

 * 1) eight

title: дякпон


text: Category:Nanai numerals

title: Category:Nanai numerals


text:
дуин

Etymology
From. Cognate with 🇨🇬, 🇨🇬, 🇨🇬, 🇨🇬 (Jurchen script: ), 🇨🇬 (diɣin) and 🇨🇬 etc.

Numeral

 * 1) four

title: дуин


text: айӈани

title: айӈани


text: Category:gld:Metals

title: Category:gld:Metals


text: モスレム

title: モスレム


text:
айло̄ки

Noun

 * 1) wolverine

title: айло̄ки


text:
User talk:Blithebear

Welcome Message
--Lo Ximiendo (talk) 02:54, 15 March 2019 (UTC)

bismer
What makes you think the entry is inherited rather than derived? The bi- isn't part of the original Germanic word it is supposed to be inherited from. — surjection ⟨?⟩ 19:37, 29 March 2019 (UTC)

Community Insights Survey
Share your experience in this survey

Hi ,

The Wikimedia Foundation is asking for your feedback in a survey about your experience with and Wikimedia. The purpose of this survey is to learn how well the Foundation is supporting your work on wiki and how we can change or improve things in the future. The opinions you share will directly affect the current and future work of the Wikimedia Foundation.

Please take 15 to 25 minutes to give your feedback through this survey. It is available in various languages.

This survey is hosted by a third-party and governed by this privacy statement (in English).

Find more information about this project. [mailto:surveys@wikimedia.org Email us] if you have any questions, or if you don't want to receive future messages about taking this survey.

Sincerely, RMaung (WMF) 14:32, 9 September 2019 (UTC)

Reminder: Community Insights Survey
Share your experience in this survey

Hi ,

A couple of weeks ago, we invited you to take the Community Insights Survey. It is the Wikimedia Foundation’s annual survey of our global communities. We want to learn how well we support your work on wiki. We are 10% towards our goal for participation. If you have not already taken the survey, you can help us reach our goal! Your voice matters to us.

Please take 15 to 25 minutes to give your feedback through this survey. It is available in various languages.

This survey is hosted by a third-party and governed by this privacy statement (in English).

Find more information about this project. [mailto:surveys@wikimedia.org Email us] if you have any questions, or if you don't want to receive future messages about taking this survey.

Sincerely, RMaung (WMF) 19:13, 20 September 2019 (UTC)

Reminder: Community Insights Survey
Share your experience in this survey

Hi ,

There are only a few weeks left to take the Community Insights Survey! We are 30% towards our goal for participation. If you have not already taken the survey, you can help us reach our goal! With this poll, the Wikimedia Foundation gathers feedback on how well we support your work on wiki. It only takes 15-25 minutes to complete, and it has a direct impact on the support we provide.

Please take 15 to 25 minutes to give your feedback through this survey. It is available in various languages.

This survey is hosted by a third-party and governed by this privacy statement (in English).

Find more information about this project. [mailto:surveys@wikimedia.org Email us] if you have any questions, or if you don't want to receive future messages about taking this survey.

Sincerely, RMaung (WMF) 17:03, 4 October 2019 (UTC)

title: User talk:Blithebear


text:
а̄ми

Etymology
From, compare 🇨🇬.

Noun

 * 1) sleep

title: а̄ми


text:
ឧទាហរណ៍

Etymology
From or.

Noun

 * 1) example; model

title: ឧទាហរណ៍


text:
долбо

Etymology
From, cognate with 🇨🇬.

Noun

 * 1) night

Adjective

 * 1) nocturnal

title: долбо


text:
токса

Etymology
From Tungusic, compare 🇨🇬 and 🇨🇬.

Noun

 * 1) rabbit

title: токса


text:
suselmann

Etymology
From.

Noun

 * 1) estate-agent

title: suselmann


text:
нгэлэ

Etymology
Cognate with 🇨🇬.

Noun

 * 1) wolf

title: нгэлэ


text:
гаса

Etymology
From, compare 🇨🇬.

Noun

 * 1) bird
 * 2) duck

title: гаса


text:
бэюн

Etymology
From, compare 🇨🇬. See also 🇨🇬.

Noun

 * 1) animal

Noun

 * 1) large animal

title: бэюн


text:
landskyld

Noun

 * 1) land-rent

title: landskyld


text:
усэлтэ

Etymology
From.

Noun

 * 1) animal

title: усэлтэ


text:
солаки

Etymology
From. Cognate with 🇨🇬 and 🇨🇬.

Noun

 * 1) fox

title: солаки


text:
енгур

Etymology
From.

Noun

 * 1) wolf

title: енгур


text:
хунгули

Noun

 * 1) insect

title: хунгули


text:
силуктэ

Etymology
From, compare 🇨🇬, 🇨🇬.

Noun

 * 1) ant

title: силуктэ


text:
勞委會

Noun

 * 1) labor committee

Proper noun

 * 1) Council of Labor Affairs, later became

title: 勞委會


text:
kroinjta

Verb

 * 1) to whimper or complain

title: kroinjta


text: 劳委会

title: 劳委会


text: 浮荡

title: 浮荡


text:
浮蕩

Verb

 * 1) to flutter ; to sway; to float ; to drift

Adjective

 * 1) frivolous; flippant
 * 2)  false; superficial
 * 3) boastful; pompous; pretentious; exaggerative

Synonyms

title: 浮蕩


text: fúdàng

title: fúdàng


text:
нёӈня

Etymology
From, compare 🇨🇬, 🇨🇬 and 🇨🇬.

Noun

 * 1) goose

title: нёӈня


text:
vegetary

Adjective

 * 1) Characterized by life and growth.
 * 2) Consisting of or characterized by vegetables or vegetation.

title: vegetary


text:
User:Fish bowl/p/mul

Korean

 * User:LoutK/sandbox

Pronunciation
  `|Mandarin `|Mandarin (官話//)   `|Standard Mandarin `|Beijing Mandarin (北京官話//): `|Standard Mandarin (普通話//, 國語//, 華語//)   nàge : na4ge0 : ㄋㄚˋ ˙ㄍㄜ `|Pinyin: nàge   `|Pinyin (ASCII): na4ge0   `|Zhuyin: ㄋㄚˋ ˙ㄍㄜ   `|Gwoyeu Romatzyh: ????????   `|Homophones:

 `|IPA: ; </li> <li class="vsHide"> `|Audio:

 nèige : nei4ge0 : ㄋㄟˋ ˙ㄍㄜ `|Pinyin: nèige <ul> <li> <i class="blueNote">colloquial</i> </li> <li> <i class="blueNote">coalescence of </i> </li> <li class="vsHide"> `|Pinyin (ASCII): nei4ge0

 `|Zhuyin: ㄋㄟˋ ˙ㄍㄜ </li> <li class="vsHide"> `|Gwoyeu Romatzyh: neyg < ney.ge

 etc

 `|Audio: <ul> <li>Forvo</li> </ul> </li> </ul> </li> </ul> </li> <li class="vsHide vsSwitcher vsToggleCategory-zhPron_官話_蘭銀官話_Dungan" data-toggle-category="Dungan"> `|Dungan `|Lan–Yin Mandarin (蘭銀官話//): `|Dungan (Хуэйзў йүян)

 ниму II-I : nimu II-I ниму II-I

 `|Wiktionary: nimu II-I </li> <li class="vsHide"> `|IPA: ,

 `|Chengdu `|Southwestern Mandarin (西南官話//): `|Sichuanese (四川話//): Chengdu (成都//) <ul> <li> [please add!] </li> </ul> </li> <li class="vsHide vsSwitcher vsToggleCategory-zhPron_官話_北方話拉丁化新文字" data-toggle-category="北方話拉丁化新文字"> `|Other: `|Beifangxua Latinxua Sin Wenz `|Other: `|Beifangxua Latinxua Sin Wenz (北方話拉丁化新文字//)

 maai < mai

 Contrasts with .

 `|Cantonese `|Cantonese (粵語//)

 `|Standard Cantonese `|???: `|Standard Cantonese (廣東話//, 廣府話//): <ul> <li> hek3 bat1 dou3-2 dik1 pou4 tou4 si6 syun1 dik1 `|Jyutping: hek3 bat1 dou3-2 dik1 pou4 tou4 si6 syun1 dik1

 `|Yale: hek-bāt-dóu dīk pòuhtòuh sih syūn dīk </li> <li class="vsHide"> etc </li> </ul> </li> <li> hoeng1- `|Jyutping: hoeng1-

 "incense"

 `|Yale: hēung </li> <li class="vsHide"> etc </li> <li class="vsHide"> <i class="blueNote">Historical:</i> <ul> <li> `|Williams: ꜀héung

 `|Jyutping: *hoeng1 </li> <li> `|IPA:

 hoeng1` `|Jyutping: hoeng1` <ul> <li class="vsHide"> `|Yale: hèung

 etc

 `|Min `|Min (閩語//)

 `|Min Nan: `|Hokkien `|Coastal Min (沿海閩語//): `|Min Nan (閩南語//): `|Hokkien (福建話//) <ul> <li> <i class="blueNote">(俗// vern.)</i> bē; bēr; bōe; běr : be7; be7; boe7; ber6 `|Peh-oe-ji: bē; bēr; bōe; běr

 bē - `|Xiamen  (廈門//, `|Amoy), `|Taipei   (臺北//) , `|Yilan  (宜蘭//) , `|Magong  (馬公//) </i> </li> <li> <i class="blueNote">bēr - `|Quanzhou   (泉州//), `|Sanxia  (三峽//) , `|Kinmen  (金門//) , `|Hsinchu  (新竹//) </i> </li> <li> <i class="blueNote">bōe - `|Zhangzhou  (漳州//), `|Yilan  (宜蘭//) , `|Tainan  (臺南//) , `|Kaohsiung  (高雄//) , `|Taichung  (臺中//) , `|Penang  (檳城//) </i> </li> <li> <i class="blueNote">běr - `|Lukang

 `|Peh-oe-ji (ASCII): be7; ber7; boe7; ber6 </li> <li class="vsHide"> `|Tai-lo: bē; bēr; buē; běr

 `|Tai-lo (ASCII): be7; ber7; bue7; ber6 </li> <li class="vsHide"> `|Phofsit Daibuun: be; -; boe; -

 `|IPA: <ul> <li> </li> <li> </li> <li> </li> <li> </li> <li> etc </li> </ul> </li> </ul> </li> <li> <i class="blueNote">(文// lit.)</i> bī : bi7 `|Peh-oe-ji: bī

 etc

 `|Min Nan: `|Teochew `|Coastal Min (沿海閩語//): `|Min Nan (閩南語//): `|Teochew (潮州話//) <ul> <li> bhuê7 : buē `|Guangdong Pinyin: bhuê7

 `|Chaozhou  (潮州//), `|Shantou  (汕頭//, `|Swatow) , `|Chaoyang  (潮陽//)

 "not; have not"

 `|Peh-oe-ji-like: buē </li> <li class="vsHide"> `|IPA:

 dêng2 : téng `|Guangdong Pinyin: dêng2 <ul> <li> <i class="blueNote">`|Chaoyang  (潮陽//)

 `|Peh-oe-ji-like: téng </li> <li class="vsHide"> `|IPA:

 ,

 `|Historical <ul class="vsHide"> <li class="vsSwitcher vsToggleCategory-zhPron_Historical_廣韻" data-toggle-category="廣韻"> `|Middle Chinese: `|Guangyun `|Middle Chinese (中古漢語//): `|Guangyun <ul> <li> 流開一平侯來 etc <ul> <li class="vsHide"> etc </li> </ul> </li> </ul> </li> </ul> </li> <li class="vsSwitcher vsToggleCategory-zhPron_Other" data-toggle-category="Other"> `|Other

 `|General Chinese `|General Chinese (通字//)

 vuu 武 `|GCC, `|GCR: vuu 武

 `|???: ꜂vu ꜂微模

 * where can i place ꜀꜂꜄꜆
 * way too ambitious lol. but it's what i want to see. mostly. while considering that this nonsense theoretically might need to be implemented someday (wishful thinking) (passive voice)
 * instead of data modules, put data directly on the character page, and have a bot (or some toolforge whatever magic) monitor changes (related to a specific data source, etc.)
 * refer to User:Justinrleung/Dialect Resources etc for grouping
 * another idea: mark 訓讀.  and in zh-forms too
 * when collapsed, show what dialects of a lect are present?
 * use the cool new hip angle brackets (<t:>
<q:>) instead

Definitions

 * 1) …
 * cmn:成都
 * zhx-min:t;cy

title: User:Fish bowl/p/mul


text:
гочин

Etymology
Cognate with 🇨🇬 and 🇨🇬 and 🇨🇬.

Numeral

 * 1) thirty

title: гочин


text: 来势汹汹

title: 来势汹汹


text:
來勢洶洶

Idiom

 * 1) arriving fiercely; bearing down menacingly; coming with great momentum or intensity

title: 來勢洶洶


text: piāoluò

title: piāoluò


text:
Template:U:en:-ese

As with other terms for people formed with -ese, the countable singular noun in reference to a person (as in "I am ", "writing about  cuisine as  ") is uncommon and often taken as incorrect. In its place, the adjective is used, by itself (as in "I am ") or with a word like person, man, or woman ("writing about cuisine as   person").

title: Template:U:en:-ese


text:
勇壯

Adjective

 * 1)  brave and strong
 * 2)  burly; well-built; strong and healthy; robust

Noun

 * 1)  brave and strong soldier

title: 勇壯


text: 勇壮

title: 勇壮


text: yǒngzhuàng

title: yǒngzhuàng


text: Thesaurus:健壯

title: Thesaurus:健壯


text:
တိရစ္ဆာန်ဥယျာဉ်

Etymology
+.

Noun

 * 1) zoo

title: တိရစ္ဆာန်ဥယျာဉ်


text:
pīti

Etymology
. Cognate with 🇨🇬,,.

Noun

 * 1) joy, delight, pleasure

title: pīti


text:
Smarandache function

Etymology
Named after Florentin Smarandache, who rediscovered the function in 1980.

Proper noun

 * 1)  A function, denoted by S(n) for some positive integer n, that yields the smallest number s such that n divides the factorial s!. For example, the number 8 does not divide 1!, 2!, 3!, but does divide 4!, so S(8) = 4.

title: Smarandache function


text: jiùyào

title: jiùyào


text: kuàiyào

title: kuàiyào


text: Thesaurus:立刻

title: Thesaurus:立刻


text: jiēhuò

title: jiēhuò


text: tōngbào

title: tōngbào


text:
예배당

Etymology
.

Noun

 * 1) chapel; church

title: 예배당


text:
人力銀行

Noun

 * 1)  employment agency; recruitment agency

title: 人力銀行


text: 人力银行

title: 人力银行


text: 警讯

title: 警讯


text:
警訊

Noun

 * 1) warning sign; police call

title: 警訊


text:
por que será

Etymology
lit. 'why would it be?'.

Interjection

 * 1) ironically implying that the answer to a question or doubt is obvious

title: por que será


text:
ungadreng

Noun

 * 1) a young unmarried man

title: ungadreng


text:
畲話

Usage notes
Not to be confused with.

title: 畲話


text: 畲话

title: 畲话


text:
brennja

Noun

 * 1) fire

title: brennja


text:
طوعا

Etymology
.

Adverb

 * 1) willingly, voluntarily

title: طوعا


text:
舌子

Noun

 * 1)  tongue
 * 2)  animal's tongue

title: 舌子


text:
kwraa

Adverb

 * 1) at all

title: kwraa


text:
Talk:changfa

 * This seems to refer to Changfa brand engines, and I'm not seeing enough WT:BRAND-compliant cites. —Μετάknowledge discuss/deeds 05:13, 15 March 2019 (UTC)
 * Yes, that's what I concluded when I created the citations page. DTLHS (talk) 05:15, 15 March 2019 (UTC)
 * OK. It's your call, but I think it's good to record this kind of thing somewhere, so that anyone who comes by looking to create an entry knows what you found. —Μετάknowledge discuss/deeds 05:17, 15 March 2019 (UTC)
 * Basically if I find something that looks like it could eventually be includable and looks like an actual word I'll create a citations page, if I think it's actually includable now it goes on my user page. DTLHS (talk) 05:18, 15 March 2019 (UTC)

title: Talk:changfa


text:
ӄуйаӄуй

Etymology
From. Compare 🇨🇬 and 🇨🇬.

Noun

 * 1) reindeer

title: ӄуйаӄуй


text:
уккуӈа

Etymology
From. Compare also 🇨🇬, 🇨🇬, 🇨🇬 and 🇨🇬.

Noun

 * 1) stone, rock

title: уккуӈа


text:
ӈавхан

Noun

 * 1) woman

title: ӈавхан


text: 牛脷酥

title: 牛脷酥


text: Sentineleses

title: Sentineleses


text: Category:English terms with 4 consecutive instances of the same letter


text:
Sealyham

Noun

 * 1) A Sealyham terrier.

title: Sealyham


text: Sealyhams

title: Sealyhams


text:
Template:U:en:-ese/documentation

If the word needs to be preceded by "an" instead of "a" (e.g. "an Andamanese"), set.

title: Template:U:en:-ese/documentation


text:
delaware

Etymology
From.

Noun

 * 1) Delaware member of Delaware native American people

Usage notes

 * Sometimes inflected in other cases than nominative singular as if this were a type 5 noun, particularly in plural ( instead of ).

Etymology
.

Noun

 * 1) Delaware; Lenape member of a native people of eastern North America

title: delaware


text: εναλλάκτη

title: εναλλάκτη


text: εναλλάκτες

title: εναλλάκτες


text: εναλλακτών

title: εναλλακτών


text: ένδειας

title: ένδειας


text: ενδείας

title: ενδείας


text: ενδοκρινολογίας

title: ενδοκρινολογίας


text: ενδοκρινολόγου

title: ενδοκρινολόγου


text: ενδοκρινολόγο

title: ενδοκρινολόγο


text: ενδοκρινολόγε

title: ενδοκρινολόγε


text: ενδοκρινολόγων

title: ενδοκρινολόγων


text: ενδοκρινολόγοι

title: ενδοκρινολόγοι


text: ενδοκρινολόγους

title: ενδοκρινολόγους


text: ενδοσπερμίου

title: ενδοσπερμίου


text: ενδοσπερμίων

title: ενδοσπερμίων


text: ενδοσπέρμια

title: ενδοσπέρμια


text: ενδυμασίας

title: ενδυμασίας


text: ενδυμασιών

title: ενδυμασιών


text: ενδυμασίες

title: ενδυμασίες


text: ενδυμάτων

title: ενδυμάτων


text: ενδύματα

title: ενδύματα


text: ενδύματος

title: ενδύματος


text: ενδοχωρών

title: ενδοχωρών


text: ενδοχώρες

title: ενδοχώρες


text: ενδοχώρας

title: ενδοχώρας


text: Category:grc:Ferns

title: Category:grc:Ferns


text: Category:grc:Spore plants

title: Category:grc:Spore plants


text: Category:grc:Morning glory family plants


text:
Malco

Etymology
From, from.

Proper noun

 * 1)  Malchus

title: Malco


text: Category:grc:Nightshades

title: Category:grc:Nightshades


text:
Talk:гидрокостюм

The Russian term "гидрокостюм" poses difficulties for interpreters, translators and modern linguists in general. Etymologically, the word simply implies a "water suit" in meaning. Depending on type, a "гидрокостюм" can be used for surface activities other than diving, such as water skiing, aquaculture, canoeing, powerboating, i.e. anything involving working or playing on, in or under water to protect the wearer from exposure to the water or water plants and creatures.

The word "гидрокостюм" is more often than not rendered into English as "wetsuit", which may be correct most of the time because of the popularity of wetsuit use, but the term can equally apply to a drysuit, which excludes water comnpletely, while a wetsuit admits a small amount of water that then remains stagnant against the wearer's skin and is warmed up by it to body temperature, providing thermal protection.

I don't have a "mot juste" when translating "гидрокостюм" into English. All I can suggest is that "immersion suit" might be used instead wherever it is unclear whether a water-admitting wetsuit or a water-excluding dry suit is under discussion. I am not entirely happy with the rendering "immersion suit", however, as it has a particular meaning as a garment used in water rescue and when working in aquatic environments and less of a generic meaning denoting any exposure suit for water-based activities, which is what a "гидрокостюм" is.

Any thoughts? Helmardine (talk) 07:46, 15 March 2019 (UTC)

title: Talk:гидрокостюм


text:
Μάλχος

Etymology
Borrowed from.

Proper noun

 * 1) Malchus

title: Μάλχος


text: Category:grc:Asparagus family plants

title: Category:grc:Asparagus family plants


text: Category:grc:Succulents

title: Category:grc:Succulents


text:
M. D.

Noun

 * 1)  medical doctor; doctor of medicine

title: M. D.


text:
δώραξ

Noun

 * 1) Hesychius' gives the definition as:, as they say in Macedonia

title: δώραξ


text: Category:grc:Borage family plants

title: Category:grc:Borage family plants


text:
ὀρειχάλκινος

Etymology
From.

Adjective

 * 1) made of orichalcum

title: ὀρειχάλκινος


text:
راسن

Etymology
From, also found borrowed in 🇨🇬.

Noun

 * 1)  elecampane

Etymology
Ultimately from, used throughout Ayurvedic literature; another plant within the family just as.

Noun

 * 1) elecampane

title: راسن


text: 通识

title: 通识


text:
witch-hunting

Noun

 * 1)  Engagement in a witch-hunt; searching for witches or for evidence against them.
 * 2) Engagement in a political witch-hunt; unjust or ideological persecution.
 * 1) Engagement in a political witch-hunt; unjust or ideological persecution.

title: witch-hunting


text:
通識

Noun

 * 1) general knowledge; common knowledge
 * 2)  knowledgeable person
 * 1)  knowledgeable person

Adjective

 * 1)  knowledgeable

title: 通識


text: witch-finder

title: witch-finder


text:
thuyền độc mộc

Etymology
.

title: thuyền độc mộc


text:
Six Nations of the Grand River

Etymology
. From the six nations (Mohawk, Cayuga, Onondaga, Oneida, Seneca, Tuscarora) living on the reserve located on the Grand River (of Ontario that feeds into Lake Erie).

Proper noun

 * 1)  The largest First Nations Indian reserve in Canada; located on the Grand River of Ontario that feeds into Lake Erie.

Synonyms

 * shortened form

Translations

 * French: Réserve des Six Nations

title: Six Nations of the Grand River


text:
ῥυπαρός

Etymology
From.

Adjective

 * 1) filthy, dirty, greasy, unpurged
 * 2) sordid, mean, uncultured
 * 3) made of base metal (of coins)

title: ῥυπαρός


text:
rauhantyö

Noun

 * 1) peace work

title: rauhantyö


text:
rikkurityövoima

Noun

 * 1) workforce of strikebreakers

title: rikkurityövoima


text:
rutiinityö

Noun

 * 1) routine work

title: rutiinityö


text:
ryhmätyöhuone

Noun

 * 1) teamwork study room

title: ryhmätyöhuone


text:
μόθος

Etymology
No cognates outside Greek. Has been compared with 🇨🇬 and with 🇨🇬 but this seems unprobable. Perhaps from.

Noun

 * 1) battle din

title: μόθος


text:
霊長

Etymology
From. Ultimately sourced from the, one version of which is dated to the late.

Noun

 * 1) the master of all things, the most powerful of beings, the lord of creation

title: 霊長


text:
poliisikunta

Noun

 * 1) police force police collectively

title: poliisikunta


text:
poliisikuulustelu

Noun

 * 1) police interrogation, police questioning

title: poliisikuulustelu


text:
poliisimerkki

Noun

 * 1) police badge

title: poliisimerkki


text:
poliisimestari

Noun

 * 1)  ; chief constable, police commissioner, police inspector

title: poliisimestari


text:
poliisineuvos

Noun

 * 1) an honorary title of the seventh rank granted by the  to accomplished people involved in police or law enforcement

title: poliisineuvos


text:
poliisipartio

Noun

 * 1) police patrol

title: poliisipartio


text:
poliisitalo

Noun

 * 1) police station

title: poliisitalo


text:
poliisitarkastaja

Noun

 * 1) superintendent, police inspector

title: poliisitarkastaja


text:
poliisitiedotus

Noun

 * 1) police announcement

title: poliisitiedotus


text:
poliisitutkinta

Noun

 * 1) police investigation

title: poliisitutkinta


text:
poliisivalvonta

Noun

 * 1) police check, police surveillance

title: poliisivalvonta


text:
poliisivartio

Noun

 * 1) police patrol, police protection

title: poliisivartio


text:
kantohihna

Noun

 * 1) carrying cord, carrying strap

title: kantohihna


text:
kantokahva

Noun

 * 1) carrying handle

title: kantokahva


text:
kantokerros

Noun

 * 1) carrying layer

title: kantokerros


text:
kantokori

Noun

 * 1) carrying basket, shopping basket

title: kantokori


text:
kantokotelo

Noun

 * 1) carrying case

title: kantokotelo


text:
kantokuorma

Noun

 * 1) bearing load

title: kantokuorma


text:
kantokyky

Noun

 * 1) carrying capacity, bearing capacity

title: kantokyky


text:
kantolaukku

Noun

 * 1) carrying case, carrying bag

title: kantolaukku


text:
kantoliina

Noun

 * 1) sling, baby sling

title: kantoliina


text:
kantomatka

Noun

 * 1) range, reach maximum distance of capability

title: kantomatka


text:
kantopommi

Noun

 * 1) explosive used to blow up tree stumps

title: kantopommi


text:
kantoryhmä

Noun

 * 1) group of people who carry something

title: kantoryhmä


text:
kantotaso

Noun

 * 1) wing, airfoil

title: kantotaso


text:
kantovesa

Noun

 * 1) stump sprout

title: kantovesa


text:
kantoväline

Noun

 * 1) carrying implement, carrying utility

title: kantoväline


text: Ἱρή

title: Ἱρή


text:
Iroquois Confederacy

Proper noun

 * 1) A confederacy of Iroquoian tribes. Initially consisting of the Five Nations (Mohawk, Onondaga, Oneida, Cayuga, Seneca), later of the Six Nations (adding the Tuscarora)

Translations

 * French: Confédération iroquoise, Ligue iroquoise,

title: Iroquois Confederacy


text:
Appendix:Quenya/ára

Noun

 * 1) dawn
 * 2) the long vowel carrier of the Tengwar system

title: Appendix:Quenya/ára


text:
Appendix:Quenya/aran

Noun

 * 1) king

title: Appendix:Quenya/aran


text:
Appendix:Quenya/aranel

Noun

 * 1) princess

Usage notes
it's not utterly certain that this was the stem

title: Appendix:Quenya/aranel


text:
Appendix:Quenya/aranië

Alternative forms

 * , attested only in the compound Ardaranyë = the Kingdom of Arda

Noun

 * 1) kingdom

title: Appendix:Quenya/aranië


text:
Appendix:Quenya/aranussë

Alternative forms

 * , with stem aranuss-

Noun

 * 1) kingship

title: Appendix:Quenya/aranussë


text: Six-Nations

title: Six-Nations


text:
Appendix:Quenya/aranya

Adjective

 * 1) free

title: Appendix:Quenya/aranya


text:
Appendix:Quenya/arata

Adjective

 * 1) high, lofty, noble

title: Appendix:Quenya/arata


text:
Appendix:Quenya/arato

Alternative forms

 * , a very archaic form

Noun

 * 1) a noble

title: Appendix:Quenya/arato


text:
Appendix:Quenya/aráto

Noun

 * 1) champion, eminent man

title: Appendix:Quenya/aráto


text:
Template:R:sd:Mewaram

Old dictionary albeit comprehensive and accessible online.

title: Template:R:sd:Mewaram


text:
Appendix:Quenya/arauca

Adjective

 * 1) swift, rushing

title: Appendix:Quenya/arauca


text: prisgis

title: prisgis


text: prisgir

title: prisgir


text:
Appendix:Quenya/arca

Adjective

 * 1) narrow

title: Appendix:Quenya/arca


text:
Appendix:Quenya/arda

Noun

 * 1) realm
 * 2) name of a tengwa letter

Usage notes
when used as a common noun it meant more or less a bounded or defined place, a region

title: Appendix:Quenya/arda


text: prisga

title: prisga


text:
Appendix:Quenya/árë

Alternative forms

 * (older times of the Elves)

Noun

 * 1) day
 * 2) sunrise
 * 3) old name of the tengwa letter

title: Appendix:Quenya/árë


text:
Appendix:Quenya/arië

Noun

 * 1) daytime

title: Appendix:Quenya/arië


text:
هلڻ

Etymology
.

Verb

 * 1) to walk, go, move, proceed

title: هلڻ


text:
Appendix:Quenya/arin

Noun

 * 1) morning

title: Appendix:Quenya/arin


text: prisgav

title: prisgav


text:
Appendix:Quenya/arinya

Adjective

 * 1) morning (in the adjectival sense)
 * 2) early

title: Appendix:Quenya/arinya


text:
Appendix:Quenya/arma

Noun

 * 1) a ray of sunlight

title: Appendix:Quenya/arma


text:
Appendix:Quenya/armar

Noun

 * 1) goods

title: Appendix:Quenya/armar


text: prisgitt

title: prisgitt


text:
Appendix:Quenya/armaro

Noun

 * 1) neighbour

title: Appendix:Quenya/armaro


text:
Appendix:Quenya/arquen

Noun

 * 1) a noble
 * 2) knight

title: Appendix:Quenya/arquen


text:
Appendix:Quenya/arta

Noun

 * 1) fortress

title: Appendix:Quenya/arta


text:
Appendix:Quenya/artarindo

Noun

 * 1) bystander, supporter

title: Appendix:Quenya/artarindo


text:
Appendix:Quenya/artaurë

Noun

 * 1) realm

title: Appendix:Quenya/artaurë


text:
Appendix:Quenya/artuilë

Noun

 * 1) dayspring, early morn

title: Appendix:Quenya/artuilë