模組:Kanjitab
本模組產生{{ja-kanjitab}}
的内容。
測試樣例
詞中漢字 |
---|
懐 |
なつ 常用漢字 |
訓讀 |
其他表記 |
---|
懷かしい (舊字體) |
詞中漢字 | |
---|---|
取 | 締 |
と(り) 三年級 |
し(まり) 常用漢字 |
訓讀 |
詞中漢字 | |
---|---|
日 | 付 |
ひ 一年級 |
つ(け) > づ(け) 四年級 |
訓讀 |
詞中漢字 | |
---|---|
関 | 係 |
かん 四年級 |
けい 三年級 |
漢音 |
其他表記 |
---|
關係 (舊字體) |
詞中漢字 | |
---|---|
東 | 京 |
とう 二年級 |
きょう 二年級 |
漢音 | 吳音 |
詞中漢字 | |||
---|---|---|---|
大 | 和 | 言 | 葉 |
やまと | こと 二年級 |
は > ば 三年級 | |
一年級 | 三年級 | ||
熟字訓 | 訓讀 |
詞中漢字 | |||
---|---|---|---|
滅 | 茶 | 苦 | 茶 |
め 常用漢字 (借字) |
ちゃ 二年級 (借字) |
く 三年級 (借字) |
ちゃ 二年級 (借字) |
不規則 | 慣用 | 吳音 | 慣用 |
詞中漢字 | |||||||||
---|---|---|---|---|---|---|---|---|---|
阿 | 弗 | 利 | 加 | 系 | 亜 | 米 | 利 | 加 | 人 |
あ 人名用漢字 (借字) |
ふつ > ふ 表外字 (借字) |
り 四年級 (借字) |
か 四年級 (借字) |
けい 六年級 |
あ 常用漢字 (借字) |
め 二年級 (借字) |
り 四年級 (借字) |
か 四年級 (借字) |
じん 一年級 |
音讀 | 不規則 | 音讀 | 漢音 | 漢音 | 漢音 | 不規則 | 音讀 | 漢音 | 漢音 |
其他表記 |
---|
阿弗利加系亞米利加人 (舊字體) |
{{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")
local show_labels = require("Module:labels").show_labels
--[=[
Other modules used: [[Module:parameters]]
]=]
local title = mw.title.getCurrentTitle()
local PAGENAME = mw.loadData("Module:headword/data").pagename
local NAMESPACE = title.nsText
local d_range = mw.loadData'Module:ja/data/range'
local kanji_grade_links = {
"[[:w:教育漢字|一年級]]",
"[[:w:教育漢字|二年級]]",
"[[:w:教育漢字|三年級]]",
"[[:w:教育漢字|四年級]]",
"[[:w:教育漢字|五年級]]",
"[[:w:教育漢字|六年級]]",
"[[:w:常用漢字|常用漢字]]", -- 7
"[[:w:人名用漢字|人名用漢字]]", -- 8
"[[:w:en:Hyōgai kanji|表外字]]" -- 9
}
local function quote(text)
return "“" .. text .. "”"
end
-- this is the function that is called from templates
function export.show(frame)
local args = require("Module:parameters").process(frame:getParent().args, {
[1] = { list = true, allow_holes = true },
k = { list = true, allow_holes = true },
o = { list = true, allow_holes = true },
r = {},
sort = {},
yomi = {},
ateji = {},
alt = {},
alt2 = {},
kyu = { list = true },
y = {alias_of = 'yomi'},
clearright = {type = "boolean"},
pagename = {},
})
local lang_code = frame.args[1]
local lang = require("Module:languages").getByCode(lang_code)
local lang_name = lang:getCanonicalName()
if args.pagename and NAMESPACE == "" then
require'Module:debug'.track'kanjitab/pagename param in mainspace'
end
local pagename = args.pagename or PAGENAME
local categories = {}
local cells = {}
-- extract kanji and non-kanji
local kanji = {}
local non_kanji = {}
local kanji_border = 1
mw.ustring.gsub(pagename, '()([' .. d_range.kanji .. '々])()', function(p1, w1, p2)
table.insert(non_kanji, mw.ustring.sub(pagename, kanji_border, p1 - 1))
kanji_border = p2
table.insert(kanji, w1)
end)
table.insert(non_kanji, mw.ustring.sub(pagename, kanji_border))
-- kyujitai
local kyu = args.kyu
if kyu[1] == '-' then
kyu = {}
elseif kyu[1] == nil then
local form_kyu = {non_kanji[1]}
local kyu_data = mw.loadData('Module:ja/data/kyu')
local has_kyu, has_kyu_nonsupple, has_shin = false, false, false
for i, v in ipairs(kanji) do
local v_kyu = kyu_data[1]:match(v .. '(%S*)%s')
if v_kyu == nil then
table.insert(form_kyu, v)
elseif v_kyu == '' then
has_shin = true
break
elseif v_kyu:sub(1, 1) == '&' then
has_kyu = true
table.insert(form_kyu, v_kyu)
else
has_kyu, has_kyu_nonsupple = true, true
table.insert(form_kyu, v_kyu)
end
table.insert(form_kyu, non_kanji[i + 1])
end
if not has_shin and has_kyu then
kyu[1] = (has_kyu_nonsupple and '' or pagename .. '|') .. table.concat(form_kyu)
end
if pagename:match'弁' then
require'Module:debug'.track'kanjitab/ambiguous kyujitai for 弁'
kyu[1] = 'which 弁?'
end
end
-- 々
for i, v in ipairs(kanji) do
if v == '々' then kanji[i] = kanji[i - 1] end
end
-- process readings
local readings = {}
local readings_actual = {}
local reading_length_total = 0
for i = 1, args[1].maxindex do
local reading_kana, reading_length
_, _, reading_kana, reading_length = mw.ustring.find(args[1][i] or '', '^([^0-9]*)([0-9]*)$')
reading_kana = reading_kana ~= "" and reading_kana or nil
reading_length = reading_kana and tonumber(reading_length) or 1
table.insert(readings, {reading_kana, reading_length})
reading_length_total = reading_length_total + reading_length
end
if reading_length_total > #kanji then
error('Readings for ' .. reading_length_total .. ' kanji are given, but this word has only ' .. #kanji .. ' kanji.')
else
for i = reading_length_total + 1, #kanji do table.insert(readings, {nil, 1}) end
end
local table_head = [=[
{| class="wikitable kanji-table" style="text-align: center; font-size: small; float: right;]=] .. (args.clearright and ' clear:right;' or '') .. [=["
! ]=] .. (#kanji > 1 and 'colspan="' .. #kanji .. '" ' or '') .. [=[style="font-weight: normal;" | 詞中[[漢字]]
|- lang="]=] .. lang_code .. [=[" 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
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',
soon = 'soon',
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',
n = 'nanori', nanori = 'nanori',
[''] = '', none = '',
}
for i in mw.text.gsplit(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 })
-- If the on'yomi is not specified as goon/kanon/toon/soon, only 'on'
if a == 'on' then
require'Module:debug'.track'kanjitab/unspecified on'
end
if (a == "jūbakoyomi" or a == "yutōyomi") and #kanji ~= 2 then
error'yutou or juubako is only applicable to 二字熟語'
end
end
if #yomi == 1 and #kanji > 1 then
yomi[1][2] = #kanji
end
elseif #kanji > 0 then
require'Module:debug'.track'kanjitab/no yomi'
end
if args.k.maxindex and args.k.maxindex > args[1].maxindex then
error'kanjitab/too many k'
end
if args.o.maxindex and args.o.maxindex > args[1].maxindex then
error'kanjitab/too many o'
end
local yomi_type_by_kanji = {}
if yomi then
for i = 1, #yomi do
for j = 1, yomi[i][2] do
table.insert(yomi_type_by_kanji, yomi[i][1])
end
end
else
for i = 1, #kanji do
table.insert(yomi_type_by_kanji, '')
end
end
local is_ateji = {}
if args.ateji then
local ateji = args.ateji
local cat_ateji = false
if ateji == 'y' then
for i = 1, #kanji do
is_ateji[i] = true
end
cat_ateji = true
else
for i in mw.text.gsplit(ateji, ';') do
string.gsub(i, '^([0-9]+)$', function(a)
is_ateji[tonumber(a)] = true
cat_ateji = true
end)
string.gsub(i, '^([0-9]+),([0-9]+)$', function (a, b)
for j = tonumber(a), tonumber(b) do
is_ateji[j] = true
end
cat_ateji = true
end)
end
end
if cat_ateji then table.insert(categories, "有借字的" .. lang_name .. "詞") 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
local cells_above = {}
local cells_below = {}
local kanji_pos = 1
for i, reading in ipairs(readings) do
local reading_kana, reading_length = reading[1], reading[2]
local cell = {}
if reading_length <= 1 then
table.insert(cell, '| rowspan="2" | ')
else
table.insert(cell, '| colspan ="' .. reading_length .. '" | ')
end
-- display reading, actual reading and okurigana
if reading_kana then
if reading_kana ~= '' and mw.ustring.match(reading_kana, '[^' .. d_range.kana .. ']') then
require'Module:debug'.track'kanjitab/not all kana'
end
local actual_reading = args.k[i]
local okurigana = args.o[i]
local okurigana_text = okurigana and "(" .. okurigana .. ")" or ""
local actual_reading_text = actual_reading and " > " .. actual_reading .. okurigana_text or ""
local text = reading_kana .. okurigana_text .. actual_reading_text
readings_actual[i] = {(actual_reading or reading_kana) .. (okurigana or ''), reading_length}
table.insert(cell, '<span class="Jpan" lang="' .. lang_code .. '">' .. text .. '</span>')
if reading_length <= 1 then table.insert(cell, '<br/>') end
else
readings_actual[i] = {nil, 1}
end
-- display kanji grade, categorize
for j = kanji_pos, kanji_pos + reading_length - 1 do
local single_kanji = kanji[j]
local kanji_grade = m_ja.kanji_grade(single_kanji)
local ateji_text = is_ateji[j] and '<br/><small>([[Appendix:日語術語表#借字|借字]])</small>' or ''
if reading_kana then
-- subcategorize by reading if this is joyo kanji, not doing that for less common kanji, with exceptions
if (kanji_grade < 8 or (
'厭昌之芽昌浩智晃淳敦聡晃旭亮糊桂隘阿唖撫鼠阿耘迂寅已伊餡姦闊礙碍凱亥价謳嘔齧日臣桶抉兎鵜卯綾飴焙肋鮫頚糞軋烏痒捷辰叩橙揃嶋澤菱彦囃覗呑之乃鼠做寅樋堤槌机杖頼辿哉叢狢峯巳卍鱒仄他惚弘宏燕倦經痙圭禽僑鋸醵墟屹綺几翫癌劫膠昂鹸牽喧餐鑽瑣些渾梱坤國壕誦哨蒐杓爾梓荼楕躁綜楚闡閃撰專泄藉棲錘錐祷盪淘點顛填擲擢闖厨蛋潭腿冪碧劈焚祓弗憑誹砒婢挽拔撥剥胚播乃狼牢蓮礫醂龍榴蕾酉祐佑耶也蔓曼沫邁呆硼牡甫步矮狸苔'
):find(single_kanji)) and yomi_type_by_kanji[j] ~= 'irregular' and yomi_type_by_kanji[j] ~= 'jukujikun' and reading_length == 1 then
table.insert(categories, "寫作「".. single_kanji .. "」讀作「" .. reading_kana .. "」的" .. lang_name .. "詞")
else
table.insert(categories, "帶「" .. single_kanji .. "」的".. lang_name .. "詞")
end
else
if yomi_type_by_kanji[j] ~= 'irregular' and yomi_type_by_kanji[j] ~= 'jukujikun' then
require'Module:debug'.track'kanjitab/no reading'
end
table.insert(categories, "帶「" .. single_kanji .. "」的".. lang_name .. "詞")
end
if reading_length <= 1 then
table.insert(cell, "<small>" .. kanji_grade_links[kanji_grade] .. "</small>" .. ateji_text)
else
table.insert(cells_below, "| <small>" .. kanji_grade_links[kanji_grade] .. "</small>" .. ateji_text)
end
end
table.insert(cells_above, table.concat(cell))
kanji_pos = kanji_pos + reading_length
end
table.insert(cells, '|- style="background: white;"')
if #cells_below > 0 then
table.insert(cells, table.concat(cells_above, '\n'))
table.insert(cells, '|- style="background: white;"')
table.insert(cells, table.concat(cells_below, '\n'))
else
for i, v in ipairs(cells_above) do
cells_above[i] = v:gsub('| rowspan="2" | ', '| ')
end
table.insert(cells, table.concat(cells_above, '\n'))
end
local yomi_info = {
["on"] = {
text = "音讀",
entry = "音読み",
category = "使用音讀的" .. lang_name .. "詞",
},
["kun"] = {
text = "訓讀",
entry = "訓読み",
category = "使用訓讀的" .. lang_name .. "詞",
},
["goon"] = {
text = "吳音",
entry = "呉音",
category = "使用音讀的" .. lang_name .. "詞",
},
["kanon"] = {
text = "漢音",
entry = "漢音",
category = "使用音讀的" .. lang_name .. "詞",
},
["soon"] = {
text = "宋音",
entry = "宋音",
category = "使用音讀的" .. lang_name .. "詞",
},
["toon"] = {
text = "唐音",
entry = "唐音",
category = "使用音讀的" .. lang_name .. "詞",
},
["kun"] = {
text = "訓讀",
entry = "訓読み",
category = "使用訓讀的" .. lang_name .. "詞",
},
["nanori"] = {
text = "名乘",
entry = "名乗り",
category = "使用名乘的" .. lang_name .. "詞",
},
["yutōyomi"] = {
text = "湯桶讀法",
entry = "湯桶読み",
category = "使用湯桶讀法的" .. lang_name .. "詞",
},
["jūbakoyomi"] = {
text = "重箱讀法",
entry = "重箱読み",
category = "使用重箱讀法的" .. lang_name .. "詞",
},
["jukujikun"] = {
text = "熟字訓",
entry = "熟字訓",
category = "使用熟字訓的" .. lang_name .. "詞",
},
["irregular"] = {
text = "不規則",
category = "漢字讀音不規則的" .. lang_name .. "詞",
},
["kanyoon"] = {
text = "慣用",
entry = "慣用音",
category = "使用慣用音的" .. lang_name .. "詞",
},
}
local rendaku = args.r
if rendaku then
table.insert(categories, "有連濁的" .. lang_name .. "詞")
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, soon = 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[1][1] == 'jūbakoyomi' or yomi[1][1] == 'yutōyomi' then
table.insert(categories, yomi_info[yomi[1][1]].category)
else
local all_yomi_of_same_type = true
for i = 2, #yomi do
if yomi[i][1] ~= yomi[1][1] then all_yomi_of_same_type = false; break end
end
if all_yomi_of_same_type then
table.insert(categories, yomi_info[yomi[1][1]].category)
elseif #yomi == 2 and yomi[1][2] == 1 and yomi[2][2] == 1 and mw.ustring.len(pagename) == 2 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
end
local kanji_table
if #kanji > 0 then
kanji_table = table_head
for _, v in ipairs(kanji) do
kanji_table = kanji_table .. '| style="padding: 0.5em;" | [[' .. v .. '#' .. lang_name .. '|-{' .. v .. '}-]]\n'
-- 禁止下面的分类里的汉字被转换
string.format("-{H|「%s」=>zh-hans:“%s”}--{H|「%s」=>zh-hant:「%s」}-\n", v, v, v, v)
end
kanji_table = kanji_table .. table.concat(cells, '\n') .. '\n|}'
else
kanji_table = ''
end
local forms_table = ""
if args.alt == '' or args.alt == '-' then args.alt = nil end
if kyu[1] or args.alt then
local forms = {}
-- |kyu=
if kyu[1] == 'which 弁?' then
table.insert(forms, '<strong class="error" style="font-size:75%;">Please specify the correct kyujitai for 弁 with the parameter "kyu".</strong>[[Category:Requests for cleanup in ' .. lang_name .. ' entries]]')
table.remove(kyu, 1)
end
for _, form in ipairs(kyu) do
local form_linkto, form_display = form:match'^(.+)|(.+)$'
if not form_linkto then form_linkto, form_display = form, form end
table.insert(forms, table.concat{
'<span class="Jpan" lang="' .. lang_code .. '" style="font-family:游ゴシック, HanaMinA, sans-serif; font-size:140%;">[[',
form_linkto,
form_linkto == pagename and '|' or '#' .. lang_name .. '|',
"-{" , form_display, "}-",
']]</span> <small>',
show_labels {labels = {'舊字體'}, lang = lang, nocat = true },
'</small>',
})
end
-- |alt=
if args.alt then
for form in mw.text.gsplit(args.alt, ',') do
local i_semicolon = string.find(form, ':')
if i_semicolon then
local altform = string.sub(form, 1, i_semicolon - 1)
local altlabels = mw.text.split(string.sub(form, i_semicolon + 1), ' ')
table.insert(forms, table.concat{
'<span class="Jpan" lang="' .. lang_code .. '" style="font-size:140%">[[',
altform,
'#' .. lang_name .. '|-{<!---->',
altform,
'<!---->}-]]</span> <small>',
show_labels { labels = altlabels, lang = lang, nocat = true },
'</small>',
})
else
table.insert(forms, table.concat{
'<span class="Jpan" lang="' .. lang_code .. '" style="font-size:140%">[[',
form,
'#' .. lang_name .. '|-{<!---->',
form,
'<!---->}-]]</span>'
})
end
end
end
forms_table = '\n' .. [[{| class="wikitable floatright"
! style="font-weight:normal" | 其他表記]] .. [[
|-
| style="text-align:center;font-size:108%" | ]] .. table.concat(forms, '<br>') .. '\n|}'
end
local forms_table2 = ""
if args.alt2 and args.alt2 ~= "" and args.alt2 ~= "-" then
local forms2 = {}
for form in mw.text.gsplit(args.alt2, ',') do
table.insert(forms2, '<span class="Jpan" lang="' .. lang_code .. '">[[' .. form .. '#' .. lang_name .. '|' .. form .. ']]</span>')
end
forms_table2 = '\n' .. [[{| class="wikitable floatright"
! style="font-weight:normal" | Variant form]] .. (#forms2 == 1 and "" or "s") .. '\n' .. [[
| style="text-align:center;font-size:140%" | ]] .. table.concat(forms2, '<br>') .. '\n|}'
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 sortkey
if args.sort then
sortkey = args.sort
else
sortkey = {non_kanji[1]}
local id = 1
for _, v in ipairs(readings_actual) do
id = id + v[2]
table.insert(sortkey, (v[1] or '') .. (non_kanji[id] or ''))
end
sortkey = table.concat(sortkey)
end
if sortkey == "" then
sortkey = nil
else
sortkey = lang:makeSortKey(sortkey)
end
if sortkey ~= lang:makeSortKey(PAGENAME) then
require("Module:debug/track"){"kanjitab/nonstandard sortkey", "kanjitab/nonstandard sortkey/" .. lang_code}
end
return kanji_table .. forms_table .. forms_table2 .. m_utilities.format_categories(categories, lang, sortkey)
end
return export