Module:kanjitab: difference between revisions

From Wiktionary, the free dictionary
Jump to navigation Jump to search
Content deleted Content added
No edit summary
simplify the code, disable categorization of irregular yomi in mixed mode (e.g. |yomi=k,irr)
Line 84: Line 84:
]=]
]=]
local yomi = args.yomi
local yomi
local yomi_extended = false
-- on/kun is jūbakoyomi; NOTE: these are only applicable for two-kanji compounds
-- on/kun is jūbakoyomi; NOTE: these are only applicable for two-kanji compounds
-- kun/on is yutōyomi; NOTE: these are only applicable for two-kanji compounds
-- kun/on is yutōyomi; NOTE: these are only applicable for two-kanji compounds
local function parse_extended_yomi(yomi, kanji_length)
local yomi_types = {

o = "on", on = "on",
end
k = "kun", kun = "kun",
ok = "jūbakoyomi", j = "jūbakoyomi",
if args.yomi then
ko = "yutōyomi", y = "yutōyomi", yu = "yutōyomi",
yomi = {}
irr = "irregular", irreg = "irregular", irregular = "irregular",
kan = "kanyoon", kanyo = "kanyoon", kanyoon = "kanyoon",
nanori = "nanori",
}
local function parse_extended_yomi(yomi)
local result = {}
local extended_yomi_code = {
local extended_yomi_code = {
o = 'on', on = 'on',
o = 'on', on = 'on',
Line 107: Line 101:
kan = 'kanyoon', kanyo = 'kanyoon', kanyoon = 'kanyoon',
kan = 'kanyoon', kanyo = 'kanyoon', kanyoon = 'kanyoon',
k = 'kun', kun = 'kun',
k = 'kun', kun = 'kun',
juku = 'jukujikun', jukuji = 'jukujikun', jukujikun = 'jukujikun', -- j alone is jūbakoyomi (on+kun) for backward compatibility
juku = 'jukujikun', jukuji = 'jukujikun', jukujikun = 'jukujikun',
ok = "jūbakoyomi", j = "jūbakoyomi",
ko = "yutōyomi", y = "yutōyomi", yu = "yutōyomi",
i = 'irregular', irr = 'irregular', irreg = 'irregular', irregular = 'irregular',
i = 'irregular', irr = 'irregular', irreg = 'irregular', irregular = 'irregular',
nanori = 'nanori',
nanori = 'nanori',
[''] = '', none = '',
[''] = '', none = '',
}
}
for _, i in ipairs(mw.text.split(yomi, ',')) do
for _, i in ipairs(mw.text.split(args.yomi, ',')) do
local _, _, a, b = mw.ustring.find(i, '^([a-z]*)([0-9]*)$')
local _, _, a, b = mw.ustring.find(i, '^([a-z]*)([0-9]*)$')
a = extended_yomi_code[a] or error("The yomi type “" .. yomi .. "” is not recognized.")
a = extended_yomi_code[a] or error("The yomi type “" .. args.yomi .. "” is not recognized.")
b = tonumber(b) or 1
b = tonumber(b) or 1
table.insert(result, { a, b })
table.insert(yomi, { a, b })
end
end
if #yomi == 1 and kanji_length > 1 then
return result
yomi[1][2] = kanji_length
end
if yomi then
if yomi_types[yomi] then
yomi = yomi_types[yomi]
else
yomi = parse_extended_yomi(yomi)
yomi_extended = true
end
end
else
else
Line 134: Line 123:
-- [[Special:WhatLinksHere/Template:tracking/ja-kanjitab/incorrect yutou or juubako]]
-- [[Special:WhatLinksHere/Template:tracking/ja-kanjitab/incorrect yutou or juubako]]
if (yomi == "jūbakoyomi" or yomi == "yutōyomi") and kanji_length ~= 2 then
if yomi and (yomi[1][1] == "jūbakoyomi" or yomi[1][1] == "yutōyomi") and kanji_length ~= 2 then
track("ja-pron/incorrect yutou or juubako")
track("ja-pron/incorrect yutou or juubako")
end
end
Line 150: Line 139:
if args.o.maxindex and args.o.maxindex > args[1].maxindex then
if args.o.maxindex and args.o.maxindex > args[1].maxindex then
track("too many o")
track("too many o")
end
local regular_yomi = {} -- regular_yomi[x] means the xth kanji is regular
if yomi then
for i = 1, #yomi do
local is_regular = yomi[i][1] ~= '' and yomi[i][1] ~= 'irregular'
for j = 1, yomi[i][2] do
table.insert(regular_yomi, is_regular)
end
end
else
for i = 1, kanji_length do
table.insert(regular_yomi, false)
end
end
end
Line 164: Line 167:
if reading and mw.ustring.match(reading, '[ぁ-ゖ]') then
if reading and mw.ustring.match(reading, '[ぁ-ゖ]') then
-- subcategorize by reading if this is joyo kanji, don't do that for less common kanji, with exceptions
-- subcategorize by reading if this is joyo kanji, don't do that for less common kanji, with exceptions
if (kanji_grade < 8 or ('厭昌之芽昌浩智晃淳敦聡晃旭亮糊桂隘阿唖撫鼠阿耘迂寅已伊餡姦闊礙碍凱亥价謳嘔齧日臣桶抉兎鵜卯綾飴焙肋鮫頚糞軋烏痒捷辰叩橙揃嶋澤菱彦囃覗呑之乃鼠做寅樋堤槌机杖頼辿哉叢狢峯巳卍鱒仄他惚弘宏燕倦經痙圭禽僑鋸醵墟屹綺几翫癌劫膠昂鹸牽喧餐鑽瑣些渾梱坤國壕誦哨蒐杓爾梓荼楕躁綜楚闡閃撰專泄藉棲錘錐祷盪淘點顛填擲擢闖厨蛋潭腿冪碧劈焚祓弗憑誹砒婢挽拔撥剥胚播乃狼牢蓮礫醂龍榴蕾酉祐佑耶也蔓曼沫邁呆硼牡甫步矮狸苔'):find(single_kanji)) and yomi ~= "irregular" then
if (kanji_grade < 8 or ('厭昌之芽昌浩智晃淳敦聡晃旭亮糊桂隘阿唖撫鼠阿耘迂寅已伊餡姦闊礙碍凱亥价謳嘔齧日臣桶抉兎鵜卯綾飴焙肋鮫頚糞軋烏痒捷辰叩橙揃嶋澤菱彦囃覗呑之乃鼠做寅樋堤槌机杖頼辿哉叢狢峯巳卍鱒仄他惚弘宏燕倦經痙圭禽僑鋸醵墟屹綺几翫癌劫膠昂鹸牽喧餐鑽瑣些渾梱坤國壕誦哨蒐杓爾梓荼楕躁綜楚闡閃撰專泄藉棲錘錐祷盪淘點顛填擲擢闖厨蛋潭腿冪碧劈焚祓弗憑誹砒婢挽拔撥剥胚播乃狼牢蓮礫醂龍榴蕾酉祐佑耶也蔓曼沫邁呆硼牡甫步矮狸苔'):find(single_kanji)) and regular_yomi[i] then
table.insert(categories, "Japanese terms spelled with " .. single_kanji .. " read as " .. reading)
table.insert(categories, "Japanese terms spelled with " .. single_kanji .. " read as " .. reading)
else
else
Line 198: Line 201:
else
else
-- [[Special:WhatLinksHere/Template:tracking/ja-kanjitab/no reading]]
-- [[Special:WhatLinksHere/Template:tracking/ja-kanjitab/no reading]]
if yomi ~= "irregular" then
if regular_yomi[i] then
track("no reading")
track("no reading")
end
end
Line 273: Line 276:
end
end
if yomi then
if yomi then
table.insert(cells, "|-")
if not yomi_extended then
if yomi_info[yomi] then
for _, i in ipairs(yomi) do
local yomi_info = yomi_info[yomi]
local yomi_info = yomi_info[i[1]] or { text = i[1] }
local text
table.insert(cells, "|-")
if yomi_info.entry then
text = "[[" .. yomi_info.entry .. "|" .. yomi_info.text .. "]]"
table.insert(categories, yomi_info.category)
local text
if yomi_info.entry then
text = "[[" .. yomi_info.entry .. "|" .. yomi_info.text .. "]]"
else
text = yomi_info.text
end
table.insert(cells, '| ' .. colspan .. '|' .. text)
else
else
text = yomi_info.text
-- [[Special:WhatLinksHere/Template:tracking/ja-kanjitab/no yomi info]]
track("no yomi info")
end
end
table.insert(cells, '| colspan="' .. i[2] .. '" |' .. text)
else -- extended mode
end
if #yomi == 1 and kanji_length > 1 then -- 大和: juku->juku2
local is_onyomi = { on = true, kanon = true, goon = true, toon = true, kanyoon = true }
yomi[1][2] = kanji_length
-- categories
end
local all_onyomi = true
table.insert(cells, "|-")
for _, i in ipairs(yomi) do
for i = 1, #yomi do
local yomi_info = yomi_info[i[1]] or { text = i[1] }
if not is_onyomi[yomi[i][1]] then all_onyomi = false; break end
end
local text
if yomi_info.entry then
if all_onyomi then
table.insert(categories, yomi_info.on.category)
text = "[[" .. yomi_info.entry .. "|" .. yomi_info.text .. "]]"
elseif #yomi == 2 and yomi[1][2] == 1 and yomi[2][2] == 1 then
else
if is_onyomi[yomi[1][1]] and yomi[2][1] == 'kun' then
text = yomi_info.text
table.insert(categories, yomi_info["jūbakoyomi"].category)
end
elseif yomi[1][1] == 'kun' and is_onyomi[yomi[2][1]] then
table.insert(cells, '| colspan="' .. i[2] .. '" |' .. text)
table.insert(categories, yomi_info["yutōyomi"].category)
end
local is_onyomi = { on = true, kanon = true, goon = true, toon = true, kanyoon = true }
-- categories
local all_onyomi = true
for i = 1, #yomi do
if not is_onyomi[yomi[i][1]] then all_onyomi = false; break end
end
if all_onyomi then
table.insert(categories, yomi_info.on.category)
elseif #yomi == 2 and yomi[1][2] == 1 and yomi[2][2] == 1 then
if is_onyomi[yomi[1][1]] and yomi[2][1] == 'kun' then
table.insert(categories, yomi_info["jūbakoyomi"].category)
elseif yomi[1][1] == 'kun' and is_onyomi[yomi[2][1]] then
table.insert(categories, yomi_info["yutōyomi"].category)
end
end
end
elseif yomi[1][1] == 'jūbakoyomi' or yomi[1][1] == 'yutōyomi' then
table.insert(categories, yomi_info[yomi[1][1]].category)
end
end
end
end

