This module is used for all Slovene headword-line templates. It provides a basic functionality common to all of them, but some of the templates have specific additional functionality to show genders or inflected forms.
All Slovene headword-line templates except {{sl-head}}
use the first parameter to provide the headword, with accented vowels where present. This uses the tonal diacritics. See Appendix:Slovene pronunciation and Wiktionary:Slovene entry guidelines for more details. For example:
{{sl-noun|jẹ̄ž|m-an}}
{{sl-adj|nȍv|novȇjši}}
With {{sl-head}}
, the first parameter is the part of speech and the second parameter is the accented headword, e.g.:
{{sl-head|pronoun|óna}}
If the word can be accented in more than one way, use additional |head2=
, |head3=
(etc.) parameters. For example on takoj:
{{sl-adv|takọ̑j|head2=takȍj}}
The headword parameter works exactly like |head=
on the {{head}}
template, so it supports all the same special features. You can therefore also use this parameter to link to individual words of a multi-word term. These words can be linked with accents still in place; the module will remove them from the page name before creating a link, much like {{l}}
does.
All Slovene words are expected to have accents specified. The module will check the parameter for the presence of accents, and categorize the entry in Category:Requests for accents in Slovene POS entries (where POS
is the appropriate part of speech) if none are found. Some words like prepositions really have no inherent accent of their own. For such words, give -
as the headword parameter, as on the preposition brez:
{{sl-head|preposition|-}}
This tells the module that you are sure that the word should not have accents, so that it will not check for them.
If you don't know where to place the accents, use a ?
, or just write the page name without accents. Don't use -
unless you're sure the word should not have any accents.
local export = {}
local pos_functions = {}
local force_cat = false -- for testing; if true, categories appear in non-mainspace pages
local langcode = "sl"
local lang = require("Module:languages").getByCode(langcode, true)
local langname = lang:getCanonicalName()
local require_when_needed = require("Module:utilities/require when needed")
local m_str_utils = require("Module:string utilities")
local m_table = require("Module:table")
local com = require("Module:sl-common")
local en_utilities_module = "Module:en-utilities"
local headword_module = "Module:headword"
local headword_data_module = "Module:headword/data"
local headword_utilities_module = "Module:headword utilities"
local links_module = "Module:links"
local m_headword_utilities = require_when_needed(headword_utilities_module)
local glossary_link = require_when_needed(headword_utilities_module, "glossary_link")
local u = m_str_utils.char
local rfind = m_str_utils.find
local ulower = m_str_utils.lower
local unfd = mw.ustring.toNFD
local list_param = {list = true, disallow_holes = true}
-- Table of all valid genders, mapping user-specified gender specs to canonicalized versions.
local valid_genders = {
= "m-an?",
= true,
= true,
= true,
= true,
= true,
= true,
= true,
= true,
= true,
= true,
= true,
= true,
}
-- Table of all valid aspects.
local valid_aspects = m_table.listToSet {
"impf", "pf", "both", "biasp", "?",
}
local function ine(val)
if val == "" then return nil else return val end
end
local function track(track_id, pos)
local tracking_pages = {}
table.insert(tracking_pages, "sl-headword/" .. track_id)
if pos then
table.insert(tracking_pages, "sl-headword/" .. track_id .. "/" .. pos)
end
require("Module:debug/track")(tracking_pages)
return true
end
local function check_accents_and_tones(term, pos, data)
if term:find("%[") then
term = require(links_module).remove_links(term)
end
if com.needs_accents(term) then
table.insert(data.categories, ("Requests for accents in %s %s entries"):format(langname, pos))
end
-- Tone check
local found_tonal = false
local found_stress = false
local found_ambiguous = false
term = ulower(term)
if rfind(term, "") then
found_tonal = true
end
if rfind(term, "") then
found_stress = true
end
if rfind(term, "") then
found_ambiguous = true
end
if found_stress then
track("stress", pos)
elseif found_ambiguous then
track("ambiguous", pos)
elseif found_tonal then
track("tonal", pos)
end
end
local function make_check_accents_frob(pos, data)
return function(term)
check_accents_and_tones(term, pos, data)
return term
end
end
-- Parse and insert an inflection not requiring additional processing into `data.inflections`. The raw arguments come
-- from `args`, which is parsed for inline modifiers. `label` is the label that the inflections are given;
-- sections enclosed in <<...>> are linked to the glossary. `accel` is the accelerator form, or nil.
local function parse_and_insert_inflection(pos, data, args, field, label, accel)
m_headword_utilities.parse_and_insert_inflection {
headdata = data,
forms = args,
paramname = field,
label = label,
accel = accel and {form = accel} or nil,
frob = make_check_accents_frob(pos, data),
}
end
-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
local iparams = {
= {},
= {},
}
local iargs = require("Module:parameters").process(frame.args, iparams)
local args = frame:getParent().args
local poscat = iargs
local def = iargs.def
local parargs = frame:getParent().args
local headarg
if poscat then
headarg = 1
else
headarg = 2
poscat = ine(parargs) or
mw.title.getCurrentTitle().fullText == "Template:" .. langcode .. "-head" and "interjection" or
error("Part of speech must be specified in 1=")
poscat = require(headword_module).canonicalize_pos(poscat)
end
local params = {
= {list = "head", required = true, disallow_holes = true, template_default = def},
= true,
= true,
-- no nolinkhead= because head in 1= is always specified
= {type = "boolean"},
= true, -- for testing
}
if headarg == 2 then
params = {required = true} -- required but ignored as already processed above
end
if pos_functions then
local posparams = pos_functions.params
if type(posparams) == "function" then
posparams = posparams(lang)
end
for key, val in pairs(posparams) do
params = val
end
end
local args = require("Module:parameters").process(parargs, params)
local pagename = args.pagename or mw.loadData(headword_data_module).pagename
local data = {
lang = lang,
pos_category = poscat,
categories = {},
heads = args,
genders = {},
inflections = {},
pagename = pagename,
id = args.id,
sort_key = args.sort,
force_cat_output = force_cat,
is_suffix = false,
}
local singular_poscat = require(en_utilities_module).singularize(poscat)
if pagename:find("^%-") and poscat ~= "suffix forms" then
data.is_suffix = true
data.pos_category = "suffixes"
table.insert(data.categories, langname .. " " .. singular_poscat .. "-forming suffixes")
table.insert(data.inflections, {label = singular_poscat .. "-forming suffix"})
end
for i, head in ipairs(data.heads) do
if head == "-" then
-- For abbreviations and the like.
track("head-hyphen", singular_poscat)
data.heads = pagename
elseif head == "?" then
track("head-question-mark", singular_poscat)
table.insert(data.categories, ("Requests for accents in %s %s entries"):format(langname, singular_poscat))
data.heads = pagename
else
check_accents_and_tones(head, singular_poscat, data)
end
end
if pos_functions then
pos_functions.func(args, data)
end
-- unfd (mw.ustring.toNFD) performs decomposition, so letters that decompose to an ASCII vowel and a diacritic,
-- such as é, are counted as vowels and do not need to be included in the pattern.
if not pagename:find("") and not rfind(ulower(unfd(pagename)), "") then
table.insert(data.categories, langname .. " words without vowels")
end
if args.json then
return require("Module:JSON").toJSON(data)
end
return require(headword_module).full_headword(data)
end
local function get_noun_params(is_proper)
return function(lang)
params = {
= {alias_of = "g"},
= {type = "genders", required = true, template_default = "?"},
= {type = "boolean"},
= list_param,
= list_param,
= list_param,
= list_param,
= list_param,
= list_param,
= list_param,
= list_param,
= list_param,
= list_param,
= list_param,
= list_param,
}
return params
end
end
local function do_nouns(is_proper, args, data)
for _, g in ipairs(args.g) do
local canon_g = valid_genders
if canon_g then
track("gender-" .. g.spec)
if canon_g ~= true then
g.spec = canon_g
end
-- Categorize by gender, in addition to what's done already by ].
if g.spec == "m-an" then
table.insert(data.categories, langname .. " masculine animate nouns")
elseif g.spec == "m-in" then
table.insert(data.categories, langname .. " masculine inanimate nouns")
end
else
error("Unrecognized gender: '" .. g.spec .. "'")
end
end
data.genders = args.g
if #data.genders == 0 then
table.insert(data.genders, "?")
end
if args.indecl then
table.insert(data.inflections, {label = glossary_link("indeclinable")})
table.insert(data.categories, langname .. " indeclinable nouns")
end
-- Parse and insert an inflection not requiring additional processing into `data.inflections`. The raw arguments
-- come from `args`, which is parsed for inline modifiers. `label` is the label that the inflections are
-- given; <<..>> ini the label is linked to the glossary). `accel` is the accelerator form, or nil. `frob` is a
-- function to apply to the values before storing.
local function handle_infl(field, label, frob)
parse_and_insert_inflection("noun", data, args, field, label)
end
handle_infl("gen", "<<genitive>> <<singular>>")
handle_infl("pl", "<<nominative>> <<plural>>")
handle_infl("genpl", "<<genitive>> <<plural>>")
handle_infl("m", "male equivalent")
handle_infl("f", "female equivalent")
handle_infl("adj", "<<relational adjective>>")
handle_infl("pos", "<<possessive adjective>>")
handle_infl("dim", "<<diminutive>>")
handle_infl("aug", "<<augmentative>>")
handle_infl("pej", "<<pejorative>>")
handle_infl("dem", "<<demonym>>")
handle_infl("fdem", "female <<demonym>>")
end
pos_functions = {
params = get_noun_params(false),
func = function(args, data)
return do_nouns(false, args, data)
end,
}
pos_functions = {
params = get_noun_params("proper noun"),
func = function(args, data)
return do_nouns("proper noun", args, data)
end,
}
pos_functions = {
params = {
= {default = "?", type = "genders"},
= list_param,
= list_param,
},
func = function(args, data)
for _, a in ipairs(args) do
if a.spec == "both" then
a.spec = "biasp"
end
if valid_aspects then
track("aspect-" .. a.spec)
else
error("Unrecognized aspect: '" .. a.spec .. "'")
end
if a.spec == "impf" and args.impf then
error("Imperfective verbs cannot have an imperfective equivalent")
elseif a.spec == "pf" and args.pf then
error("Perfective verbs cannot have a perfective equivalent")
end
end
data.genders = args
parse_and_insert_inflection("verb", data, args, "pf", "perfective")
parse_and_insert_inflection("verb", data, args, "impf", "imperfective")
end,
}
local function do_comparative_superlative(pos, data, args)
local plpos = pos .. "s" -- safe because pos is either 'adjective' or 'adverb'
if args == "-" then
table.insert(data.inflections, {label = "not " .. glossary_link("comparable")})
table.insert(data.categories, langname .. " uncomparable " .. plpos)
elseif args then
local comps = m_headword_utilities.parse_term_list_with_modifiers {
paramname = {2, "comp"},
forms = args,
frob = make_check_accents_frob(pos, data),
}
local sups = m_headword_utilities.parse_term_list_with_modifiers {
paramname = {3, "sup"},
forms = args,
frob = make_check_accents_frob(pos, data),
}
local saw_bolj = false
for _, comp in ipairs(comps) do
if comp.term == "bolj" then
saw_bolj = true
break
end
end
if saw_bolj then
local new_comps = {}
for _, comp in ipairs(comps) do
if comp.term == "bolj" then
for _, head in ipairs(data.heads) do
local new_comp = m_table.deepCopy(comp)
new_comp.term = "] " .. head
table.insert(new_comps, new_comp)
end
else
table.insert(new_comps, comp)
end
end
comps = new_comps
end
if not sups then
sups = m_table.deepCopy(comps)
for _, s in ipairs(sups) do
local term_after_bolj = s.term:match("^%%] (.*)$")
if term_after_bolj then
s.term = "] " .. term_after_bolj
else
s.term = "nȁj" .. s.term
end
end
end
if comps then
m_headword_utilities.insert_inflection {
headdata = data,
terms = comps,
label = "comparative"
}
m_headword_utilities.insert_inflection {
headdata = data,
terms = sups,
label = "superlative"
}
table.insert(data.categories, langname .. " comparable " .. plpos)
end
end
end
pos_functions = {
params = function(lang)
local params = {
= {list = "comp", disallow_holes = true},
= {list = "sup", disallow_holes = true},
= list_param,
= {type = "boolean"},
}
return params
end,
func = function(args, data)
if args.indecl then
table.insert(data.inflections, {label = glossary_link("indeclinable")})
table.insert(data.categories, langname .. " indeclinable adjectives")
end
do_comparative_superlative("adjective", data, args)
parse_and_insert_inflection("adjective", data, args, "adv", "adverb")
end,
}
pos_functions = {
params = {
= {list = "comp", disallow_holes = true},
= {list = "sup", disallow_holes = true},
},
func = function(args, data)
do_comparative_superlative("adverb", data, args)
end,
}
return export