Module:User:Dine2016/ja-kanjitab

Hello, you have come here looking for the meaning of the word Module:User:Dine2016/ja-kanjitab. In DICTIOUS you will not only get to know all the dictionary meanings for the word Module:User:Dine2016/ja-kanjitab, but we will also tell you about its etymology, its characteristics and you will know how to say Module:User:Dine2016/ja-kanjitab in singular and plural. Everything you need to know about the word Module:User:Dine2016/ja-kanjitab you have here. The definition of the word Module:User:Dine2016/ja-kanjitab will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofModule:User:Dine2016/ja-kanjitab, as well as those of other words, enriches your vocabulary and provides you with more and better linguistic resources.

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


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

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

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

-- TODO: centralize internal tables here

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

local kanji_grade_links = {
	"]",
	"]",
	"]",
	"]",
	"]",
	"]",
	"]",		-- 7
	"]",	-- 8
	"]"		-- 9
}

local function link(text)
	if text == title then
		return '<span lang="ja" class="Jpan" style="font-weight: bold;">' .. text .. '</span>'
	else
		return '<span lang="ja" class="Jpan">' .. ']' .. '</span>'
	end
end

-- export this?
local function shin_to_kyu(shin)
	local ambiguous_char = '' -- TODO: check if there is more
	if mw.ustring.find(shin, ambiguous_char) then return nil end
	
	local s_to_k = {
		 = "亞",  = "惡",  = "壓",  = "圍",  = "醫",  = "爲",
		 = "壹",  = "逸",  = "隱",  = "榮",  = "營",  = "衞",
		 = "驛",  = "謁",  = "圓",  = "鹽",  = "緣",  = "艷",
		 = "應",  = "歐",  = "毆",  = "櫻",  = "奧",  = "橫",
		 = "溫",  = "穩",  = "假",  = "價",  = "禍",  = "畫",
		 = "會",  = "悔",  = "海",  = "繪",  = "壞",  = "懷",
		 = "慨",  = "槪",  = "擴",  = "殼",  = "覺",  = "學",
		 = "嶽",  = "樂",  = "喝",  = "渴",  = "褐",  = "罐",
		 = "卷",  = "陷",  = "勸",  = "寬",  = "漢",  = "關",
		 = "歡",  = "觀",  = "氣",  = "祈",  = "卽",  = "歸",
		 = "器",  = "僞",  = "戲",  = "犧",  = "舊",  = "據",
		 = "擧",  = "虛",  = "峽",  = "挾",  = "狹",  = "鄕",
		 = "響",  = "曉",  = "勤",  = "謹",  = "區",  = "驅",
		 = "勳",  = "薰",  = "徑",  = "莖",  = "惠",  = "揭",
		 = "溪",  = "經",  = "螢",  = "輕",  = "繼",  = "鷄",
		 = "藝",  = "擊",  = "缺",  = "硏",  = "縣",  = "儉",
		 = "劍",  = "險",  = "圈",  = "檢",  = "獻",  = "權",
		 = "顯",  = "驗",  = "嚴",  = "廣",  = "效",  = "恆",
		 = "黃",  = "鑛",  = "號",  = "國",  = "黑",  = "穀",
		 = "碎",  = "濟",  = "齋",  = "劑",  = "殺",  = "雜",
		 = "參",  = "棧",  = "蠶",  = "慘",  = "贊",  = "殘",
		 = "絲",  = "祉",  = "視",  = "齒",  = "兒",  = "辭",
		 = "濕",  = "實",  = "寫",  = "社",  = "者",  = "煮",
		 = "釋",  = "壽",  = "收",  = "臭",  = "從",  = "澁",
		 = "獸",  = "縱",  = "祝",  = "肅",  = "處",  = "暑",
		 = "署",  = "緖",  = "諸",  = "敍",  = "將",  = "祥",
		 = "稱",  = "涉",  = "燒",  = "證",  = "獎",  = "條",
		 = "狀",  = "乘",  = "淨",  = "剩",  = "疊",  = "繩",
		 = "壤",  = "孃",  = "讓",  = "釀",  = "觸",  = "囑",
		 = "神",  = "眞",  = "寢",  = "愼",  = "盡",  = "圖",
		 = "粹",  = "醉",  = "穗",  = "隨",  = "髓",  = "樞",
		 = "數",  = "瀨",  = "聲",  = "齊",  = "靜",  = "竊",
		 = "攝",  = "節",  = "專",  = "淺",  = "戰",  = "踐",
		 = "錢",  = "潛",  = "纖",  = "禪",  = "祖",  = "雙",
		 = "壯",  = "爭",  = "莊",  = "搜",  = "插",  = "巢",
		 = "曾",  = "瘦",  = "裝",  = "僧",  = "層",  = "總",
		 = "騷",  = "增",  = "憎",  = "藏",  = "贈",  = "臟",
		 = "卽",  = "屬",  = "續",  = "墮",  = "對",  = "體",
		 = "帶",  = "滯",  = "臺",  = "瀧",  = "擇",  = "澤",
		 = "擔",  = "單",  = "膽",  = "嘆",  = "團",  = "斷",
		 = "彈",  = "遲",  = "癡",  = "蟲",  = "晝",  = "鑄",
		 = "著",  = "廳",  = "徵",  = "聽",  = "懲",  = "敕",
		 = "鎭",  = "塚",  = "遞",  = "鐵",  = "點",  = "轉",
		 = "傳",  = "都",  = "燈",  = "當",  = "黨",  = "盜",
		 = "稻",  = "鬭",  = "德",  = "獨",  = "讀",  = "突",
		 = "屆",  = "難",  = "貳",  = "惱",  = "腦",  = "霸",
		 = "拜",  = "廢",  = "賣",  = "梅",  = "麥",  = "發",
		 = "髮",  = "拔",  = "繁",  = "晚",  = "蠻",  = "卑",
		 = "祕",  = "碑",  = "濱",  = "賓",  = "頻",  = "敏",
		 = "甁",  = "侮",  = "福",  = "拂",  = "佛",  = "倂",
		 = "竝",  = "塀",  = "餠",  = "邊",  = "變",  = "勉",
		 = "步",  = "寶",  = "豐",  = "襃",  = "墨",  = "飜",
		 = "每",  = "萬",  = "滿",  = "免",  = "麵",  = "彌",
		 = "默",  = "譯",  = "藥",  = "與",  = "豫",  = "餘",
		 = "譽",  = "搖",  = "樣",  = "謠",  = "來",  = "賴",
		 = "亂",  = "覽",  = "欄",  = "龍",  = "隆",  = "虜",
		 = "兩",  = "獵",  = "綠",  = "淚",  = "壘",  = "類",
		 = "禮",  = "勵",  = "戾",  = "靈",  = "齡",  = "曆",
		 = "歷",  = "戀",  = "練",  = "鍊",  = "爐",  = "勞",
		 = "郞",  = "朗",  = "廊",  = "樓",  = "錄",  = "灣",
		
		-- TODO: add Z-variants like 青/靑, 説/說
	}
	return mw.ustring.gsub(shin, '.', s_to_k)
