İçeriğe atla

Modül:ja-kanji-okunuş

Vikisözlük sitesinden
Modül belgelemesi [Düzenle] [Tazele]


local export = {}

local titleObj = mw.title.getCurrentTitle()
local fullpagename = titleObj.fullText
local pagename = titleObj.text
local namespace = titleObj.nsText

local get_script_by_code = require("Modül:alfabeler").getirKodaGore
local Jpan = get_script_by_code("Jpan")
-- local katakana_script = get_script_by_code("Kana")
local hiragana_script = get_script_by_code("Hira")
local ja = require("Modül:diller").getirKodaGore("ja")
local module_ja = require("Modül:ja")

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

local data = mw.loadData("Modül:ja/veri")

local CONCAT_SEP = ', '
	
local labels = {
	kanon = {
		index = 2,
		entry = "漢音",
		text = "Kan-on",
		text2 = "kan'on",
		classification = "on",
	},
	goon = {
		index = 1,
		entry = "呉音",
		text = "Go-on",
		text2 = "goon",
		classification = "on",
	},
	toon = {
		index = 3,
		entry = "唐音",
		text = "Tō-on",
		text2 = "tōon",
		classification = "on",
	},
	soon = {
		index = 4,
		entry = "宋音",
		text = "Sō-on",
		text2 = "sōon",
		classification = "on",
	},
	kanyoon = {
		index = 5,
		entry = "慣用音",
		text = "Kan’yō-on",
		text2 = "kan'yōon",
		classification = "on",
	},
	on = {
		index = 6,
		entry = "音読み",
		text = "On",
		text2 = "on",
		classification = "on",
		unclassified = " (sınıflandırılmamış)",
	},
	kun = {
		index = 7,
		entry = "訓読み",
		text = "Kun",
		text2 = "kun",
		classification = "kun",
	},
	nanori = {
		index = 8,
		entry = "名乗り",
		text = "Nanori",
		text2 = "nanori",
		classification = "nanori",
	},
}
labels["kan'yōon"] = labels["kanyoon"]
labels["sōon"] = labels["soon"]
labels["kan'on"] = labels["kanon"]
labels["tōon"] = labels["toon"]

export.accented_labels_to_labels = {}
for k, v in pairs(labels) do
	export.accented_labels_to_labels[v.text2] = k
end

local function if_not_empty(var)
	if var == "" then
		return nil
	else
		return var
	end
end

-- If table contains at least one key, returns false.
local function is_empty(t)
	if next(t) then
		return false
	else
		return true
	end
end

local function track(code)
	--require("Modül:debug").track("ja-kanji-readings/" .. code)
end

local script_methods = getmetatable(Jpan).__index
function script_methods:containsOnly(text)
	text = text:gsub('[%z-\127]', '') -- Remove ASCII.
	return mw.ustring.find(text, '^[' .. self._rawData.karakterler .. ']+$') ~= nil
end

function export.get_script(term)
	return hiragana_script:containsOnly(term) and hiragana_script
		-- or katakana_script:containsOnly(term) and katakana_script
		or Jpan
end

local function plain_link(veri)
	veri.sozcuk = string.gsub(veri.sozcuk, '[%.%- ]', '') -- 「かな-し.い」→「かなしい」, 「も-しく は」→「もしくは」
	if veri.c then
		veri.c = string.gsub(veri.c, '[%.%-]', '')
	end
	veri.dil = ja
	veri.alf = hiragana_script:containsOnly(veri.alt or veri.sozcuk) and hiragana_script
		-- or katakana_script:containsOnly(veri.alt or veri.sozcuk) and katakana_script
		or Jpan
	veri.soz = if_not_empty(veri.soz)
	veri.anlam = if_not_empty(veri.anlam)
	return require("Modül:bağlantılar").tam_bag(veri, "sözcük") --"term" makes italic
end

local function process_okurigana(reading, kanji)
	if not (reading and kanji) then
		return nil
	end
	
	 -- 「むす-ぶ」→「結ぶ」
	return string.gsub(reading, '^(.+)(%-)', kanji)
