Jump to content

Module:IPA/overview

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Nardog (talk | contribs) at 15:36, 20 September 2023 (lower). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

require('strict')
local data = mw.title.getCurrentTitle().subpageText == 'sandbox'
	and mw.loadData('Module:IPA/data/sandbox')
	or mw.loadData('Module:IPA/data')
local p = {}

local function getNameAndLink(code)
	local res = require('Module:Lang')._name_from_tag({ code, link = 'yes' })
	local name = res:match('([^%[|%]]+)%]%]$')
	local link = res:match('^%[%[([^|%]]+)')
	return name, link
end

local function addNotes(notes)
	return #notes == 0 and '' or
		string.format(' <small>(%s)</small>', table.concat(notes, '; '))
end

local function formatName(internal, external, text)
	local notes = {}
	if internal then
		if internal == external then
			table.insert(notes, 'redundant')
		elseif external then
			table.insert(notes, string.format('overrides "%s"', external))
		end
	end
	local s = internal or external
	if text then
		table.insert(notes, string.format('label: "%s"', text))
	end
	return s .. addNotes(notes)
end

local function formatLink(internal, external, name)
	local notes = {}
	local generated = not internal and name and name ~= '' and name .. ' language'
	if internal or generated then
		if (internal or generated) == external then
			table.insert(notes, 'redundant')
		elseif external then
			local note = string.format('overrides [[%s]]', external)
			local intTitle = mw.title.new(internal or generated)
			local intRedir = intTitle.redirectTarget
			intTitle = intRedir or intTitle
			local extTitle = mw.title.new(external)
			local extRedir = extTitle.redirectTarget
			extTitle = extRedir or extTitle
			if intTitle ~= extTitle then
				note = note .. ', a different article'
			end
			table.insert(notes, note)
		end
	end
	local s = generated or internal or external
	s = generated and '([[' .. s .. ']])' or '[[' .. s .. ']]'
	return s .. addNotes(notes)
end

