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 = 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
if not area then
area = { = parish:getArea(), = { } }
table.insert(areas, area)
seen_areas = 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 or #dialect_area_order)
< (dialect_area_order 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></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(']')
: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 or term
else
local text, id = m_common.parse_term(term)
if data.nolink then
return m_common.tag(data.labels and data.labels or text)
else
local target = data.links and data.links or text
local label = data.labels and (data.labels and data.labels 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 then
areas_text = areas_text .. '|- class="vsHide" \n'
areas_text = areas_text .. '|colspan="2"|' .. m_common.special .. '\n'
areas_text = areas_text .. '|' .. format_synonyms(synonyms, data) .. '\n'
end
end
local parishes = {}
for parish, _ in pairs(synonyms) do
if not m_common.special 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 then
table.insert(areasyns, syn)
areasyns_parishes = {}
end
table.insert(areasyns_parishes, 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 = index
local syns = synonyms
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, "\n")
for i = 1, #areasyns_original do
if result == areasyns_original then
if not mergers] then
mergers] = {}
end
table.insert(mergers], syn)
break
end
end
areasyns_original = result
end
-- apply mergers
for syn1, syns in pairs(mergers) do
local parishes = areasyns_parishes
local merged_syns = {syn1}
areasyns_parishes = nil
for _, syn in ipairs(syns) do
table.insert(merged_syns, syn)
areasyns_parishes = nil
end
table.sort(parishes, function (a, b) return parish_indexes < parish_indexes end)
areasyns_parishes = parishes
table.insert(areasyns, merged_syns)
end
table.sort(areasyns, function (a, b) return #(areasyns_parishes or {}) > #(areasyns_parishes or {}) end)
local result_text = ""
local rows = 0
for _, syn in ipairs(areasyns) do
if areasyns_parishes 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, ', ') .. '\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></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) .. ' (])\n' .. areas_text .. [[
|- class="vsHide"
| colspan="3" | ]] .. eager_wrap("''" .. m_common.disclaimer .. "''") .. ] .. '(])' .. [[</small></div>
]] .. m_common.format_sources(source) .. [[
|}]]
end
function export.show(frame)
local title = mw.title.getCurrentTitle().text
local params = {
= { default = title },
= { default = nil },
= { default = nil },
= { default = nil },
= { default = nil }
}
local args = require("Module:parameters").process(frame:getParent().args, params)
local parishes = {}
if args then
return parish_map(frame, args, mw.text.split(args, ",%s*"), { source = args and mw.text.split(args, ",%s*") or {}, gloss = args })
else
local word_id = args
if args then
word_id = word_id .. " (" .. args .. ")"
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 (]). See ] 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, word_id, data)
end
end
return export