local export = {}
local m_links = require("Module:links")
local lang = require("Module:languages").getByCode("zh")
local radius = 0.001
local colors = {
"d2502e", "6941c7", "9fdd42", "e7ff79", "b66063",
"30bcff", "c6ceff", "02f291", "2e1200", "a4ff46",
"ffcccf", "63001e", "c124de", "00ae2d", "ff4ce4",
"6fff8b", "b900b1", "bfff6b", "0035b6", "fffe8d",
"61008c", "adff9e", "d463ff", "3c8a00", "db0098",
"00c97f", "a20090", "01a145", "ff5ec8", "59ffc6",
"e50025", "01c0cc", "a60003", "02b9db", "d37200",
"0151c6", "949900", "00156f", "ffa938", "290062",
"b69700", "6d87ff", "c88100", "014592", "ff823e",
"000f36", "bdffc4", "1e003b", "ffce7a", "320029",
"d5ffea", "6a0050", "009267", "ff4c61", "019282",
"fd98ff", "094300", "ad96ff", "965a00", "8eb0ff",
"761f00", "9bd8ff", "490d00", "fbffe9", "1d000f",
"feecff", "00141e", "ffddad", "001b14", "ff93ce",
"004f23", "9d0050", "005e5e", "ffa291", "003e33",
"ff9cac", "00536c", "ffc594", "0079b1", "5a3600",
}
local grey = "ccccbf"
local groupZH = {
= "燕京官話",
= "冀魯官話",
= "膠遼官話",
= "蘭銀官話",
= "中原官話",
= "西南官話",
= "江淮官話",
= '官話',
= '粵語',
= '客家話',
= '徽語',
= '贛語',
= '晉語',
= '九姓漁民方言',
= '閩北語',
= '閩東語',
= '閩南語',
= '莆仙閩語',
= '中山閩語',
= '閩中語',
= '邵將閩語',
= '桂南平話',
= '桂北平話',
= '畬話',
= '瓦鄉話',
= '吳語',
= '湘語',
= '湘南土話',
= '粵北土話',
}
function export.make_list(data)
return "<ul><li>" .. table.concat(data,"</li><li>") .. "</li></ul>"
end
function export.map_header(text)
return tostring(
mw.html.create("h2")
:wikitext(text)
:done()
)
end
function export.get_coords(lat,long,i,n)
if n > 1 then
return {long+radius*math.cos(2*math.pi*i/n),lat+radius*math.sin(2*math.pi*i/n)}
else
return {long,lat}
end
end
function export.make_point(lat,long,color,text,i,n)
return {
type = "Feature",
properties = {
title = text,
= color,
= "small",
},
geometry = {
type = "Point",
coordinates = export.get_coords(lat,long,i,n)
}
}
end
function export.legend(colour, show, cat, hide)
return tostring(
mw.html.create("div")
:addClass("zh-dial-map__legend-row")
:addClass((colour == grey and "zh-dial-map__legend-row-other" or nil))
:tag("div")
:addClass("vsSwitcher")
:attr("data-toggle-category", cat)
:attr("data-vs-showtext", "lects ▼")
:attr("data-vs-hidetext", "lects ▲")
:tag("span")
:addClass("zh-dial-map__legend-row-dot")
:css("background-color", "#" .. colour)
:wikitext("")
:done()
:tag("span")
:addClass("vsToggleElement")
:wikitext("")
:done()
:wikitext(show)
:tag("div")
:addClass("vsHide")
:wikitext(hide)
:allDone()
)
end
function export.make_legends(legend)
-- divide into five columns manually
-- DO NOT replace with css column-count
local r = #legend%5
local q = math.floor(#legend/5)
local d1 = q+(r>0 and 1 or 0)
local d2 = d1+q+(r>1 and 1 or 0)
local d3 = d2+q+(r>2 and 1 or 0)
local d4 = d3+q+(r>3 and 1 or 0)
local l1 = table.concat(legend,"",1,d1)
local l2 = table.concat(legend,"",d1+1,d2)
local l3 = table.concat(legend,"",d2+1,d3)
local l4 = table.concat(legend,"",d3+1,d4)
local l5 = table.concat(legend,"",d4+1,#legend)
local cell = {width="20%",="top"}
return tostring(
mw.html.create("table"):css("width","100%"):tag("tr")
:tag("td"):css(cell):wikitext(l1):done()
:tag("td"):css(cell):wikitext(l2):done()
:tag("td"):css(cell):wikitext(l3):done()
:tag("td"):css(cell):wikitext(l4):done()
:tag("td"):css(cell):wikitext(l5):done()
:allDone()
)
end
function export.make_map(frame,geojson,legend)
return tostring(
mw.html.create("div")
:addClass("thumb")
:addClass("zh-dial-map__container")
:wikitext(frame:extensionTag("mapframe",mw.text.jsonEncode(geojson),{
class = "zh-dial-map__map",
mapstyle = "osm-intl",
width = 1200,
height = 600,
longitude = 104.1954,
latitude = 35.8617,
zoom = 4
}))
:done()
:tag("div")
:wikitext(legend)
:done()
:done()
)
end
function export.show(frame)
local geojson = {}
local legend = {}
local dial = mw.loadData("Module:zh/data/dial")
local syn = mw.loadData("Module:zh/data/dial-syn/"..frame.args).list
local locs = {}
local n = {}
for _,lect in ipairs(dial) do
local syn_lect = syn or {""}
if syn_lect ~= "" and lect.lat then
n = 0 -- `#` doesn't work with mw.loadData
local lect_en = (lect.english or lect.key) .. " " .. lect.group
local lect_zh = lect.chinese .. groupZH
local i = 0
for _,form in ipairs(syn_lect) do
local notes = form:match(":(.+)")
if not notes or not notes:find("GT",1,true) then
i = i + 1
n = n + 1
form = form:gsub(":.+","")
locs = locs or {}
table.insert(locs,{
key=lect.key,
en=lect_en,
zh=lect_zh,
lat=lect.lat,
long=lect.long,
i=i})
end
end
end
end
local forms = {}
for form,lects in pairs(locs) do
table.insert(forms,form)
end
table.sort(forms, function(fst, snd) return #locs > #locs end)
local grey_limit = #forms > 80 and #locs] or 0
local greyed = false
local greys = {}
local grey_count = 0
for i,form in ipairs(forms) do
local lects = locs
greyed = greyed or (#lects <= grey_limit)
local color = greyed and grey or colors
local legend_lects = {}
for _,lect in ipairs(lects) do
local display = lect.en .. "<br>" .. lect.zh
.. ":<br>"
table.insert(geojson,export.make_point(lect.lat,lect.long,color,display,lect.i,n))
if not greyed then
table.insert(legend_lects, lect.zh .. " (" .. lect.en .. ")")
end
end
local link = m_links.full_link({
lang = lang,
term = form:gsub("_$", ""),
alt = form:gsub("_()$", "%1<sub>%2</sub>"),
tr = "-",
})
if greyed then
for _,lect in ipairs(lects) do
table.insert(greys, lect.zh .. " (" .. lect.en .. "): " .. link)
end
grey_count = grey_count + #lects
else
table.insert(legend, export.legend(color, link .. " (" .. #lects .. ")", form, export.make_list(legend_lects)))
end
end
if greyed then
table.insert(legend, export.legend(grey, "other terms ("..grey_count..")", "others", export.make_list(greys)))
end
local title = syn.title and syn.title ~= "" and syn.title or frame.args
title = title:gsub("", "") .. "//"
local map_header = export.map_header(
"Map of Chinese dialectal equivalents for " .. m_links.full_link(
{
lang = lang,
term = title,
gloss = syn.meaning,
tr = '-'
}
)
)
local legends = export.make_legends(legend)
local map = export.make_map(frame, geojson, legends)
return map_header .. map
end
return export