Revision as of 15:10, 19 January 2019

This module generates the content of {{ja-kanjitab}}, {{ryu-kanjitab}} etc.

Testcases

Lua error at line 317: attempt to call field 'jsort' (a nil value) Lua error at line 317: attempt to call field 'jsort' (a nil value) Lua error at line 317: attempt to call field 'jsort' (a nil value)
Lua error at line 317: attempt to call field 'jsort' (a nil value) Lua error at line 317: attempt to call field 'jsort' (a nil value) Lua error at line 317: attempt to call field 'jsort' (a nil value)
Lua error at line 63: “ateji” is not a recognized parameter. Lua error at line 63: “ateji” is not a recognized parameter.

{{ja-kanjitab|pagename=大和言葉|||こと|は|k4=ば|yomi=juku2,k2}}
{{ja-kanjitab|pagename=大和言葉|やまと2|こと|は|k3=ば|yomi=juku2,k2}} // "3" is # of argument, not # of kanji

local export = {}

local m_utilities = require("Module:utilities")
local m_ja = require("Module:ja")
--[=[
	Other modules used: [[Module:parameters]], [[Module:table]], [[Module:debug]]
]=]

local title = mw.title.getCurrentTitle()
local PAGENAME = title.text
local NAMESPACE = title.nsText