end

local function genspec(args)
--[=[
	kanji_length -- the number of kanji in the term
	kanji -- e.g. { '追払', '追拂' }
	kanji_types -- e.g. { 'shin', 'kyu' } (or 位: { 'shinkyu' }, 儘/侭: { 'kyu', 'extshin' })
	kanji_spellings -- e.g. { '追い払う', '追い拂う' }
	yomi -- a list of { original reading, actual reading, okurigana } of the kanji spans, e.g. { { 'お', 'お', 'い' }, { 'はら', 'はら', 'う' } }.
	yomi_types -- a list of reading types, each formatted like { 'on', span=1 }, { 'jukujikun', span=2 }. The sum of the spans should equal kanji_length.
	altforms -- e.g. { { '追いはらう', type='' }, { '追払う', '追拂う', type='irregular okurigana' }, { '追ひ払ふ', '追ひ拂ふ', type='historical kana' } }
]=]
	local kanji_types = {}
	local kanji_spellings = {}
	
	local shin = args.s;  if shin == '-' then shin = nil end
	local kyu = args.k;  if kyu == '-' then kyu = nil end
	local extshin = args.es;  if extshin == '-' then extshin = nil end
	if kyu and not shin and not extshin then shin = PAGENAME end
	if extshin and not shin and not kyu then kyu = PAGENAME end
	
	if shin and kyu and not extshin then
		kanji_types = { 'shin', 'kyu' }
		kanji_spellings = { shin, kyu }
	elseif kyu and extshin and not shin then
		kanji_types = { 'kyu', 'extshin' }
		kanji_spellings = { kyu, extshin }
	elseif not kyu and not extshin then
		if not shin then shin = PAGENAME end
		kanji_types = { 'shin', 'kyu' }
		kanji_spellings = { shin, shin_to_kyu(shin) or error('automatic jitai conversion of ' .. shin .. ' failed, please supply the kyujitai manually') }
	else
		error('combination of kanji types not yet supported') -- shin + kyu + extshin can be supported if needed
	end
	if #kanji_spellings == 2 and kanji_spellings == kanji_spellings then
		kanji_types = { 'shinkyu' }
		kanji_spellings = { kanji_spellings }
	end
	
	local kanji = {}
	for _, i in ipairs(kanji_spellings) do
		local kj = mw.ustring.gsub(i, '()々', '%1%1')
		kj = mw.ustring.gsub(kj, '', '')
		table.insert(kanji, kj)
	end
	
	local kanji_length = mw.ustring.len(kanji)
	if kanji_length == 0 then error('there is no kanji in the term ' .. kanji) end
	
	local yomi = {}
	for i = 1, args.maxindex do
		local ym = args or ''
		if not mw.ustring.find(ym, '%.') then ym = ym .. '.' end
		if not mw.ustring.find(ym, '>') then ym = mw.ustring.gsub(ym, '^(.*)%.(.*)$', '%1>%1.%2') end 
		local _, _, a, b, c = mw.ustring.find(ym, '^(.*)>(.*)%.(.*)$')
		table.insert(yomi, { a, b, c })
	end
	
	local yomi_types = {}
	local yt = args or ''
	local yomi_code = {
		o = 'on',			on = 'on',
		kanon = 'kanon',
		goon = 'goon',
		toon = 'toon',
		kan = 'kanyoon',	kanyo = 'kanyoon',		kanyoon = 'kanyoon',
		k = 'kun',			kun = 'kun',
		juku = 'jukujikun',	jukuji = 'jukujikun',	jukujikun = 'jukujikun',  -- j alone is jūbakoyomi (on+kun) for backward compatibility
		irr = 'irregular',	irreg = 'irregular',	irregular = 'irregular',
		p = 'phonetic',		phonetic = 'phonetic',
		nanori = 'nanori',
		 = '',			none = '',
	}
	if yt == 'j' then yt = 'on,kun' elseif yt == 'y' then yt='kun,on' end
	if not mw.ustring.find(yt, ',') and not yomi_code*$', '%1')] then
		yt = mw.ustring.gsub(mw.ustring.gsub(yt, '(*)', '%1,'), ',$', '') -- 'j2kk' to 'j2,k,k'
	end
	yt = mw.text.split(yt, ',')
	for _, i in ipairs(yt) do
		local _, _, a, b = mw.ustring.find(i, '^(*)(*)$')
		a = yomi_code or error('cannot recognize yomi type "' .. args .. '"')
		b = tonumber(b) or 1
		table.insert(yomi_types, { a, span=b })
	end
	-- allow using a single yomi type for the whole kanji
	-- Case 1: {{ja-kanjitab|かん|れん|yomi=kan|s=関連}} -> kanon, kanon
	-- Case 2: {{ja-kanjitab|やまと|yomi=j|s=大和}} -> jukujikun2
	if #yomi_types == 1 and yomi_types.span == 1 and kanji_length > 1 then
		local yomi_jukujikun_type = {  = true,  = true,  = true }
		if yomi_jukujikun_type] then -- Case 2
			yomi_types.span = kanji_length
		else -- Case 1
			local a = yomi_types
			local b = yomi_types.span
			for i = 2, kanji_length do table.insert(yomi_types, { a, span=b }) end
		end
	end
	-- check the sum of the spans
	local span_sum = 0
	for _, i in ipairs(yomi_types) do span_sum = span_sum + i.span end
	if span_sum ~= kanji_length then error('the |yomi= parameter does not match the number of kanji: ' .. span_sum .. ' vs ' .. kanji_length) end
	
	local altforms = {}
	local af = args.alt or ''
	af = mw.text.split(af, ',')
	for _, i in ipairs(af) do
		if i ~= '' then
			if not mw.ustring.find(i, '-') then i = i .. '-' end
			local _, _, a, b = mw.ustring.find(i, '^(.*)%-(.*)$')
			local alt_code = {
				 = 'irregular okurigana',
				 = 'historical kana',
				 = 'variant kana',
				 = 'obsolete kana', -- e.g. 用ひる
			}
			if alt_code then b = alt_code end
			-- syntax borrowed from {{zh-l}}: *字体 supresses automatic conversion, and 字体/字體 provides manual conversions
			if mw.ustring.find(a, '%*') then
				table.insert(altforms, { mw.ustring.gsub(a, '%*', ''), type=b })
			elseif mw.ustring.find(a, '/') then
				a = mw.text.split(a, '/')
				a = b
				table.insert(altforms, a)
			else
				local shin = a
				local kyu = shin_to_kyu(shin) or shin
				if shin == kyu then
					table.insert(altforms, { shin, type=b })
				else
					table.insert(altforms, { shin, kyu, type=b })
				end
			end
		end
	end
	
	return { kanji_length = kanji_length, kanji = kanji, kanji_types = kanji_types, kanji_spellings = kanji_spellings, yomi = yomi, yomi_types = yomi_types, altforms = altforms }