end

local function make_romaji(rom, options)
	if not rom then
		return nil
	end
	
	 -- 「むす-ぶ」→「<u>むす</u>ぶ」
	rom = string.gsub(rom, '^(.+)(%-)', '<u>%1</u>')
	
	return module_ja.kana_to_romaji(rom, options)
end

local function format_historical_reading(reading, romanization, pos)
	if not reading then
		return ""
	end
	return '<sup>←' .. plain_link{ sozcuk = reading, c = romanization, soz = table.concat(pos, CONCAT_SEP) } .. '</sup>'
end

local function check(categories, reading_mod, reading_hist, reading_oldest)
	-- test if reading contains katakana
	if find(reading_mod .. (reading_hist or "") .. (reading_oldest or ""), '[ァ-ヺ]') then
		categories:insert('[[Kategori:Japonca girdi bakımı|1]]') -- sometimes legit, like 「頁(ページ)」
	end

	if reading_hist or reading_oldest then
		-- test if historical readings contain small kana (anachronistic)
		if find(reading_hist .. (reading_oldest or ""), '[ぁぃぅぇぉゃゅょ]') then
			categories:insert('[[Kategori:Japonca girdi bakımı|2]]') -- 
		end
		
		-- test if reading contains kun'yomi delimiter thing but historical readings don't
		if string.find(reading_mod, '%-') and
				(reading_hist and not string.find(reading_hist, '%-')		or
				reading_oldest and not string.find(reading_oldest, '%-'))	then
			categories:insert('[[Kategori:Japonca girdi bakımı|3]]')
		end
	end
end

local function add_category_gen(categories, sortkey)
	local str_gsub = string.gsub
	return function(reading, subtype, period)
		reading = str_gsub(str_gsub(reading, "[%. ]", ""), "%-$", "")
		if subtype then
			return categories:insert('[[Kategori:Japonca ' .. (period or '') .. ' ' .. subtype .. " " .. reading .. ' okunuşlu' ..
				' kanjiler' ..
				'|' .. sortkey .. ']]')
		else
			return categories:insert('[[Kategori:Japonca ' .. reading .. ' okunuşlu' ..
				' kanjiler|' .. sortkey .. ']]')
		end
	end
end

