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("Module:scripts").getByCode
local Jpan = get_script_by_code("Jpan")
-- local katakana_script = get_script_by_code("Kana")
local hiragana_script = get_script_by_code("Hira")
local ryu = require("Module:languages").getByCode("ryu")
local module_ryu = require("Module:ryu")
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
-- Only used by commented-out code.
-- local data = mw.loadData("Module:ryu/data")
local CONCAT_SEP = ', '
export.labels = {
goon = {
index = 1,
entry = "呉音",
text = "吳音",
text2 = "goon",
classification = "on",
},
kanon = {
index = 2,
entry = "漢音",
text = "漢音",
text2 = "kan'on",
classification = "on",
},
toon = {
index = 3,
entry = "唐音",
text = "唐音",
text2 = "tōon",
classification = "on",
},
soon = {
index = 4,
entry = "宋音",
text = "宋音",
text2 = "sōon",
classification = "on",
},
kanyoon = {
index = 5,
entry = "慣用音",
text = "慣用音",
text2 = "kan'yōon",
classification = "on",
},
on = {
index = 6,
entry = "音読み",
text = "音讀",
text2 = "on",
classification = "on",
unclassified = "(未分類)",
},
kun = {
index = 7,
entry = "訓読み",
text = "訓讀",
text2 = "kun",
classification = "kun",
},
nanori = {
index = 8,
entry = "名乗り",
text = "名乘",
text2 = "nanori",
classification = "nanori",
},
}
export.accented_labels_to_labels = {}
for k, v in pairs(export.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("Module:debug").track("ryu-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.characters .. ']+$') ~= 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
function export.plain_link(data)
data.term = string.gsub(data.term, '[%.%- ]', '') -- 「かな-し.い」→「かなしい」, 「も-しく は」→「もしくは」
if data.tr then
data.tr = string.gsub(data.tr, '[%.%-]', '')
end
data.lang = ryu
data.sc = export.get_script(data.alt or data.term)
data.pos = if_not_empty(data.pos)
data.gloss = if_not_empty(data.gloss)
return require("Module:links").full_link(data, "term") --"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_ryu.kana_to_romaji(rom, options)
end
local function format_historical_reading(reading, romanization, pos)
if not reading then
return ""
end
return '<sup>←' .. export.plain_link{ term = reading, tr = romanization, pos = 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('[[Category:需要注意的沖繩語詞|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('[[Category:需要注意的沖繩語詞|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('[[Category:需要注意的沖繩語詞|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('[[Category:' ..
(period or '') .. subtype .. '讀作「' .. reading ..
'」的沖繩語漢字|' .. sortkey .. ']]')
else
return categories:insert('[[Category:讀作「' ..
reading .. '」的沖繩語漢字|' .. sortkey .. ']]')
end
end
end
--[=[
Copied from [[Module: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"] = {},
["pagename"] = {},
}
local args = require("Module:parameters").process(frame:getParent().args, params)
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
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("Module:array")
local links = Array()
local categories = Array()
local is_old_format = false
-- We need a separate kanji sortkey module.
local sortkey = require("Module:zh-sortkey").makeSortKey(pagename, "ryu")
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 = export.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:getCharacters() .. "]+$") then
return export.plain_link{ term = 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:历史假名遣|历史假名遣]]' }, { 'ancient' }
-- 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("The reading " .. reading .. " contains too many historical readings: " .. #hist_readings .. ". The maximum is 3: modern, historical, ancient.")
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)
local subtype = label.text --<en>label.text2
if reading_mod then
add_reading_category(reading_mod, subtype)
end
if reading_hist then
add_reading_category(reading_hist, subtype, '歷史假名遣')
end
if reading_oldest then
add_reading_category(reading_oldest, subtype, '古沖繩語')
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, export.plain_link{ term = kanji })
if kanji_hist then
kanji_hist = process_okurigana(reading_hist, pagename)
table.insert(pos_hist, 1, export.plain_link{ term = kanji_hist })
end
if kanji_oldest then
kanji_oldest = process_okurigana(reading_oldest, pagename)
table.insert(pos_oldest, 1, export.plain_link{ term = kanji_oldest })
end
elseif label.classification == 'kun' then
categories:insert('[[Category:有訓讀但缺少振假名的沖繩語漢字|' .. sortkey .. ']]')
end
local rom = make_romaji(reading_mod)
local rom_hist = make_romaji(reading_hist, {hist=true})
local rom_oldest = make_romaji(reading_oldest, {anc=true})
local mod_link = export.plain_link{ term = reading_mod, tr = rom, pos = table.concat(pos, CONCAT_SEP) }
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 = ('[' .. data.joyo_kanji .. ']')
local jinmeiyo_kanji_pattern = ('[' .. data.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, '[[Category:使用舊參數形式的沖繩語漢字|' .. sortkey .. ']]')
end
links = links:concat("\n")
-- Categorize only in mainspace.
if namespace == "" then
categories = categories:concat("\n")
else
categories = ""
end
local output = links .. categories ..
require("Module:TemplateStyles")("Template:ja-readings/style.css")
-- mw.log(output)
return output
end
function export.parse_pagename(pagename)
local kana_capture = "([-ぁ-ー𛀁]+)"
local period, reading_type, reading = match(pagename, "^(.-[遣語])([^作]-)讀作「" .. kana_capture .. "」的沖繩語漢字$")
if not reading_type then
reading = match(pagename, "^([^作]*)讀作「" .. kana_capture .. "」的沖繩語漢字$")
end
if not reading then
period, reading_type = match(pagename, "^讀作「" .. kana_capture .. "」的沖繩語漢字$")
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 == "Module" then
return nil
else
error('The category name "' .. pagename .. '" is not recognized.')
end
end
local periods = {
historical = true,
ancient = true,
}
if period and not periods[period] then
error('The period name "' .. period .. '" is not valid.')
end
return { period = period, reading_type = reading_type, reading = reading }
end
local kanji_categories_mt = {}
kanji_categories_mt.__index = require("Module:array")()
kanji_categories_mt.__index.add = function(self, postfix, sortkey)
self:insert("[[Category:" .. postfix .. "的沖繩語漢字|" .. 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 = {
["呉音"] = true,
["漢音"] = true,
["唐音"] = true,
["宋音"] = true,
["慣用音"] = true,
["音讀"] = true,
}
local hira_sortkey
local is_on_variant = false
if reading_type and reading_type:find("(音|音讀)$") then
if not on_types[reading_type] then
error('"' .. reading_type .. '" is not a valid type of on\'yomi.')
end
is_on_variant = true
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 .. "分類", hira_sortkey) --<en>by, reading
if is_on_variant then
categories:add(period_text .. "音讀讀作「" .. reading .. "」", reading_type) --<en>with, on reading
elseif period then
categories:add(period_text .. "讀作「" .. reading .. "」", reading_type) --<en>with, reading
end
if not period then
categories:add("讀作「" .. reading .. "」", reading_type) --<en>read as
end
else
categories:add("依讀音分類", hira_sortkey) --<en>by reading
end
else
if is_on_variant then
categories:add("依" .. period_text .. "音讀分類", reading_type) --<en>by, on reading
else
if period then
categories:add("依" .. reading_type .. "分類", period) --<en>by, reading
else
categories:add("依讀音分類", reading_type) --<en>by reading
end
end
if period then
categories:add("依" .. period_text .. "讀音分類", reading_type) --<en>by, reading
end
end
return categories
end
function export.catboiler(frame)
local output = require("Module:array")()
local catfix = ""
local title = mw.title.getCurrentTitle()
local pagename = title.text
local namespace = title.nsText
local testing_mode = false
-- formerly used on documentation page
if frame.args[1] then
pagename = frame.args[1]
pagename = string.gsub(pagename, "^Category:", "")
namespace = "Category"
testing_mode = true
end
local pagename_info = export.parse_pagename(pagename)
local categories = export.get_catboiler_cats(pagename_info)
if pagename_info.reading and not testing_mode then
-- Okinawan kanji with on reading あつ, Okinawan kanji with historical on reading あつ
catfix = require("Module:utilities").catfix(ryu, Jpan)
frame:callParserFunction("DISPLAYTITLE",
require("Module:string").plain_gsub(fullpagename,
pagename_info.reading,
'<span class="Jpan" lang="ryu">%0</span>'))
end
local label = export.labels[pagename_info.reading_type]
if label and not testing_mode and pagename_info.reading then
output:insert(
"此分類包含具有" .. (period and period .. " " or "") ..
"[[" .. label.entry .. "|".. mw.ustring.lower(label.text) .. "]]讀音的沖繩語[[漢字]]" ..
export.plain_link{ term = pagename_info.reading, tr = module_ja.kana_to_romaji(string.gsub(pagename_info.reading, '%-', ''), pagename_info.period and { hist = true }) } ..
"."
)
end
if namespace ~= "Category" then
error("This template should only be used in the Category namespace.")
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 = "Template:ryu-categoryTOC", args = {}})
end
end
categories = categories:concat()
if testing_mode then
output:insert(pagename)
categories = categories:gsub("%]%]%[%[", "]]\n[[")
categories = frame:extensionTag{ name = "syntaxhighlight", content = categories }
if categories == "" then
categories = '<span class="error">failed to generate categories for ' .. pagename .. '</span>'
end
end
output = output:concat() .. categories .. ( mode ~= "texting" and catfix or "" )
return output
end
return export