end

local function gentable(spec, collapsed)
	local table_code = '{| align=right style="clear: right;margin: 1em;border-collapse: collapse;text-align: center"\n!\n'
	
	-- generate the yomi tabs
	for i, j in ipairs(spec.yomi_types) do
		local yomi = spec.yomi or { '', '', '' }
		local yomi_text = (yomi == yomi) and (yomi .. '`') or (yomi .. '` > ' .. yomi .. '`')
		yomi_text = mw.ustring.gsub(yomi_text, '`', (yomi == '') and '' or ('(' .. yomi .. ')'))
		local yomi_type = j
		local yomi_link = {
			on = "]",
			kanon = "]",
			goon = "]",
			kanyoon = "]",
			toon = "]",
			kun = "]",
			jukujikun = "]",
			irregular = "irregular",
			phonetic = "phonetic",
			nanori = "]",
			 = "",
		}
		local span = j.span
		table_code = table_code .. '! style="padding: 0.5em;border: 1px solid #aaa;background:#F5F5DC;font-weight: normal;font-size: 85%;" colspan=' .. span .. '|<span class="Jpan" lang="ja">' .. yomi_text .. '</span><br>' .. yomi_link .. '\n'
	end
	
	-- generate the main jitai lines
	for i = 1, #spec.kanji_types do
		table_code = table_code .. '|- style="line-height:1.3"\n'
		local jitai_link = {
			shin = ']',
			kyu = ']',
			shinkyu = '] and ]',
			extshin = '] (])',
		}
		local kanji_type = spec.kanji_types
		-- cell showing the jitai type and the spelling
		table_code = table_code .. '! style="padding: 0.5em;border: 1px solid #aaa;background: #E0FFFF;font-weight: normal;font-size: smaller;" |' .. jitai_link
		local kanji_spelling = spec.kanji_spellings
		if mw.ustring.len(kanji_spelling) > 6 then 
			table_code = table_code .. ' <span style="font-size:100%">(' .. link(kanji_spelling) .. ')</span>'
		elseif mw.ustring.len(kanji_spelling) > 1 then 
			table_code = table_code .. ' <span style="font-size:140%">(' .. link(kanji_spelling) .. ')</span>'
		end
		table_code = table_code .. '\n'
		-- cells showing the kanji
		local kanji_string = spec.kanji
		for j = 1, mw.ustring.len(kanji_string) do
			local kanji = mw.ustring.sub(kanji_string, j, j)
			table_code = table_code .. '| style="padding: 0.5em; background-color:white;border-right: 1px solid #aaa;border-bottom: 1px solid #aaa;" | <span style="font-size:x-large">' .. link(kanji) .. '</span>'
			local kanji_grade = m_ja.kanji_grade(kanji)
			table_code = table_code .. '<br><small>' .. kanji_grade_links .. '</small>'
			table_code = table_code .. '\n'
		end
	end
	
	-- alt forms cell
	if #spec.altforms > 0 then
		table_code = table_code .. '|-\n| style="background-color:white;border: 1px solid #aaa; font-size:90%;" colspan=' .. spec.kanji_length + 1 ..  '|\n<b>Variant forms</b><br>'
		local alt1 = {}
		for _, altform in ipairs(spec.altforms) do
			local alt2 = {}
			for _, i in ipairs(altform) do table.insert(alt2, link(i)) end
			alt2 = table.concat(alt2, '/')
			if altform and altform ~= '' then
				alt2 = alt2 .. ' <span style="font-size:70%"><i>' .. altform .. '</i></span>'
			end
			table.insert(alt1, alt2)
		end
		table_code = table_code .. table.concat(alt1, '<br>') .. '\n'
	end
	table_code = table_code .. '|}\n'
	return table_code
