Module:ja-spellings

Module for {{ja-spellings}}.


local export = {}
local m_ja = require("Module:ja")

local kanji_pattern = "㐀-䶵一-鿌\239\164\128-\239\171\153𠀀-𯨟"
local japanese_pattern = 'ぁ-ゖァ-ヺー' .. kanji_pattern .. 'a-zA-Z0-9〆々'

local function link(text, PAGENAME)
	if text == PAGENAME then
		return '<span lang="ja" class="Jpan">' .. '[[' .. text .. ']]' .. '</span>' -- trigger selflink
	else
		return '<span lang="ja" class="Jpan">' .. '[[' .. text .. '#Japanese|' .. text .. ']]' .. '</span>'
	end
end

local function generate_forms(l, PAGENAME, separator)
	if not separator then separator = "<br>" end
	if #l == 0 then
		return ""
	else
		local result = link(l[1], PAGENAME)
		for i = 2, #l do
			result = result .. separator .. link(l[i], PAGENAME)
		end
		return result
	end
end

local function anchor(title, PAGENAME)
	return (title == PAGENAME) and "" or ('<span id="ja-' .. title .. '"></span>')
end

function export.show(frame)
	local params = {
		[1] = { list = true },
		["h"] = { list = true },
		["notes"] = {},
		["note"] = { alias_of = "notes" },
		["pagename"] = {},
	}
	local args, unrecognized_args = require("Module:parameters").process(frame:getParent().args, params, true)
	for key, value in pairs(unrecognized_args) do
		error("“" .. key .. "” is not a recognized parameter.")
	end
	local title = mw.title.getCurrentTitle()
	local PAGENAME = title.text
	local NAMESPACE = title.nsText
	if args["pagename"] and args["pagename"] ~= "" then PAGENAME = args["pagename"] end

	if NAMESPACE == "" then error("This template is deprecated, please replace it with ja-kanjitab.") end
	
	local modern_kana = {}
	local historical_kana = {}
	local kanji_spellings = {}
	local has_hiragana = false
	local has_katakana = false
	
	local function insert_spelling(spelling, is_historical)
		local script = m_ja.script(spelling)
		local target_table = kanji_spellings -- I'll assume Lua uses reference types
		if (script == "Hira") or (script == "Kana") or (script == "Hira+Kana") then
			target_table = is_historical and historical_kana or modern_kana
			if (script == "Hira") or (script == "Hira+Kana") then
				has_hiragana = true
			end
			if (script == "Kana") or (script == "Hira+Kana") then
				has_katakana = true
			end
		end
		-- Lua has nothing comparable to Python's 'in' operator, not even an index/find method to search an array :(
		local present = false
		for _, v in ipairs(target_table) do
			if v == spelling then
				present = true
			end
		end
		if not present then
			table.insert(target_table, spelling)
		end
	end
	if NAMESPACE == "" or args["pagename"] then
		insert_spelling(PAGENAME, false)
	end
	for _, v in ipairs(args[1]) do insert_spelling(v, false) end
	for _, v in ipairs(args["h"]) do insert_spelling(v, true) end
	
	local key_spellings = {}
	for _, v in ipairs(modern_kana) do
		table.insert(key_spellings, v)
	end
	for _, v in ipairs(kanji_spellings) do
		table.insert(key_spellings, v)
	end
	
	-- format notes
	local notes = {}
	if args["notes"] and args["notes"] ~= "" then
		for _, v in ipairs(mw.text.split(args["notes"], ';')) do
			table.insert(notes, '<i style="font-size:85%;">' .. mw.ustring.gsub(mw.ustring.gsub(v, ' %- ', ' – '), '[' .. japanese_pattern .. ']+', '<span lang="ja" class="Jpan" style="font-size: larger">%1</span>') .. '</i>')
		end
	end
	
	-- generate anchors
	local anchors = {}
	for _, v in ipairs(key_spellings) do
		table.insert(anchors, anchor(v, PAGENAME))
		local kanji = mw.ustring.gsub(v, '[^' .. kanji_pattern .. ']', '')
		if kanji ~= "" and kanji ~= v then table.insert(anchors, anchor(kanji, PAGENAME)) end
	end
	anchors = table.concat(anchors, '')
	
	-- generate the table
	local result = { '{| class="wikitable floatright" style="text-align: center; white-space: nowrap"' }
	if #modern_kana > 0 or #historical_kana > 0 then
		local kana_type = "Kana"
		if (has_hiragana == true) and (has_katakana == false) then kana_type = "Hiragana" end
		if (has_katakana == true) and (has_hiragana == false) then kana_type = "Katakana" end
		
		table.insert(result, '|-')
		if #historical_kana == 0 then -- modern only
			table.insert(result, '! ' .. kana_type)
			table.insert(result, '| colspan=2 | <span style="font-size:large; line-height: 1.5;">' .. generate_forms(modern_kana, PAGENAME) .. '</span>')
		else -- historical and modern
			table.insert(result, '! rowspan=2 | ' .. kana_type)
			table.insert(result, '! [[w:Modern kana usage|modern]]')
			table.insert(result, '| <span style="font-size:large; line-height: 1.5;">' .. generate_forms(modern_kana, PAGENAME) .. '</span>')
			table.insert(result, '|-')
			table.insert(result, '! [[w:Historical kana orthography|historical]]')
			table.insert(result, '| <span style="font-size:large; line-height: 1.5;">' .. generate_forms(historical_kana, PAGENAME) .. '</span>')
		end
	end
	if #kanji_spellings > 0 then
		table.insert(result, '|-')
		table.insert(result, '! Kanji')
		table.insert(result, '| colspan=2 | <span style="font-size: x-large; line-height: 1.5;">' .. generate_forms(kanji_spellings, PAGENAME) .. '</span>')
	end
	if #notes > 0 then
		table.insert(result, '|-')
		table.insert(result, '! ' .. ((#notes == 1) and "Note" or "Notes"))
		table.insert(result, '| colspan=2 | ' .. table.concat(notes, '<br>'))
	end
	table.insert(result, '|}')
	
	-- check if the kanji spellings have been created
	if NAMESPACE == "" then
		local uncreated = {}
		for _, v in ipairs(key_spellings) do
			if v ~= PAGENAME then
				local page = mw.title.new(v):getContent()
				local function search(page, word)
					return mw.ustring.find(page, '{{ja%-see|' .. word .. '[|}]') or mw.ustring.find(page, '{{ja%-see%-kango|[^}]-' .. word .. '[|}]')
				end
				if not (page and search(page, PAGENAME)) then
					table.insert(uncreated, link(v, PAGENAME))
				end
			end
		end
		table.insert(result, (#uncreated > 0) and '[[Category:Japanese terms with uncreated forms]]' .. 
			'<small class="attentionseeking">(' .. (#uncreated == 1 and 'This form' or 'These forms') ..
			' in the box ' .. (#uncreated == 1 and 'is' or 'are') .. ' either uncreated or lack a soft redirect to this page: ' .. 
			table.concat(uncreated, ", ") .. '.)</small>' or nil)
	end
	
	return table.concat(result, '\n')
end

return export