Module:User:Suzukaze-c/Hani-tab/ja

Hello, you have come here looking for the meaning of the word Module:User:Suzukaze-c/Hani-tab/ja. In DICTIOUS you will not only get to know all the dictionary meanings for the word Module:User:Suzukaze-c/Hani-tab/ja, but we will also tell you about its etymology, its characteristics and you will know how to say Module:User:Suzukaze-c/Hani-tab/ja in singular and plural. Everything you need to know about the word Module:User:Suzukaze-c/Hani-tab/ja you have here. The definition of the word Module:User:Suzukaze-c/Hani-tab/ja will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofModule:User:Suzukaze-c/Hani-tab/ja, 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 Suzukaze-c, for their own experimentation. Items in this module may be added and removed at Suzukaze-c's discretion; do not rely on this module's stability.


--[==[
TODO:
* 
** juubako & yutou
*** automatic → need to examine original entry title?
** "|yomi=x,x3"
** kan'youon, goon, etc? ] (いつの間に?)
** disable "cat:read as x" categories for irregular readings!!
** sortkeys
** 
* "cat:read with on'yomi" "secondary school kanji" "one kanji" etc?
* read data from "cat:字 read as じ", or read data from "字#Readings"?
** have "cat:" and "{{ja-kanjitab}}" read from "#Readings"
* ]
]==]

local export = {}

local gsub = mw.ustring.gsub
local match = mw.ustring.match
local split = mw.text.split

-- XXX: share this data with ]?
local yomi_class_aliases = {
	 = "on",
	 = "kun",
	 = "irregular",
	 = "irregular",
}

local yomi_class_data = {
	 = {
		text = "on’yomi",
		entry = "音読み",
		category = "Japanese terms read with on'yomi",
	},
	 = {
		text = "kun’yomi",
		entry = "訓読み",
		category = "Japanese terms read with kun'yomi",
	},
	 = {
		text = "yutōyomi",
		entry = "湯桶読み",
		category = "Japanese terms read with yutōyomi",
	},
	 = {
		text = "jūbakoyomi",
		entry = "重箱読み",
		category = "Japanese terms read with jūbakoyomi",
	},
	 = {
		text = "kan’yōon",
		entry = "慣用音",
		category = "Japanese terms read with kan'yōon",
	},
	 = {
		text = "nanori",
		entry = "名乗り読み",
		category = "Japanese terms read with nanori",
	},
	 = {
		text = "<i>irregular</i>",
		category = "Japanese terms with irregular kanji readings",
	},
}

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

local category_models = {
	 = "Japanese terms spelled with %s read as %s",
	 = "Japanese terms with rendaku",
	 = "Japanese terms with omitted okurigana",
}

local function tag_text(text)
	return require('Module:script utilities').tag_text(text, require('Module:languages').getByCode('ja'))
end

local function clean_reading(reading)
	reading = gsub(reading, '%(+%)', '')
	reading = gsub(reading, '>.+', '')
	return reading
end

local function analyze_reading(categories, char, reading)
	if not reading then
		return
	end

	-- error checking

	if match(reading, '>') then
		if match(reading, '%(') and not match(reading, '.+%(.+%)>.+%(.+%)') then
			error('Please fix your parentheses.')
			-- BUT maybe "かた>がた(り)" is nicer than "かた(り)>がた(り)"
		end
	elseif match(reading, '<') then
		error('Please show sound change in the ">" direction.')
	end

	if match(reading, '') and not match(reading, '.+%(.+%)') then
		error('Please close your parentheses.')
	end

	-- 本番

	if match(reading, '%(') then
		table.insert(categories, category_models)

		reading = gsub(reading, '%(+%)', '')
	end

	if match(reading, '>') then
		local reading_forms = split(reading, '>')

		-- if reading_forms == gsub(mw.ustring.toNFD(reading_forms), '', '') then
		-- 

		local kanaA = mw.ustring.sub(reading_forms, 1, 1) -- pre-rendaku kana
		local kanaB = mw.ustring.sub(reading_forms, 1, 1) -- post-rendaku kana
		kanaB = mw.ustring.char(mw.ustring.codepoint(kanaB) - 1) -- strip dakuon
		kanaC = mw.ustring.char(mw.ustring.codepoint(kanaB) - 1) -- strip dakuon again, for パ行
		if (kanaA == kanaB) or (kanaA == kanaC) then
			table.insert(categories, category_models)
		end

		reading = gsub(reading, '>.+', '')
	end

	table.insert(categories, category_models:format(char, reading))