local lang = require("Module:languages").getByCode("ja")

local kanji_pattern = "㐀-䶵一-鿌\239\164\128-\239\171\153𠀀-𯨟"

local kanji_grade_links = {
	"[[:w:Kyōiku_kanji|Grade: 1]]",
	"[[:w:Kyōiku_kanji|Grade: 2]]",
	"[[:w:Kyōiku_kanji|Grade: 3]]",
	"[[:w:Kyōiku_kanji|Grade: 4]]",
	"[[:w:Kyōiku_kanji|Grade: 5]]",
	"[[:w:Kyōiku_kanji|Grade: 6]]",
	"[[:w:Jōyō kanji|Grade: S]]",		-- 7
	"[[:w:Jinmeiyō kanji|Jinmeiyō]]",	-- 8
	"[[:w:Hyōgai kanji|Hyōgaiji]]"		-- 9
}

local _track
local function track(code)
	if type(code) == "string" then
		_track = _track or require("Module:debug").track
		require("Module:debug").track("ja-kanjitab/" .. code)
	end
end

local function quote(text)
	return "“" .. text .. "”"
end

-- this is the function that is called from templates
function export.show(frame)
	local params = {
		[1] = { list = true, allow_holes = true },
		k = { list = true, allow_holes = true },
		o = { list = true, allow_holes = true },
		r = {},
		sort = {},
		yomi = {},
		pagename = {},
	}
	local args, unrecognized_args = require("Module:parameters").process(frame:getParent().args, params, true)
	
	if args.pagename and NAMESPACE == "" then
		require("Module:debug").track("ja-kanjitab/pagename param in mainspace")
	end
	
	for key, value in pairs(unrecognized_args) do
		local additional
		if mw.ustring.sub(key, 1, 1) == "y" then
			additional =  " Perhaps you meant " .. quote("yomi") .. "?"
		end
		error(quote(key) .. " is not a recognized parameter." .. (additional or ""))
	end
	
	local categories = {}
	local cells = {}
	-- replace e.g. 時々 with 時時
	local kanji = mw.ustring.gsub(args.pagename or PAGENAME, '([' .. kanji_pattern .. '])々', '%1%1')
	-- remove non-kanji characters
	kanji = mw.ustring.gsub(kanji, '[^' .. kanji_pattern .. ']', '')
		
	local kanji_length = mw.ustring.len(kanji)
	local colspan = ""
	if kanji_length > 1 then
		colspan = 'colspan="' .. kanji_length .. '" '
	end

	local table_head = [=[
{| class="wikitable kanji-table" style="float: right; text-align: center; font-size: small; margin: 0;"
! ]=] .. colspan .. [=[style="font-weight: normal;" | [[kanji|Kanji]] in this term
|- lang="ja" class="Jpan" style="font-size: 2em; background: white; line-height: 1em;"

]=]
	
	local yomi
	
	-- on/kun is jūbakoyomi; NOTE: these are only applicable for two-kanji compounds
	-- kun/on is yutōyomi; NOTE: these are only applicable for two-kanji compounds
	local function parse_extended_yomi(yomi, kanji_length)

	end
	
	if args.yomi then
		yomi = {}
		local extended_yomi_code = {
			o = 'on',			on = 'on',
			kanon = 'kanon',  -- kan is kan'yoon, and ko is kun+on for backward compatibility
			goon = 'goon',
			toon = 'toon',
			kan = 'kanyoon',	kanyo = 'kanyoon',		kanyoon = 'kanyoon',
			k = 'kun',			kun = 'kun',
			juku = 'jukujikun',	jukuji = 'jukujikun',	jukujikun = 'jukujikun',
			ok = "jūbakoyomi",	j = "jūbakoyomi",
			ko = "yutōyomi",	y = "yutōyomi",			yu = "yutōyomi",
			i = 'irregular',	irr = 'irregular',		irreg = 'irregular',	irregular = 'irregular',
			nanori = 'nanori',
			[''] = '',			none = '',
		}
		for _, i in ipairs(mw.text.split(args.yomi, ',')) do
			local _, _, a, b = mw.ustring.find(i, '^([a-z]*)([0-9]*)$')
			a = extended_yomi_code[a] or error("The yomi type “" .. args.yomi .. "” is not recognized.")
			b = tonumber(b) or 1
			table.insert(yomi, { a, b })
		end
		if #yomi == 1 and kanji_length > 1 then
			yomi[1][2] = kanji_length
		end
	else
		-- [[Special:WhatLinksHere/Template:tracking/ja-kanjitab/no yomi]]
		track("no yomi")
	end
	
	-- [[Special:WhatLinksHere/Template:tracking/ja-kanjitab/incorrect yutou or juubako]]
	if yomi and (yomi[1][1] == "jūbakoyomi" or yomi[1][1] == "yutōyomi") and kanji_length ~= 2 then
		track("ja-pron/incorrect yutou or juubako")
	end

	
	-- readings and okurigana are appended to this
	local sortkey = ""
	
	-- [[Special:WhatLinksHere/Template:tracking/ja-kanjitab/too many k]]
	-- [[Special:WhatLinksHere/Template:tracking/ja-kanjitab/too many o]]
	if args.k.maxindex and args.k.maxindex > args[1].maxindex then
		track("too many k")
	end
	
	if args.o.maxindex and args.o.maxindex > args[1].maxindex then
		track("too many o")
	end
	
	local regular_yomi = {} -- regular_yomi[x] means the xth kanji is regular
	if yomi then
		for i = 1, #yomi do
			local is_regular = yomi[i][1] ~= '' and yomi[i][1] ~= 'irregular'
			for j = 1, yomi[i][2] do
				table.insert(regular_yomi, is_regular)
			end
		end
	else
		for i = 1, kanji_length do
			table.insert(regular_yomi, false)
		end
	end
	
	-- if hiragana readings were passed,
	-- make the "spelled with ..." categories, the readings cells on the lower level and build the sort key
	-- otherwise rely on the pagename to make the original kanjitab and categories
	table.insert(cells, '|- style="background: white;"')
	for i = 1, kanji_length do
		local single_kanji = mw.ustring.sub(kanji, i, i)
		local kanji_grade = m_ja.kanji_grade(single_kanji)
		local reading = args[1][i]
		local cell = {}
		table.insert(cell, "| ")
		if reading and mw.ustring.match(reading, '[ぁ-ゖ]') then
			-- subcategorize by reading if this is joyo kanji, don't do that for less common kanji, with exceptions
			if (kanji_grade < 8 or ('厭昌之芽昌浩智晃淳敦聡晃旭亮糊桂隘阿唖撫鼠阿耘迂寅已伊餡姦闊礙碍凱亥价謳嘔齧日臣桶抉兎鵜卯綾飴焙肋鮫頚糞軋烏痒捷辰叩橙揃嶋澤菱彦囃覗呑之乃鼠做寅樋堤槌机杖頼辿哉叢狢峯巳卍鱒仄他惚弘宏燕倦經痙圭禽僑鋸醵墟屹綺几翫癌劫膠昂鹸牽喧餐鑽瑣些渾梱坤國壕誦哨蒐杓爾梓荼楕躁綜楚闡閃撰專泄藉棲錘錐祷盪淘點顛填擲擢闖厨蛋潭腿冪碧劈焚祓弗憑誹砒婢挽拔撥剥胚播乃狼牢蓮礫醂龍榴蕾酉祐佑耶也蔓曼沫邁呆硼牡甫步矮狸苔'):find(single_kanji)) and regular_yomi[i] then
				table.insert(categories, "Japanese terms spelled with " .. single_kanji .. " read as " .. reading)
			else
				table.insert(categories, "Japanese terms spelled with " .. single_kanji)
			end
			local actual_reading = args.k[i]
			local okurigana = args.o[i]
			
			sortkey = sortkey .. (actual_reading or reading) .. (okurigana or "")
			
			local reading_text = reading
			local actual_reading_text
			
			if actual_reading then
				actual_reading_text = " > " .. actual_reading
			end
			
			if okurigana then
				local okurigana_text = "(" .. okurigana .. ")"
				
				if reading_text then
					reading_text = reading_text .. okurigana_text
				end
				
				if actual_reading_text then
					actual_reading_text = actual_reading_text .. okurigana_text
				end
			end
			
			local text = reading_text .. (actual_reading_text or "")
			
			table.insert(cell, '<span class="Jpan" lang="ja">' .. text .. '</span>')
		else
			-- [[Special:WhatLinksHere/Template:tracking/ja-kanjitab/no reading]]
			if regular_yomi[i] then
				track("no reading")
			end
			table.insert(categories, "Japanese terms spelled with " .. single_kanji)
		end
		
		if reading and mw.ustring.match(reading, '[ぁ-ゖ]') then
			table.insert(cell, "<br/>")
		end
		table.insert(cell, "<small>" .. kanji_grade_links[kanji_grade] .. "</small>")
		table.insert(cells, table.concat(cell))
	end
	
	local yomi_info = {
		["on"] = {
			text = "on’yomi",
			entry = "音読み",
			category = "Japanese terms read with on'yomi",
		},
		["kanon"] = {
			text = "kan’on",
			entry = "漢音",
			category = "Japanese terms read with on'yomi",
		},
		["goon"] = {
			text = "goon",
			entry = "呉音",
			category = "Japanese terms read with on'yomi",
		},
		["toon"] = {
			text = "tōon",
			entry = "唐音",
			category = "Japanese terms read with on'yomi",
		},
		["kun"] = {
			text = "kun’yomi",
			entry = "訓読み",
			category = "Japanese terms read with kun'yomi",
		},
		["nanori"] = {
			text = "nanori",
			entry = "名乗り",
			category = "Japanese terms read with nanori",
		},
		["yutōyomi"] = {
			text = "yutōyomi",
			entry = "湯桶読み",
			category = "Japanese terms read with yutōyomi",
		},
		["jūbakoyomi"] = {
			text = "jūbakoyomi",
			entry = "重箱読み",
			category = "Japanese terms read with jūbakoyomi",
		},
		["jukujikun"] = {
			text = "jukujikun",
			entry = "熟字訓",
			category = "Japanese terms read with jukujikun",
		},
		["irregular"] = {
			text = "''Irregular''",
			category = "Japanese terms with irregular kanji readings",
		},
		["kanyoon"] = {
			text = "kan’yōon",
			entry = "慣用音",
			category = "Japanese terms read with kan'yōon",
		},
	}

	local rendaku = args.r
	if rendaku then
		table.insert(categories, "Japanese terms with rendaku")
	end
	if yomi then
		table.insert(cells, "|-")
		for _, i in ipairs(yomi) do
			local yomi_info = yomi_info[i[1]] or { text = i[1] }
			local text
			if yomi_info.entry then
				text = "[[" .. yomi_info.entry .. "|" .. yomi_info.text .. "]]"
			else
				text = yomi_info.text
			end
			table.insert(cells, '| colspan="' .. i[2] .. '" |' .. text)
		end
		local is_onyomi = { on = true, kanon = true, goon = true, toon = true, kanyoon = true }
		-- categories
		local all_onyomi = true
		for i = 1, #yomi do
			if not is_onyomi[yomi[i][1]] then all_onyomi = false; break end
		end
		if all_onyomi then
			table.insert(categories, yomi_info.on.category)
		elseif #yomi == 2 and yomi[1][2] == 1 and yomi[2][2] == 1 then
			if is_onyomi[yomi[1][1]] and yomi[2][1] == 'kun' then
				table.insert(categories, yomi_info["jūbakoyomi"].category)
			elseif yomi[1][1] == 'kun' and is_onyomi[yomi[2][1]] then
				table.insert(categories, yomi_info["yutōyomi"].category)
			end
		elseif yomi[1][1] == 'jūbakoyomi' or yomi[1][1] == 'yutōyomi' then
			table.insert(categories, yomi_info[yomi[1][1]].category)
		end
	end

	-- use user-provided sortkey if we got one, otherwise 
	-- use the sortkey we've already made by combining the 
	-- readings if provided, if we have neither then 
	-- default to empty string and don't sort
	local userprovided_sortkey = args.sort
	if userprovided_sortkey then
		sortkey = userprovided_sortkey
	end
	if sortkey then
		sortkey = m_ja.jsort(sortkey)
	end

	return
		table_head ..
		mw.ustring.gsub(kanji, '(.)', '| style="padding: 0.5em;" | [[%1#Japanese|%1]]\n') ..
		table.concat(cells, '\n') ..
		'\n|}' ..
		m_utilities.format_categories(categories, lang, sortkey)
end

return export