মডিউল:sem-arb-utilities
অবয়ব
এই মডিউলের জন্য মডিউল:sem-arb-utilities/নথি-এ নথিপত্র তৈরি করা হয়ে থাকতে পারে
local export = {}
local m_str_utils = require("Module:string utilities")
local m_utilities = require("Module:utilities")
local m_links = require("Module:links")
local m_headword = require("Module:headword")
local m_langs = require("Module:languages")
local m_params = require("Module:parameters")
local m_parse_utils = require("Module:parse utilities")
local m_affix = require("Module:affix")
local m_sc_utils = require("Module:script utilities")
local pluralize = require("Module:en-utilities").pluralize
local lg_ar = m_langs.getByCode("ar")
local lg_sem_arb = lg_ar:getFamily():getCode()
local rsplit = m_str_utils.split
local rsubn = m_str_utils.gsub
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local separator_langs = { ["mt"] = true, ["acy"] = true }
local color_langs = { ["mt"] = "red", ["ary"] = "red", ["ar"] = "green", ["shu"] = "yellow" }
local template_preview_per_langcode = { ["mt"] = "k-t-b", ["acy"] = "k-t-p" }
local lang
local sc
local function ifelse(cond, yes, no)
if cond then
return yes
end
return no
end
local function ucfirst(str)
if str == nil then
return str
end
return mw.language.getContentLanguage():ucfirst(str)
end
local function link(term, alt, id)
if term == "" or term == "—" then
return term
else
return m_links.full_link({
term = term,
alt = alt,
lang = lang,
id = id,
})
end
end
local function parse_inlines(term)
return m_parse_utils.parse_inline_modifiers(
term,
{
param_mods = {tr = {}, t = {}, pos = {}},
generate_obj = function(term) return {term} end,
}
)
end
local function make_part(noninline, lang)
local keys = {"tr", "t", "pos"}
local inline
if type(noninline) == "string" then
inline = parse_inlines(noninline)
else
inline = parse_inlines(noninline[1])
end
local return_value = {
term = m_sc_utils.tag_text(inline[1], lang),
}
for i, key in ipairs(keys) do
if inline[key] and noninline[key] then
error(
key .. " specified twice: "
.. "<" .. key .. ":" .. inline[key] .. ">"
.. " and "
.. "|" .. key .. "=" .. nonline[key]
)
end
return_value[key] = inline[key] or noninline[key]
end
if not return_value.tr then
return_value.tr = lang:transliterate(inline[1])
end
return return_value
end
local function make_parts(lang, raw_parts)
local parts = {}
for i, part in ipairs(raw_parts) do
parts[#parts + 1] = make_part(part, lang)
end
return {
parts = parts,
lang = lang,
sc = lang:findBestScript(parts[1][1]),
}
end
local function show_affix(lang, raw_parts)
return m_affix.show_affix(
make_parts(lang, raw_parts),
{},
lang
)
end
local appendices = {
["active participle"] = {
-- participles have verbal force in (most?) vernaculars
function(args, lang)
return ifelse(lang:getCode() == lg_ar:getCode(), "nominals", "verbs")
end,
derived = true,
},
["characteristic adjective"] = "nominals",
["color/defect adjective"] = {
"nominals",
fragment = "Color or defect adjectives",
},
["diminutive"] = "nominals",
["elative"] = "nominals",
["relative"] = {
"nominals",
params = function(lang)
return {
[1] = {
required = true,
},
[2] = {
alias_of = "t",
},
[3] = {
alias_of = "suffix",
},
["id"] = {},
["id1"] = {
alias_of = "id",
},
["tr"] = {},
["pl"] = {
type = "boolean",
},
["t"] = {
required = true,
},
["suffix"] = {
default = ifelse(lang:getCode() == lg_ar:getCode(), "ـِيَّة", "ـية"),
},
}
end,
title = function(args)
if args.pl then
return "relative nouns (nisba)"
end
return "relative noun (nisba)"
end,
desc = function(args, lang)
if not args[1] then
return ""
end
return (
"composed from "
.. show_affix(
lang,
{
args,
{args.suffix, pos="feminine nisba"},
}
)
)
end,
},
["relative-a"] = {
"nominals",
params = function(lang)
return {
[1] = {
required = true,
},
[2] = {
alias_of = "t",
},
["tr"] = {},
["pl"] = {
type = "boolean",
},
["suffix"] = {
default = ifelse(lang:getCode() == lg_ar:getCode(), "ـَة", "ـة"),
},
["t"] = {
required = true,
},
}
end,
title = function(args)
if args.pl then
return "relative nouns (nisba)"
end
return "relative noun (nisba)"
end,
desc = function(args, lang)
if not args[1] then
return ""
end
return (
"composed from "
.. show_affix(
lang,
{
args,
{args.suffix, pos="feminine ending"},
}
)
)
end,
},
["relative-linking"] = {
"nominals",
params = function(lang)
return {
[1] = {
required = true,
},
[2] = {
alias_of = "t",
},
[3] = {
alias_of = "linking",
},
["tr"] = {},
["pl"] = {
type = "boolean",
},
["suffix"] = {
default = ifelse(lang:getCode() == lg_ar:getCode(), "ـِيّ", "ـي"),
},
["t"] = {
required = true,
},
["linking"] = {
required = true,
}
}
end,
title = function(args)
if args.pl then
return "relative adjectives (nisba)"
end
return "relative adjective (nisba)"
end,
desc = function(args, lang)
if not args[1] then
return ""
end
return (
"composed from "
.. show_affix(
lang,
{
args,
args.linking,
{args.suffix, pos = "nisba"},
}
)
)
end,
},
["relative-linking-noun"] = {
"nominals",
params = function(lang)
return {
[1] = {
required = true,
},
[2] = {
alias_of = "t",
},
[3] = {
alias_of = "linking",
},
["tr"] = {},
["pl"] = {
type = "boolean",
},
["t"] = {
required = true,
},
["linking"] = {
required = true,
},
["suffix"] = {
default = ifelse(lang:getCode() == lg_ar:getCode(), "ـِيّ", "ـي"),
}
}
end,
title = function(args)
if args.pl then
return "relative nouns (nisba)"
end
return "relative noun (nisba)"
end,
desc = function(args, lang)
if not args[1] then
return ""
end
return (
"composed from "
.. show_affix(
lang,
{args, args.linking, args.suffix}
)
)
end,
},
["form"] = {
"verbs",
params = {
[1] = {
alias_of = "wazn",
},
["wazn"] = {
required = true,
},
},
fragment = function(args) return "Form_" .. args.wazn end,
title = function(args) return "form " .. args.wazn end,
},
["instance noun"] = "nominals",
["noun of place"] = "nominals",
["occupational noun"] = "nominals",
["passive participle"] = {
"nominals",
derived = true,
},
["reduplicated"] = {
glossary = "reduplication",
},
["singulative noun"] = "nominals",
["tool noun"] = "nominals",
["verbal noun"] = "nominals",
}
local radicals = {
["Arab"] = {
["ء"] = true,
["ب"] = true,
["ت"] = true,
["ث"] = true,
["ج"] = true,
["ح"] = true,
["خ"] = true,
["د"] = true,
["ذ"] = true,
["ر"] = true,
["ز"] = true,
["س"] = true,
["ش"] = true,
["ص"] = true,
["ض"] = true,
["ط"] = true,
["ظ"] = true,
["ع"] = true,
["غ"] = true,
["ف"] = true,
["ق"] = true,
["ك"] = true,
["ل"] = true,
["م"] = true,
["ن"] = true,
["ه"] = true,
["و"] = true,
["ي"] = true,
["گ"] = true,
["چ"] = true,
["پ"] = true,
["ڭ"] = true,
},
["Latn"] = {
["'"] = true,
["b"] = true,
["t"] = true,
["θ"] = true,
["d"] = true,
["δ"] = true,
["f"] = true,
["ġ"] = true,
["g"] = true,
["għ"] = true,
["h"] = true,
["ħ"] = true,
["j"] = true,
["k"] = true,
["l"] = true,
["m"] = true,
["n"] = true,
["p"] = true,
["q"] = true,
["r"] = true,
["s"] = true,
["ş"] = true,
["t"] = true,
["v"] = true,
["w"] = true,
["x"] = true,
["y"] = true,
["ż"] = true,
["z"] = true,
["θ"] = true,
}
}
local function validateRoot(rootTable, joined_root)
if type(rootTable) ~= "table" then
error("rootTable is not a table", 2)
end
local len = #rootTable
if len < 3 then
error("Root must have at least three radicals.")
end
if sc == nil then
sc = lang:findBestScript(joined_root):getCode()
end
for i, radical in ipairs(rootTable) do
if not radicals[sc][radical] then
error("Unrecognized radical " .. radical .. " in " .. joined_root)
end
end
end
function export.root(frame)
local output = {}
local categories = {}
local title = mw.title.getCurrentTitle()
local namespace = title.nsText
local fulltitle = title.fullText
if frame.args["lang"] then
lang = require("Module:languages").getByCode(frame.args["lang"])
else
error("Please provide a language code.")
end
local subpage = "Appendix:" .. lang:getCanonicalName() .. " roots/"
local fulltitle = rsubn(fulltitle, rsubn(subpage, "([^%w])", "%%%1"), "")
local params = {
[1] = { list = true },
["nocat"] = { type = "boolean" },
["plain"] = { type = "boolean" },
["notext"] = { type = "boolean" },
["sense"] = {}
}
local args = require("Module:parameters").process(frame:getParent().args, params)
local rootLetters = {}
local roots = args[1]
local plain = args["plain"]
if frame.args["plain"] then
plain = true
end
local langCode = lang:getCode()
local separator = " "
if separator_langs[langCode] then
separator = "-"
else
separator = " "
end
local roots_len = #roots
if #roots == 0 and namespace == "Template" then
if template_preview_per_langcode[langCode] ~= nil then
table.insert(rootLetters, rsplit(template_preview_per_langcode[langCode], separator))
else
table.insert(rootLetters, rsplit("ك ت ب", separator))
end
elseif #roots ~= 0 then
for _, root in ipairs(roots) do
table.insert(rootLetters, rsplit(root, separator))
end
else
table.insert(rootLetters, rsplit(fulltitle, separator))
end
local joined_roots = {}
for i, rootLetter in ipairs(rootLetters) do
table.insert(joined_roots, table.concat(rootLetter, separator))
validateRoot(rootLetter, joined_roots[i])
end
local sense = args["sense"]
local sense_formatted = ""
if sense ~= nil then
sense_formatted = " (" .. sense .. ") "
end
if fulltitle == joined_roots[1] then
if namespace == "" then
error("The root page should be in the Appendix namespace. Please move it to : [[" ..
subpage .. joined_roots[1] .. "]]")
end
if roots_len > 1 then
error("There should be only one root.")
end
table.insert(output,
m_headword.full_headword({ lang = lang, pos_category = "roots", categories = {}, heads = { fulltitle }, nomultiwordcat = true, noposcat = true }))
if args["nocat"] then
return table.concat(output)
else
return table.concat(output) .. table.concat(categories)
end
else
local link_texts = {}
local term_counts = {}
for i, joined_root in ipairs(joined_roots) do
local link_text = subpage .. joined_root
table.insert(link_texts, link(link_text, joined_root .. sense_formatted, sense))
table.insert(
categories,
m_utilities.format_categories(
{ lang:getCanonicalName() .. " terms belonging to the root " .. joined_root .. sense_formatted },
lang)
)
table.insert(term_counts,
mw.site.stats.pagesInCategory(
lang:getCanonicalName() .. " terms belonging to the root " .. joined_root .. sense_formatted, "pages")
)
end
if args["nocat"] or plain then
if args["nocat"] then
return table.concat(link_texts, ", ")
else
return table.concat(link_texts, ", ") .. table.concat(categories)
end
else
local link_text_output = ""
for i, link_text in ipairs(link_texts) do
link_text_output = link_text_output ..
"\n|-\n| " .. link_text ..
"\n|-\n| [[:Category:" ..
lang:getCanonicalName() ..
" terms belonging to the root " ..
joined_roots[i] ..
sense_formatted .. "|" .. term_counts[i] .. " term" .. (term_counts[i] == 1 and "" or "s") .. "]]\n"
end
local color = "grey"
if color_langs[langCode] ~= nil then
color = color_langs[langCode]
end
local wikicode = mw.getCurrentFrame():expandTemplate {
title = 'inflection-table-top',
args = {
title = "-",
palette = color,
class = "floatright tr-alongside"
}
}
wikicode = wikicode .. [=[
! [[w:Semitic root|Root]=] .. (#term_counts == 1 and "" or "s") .. [=[]]]=]
wikicode = wikicode .. link_text_output
wikicode = wikicode .. mw.getCurrentFrame():expandTemplate {
title = 'inflection-table-bottom',
}
return wikicode .. table.concat(categories)
end
end
end
local function iffn(val, ...)
if type(val) == "function" then
return val(unpack(arg))
end
return val
end
function export.etym(frame)
local params = {
[1] = {
alias_of = "lang",
},
[2] = {
alias_of = "class"
},
["fragment"] = {},
["nocat"] = {
type = boolean,
},
["lang"] = {
type = "language",
replaced_by = false,
required = true,
},
["class"] = {
required = true,
},
}
local args, extra = m_params.process(frame:getParent().args, params, true)
local fixed_indices = {}
for k, v in pairs(extra) do
if type(k) == "number" then
k = k - 2
end
fixed_indices[k] = v
end
extra = fixed_indices
if args.lang:getFamily():getCode() ~= lg_sem_arb then
error(
args.lang:getCode()
.. "'s family is "
.. args.lang:getFamily():getCode()
.. ", not "
.. lg_sem_arb
)
end
local lookup = appendices[mw.ustring.lower(args.class)]
local lookup_args = {}
if not lookup then
error("Unrecognized word type " .. mw.ustring.lower(args.class))
end
if lookup.glossary then
return "[[Appendix:Glossary#" .. lookup.glossary .. "]]"
end
if lookup.params then
lookup_args = m_params.process(extra, iffn(lookup.params, args.lang))
end
local appendix = nil
if lookup.glossary then
appendix = "Glossary"
else
local appendix_lang = args.lang:getCanonicalName()
local appendix_title = ifelse(type(lookup) == "string", lookup, iffn(lookup[1], args.lang))
appendix = appendix_lang .. " " .. appendix_title
if not mw.title.new(appendix, "Appendix").exists then
appendix_lang = lg_ar:getCanonicalName()
appendix_title = ifelse(type(lookup) == "string", lookup, iffn(lookup[1], lg_ar))
appendix = appendix_lang .. " " .. appendix_title
end
end
local title = args.class
local desc = ""
local intro = ""
if lookup.derived then
intro = "derived from the "
end
if type(lookup) ~= "string" then
title = iffn(lookup.title, lookup_args, args.lang) or ""
desc = iffn(lookup.desc, lookup_args, args.lang) or ""
if mw.ustring.match(args.class, "^%u.*") then
if intro == "" then
title = ucfirst(title) or ""
else
intro = ucfirst(intro) or ""
end
end
end
local fragment = (
iffn(lookup.fragment, lookup_args, args.lang)
or ucfirst(iffn(lookup.title, {pl=true}, args.lang))
or pluralize(ucfirst(args.class))
) or ""
return (
intro
.. "[[Appendix:"
.. appendix
.. ifelse(fragment, "#" .. fragment, "")
.. "|"
.. title
.. "]] "
.. desc
)
end
return export