local export = {}
function no_rule_error(params) -- Intentionally global; better way to do this?
return error(('No rule for "%s" in language "%s".')
:format(params.form, params.lang), 2)
end
messages = require("Module:array")() -- intentionally global
local function default_entry(params)
local entry = {
pronunc = nil,
pos_header = mw.getContentLanguage():ucfirst(params.pos),
head =
"{{head|" .. params.lang .. "|" .. params.pos .. " form" ..
(params.target ~= params.target_pagename and '|head=' .. params.target or "") ..
(params.transliteration and "|tr=" .. params.transliteration or "") ..
(params.gender and "|g=" .. params.gender or "") ..
"}}",
def =
"{{inflection of|" ..
params.origin ..
(params.origin_transliteration and "|tr=" .. params.origin_transliteration or "") ..
"||" .. params.form ..
"|lang=" .. params.lang ..
"}}",
inflection = nil,
declension = nil,
conjugation = nil,
mutation = nil,
}
-- Exceptions for some forms
local templates = {
["p"] = "plural of",
["f"] = "feminine of",
["n"] = "neuter of",
["f|s"] = "feminine singular of",
["m|p"] = "masculine plural of",
["f|p"] = "feminine plural of",
}
if params.form == "comparative" or params.form == "superlative" then
entry.head =
"{{head|" .. params.lang .. "|" .. params.form .. " " .. params.pos ..
(params.target ~= params.target_pagename and "|head=" .. params.target or "") ..
(params.gender and "|g=" .. params.gender or "") ..
"}}"
entry.def =
"{{" .. params.form .. " of" ..
"|" .. params.origin ..
(params.origin_transliteration and "|tr=" .. params.origin_transliteration or "") ..
(params.pos ~= "adjective" and "|POS=" .. params.pos or "") ..
"|lang=" .. params.lang ..
"|nocat=1}}"
elseif params.form == "equative" then
entry.head =
"{{head|" .. params.lang .. "|" .. params.pos .. " " .. params.form .. " form" ..
(params.target ~= params.target_pagename and "|head=" .. params.target or "") ..
(params.gender and "|g=" .. params.gender or "") ..
"}}"
entry.def =
"{{" .. params.form .. " of" ..
"|" .. params.origin ..
(params.origin_transliteration and "|tr=" .. params.origin_transliteration or "") ..
(params.pos ~= "adjective" and "|POS=" .. params.pos or "") ..
"|lang=" .. params.lang ..
"|nocat=1}}"
elseif templates[params.form] then
entry.def =
"{{" .. templates[params.form] ..
"|" .. params.origin ..
(params.origin_transliteration and "|tr=" .. params.origin_transliteration or "") ..
"|lang=" .. params.lang ..
"}}"
end
return entry
end
-- Merges multiple entries into one if they differ only in the definition
local function merge_entries(entries)
local entries_new = {}
for i, entry in ipairs(entries) do
local last_entry = entries_new[#entries_new]
if last_entry and
entry.pronunc == last_entry.pronunc and
entry.pos_header == last_entry.pos_header and
entry.head == last_entry.head and
entry.inflection == last_entry.inflection and
entry.declension == last_entry.declension and
entry.conjugation == last_entry.conjugation then
local params1 = mw.ustring.match(last_entry.def, "^{{inflection of|([^{}]+)}}$")
local params2 = mw.ustring.match(entry.def, "^{{inflection of|([^{}]+)}}$")
last_entry.def = last_entry.def .. "\n# " .. entry.def
-- Do some extra-special merging with "inflection of"
if params1 and params2 then
-- Find the last unnamed parameter of the first template
params1 = mw.text.split(params1, "|", true)
local last_numbered_index
for j, param in ipairs(params1) do
if not mw.ustring.find(param, "=", nil, true) then
last_numbered_index = j
end
end
-- Add grammar tags of the second template
params2 = mw.text.split(params2, "|")
local tags = {}
local n = 0
for k, param in ipairs(params2) do
if not mw.ustring.find(param, "=", nil, true) then
n = n + 1
-- Skip the first two unnamed parameters,
-- which don't indicate grammar tags
if n >= 3 then
-- Now append the tags
table.insert(tags, param)
end
end
end
-- Add the new parameters after the existing ones
params1[last_numbered_index] = params1[last_numbered_index] .. "|;|" .. table.concat(tags, "|")
last_entry.def = "{{inflection of|" .. table.concat(params1, "|") .. "}}"
end
else
table.insert(entries_new, entry)
end
end
return entries_new
end
local function entries_to_text(entries, lang)
lang = require("Module:languages").getByCode(lang) or require("Module:languages").err(lang, "lang")
for i, entry in ipairs(entries) do
entry =
(entry.pronunc and "===Pronunciation===\n" .. entry.pronunc .. "\n\n" or "") ..
"===" .. entry.pos_header .. "===\n" ..
entry.head .. "\n\n" ..
"# " .. entry.def ..
(entry.inflection and "\n\n====Inflection====\n" .. entry.inflection or "") ..
(entry.declension and "\n\n====Declension====\n" .. entry.declension or "") ..
(entry.conjugation and "\n\n====Conjugation====\n" .. entry.conjugation or "") ..
(entry.mutation and "\n\n===Mutation===\n" .. entry.mutation or "")
entries[i] = entry
end
return "==" .. lang:getCanonicalName() .. "==\n\n" .. table.concat(entries, "\n\n")
end
function export.generate(frame)
local fparams = {
lang = {required = true},
origin_pagename = {required = true},
target_pagename = {required = true},
num = {required = true, type = "number"},
pos = {list = true, allow_holes = true},
form = {list = true, allow_holes = true},
gender = {list = true, allow_holes = true},
transliteration = {list = true, allow_holes = true},
origin = {list = true, allow_holes = true},
origin_transliteration = {list = true, allow_holes = true},
target = {list = true, allow_holes = true},
}
local args = require("Module:parameters").process(frame.args, fparams)
local entries = {}
-- Generate each entry
for i = 1, args.num do
local params = {
lang = args.lang,
origin_pagename = args.origin_pagename,
target_pagename = args.target_pagename,
pos = args.pos[i] or error("The argument \"pos\" is missing for entry " .. i),
form = args.form[i] or error("The argument \"form\" is missing for entry " .. i),
gender = args.gender[i],
transliteration = args.transliteration[i],
origin = args.origin[i] or error("The argument \"origin\" is missing for entry " .. i),
origin_transliteration = args.origin_transliteration[i],
target = args.target[i],
}
params.form = mw.ustring.gsub(params.form, "|", "|")
-- Make a default entry
local entry = default_entry(params)
-- Try to use a language-specific module, if one exists
local success, lang_module = pcall(require, "Module:accel/" .. args.lang)
if success then
lang_module.generate(params, entry)
end
-- Add it to the list
table.insert(entries, entry)
end
-- Merge entries if possible
entries = merge_entries(entries)
entries = entries_to_text(entries, args.lang)
return entries
end
function export.generate_JSON(frame)
local success, entries = pcall(export.generate, frame)
-- If success is false, entries is an error message.
local ret = { [success and "entries" or "error"] = entries, messages = messages }
return require("Module:JSON").toJSON(ret)
end
return export