end

local function build_tab_row_b_cell(char, reading)
	local tab_row_b_cell = mw.html.create('td')

	local kanji_grade = require('Module:ja').kanji_grade(char)

	if reading then
		-- reading = gsub(reading, '>', '<sub>&gt;</sub>')
		-- reading = gsub(reading, '%(+%)', '<sup>%1</sup>')
		reading = gsub(reading, '>', '→')

		tab_row_b_cell
			:wikitext(tag_text(reading))
			:tag('br')
		:done()
	end

	tab_row_b_cell
		:wikitext('<small>' .. kanji_grade_links .. '</small>')
	:done()

	return tab_row_b_cell
end

local function build_tab_row_c(tab_row_c, yomi, chars)
	for i, yomi_class in ipairs(yomi) do
		yomi = yomi_class_aliases or yomi_class -- "o"→"on"
		yomi = yomi_class_data].text -- "on"→"on’yomi"
	end
		
	if #yomi == 1 then
		local tab_row_c_cell = mw.html.create('td')
			:attr('colspan', #chars)
			:wikitext(yomi)
		:done()

		tab_row_c
			:node(tab_row_c_cell)
		:done()
	else
		local tab_row_c_cells = {}

		for i, yomi_class in ipairs(yomi) do
			if (yomi == yomi) then
				tab_row_c_cells
					:attr('colspan', tab_row_c_cells:getAttr('colspan') + 1)
				:done()
			else
				local tab_row_c_cell = mw.html.create('td')
					:wikitext(yomi)
					:attr('colspan', 1)
				:done()

				table.insert(tab_row_c_cells, tab_row_c_cell)
			end
		end

		for i, tab_row_c_cell in ipairs(tab_row_c_cells) do
			tab_row_c
				:node(tab_row_c_cell)
			:done()
		end
	end

	return tab_row_c
end

local function detect_yomi_classes(chars, readings)
	local yomi = {}

	for i, char in ipairs(chars) do
		if readings then
			local category_name = category_models:format(char, clean_reading(readings))
			local category_content = mw.title.new(category_name, 'Category'):getContent()

			if not category_content then
				error('Please verify that ] is formatted correctly, or fill out the "yomi" parameter.')
			end

			category_content = gsub(category_content, '^{{', '')
			category_content = gsub(category_content, '}}$', '')
			category_content = split(category_content, '|')
			table.remove(category_content, 1) -- "ja-readingcat"
			table.remove(category_content, 1) -- 
			table.remove(category_content, 1) -- 

			-- XXX: 🤔
			local detected_yomi_types = ''
			for i, yomi_type in ipairs(category_content) do
				if match(yomi_type, 'on$') then
					detected_yomi_types = detected_yomi_types .. '0'
				else
					detected_yomi_types = detected_yomi_types .. '1'
				end
			end
			if match(detected_yomi_types, '01') or match(detected_yomi_types, '10') then
				error('Could not determine if ] was an on reading or a kun reading; please fill out the "yomi" parameter.')
			elseif match(detected_yomi_types, '0') then
				yomi = 'o'
			else
				yomi = category_content -- 🤔
			end
		else
			-- yomi = ''
			error('reading was not provided for ]?')
		end
	end

	return yomi
end

function export.main(data)
	local tab_row_b = mw.html.create('tr')
	local tab_row_c = mw.html.create('tr')
	local categories = {}

	if data.yomi then
		data.yomi = split(data.yomi, ',')
	elseif data.readings then
		data.yomi = detect_yomi_classes(data.chars, data.readings)
	end

	if table.maxn(data.yomi) ~= 1 then
		if table.maxn(data.yomi) ~= table.maxn(data.readings) then
			error(table.maxn(data.readings) .. ' readings and ' .. table.maxn(data.yomi) .. ' yomi designations?')
		end
	end

	for i, char in ipairs(data.chars) do
		tab_row_b
			:node(build_tab_row_b_cell(char, data.readings))
		:done()

		analyze_reading(categories, char, data.readings)
	end

	if data.yomi then
		tab_row_c = build_tab_row_c(tab_row_c, data.yomi, data.chars)
	end

	data.hani_tab
		:node(tab_row_b)
		:node(tab_row_c)
	:done()

	return data.hani_tab, categories
end

return export