Module:fi-dialects/template
Appearance
- The following documentation is located at Module:fi-dialects/template/documentation. [edit]
- Useful links: root page • root page’s subpages • links • transclusions • testcases • sandbox
Implements {{fi-dial}}
.
local export = {}
local m_dial = require("Module:fi-dialects")
local m_common = require("Module:fi-dialects/template/common")
local dialect_area_order = {
"Varsinais-Suomi/Etelä",
"Varsinais-Suomi/Pohjoinen",
"Varsinais-Suomi/Ylämaa",
"Varsinais-Suomi/Itä",
"Satakunta/Etelä",
"Satakunta/Länsi",
"Satakunta/Pohjoinen",
"Häme/Pohjoinen",
"Häme/Etelä",
"Häme/Kaakko",
"Kymenlaakso",
"Pohjanmaa/Etelä",
"Pohjanmaa/Keski",
"Pohjanmaa/Pohjoinen",
"Peräpohjola",
"Länsi-Pohja",
"Kainuu",
"Keski-Suomi/Pohjoinen",
"Keski-Suomi/Länsi",
"Keski-Suomi/Etelä",
"Savo/Pohjoinen",
"Savo/Etelä",
"Karjala/Pohjoinen",
"Karjala/Keski",
"Karjala/Etelä",
"Inkeri",
"Vermlanti",
}
for v, k in ipairs(dialect_area_order) do
dialect_area_order[k] = v
end
local function eager_wrap(text)
return '<p style="white-space:pre-wrap;min-width:100%;max-width:min-content;">' .. text .. '</p>'
end
local function get_parishes_by_area(parishes)
local seen_areas = {}
local areas = {}
for _, parish in ipairs(parishes) do
local area_code = parish:getAreaCode()
local area = seen_areas[area_code]
if not area then
area = { ["area"] = parish:getArea(), ["parishes"] = { } }
table.insert(areas, area)
seen_areas[area_code] = area
end
table.insert(area.parishes, parish)
end
for _, area in ipairs(areas) do
table.sort(area.parishes, function (a, b) return a:getEnglishName() < b:getEnglishName() end)
end
table.sort(areas, function (a, b)
return (dialect_area_order[a.area:getCode()] or #dialect_area_order)
< (dialect_area_order[b.area:getCode()] or #dialect_area_order)
end)
return areas
end
local function parish_map(frame, term, parishes_by_name, extra)
local parishes = {}
for _, parish in ipairs(parishes_by_name) do
local result = m_dial.getParish(mw.text.trim(parish), true)
if result then table.insert(parishes, result) end
end
local areas = get_parishes_by_area(parishes)
local areas_text = {}
-- construct list of parishes grouped by areas
for _, area in ipairs(areas) do
local formatted_parishes = {}
for _, parish in ipairs(area.parishes) do
table.insert(formatted_parishes, parish:getFormattedName())
end
formatted_parishes = table.concat(formatted_parishes, ", ")
table.insert(areas_text, "* " .. area.area:getFormattedName() .. " <small>[" .. area.area:getGroup():getEnglishName() .. "]</small>\n** " .. formatted_parishes)
end
local list_by_area = table.concat(areas_text, "\n")
local function peg(parish, top, left)
-- simple peg
return tostring(mw.html.create('div')
:attr('class', 'peg_outer')
:css('position', 'absolute')
:css('top', top) -- positioning
:css('left', left)
:css('line-height', '0')
:tag('div')
:css('position', 'relative')
:css('left', '-3px') -- center (6px / 2 = 3px)
:css('top', '-3px')
:attr('title', parish:getFormattedName())
:wikitext('[[File:Red pog.svg|6x6px|link=]]')
:done())
end
return [[{| cellspacing="2" cellpadding="2" class="wikitable vsSwitcher" data-toggle-category="dialectal data"
|-
! class="vsToggleElement" colspan="2" | ]] .. "Dialectal distribution of " .. m_common.mention(term, extra.gloss) .. '\n' .. [[|- class="vsHide"
|<div style="text-align: left; min-width: 25em;">
]] .. frame:preprocess(list_by_area) .. [[
</div>
|
]] .. require("Module:fi-dialects/map").show{frame = frame, parishes = parishes, peg = peg, size = "550px"} .. [[
|- class="vsHide"
| colspan="2" | ]] .. eager_wrap("''" .. m_common.disclaimer .. "''") .. [[
]] .. m_common.format_sources(extra.source, true) .. [[
|}]] .. require("Module:TemplateStyles")("Module:fi-dialects/style.css")
end
local function format_synonym(term, data)
if data.semantic then
return data.labels[term] or term
else
local text, id = m_common.parse_term(term)
if data.nolink then
return m_common.tag(data.labels and data.labels[term] or text)
else
local target = data.links and data.links[term] or text
local label = data.labels and (data.labels and data.labels[term] or nil) or text
return m_common.make_link(target, label, id)
end
end
end
local function format_synonyms(syns, data)
if type(syns) == "table" then
local result = {}
for _, syn in ipairs(syns) do
table.insert(result, format_synonym(syn, data))
end
return table.concat(result, "\n")
else
return format_synonym(syns, data)
end
end
local function synonym_table(frame, term, word_id, data)
local synonyms = data.syns
local source = data.source and (type(data.source) == "table" and data.source or { data.source }) or { }
local areas_text = ""
for _, special_key in ipairs(m_common.specials) do
if synonyms[special_key] then
areas_text = areas_text .. '|- class="vsHide" \n'
areas_text = areas_text .. '|colspan="2"|' .. m_common.special[special_key] .. '\n'
areas_text = areas_text .. '|' .. format_synonyms(synonyms[special_key], data) .. '\n'
end
end
local parishes = {}
for parish, _ in pairs(synonyms) do
if not m_common.special[parish] then
local result = m_dial.getParish(parish, true)
if result then table.insert(parishes, result) end
end
end
local areas = get_parishes_by_area(parishes)
for _, area in ipairs(areas) do
local areasyns = {}
local areasyns_parishes = {}
local parish_indexes = {}
local function visit(syn, parish)
if not areasyns_parishes[syn] then
table.insert(areasyns, syn)
areasyns_parishes[syn] = {}
end
table.insert(areasyns_parishes[syn], parish)
end
-- gather all synonyms and parishes that have them
for index, parish in ipairs(area.parishes) do
local parish_code = parish:getCode()
local parish_text = parish:getFormattedName()
parish_indexes[parish_text] = index
local syns = synonyms[parish_code]
if type(syns) == 'table' then
for _, syn in ipairs(syns) do
visit(syn, parish_text)
end
else
visit(syns, parish_text)
end
end
-- if the list of parishes is equivalent between any two pairs of synonyms, merge them
local mergers = {}
local areasyns_original = {}
for i, syn in ipairs(areasyns) do
local result = table.concat(areasyns_parishes[syn], "\n")
for i = 1, #areasyns_original do
if result == areasyns_original[i] then
if not mergers[areasyns[i]] then
mergers[areasyns[i]] = {}
end
table.insert(mergers[areasyns[i]], syn)
break
end
end
areasyns_original[i] = result
end
-- apply mergers
for syn1, syns in pairs(mergers) do
local parishes = areasyns_parishes[syn1]
local merged_syns = {syn1}
areasyns_parishes[syn1] = nil
for _, syn in ipairs(syns) do
table.insert(merged_syns, syn)
areasyns_parishes[syn] = nil
end
table.sort(parishes, function (a, b) return parish_indexes[a] < parish_indexes[b] end)
areasyns_parishes[merged_syns] = parishes
table.insert(areasyns, merged_syns)
end
table.sort(areasyns, function (a, b) return #(areasyns_parishes[a] or {}) > #(areasyns_parishes[b] or {}) end)
local result_text = ""
local rows = 0
for _, syn in ipairs(areasyns) do
if areasyns_parishes[syn] then
if #result_text > 0 then result_text = result_text .. '|- class="vsHide"\n' end
result_text = result_text .. '| style="max-width:32em;" |' .. table.concat(areasyns_parishes[syn], ', ') .. '\n'
result_text = result_text .. '|' .. format_synonyms(syn, data) .. '\n'
rows = rows + 1
end
end
areas_text = areas_text .. '|- class="vsHide"\n|rowspan="' .. rows .. '"|' .. area.area:getFormattedName():gsub(" %(", "\n(") .. "<br><small>[" .. area.area:getGroup():getEnglishName() .. "]</small>\n" .. result_text
end
return [[{| cellspacing="2" cellpadding="2" class="wikitable vsSwitcher" data-toggle-category="dialectal data"
|-
! class="vsToggleElement" colspan="3" | ]] .. "Dialectal " .. (data.semantic and "meanings" or "synonyms") .. " for " .. m_common.mention(term, data.gloss) .. ' ([[Template:fi-dial-map/' .. word_id .. '|map]])\n' .. areas_text .. [[
|- class="vsHide"
| colspan="3" | ]] .. eager_wrap("''" .. m_common.disclaimer .. "''") .. [[<div style="float:right;"><small>]] .. '([[Module:fi-dialects/data/word/' .. word_id .. '|edit data]])' .. [[</small></div>
]] .. m_common.format_sources(source) .. [[
|}]]
end
function export.show(frame)
local title = mw.title.getCurrentTitle().text
local params = {
[1] = { default = title },
[2] = { default = nil },
["p"] = { default = nil },
["ref"] = { default = nil },
["t"] = { default = nil }
}
local args = require("Module:parameters").process(frame:getParent().args, params)
local parishes = {}
if args["p"] then
return parish_map(frame, args[1], mw.text.split(args["p"], ",%s*"), { source = args["ref"] and mw.text.split(args["ref"], ",%s*") or {}, gloss = args["t"] })
else
local word_id = args[1]
if args[2] then
word_id = word_id .. " (" .. args[2] .. ")"
end
local data_ok, data = pcall(function() return mw.loadData("Module:fi-dialects/data/word/" .. word_id) end)
if not data_ok then
return "<div><em>No data found ([[Module:fi-dialects/data/word/" .. word_id .. "|create it]]). See [[Template:fi-dial]] for more information on how to use this template.</em></div>" .. require("Module:utilities").format_categories({"fi-dial missing data"}, m_common.lang)
end
return synonym_table(frame, args[1], word_id, data)
end
end
return export