Module:User:Kritixilithos/test

From Wiktionary, the free dictionary
Jump to navigation Jump to search

This is a private module sandbox of Kritixilithos, for his own experimentation. Items in this module may be added and removed at Kritixilithos's discretion; do not rely on this module's stability.


local export = {}
local m_links = require("Module:links")
local m_languages = require("Module:languages")
local m_table = require("Module:table")
local dial_syns = require("Module:dialect synonyms")
--local lang = require("Module:languages").getByCode("ar")
--local variety_data = require("Module:ar/data/dial")

--TODO change?
local dots = {
	"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 elements = {}

local function prompt_create_data(dpath, preload_path)
	local url = mw.uri.fullUrl(dpath, {action='edit', preload=preload_path})
	return ("→Create [%s %s]?"):format(tostring(url), dpath)
end

-- local function format_syns(data_variety)
-- 	local words_formatted = {}
-- 	for i, text in ipairs(data_variety.syns) do
-- 		table.insert(words_formatted, dial_syns.format_word(data_variety, text))
-- 	end
-- 	return words_formatted
-- end

elements.map_header = function(text)
	return tostring(
		mw.html.create( "h2" )
		:wikitext( text )
		:done()
	)
end

elements.map = function(data)
	-- points, legend
	return tostring(
		mw.html.create( "div" )
		:addClass( "thumb" )
		:addClass( "dial-map__container" )

		:tag( "div" )
		:addClass( "thumbinner" )
		:addClass( "dial-map__frame" )
		-- these styles can't be moved to the .css file because .thumbinner has its own definitions
		:css( "overflow", "auto" )
		:css( "font-size", "1px" ) -- related to the positioning of the dots

		:tag( "div" )
		:addClass( "dial-map__map" )
		:wikitext( '[[File:'..data.map..'|'..data.size..'px|link=]]' )
		:wikitext( data.points )
		:done()
		:done()

		:tag( "div" )
		:addClass( "dial-map__legend" )
		:wikitext( data.legend )
		:done()
		:done()
	)
end

elements.dot = function(d)
	return tostring(
		mw.html.create( "span" )
		:attr( "data-word", d.d.t )
		:attr( "data-tr", d.d.tr )
		:attr( "data-location-en", d.l.name )
		-- :attr( "data-location", loc_info.arabic )
		-- :attr( "data-group", loc_info.group )
		:addClass( "dial-map__dot" )
		-- :addClass( (colour == grey and "dial-map__dot-other" or nil) )

		:css( "top", d.top .. "em" ) -- The size of 1 em is tied to the font-size of .dial-map__frame
		:css( "left", d.left .. "em" )
		:css( "background-color", "#" .. d.c )
		:attr( "title", d.l.name .. ": " .. d.d.t .. (d.d.tr and '('..d.d.tr..')' or ''))

		-- without text in the <span> it seems like the wikitext render discards the whole <span>???
		-- and makes a link with no text at all??????
		:wikitext( "&nbsp;" )
		:done()
	)
end

elements.legend = function(d)
	return tostring(
		mw.html.create( "div" )
		:attr( "data-word", d.d.t )
		:attr( "data-tr", d.d.tr )
		:addClass( "dial-map__legend-row" )
		-- :addClass( (colour == grey and "dial-map__legend-row-other" or nil) )

		:tag( "span" )
		:addClass( "dial-map__legend-row-dot" )
		:css( "background-color", "#" .. d.c )

		:wikitext( "&nbsp;" ) -- please let me make empty spans
		:done()

		:wikitext( d.a )
		:done()
	)
end

function export.show(frame)
	local params = {
		[1] = { required = true, default = "und" },
		[2] = { default = mw.title.getCurrentTitle().text },
		['dpath syns'] = {}, -- for testing: use arbitrary module. like [[Module:sandbox]] or something
	}
	local args = require("Module:parameters").process(frame:getParent().args, params)
	-- mw.log(args[1],args[2])

	-- data modules
	local dpath = "Module:dialect synonyms"
	local dpath_mul = dpath .. "/" .. "mul"
	local dpath_lang = dpath .. "/" .. args[1]
	local dpath_syns = dpath_lang  .. "/" .. args[2]
	if args['dpath syns'] then dpath_syns = args['dpath syns'] end
	local dpath_map = "Template:dialect synonym map/" .. args[1] .. "/" .. args[2]
	local data_mul = require(dpath_mul)
	local data_lang = mw.title.new(dpath_lang).exists and require(dpath_lang) or nil
	local data_syns = mw.title.new(dpath_syns).exists and require(dpath_syns) or nil
	local data_map = data_lang and data_lang.map or nil

	-- prompt creation of missing data modules
	if (not data_lang) then
		return prompt_create_data(dpath_lang, 'Module:dialect synonyms/und')
	end
	if (not data_syns) then
		return prompt_create_data(dpath_syns, 'Module:dialect synonyms/' .. args[1] .. '/')
	end

	-- throw error if synonyms table does not even exist
	if (not data_syns.syns) and (not data_syns.list) then
		error(('Could not find .syns in [[%s]].'):format(dpath_syns))
	end

	-- create $data_lang.title fallback
	if not data_lang.title then
		data_lang.title = "Map of dialectal synonyms of %s"
	end

	data_map.display_size = data_map.display_size or 1200

	-- TEMP: backwards compatibility with the original [[Module:zh-dial-syn]] format
	if (not data_syns.syns) and (data_syns.list) then
		data_syns.syns = data_syns.list
		data_syns.list = nil
	end
	if (not data_syns.gloss) and (data_syns.syns.meaning) then
		data_syns.gloss = data_syns.syns.meaning
		data_syns.syns.meaning = nil
	end
	if (not data_syns.note) and (data_syns.syns.note) then
		data_syns.note = data_syns.syns.note
		data_syns.syns.note = nil
	end

	-- initialize $lang, $main_word, $main_word_link
	-- for $lang="zh:regional", the data modules are named in English,
	-- so the $lang of $main_word is "en";
	-- and the language of the words is "zh", not "zh:regional"
	local lang, lang_qualifier = string.match(args[1], '^(.+):(.+)$')
	lang = lang or args[1]
	local main_word = args[2]
	main_word = mw.ustring.gsub(main_word, "%-[%d]$", "") -- "媽媽-2"→"媽媽"
	local main_word_link = m_links.full_link({
			lang = m_languages.getByCode(lang_qualifier and "en" or lang),
			term = main_word,
			gloss = data_syns.gloss,
																					 }, "term")

	local pd={}
	mw.log(1)
	local function recurse(dv)
		if dv.name and data_syns.syns[dv.name] then
			local ss=data_syns.syns[dv.name]
			if ss and ss[1] ~= "" then
				for i, s in ipairs(ss) do
					local t, tr = mw.ustring.match(s, '^(.+)/(.+)$')
					t=t or s
					-- XXX: find better solution to c
					mw.log(dv.c)
					if not pd[s] then
						pd[s]={c=dv.c,t=t,tr=tr,l={dv}}
					else
						table.insert(pd[s].l,dv)
					end
				end
			end
		else
			for i, _ in ipairs(dv) do
				_.c=_.c or dv.code
				if _.name~='special' then
					recurse(_)
				end
			end
		end
	end
	recurse(data_lang.varieties)
	local legend={}
	local points={}
	local i=0
	for t, d in pairs(pd) do
		i=i+1 --sighs
		-- table.insert(d, {t=t,l=ls,c=#ls})
		local link = m_links.full_link({
				lang = m_languages.getByCode(d.c),
				term = (d.t), --TODO: handle $term_\d*
				alt = (d.t),
				tr = d.tr
		})
		table.insert(legend, elements.legend({
										 d=d,
										 c=dots[i],
										 a=link .. " (" .. #d.l .. ")"}))
		for _,l in ipairs(d.l)do
			local top_offset, left_offset = 0, 0
			if #data_syns.syns[l.name] > 1 then
				top_offset = math.random(-300, 300) / 100
				left_offset = math.random(-300, 300) / 100
			end
			local coords = mw.wikibase.getBestStatements(l.wikidata,'P625')[1]["mainsnak"]["datavalue"]["value"]
			local lat = coords["latitude"]
			local long = coords["longitude"]
			local top = ((data_map.north - lat) * data_map.display_size * data_map.height / data_map.width / (data_map.north+data_map.south)) + top_offset --((55 - loc_info.lat) * 1200 * 746 / 799 / 70) + top_offset
			local left = ((long + data_map.west) * data_map.display_size / (data_map.east+data_map.west)) + left_offset --((loc_info.long - 70) * 1200 / 75) + left_offset
			table.insert(points, ('[[%s|%s]]'):format(d.t,elements.dot({d=d,
																																	l=l,
																																	top=top,
																																	left=left,
																																	c=dots[i]})))
		end
	end

	-- TODO: s/title/map_&/
	local map_header = elements.map_header(data_lang.title:format(main_word_link))
	local note = "\n''Note: This map may not be well-supported on mobile devices. Please view this page on a computer.''"
	local map = elements.map({
			map=data_lang.map.file,
			points=table.concat(points),
			legend=table.concat(legend),
			size=('%dpx'):format(data_map.display_size)
	})

	return map_header..note..map
end

return export