--[=[
		Copied from [[Modül:ja]] on 2017/6/14.
		Replaces the code in Template:ja-readings which accepted kanji readings,
		and displayed them in a consistent format.
		Substantial change in function was introduced in https://en.wiktionary.org/w/index.php?diff=46057625
]=]
function export.show(frame)
	local params = {
		["goon"] = {},
		["kanon"] = {},
		["toon"] = {},
		["soon"] = {},
		["on"] = {},
		["kanyoon"] = {},
		["kun"] = {},
		["nanori"] = {},
		["sayfaadı"] = {},
	}
	
	local args = require("Modül:parameters").process(frame:getParent().args, params)
	
	if args["sayfaadı"] then
		if namespace == "" then
			error("Maddelerde sayfaadı parametresi kullanılmamalı, bu parametre yalnızca test amaçlıdır.")
		end
		pagename = args["sayfaadı"]
	end

	local yomi_data = mw.loadData("Modül:ja/veri/jouyou-yomi").yomi

	local items = {
		goon = args["goon"],
		kanon = args["kanon"],
		toon = args["toon"],
		soon = args["soon"],
		on = args["on"],
		kanyoon = args["kanyoon"],
		kun = args["kun"],
		nanori = args["nanori"],
	}

	-- this holds the finished product composed of wikilinks to be displayed
	-- in the Readings section under the Kanji section
	local Array = require("Modül:dizi")
	local links = Array()
	local categories = Array()

	local is_old_format = false
	
	-- We need a separate kanji sortkey module.
	local sortkey = require("Modül:zh-sıraanahtarı").makeSortKey(pagename, "ja")
	local add_reading_category = add_category_gen(categories, sortkey)
	
	local unclassified_on = {}
	local classified_on = {}
	local kun = {}
			
	local kana = "[ぁ-ー]"
	
	for class, readings in pairs(items) do
		if readings then
			local label = labels[class]
			
			local unclassified = ""

			if label.unclassified then
				if not (items.goon or items.kanon or items.toon or items.soon or items.kanyoon) then
					unclassified = label.unclassified
				end
			end
			
			if find(readings, '%[%[' .. kana) then
				is_old_format = true

				if label.classification == 'on' then
					for reading in gmatch(readings, kana .. '+') do
						add_reading_category(reading)
					end
				end

				readings = string.gsub(
					readings,
					"%[%[([^%]|]+)%]%]",
					function(entry)
						if find(entry, "^[" .. Jpan:getirKarakterler() .. "]+$") then
							return plain_link{ sozcuk = entry  }
						else
							return "[[" .. entry .. "]]"
						end
					end
				)
			else
				readings = split(readings, ',%s*')

				for i, reading in ipairs(readings) do
					local is_jouyou = false

					local reading_mod, reading_hist, reading_oldest

					local gloss = ''

					local pos, pos_hist, pos_oldest = { }, { '[[w:Kana|geleneksel]]' }, { 'antik' }

					-- check for formatting indicating presence of historical kana spelling
					local hist_readings = mw.text.split(reading, "<")
					
					if #hist_readings <= 3 then
						reading_mod, reading_hist, reading_oldest = unpack(hist_readings)
					else
						error("Girilen " .. reading .. " okunuşta çok fazla geleneksel karakter mevcut: " .. #hist_readings .. ". En fazla 3 olabilir: modern, geleneksel, antik.")
					end
					
					if class == "on" then
						unclassified_on[reading_mod] = true
						table.insert(unclassified_on, reading_mod)
					elseif class == "kun" then
						kun[reading_mod] = true
						table.insert(kun, reading_mod)
					elseif label.classification == "on" then
						classified_on[reading_mod] = true
						table.insert(classified_on, reading_mod)
					end
					
					check(categories, reading_mod, reading_hist, reading_oldest)

					-- check if there is data indicating that our kanji is a jouyou kanji
					if yomi_data[pagename] then
						local reading = (label.classification == 'on' and module_ja.hira_to_kata(reading_mod) or reading_mod)
						reading = string.gsub(reading, '%.', '') -- 「あたら-し.い」→「あたら-しい」
						local type = yomi_data[pagename][reading]

						if type then
							is_jouyou = true

							if type == 1 or type == 2 then
								table.insert(pos, '[[w:Jōyō kanji|<abbr title="Bu okunuş Jōyō kanji tablosunda listelenmektedir. Jōyō kanji hakkındaki Vikipedi maddesini okumak için tıklayın.">Jōyō</abbr>]]')
							elseif type == 3 or type == 4 then
								table.insert(pos, '[[w:Jōyō kanji|<abbr title="Bu okunuş Jōyō kanji tablosunda listelenmektedir, ama sınırlı veya nadir olarak işaretlenmiş. Jōyō kanji hakkındaki Vikipedi maddesini okumak için tıklayın.">Jōyō <sup>†</sup></abbr>]]')
							end
						end
					end
					
					local subtype = label.text2
					if reading_mod then
						add_reading_category(reading_mod, subtype)
					end
					if reading_hist then
						add_reading_category(reading_hist, subtype, 'geleneksel')
					end
					if reading_oldest then
						add_reading_category(reading_oldest, subtype, 'antik')
					end
					
					local kanji, kanji_hist, kanji_oldest
					-- process kun readings with okurigana, create kanji-okurigana links
					if string.find(reading, '%-') then
						kanji = process_okurigana(reading_mod, pagename)
						table.insert(pos, 1, plain_link{ sozcuk = kanji })
						
						if kanji_hist then
							kanji_hist = process_okurigana(reading_hist, pagename)
							table.insert(pos_hist, 1, plain_link{ sozcuk = kanji_hist })
						end
						
						if kanji_oldest then
							kanji_oldest = process_okurigana(reading_oldest, pagename)
							table.insert(pos_oldest, 1, plain_link{ sozcuk = kanji_oldest })
						end
					elseif label.classification == 'kun' then
						categories:insert('[[Kategori:Japonca okurigana adı eksik olan kun okunuşlu kanjiler|' .. sortkey .. ']]')
					end

					local rom = make_romaji(reading_mod)
					local rom_hist = make_romaji(reading_hist, {hist=true})
					local rom_oldest = make_romaji(reading_oldest, {hist=true})
					
					local mod_link = plain_link{ sozcuk = reading_mod, c = rom, soz = table.concat(pos, CONCAT_SEP) }
					if is_jouyou then
						mod_link = '<mark style="background-color: rgb(224, 255, 255);">'
							.. mod_link .. '</mark>'
					end
					
					readings[i] =
						mod_link
						..
						format_historical_reading(reading_hist, rom_hist, pos_hist)
						..
						format_historical_reading(reading_oldest, rom_oldest, pos_oldest)
				end

				readings = table.concat(readings, '; ')
			end
			
			-- Add "on-yomi", "kun-yomi", or "nanori-yomi" class around list of
			-- readings to allow JavaScript to locate them.
			links[label.index] = "* '''[[" .. label.entry .. '|'.. label.text ..
				"]]'''" .. unclassified .. ': <span class="' ..
				label.classification .. '-yomi">' .. readings .. '</span>'
		end
	end
	
	for i, reading in ipairs(unclassified_on) do
		-- [[Special:WhatLinksHere/Template:tracking/ja-kanji-readings/duplicate reading]]
		if classified_on[reading] then
			track("duplicate reading")
		end
	end
	
	if is_empty(classified_on) and is_empty(unclassified_on) then
		if not is_empty(kun) then
			-- [[Special:WhatLinksHere/Template:tracking/ja-kanji-readings/kun only]]
			track("kun only")
		end
	elseif is_empty(kun) then
		-- [[Special:WhatLinksHere/Template:tracking/ja-kanji-readings/on only]]
		track("on only")
	end

	links = links:compress()
	
	--[==[
	-- determine if this is joyo kanji (常用) or jinmeiyo kanji (人名用) or neither (表外)
	local joyo_kanji_pattern = ('[' .. veri.joyo_kanji .. ']')
	local jinmeiyo_kanji_pattern = ('[' .. veri.jinmeiyo_kanji .. ']')
	local sortkey = ""
	if match(pagename, joyo_kanji_pattern) then
		sortkey = "Common"
	elseif match(pagename, jinmeiyo_kanji_pattern) then
		sortkey = "Names"
	else
		sortkey = "Uncommon"
	end
	]==]
	-- NOTE: with the introduction of the new {{ja-readings}} formatting the above block of code currently does nothing...

	if is_old_format then
		table.insert(links, '[[Kategori:Japonca eski ja-okunuş biçimini kullanan kanjiler|' .. sortkey .. ']]')
	end
	
	links = links:concat("\n")
	-- Categorize only in mainspace.
	if namespace == "" then
		categories = categories:concat("\n")
	else
		categories = ""
	end

	local output = links .. categories
	
	-- mw.log(output)
	
	return output
end

function export.parse_pagename(pagename)
	local kana_capture = "([-ぁ-ー𛀁𛀆]+)"
	
	local period, reading_type, reading = match(pagename, "^Japonca ([a-z]-) ?([%a']+) " .. kana_capture .. " okunuşlu kanjiler$")
	
	if not reading_type then
		reading = match(pagename, "^Japonca " .. kana_capture .. " okunuşlu kanjiler$")
	end
	
	if not reading then
		period, reading_type = match(pagename, "^Japonca ([a-z]-) ?([%a']+) okunuşuna göre kanjiler$")
	end
	
	period, reading_type, reading = if_not_empty(period), if_not_empty(reading_type), if_not_empty(reading)
	
	if not (period or reading_type or reading) then
		if namespace == "Modül" then
			return nil
		else
			error('"' .. pagename .. '" isimli kategori adı tanınmıyor.')
		end
	end
	
	local periods = {
		geleneksel = true,
		antik = true,
	}
	
	if period and not periods[period] then
		error('"' .. period .. '" periyot adı geçersiz.')
	end
	
	if reading_type == "geleneksel" or reading_type == "antik" then
		period = reading_type
		reading_type = nil
	end
	
	return { period = period, reading_type = reading_type, reading = reading }
end

local kanji_categories_mt = {}
kanji_categories_mt.__index = require("Modül:dizi")()
kanji_categories_mt.__index.add = function(self, postfix, sortkey)
	self:insert("[[Kategori:Japonca " .. postfix .. " kanjiler|" .. sortkey .. "]]")
end
function kanji_categories_mt:new()
	return setmetatable({}, self)
end

function export.get_catboiler_cats(pagename_info)
	local categories = kanji_categories_mt:new()
	
	-- This outcome is only reached in module namespace.
	-- Elsewhere, parse_pagename throws an error.
	if type(pagename_info) ~= "table" then
		return { nil }
	end
	
	local period, reading_type, reading =
		pagename_info.period, pagename_info.reading_type, pagename_info.reading
	
	local on_types = {
		["goon"] = true,
		["kan'on"] = true,
		["tōon"] = true,
		["sōon"] = true,
		["kan'yōon"] = true,
		["on"] = true,
	}
	
	local hira_sortkey
	
	local is_on_variant = false
	if reading_type and reading_type:find(".on$") then
		if not on_types[reading_type] then
			error('"' .. reading_type .. '" okunuşu bir on\'yomi tipi değil.')
		end
		is_on_variant = true
	end
	
	if not reading_type and period then
		reading_type = period
		period = nil
	end
	
	local period_text = period and period .. " " or ""
	
	-- If the pagename contains kana, it is a "with x reading" category; otherwise, it's a "by x reading" category.
	if reading then
		hira_sortkey = module_ja.jsort(reading)
		
		if reading_type then
			categories:add(period_text .. reading_type .. " okunuşuna göre", hira_sortkey)
			
			if is_on_variant then
				categories:add(period_text .. " on " .. reading .. " okunuşlu", reading_type)
			elseif period then
				categories:add(period_text .. reading .. " okunuşlu", reading_type)
			end
			
			if not period then
				categories:add(reading .. " okunuşlu", reading_type)
			end
		else
			categories:add("okunuşuna göre", hira_sortkey)
		end
	else
		if is_on_variant then
			categories:add(period_text .. " on okunuşuna göre", reading_type)
		else
			if period then
				categories:add(reading_type .. " okunuşuna göre", period)
			else
				categories:add("okunuşuna göre", reading_type)
			end
		end
		
		if period then
			categories:add(period_text .. "okunuşuna göre", reading_type)
		end
	end
	
	return categories
end

function export.hiyerasi(tum)
	local function ters(tbl)
		--bir string'i ters çevirmeye yarıyan fonksiyon
		for i=1, math.floor(#tbl / 2) do
			tbl[i], tbl[#tbl - i + 1] = tbl[#tbl - i + 1], tbl[i]
		end
	end
	
	local function ekle(t, ad)
		table.insert(t, "[[:Kategori:Japonca "..ad.." okunuşuna göre kanjiler|"
			..mw.getContentLanguage():ucfirst(ad).."]]")
	end
	
	--gerekli tabloları oluştur
	local tablo = {}

	local ebeveyn = "okunuşuna göre kanjiler"
	while ebeveyn and ebeveyn ~= "maddeler" do
		nesne = require("Modül:temalar").getirAsilAdaGore(ebeveyn)
		table.insert(tablo, "[[:Kategori:Japonca "..ebeveyn.."|"..nesne:getirAsilAd().."]]")
		ebeveyn = nesne:getirEbeveynler()[1]
	end
	
	--en başta her zaman ana kategoriler ve tüm diller kategorileri yer almalı
	table.insert(tablo, "[[:Kategori:Japonca|Japonca]]")
	table.insert(tablo, "[[:Kategori:Tüm diller|Tüm diller]]")
	table.insert(tablo, "[[:Kategori:Ana kategoriler|Ana kategoriler]]")
	
	ters(tablo)
	
	local pagename = mw.title.getCurrentTitle().text
	local info = export.parse_pagename(pagename)
	local label = labels[info.reading_type]
	
	if label and label.text ~= "On" and label.classification == "on" then
		ekle(tablo, "on")
	end
	if info.reading_type then
		ekle(tablo, label.text2)
	end
	if info.period then
		if label and label.text ~= "On" and label.classification == "on" then
			table.remove(tablo, #tablo)
			ekle(tablo, info.period.." on")
		end
		local period = info.reading_type and info.period .. " " .. label.text2 or info.period
		ekle(tablo, period)
	end
	if info.reading then
		local okunus = (info.period and info.period.." " or "")..
			(info.reading_type and info.reading_type.." " or "")..info.reading
		table.insert(tablo, "<span lang='ja' class='Hira'>"
			.."[[:Kategori:Japonca "..okunus.." okunuşlu kanjiler|"..info.reading.."]]</span>")
	end

	return "<p class=\"clearThis\"><small>" .. table.concat(tablo, " » ") .. "</small></p>"
end

function export.kategoriAgaci(tum)
	local output = require("Modül:dizi")()
	local catfix = ""
	
	local title = mw.title.getCurrentTitle()
	local pagename = title.text
	local namespace = title.nsText
	
	local testing_mode = false
	
	local pagename_info = export.parse_pagename(pagename)
	local categories = export.get_catboiler_cats(pagename_info)
	
	if pagename_info.reading and not testing_mode then
		-- Japanese kanji with on reading あつ, Japanese kanji with historical on reading あつ
		catfix = require("Modül:araçlar").catfix(ja, Jpan)
		tum.frame:callParserFunction("DISPLAYTITLE",
			require("Modül:string").plain_gsub(fullpagename,
				pagename_info.reading,
				'<span class="Jpan" lang="ja">%0</span>'))
	end
	
	local period = pagename_info.period
	
	local label = labels[pagename_info.reading_type]
	if not testing_mode and pagename_info.reading then
		output:insert(
			"Bu kategori " .. (period and period .. " " or "") ..
			(label and ("[[" .. label.entry .. "|".. mw.ustring.lower(label.text) .. "]] ") or "") ..
				plain_link{ sozcuk = pagename_info.reading, c = module_ja.kana_to_romaji(string.gsub(pagename_info.reading, '%-', ''), pagename_info.period and { hist = true }) } ..
				" okunuşlu [[kanji]] karakterlerini barındırmaktadır."
		)
	end

	if namespace ~= "Kategori" then
		error("Bu şablon yalnızca kategori alan adında kullanılmalıdır.")
	end
	
	if not testing_mode then
		local in_category
		if reading then
			in_category = mw.site.stats.pagesInCategory(pagename, "pages")
		else
			in_category = mw.site.stats.pagesInCategory(pagename, "subcats")
		end
		
		if in_category > 200 then
			output:insert(mw.getCurrentFrame():expandTemplate{title = "Şablon:Japonca içerik çizelgesi", args = {}})
		end
	end
	
	categories = categories:concat()
	
	if testing_mode then
		output:insert(pagename)
		
		categories = categories:gsub("%]%]%[%[", "]]\n[[")
		
		categories = tum.frame:extensionTag{ name = "syntaxhighlight", content = categories }
		if categories == "" then
			categories = '<span class="error">' .. pagename .. ' için kategoriler oluşturulamadı</span>'
		end
	end
	
	output = output:concat() .. categories .. ( mode ~= "texting" and catfix or "" )
	
	table.insert(tum.gor, output)
end

return export