end

function export.show(frame)
	local params = {
		 = { list = true, allow_holes = true, allow_empty = true },
		 = {},
		 = {},
		 = {},
		 = {},
		 = {},
		 = {},
		 = {},
	}
	local args, unrecognized_args = require("Module:parameters").process(frame:getParent().args, params, true)
	
	for key, value in pairs(unrecognized_args) do
		local additional
		if mw.ustring.sub(key, 1, 1) == "y" then
			additional =  " Perhaps you meant “yomi”?"
		end
		error("“" .. key .. "” is not a recognized parameter." .. (additional or ""))
	end
	
	if args.pagename then
		if NAMESPACE == "" then error("The pagename parameter should not be used in entries, as it is only for testing.") end
		PAGENAME = args.pagename
	end
	
	return gentable(genspec(args))
end

function export:test()
	--[[
	mw.logObject(genspec({
		 = { 'き', 'つ>づ.く', maxindex = 2 },
		s = '気付く',
		yomi = 'ok',
		alt = '気づく,気ずく-ik',
	}))
	mw.logObject(genspec({
		 = { 'とう', 'きょう', 'けしき', maxindex = 3 },
		s = '東京景色',
		yomi = 'kan,go,j2',
	}))
	mw.logObject(genspec({
		 = { 'まま', maxindex = 1 },
		k = '儘',
		es = '侭',
		yomi = 'k',
	}))
	mw.logObject(genspec({
		 = { maxindex = 0 },
		s = 'かんじなし',
	}))
	mw.logObject(genspec({
		 = { 'やまと', maxindex = 1 },
		s = '大和',
		yomi = 'j',
	}))
	]]--
	mw.log(gentable(genspec({
		 = { 'こく', 'さい', 'おん', 'せい', 'き', 'ごう', maxindex = 6 },
		s = '国際音声記号',
		yomi = 'o',
	})))
end

return export