local function organize(lects, parent, parentCode)
	local t, aliases = {}, {}
	for code, lect in pairs(lects) do
		if lect.aliasOf then
			aliases[lect.aliasOf] = aliases[lect.aliasOf] or {}
			table.insert(aliases[lect.aliasOf], code)
		end
	end
	for code, lect in pairs(lects) do
		if not lect.aliasOf then
			if lect.isVariant or code:sub(1, 2) == 'X-' then
				code = code:lower()
			end
			local name, link = getNameAndLink(
				parent and parentCode .. '-' .. code or code
			)
			table.insert(t, {
				code = '<code>' .. code .. '</code>',
				name = formatName(lect.name, name, lect.text),
				link = formatLink(lect.link, link, lect.name),
				key = lect.key and '[[' .. lect.key .. ']]'
					or '([[' .. (parent and parent.key or data.defaultKey) .. ']])'
			})
			if lect.dialects then
				t[#t].dialects = organize(lect.dialects, lect, code)
			end
			if aliases[code] then
				table.sort(aliases[code])
				t[#t].code = string.format(
					'%s <small>(also <code>%s</code>)</small>',
					t[#t].code,
					table.concat(aliases[code], '</code>, <code>')
				)
			end
		end
	end
	table.sort(t, function (a, b) return a.code < b.code end)
	return t
end

local function makeRow(t, lect, isDialect)
	local row = t:tag('tr')
	for _, key in ipairs({ 'code', 'name', 'link', 'key' }) do
		local cell = row:tag('td'):wikitext(lect[key])
		if lect.dialects then
			cell:attr('rowspan', #lect.dialects + 1)
		end
	end
	if not isDialect then
		if lect.dialects then
			for _, dialect in ipairs(lect.dialects) do
				makeRow(t, dialect, true)
			end
		else
			for _ = 1, 4 do
				row:tag('td'):css('background', '#ececec')
			end
		end
	end
end

function p.main()
	local t = mw.html.create('table'):addClass('wikitable sortable mw-collapsible')
		:tag('caption'):addClass('nowrap'):wikitext('Data overview'):done()
		:tag('tr')
			:tag('th'):attr('colspan', 4):wikitext('Language'):done()
			:tag('th'):attr('colspan', 4):wikitext('Dialect'):done()
			:done()
		:tag('tr')
			:tag('th'):wikitext('Code'):done()
			:tag('th'):wikitext('Name'):done()
			:tag('th'):wikitext('Link'):done()
			:tag('th'):wikitext('Key'):done()
			:tag('th'):wikitext('Code'):done()
			:tag('th'):wikitext('Name'):done()
			:tag('th'):wikitext('Link'):done()
			:tag('th'):wikitext('Key'):done()
			:done()
	for _, lang in ipairs(organize(data.langs)) do
		makeRow(t, lang)
	end
	return tostring(t)
end

local function organizeKeys(t, lects, parent, parentCode)
	for code, lect in pairs(lects) do
		local origCode = (lect.isVariant or code:sub(1, 2) == 'X-')
			and code:lower()
			or code
		if lect.aliasOf then
			code = lect.aliasOf
			lect = lects[lect.aliasOf]
		end
		local key = lect.key or parent and parent.key
		if key then
			code = parent and parentCode .. '-' .. code or code
			local name, link = getNameAndLink(code)
			table.insert(t, {
				key = key,
				link = lect.link or lect.name and lect.name .. ' language' or link,
				name = lect.name or name ,
				code = parent and parentCode .. '-' .. origCode or origCode
			})
		end
		if lect.dialects then
			organizeKeys(t, lect.dialects, lect, code)
		end
	end
end

function p.keys()
	local wt = mw.html.create('table'):addClass('wikitable sortable mw-collapsible')
		:tag('caption'):addClass('nowrap'):wikitext('Languages with dedicated keys'):done()
		:tag('tr')
			:tag('th'):wikitext('Key'):done()
			:tag('th'):wikitext('Language'):done()
			:tag('th'):wikitext('Code'):done()
			:done()
	local t = {}
	organizeKeys(t, data.langs)
	local byKey, keys = {}, {}
	for _, lect in ipairs(t) do
		if not byKey[lect.key] then
			byKey[lect.key] = {}
			table.insert(keys, lect.key)
		end
		table.insert(byKey[lect.key], lect)
	end
	table.sort(keys)
	for _, key in ipairs(keys) do
		local row = wt:tag('tr')
		local keyCell = row:tag('td'):wikitext('[[' .. key .. ']]')
		local lects = byKey[key]
		local lang
		if #lects > 1 then
			keyCell:attr('rowspan', #lects)
			table.sort(lects, function (a, b)
				if a.name ~= b.name then
					return a.name < b.name
				end
				return a.code < b.code
			end)
			local keyName = mw.ustring.gsub(key, '^[^/]*/', '')
			for _, lect in ipairs(lects) do
				if lect.name == keyName then
					lang = lect
					break
				end
			end
		end
		if not lang then
			lang = lects[1]
		end
		local nameCell = row:tag('td'):wikitext(
			string.format('[[%s|%s]]', lang.link, lang.name)
		)
		local nameRowspan = 1
		row:tag('td'):wikitext('<code>' .. lang.code .. '</code>')
		for i, lect in ipairs(lects) do
			if lect ~= lang then
				local subRow = wt:tag('tr')
				local prev = i == 1 and lang or lects[i - 1]
				if prev.name == lect.name then
					nameRowspan = nameRowspan + 1
					nameCell:attr('rowspan', nameRowspan)
				else
					nameRowspan = 1
					nameCell = subRow:tag('td'):wikitext(
						string.format('[[%s|%s]]', lect.link, lect.name)
					)
				end
				subRow:tag('td'):wikitext('<code>' .. lect.code .. '</code>')
			end
		end
	end
	return tostring(wt)
end


return p