模組:Zh-han
外观
local m_str_utils = require("Module:string utilities")
local codepoint = m_str_utils.codepoint
local find = m_str_utils.find
local get_section = require("Module:utilities").get_section
local gsub = m_str_utils.gsub
local sub = m_str_utils.sub
local m_links = require("Module:links")
local m_script_utils = require("Module:script utilities")
local export = {}
local PAGENAME = mw.loadData("Module:headword/data").pagename
local cangjie = {
A = "日", B = "月", C = "金", D = "木", E = "水", F = "火", G = "土", H = "竹", I = "戈", J = "十", K = "大", L = "中", M = "一", N = "弓", O = "人", P = "心", Q = "手", R = "口", S = "尸", T = "廿", U = "山", V = "女", W = "田", X = "難", Y = "卜", Z = "重"
}
local radicals = {
"一","丨","丶","丿","乙","亅",
"二","亠","人","儿","入","八","冂","冖","冫","几","凵","刀","力","勹","匕","匚","匸","十","卜","卩","厂","厶","又",
"口","囗","土","士","夂","夊","夕","大","女","子","宀","寸","小","尢","尸","屮","山","巛","工","己","巾","干","幺","广","廴","廾","弋","弓","彐","彡","彳",
"心","戈","戶","手","支","攴","文","斗","斤","方","无","日","曰","月","木","欠","止","歹","殳","毋","比","毛","氏","气","水","火","爪","父","爻","爿","片","牙","牛","犬",
"玄","玉","瓜","瓦","甘","生","用","田","疋","疒","癶","白","皮","皿","目","矛","矢","石","示","禸","禾","穴","立",
"竹","米","糸","缶","网","羊","羽","老","而","耒","耳","聿","肉","臣","自","至","臼","舌","舛","舟","艮","色","艸","虍","虫","血","行","衣","襾",
"見","角","言","谷","豆","豕","豸","貝","赤","走","足","身","車","辛","辰","辵","邑","酉","釆","里",
"金","長","門","阜","隶","隹","雨","靑","非",
"面","革","韋","韭","音","頁","風","飛","食","首","香",
"馬","骨","高","髟","鬥","鬯","鬲","鬼",
"魚","鳥","鹵","鹿","麥","麻",
"黃","黍","黑","黹",
"黽","鼎","鼓","鼠",
"鼻","齊",
"齒",
"龍","龜",
"龠"
}
local simplified_radical = {
['讠']='言',['门']='門',['饣']='食',['飞']='飛',['马']='馬',['见']='見',['贝']='貝',['纟']='糸',['车']='車',['长']='長',['韦']='韋',['风']='風',['钅']='金',['鸟']='鳥',['竜']='龍',['龙']='龍',['页']='頁',['斉']='齊',['齐']='齊',['麦']='麥',['亀']='龜',['龟']='龜',['鱼']='魚',['黾']='黽',['鼡']='鼠',['歯']='齒',['齿']='齒',['卤']='鹵',['𬺞']='龜',['丬']='爿',['黒']='黑',['黄']='黃',
}
local codes = {
c = '<small>(簡體中文)</small>', m = '<small>(中國大陸漢字)</small>',
j = '<small>(日本漢字)</small>', k = '<small>(韓國漢字)</small>'
}
-- Letters in "as" or "sn" parameter names follow these criteria:
-- There must be 1 or 2 of them.
-- They must be c, m, j, or k.
-- They must be in the order [cm]jk.
local function validate_letters(letters)
local letter_count = #letters
return letter_count == 3 and (letters == 'mjk' or letters == 'cjk')
or letter_count == 2 and (letters == 'jk' or letters == 'cj' or letters == 'mj')
or letter_count == 1 and codes[letters]
end
local function mul_link(term)
return m_links.full_link({lang = require('Module:languages').getByCode('zh'), term = term.."//", tr="-"})
end
local function radical(name,number,variant)
number = number or 1
local padleft = ("%03d"):format(number)
local text = '<div class="noprint" style="border:solid #aaa 1px;margin:0;font-size:74%;background:#f9f3f6;width:120px;padding:3px;spacing:0;text-align:center;float:right"><div style="float:left">[[Image:Commons-logo.svg|24px|none|link=Commons:Category:Radical ' .. padleft .. ']]</div>[[Commons:Category:Radical ' .. padleft .. "-0|參看關於<br>'''部首 " .. number .. " <big>" .. ((name and name ~= '') and PAGENAME or '※') .. "</big>''']]的圖片</div>"
if name == PAGENAME or (variant and variant ~= '') then
text = text .. '[[Category:漢字部首| ]]'
else
text = text .. '[[Category:派生漢字| ]]'
end
return text
end
function export.simp(frame)
local args = frame:getParent().args
local trad = args[1] or ''
if trad == '' then
trad = mw.loadData("Module:zh/data/st")[PAGENAME] or PAGENAME
end
local nocap = args['nocap'] or ''
local alt = args['a'] or ''
local from = {args['f'] or '',args['f2'] or ''}
local to = {args['t'] or '',args['t2'] or ''}
if from[1] == '' and to[1] ~= '' then from[1] = trad end
local text = {}
local result = ('「' .. mul_link(trad) .. '」')
if alt ~= '' then
result = result .. '和「' .. mul_link(alt) .. '」'
end
result = result .. '的簡化'
for i=1,2 do
if from[i] ~= '' then
if to[i] == '' then
table.insert(text,mul_link(from[i]) .. " → 一個無法單獨顯示的字[[分類:Kenny's testing category 3]]")
elseif to[i] == ' ' or to[i] == ' ' then
table.insert(text,'去除「' .. mul_link(from[i]) .. '」')
else
table.insert(text,mul_link(from[i]) .. ' → ' .. mul_link(to[i]))
end
end
end
if #text > 0 then
result = result .. '(' .. table.concat(text,' 和 ') .. ')'
result = result:gsub('」 ','」')
end
return result
end
-- NOTE: added 2023 Nov as a sanity check for {{Han ref}}
function export.cp()
return string.format('%.4X', codepoint(PAGENAME))
end
do
local function check_translingual_only()
for _, sec in pairs(mw.loadData("Module:headword/data").page.L2_sections) do
if sec ~= "跨語言" or sec~= "跨语言" then -- LOCALIZATION
return
end
end
require('Module:debug').track('zh-han/translingual-only character')
end
function export.character(frame)
local args = {}
for arg, val in pairs(frame:getParent().args) do -- Set empty args to nil.
if val ~= '' then
args[arg] = val
end
end
if radicals[tonumber(args['rn'])] ~= (simplified_radical[args['rad']] or args['rad']) then
error('Radical number (rn) and radical (rad) do not match')
end
local text = { insert = table.insert }
local categories = { insert = table.insert }
local as = tostring(tonumber(args['as'] or '-1'))
if as == '0' then
text:insert(radical(args['rad'], args['rn'], (args['var'] or '')))
end
-- Creating headword with [[Module:headword]] ensures that page title is script-tagged with Hani (generic Han).
-- This assumes that {{Han char}} is only used in Translingual sections.
local mul = require("Module:languages").getByCode("mul")
local Hani = require("Module:scripts").getByCode("Hani")
local sort_key = args['rad'] .. args['as'] .. PAGENAME
text:insert(
require("Module:headword").full_headword{
lang = mul,
sc = Hani,
heads = { args['head'] },
categories = {},
pos_category = "符號",
sort_key = sort_key,
}
)
text:insert("([[Appendix:部首索引/" .. (args['rad'] or '') .. '|-{' .. (args['rad'] or ' ') .. '}-部]]+' .. as .. "畫")
if args['asj'] then
text:insert("<small>(中文)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['asj']) .. "畫<small>(日本漢字)</small>")
end
if args['asc'] then
text:insert("<small>(繁體中文)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['asc']) .. "畫<small>(簡體中文)</small>")
end
if args['ask'] then
text:insert("<small>(中文)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['ask']) .. "畫<small>(韓國漢字)</small>")
end
if args['asjk'] then
text:insert("<small>(中文)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['asjk']) .. "畫<small>(日本漢字和韓國漢字)</small>")
end
if args['asj+'] then
text:insert("<small>(中文和韓國漢字)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['asj+']) .. "畫<small>(日本漢字)</small>")
end
if args['ask+'] then
text:insert("<small>(中文和日本漢字)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['ask+']) .. "畫<small>(韓國漢字)</small>")
end
if args['asc+'] then
text:insert("<small>(繁體中文和日本漢字)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['asc+']) .. "畫<small>(簡體中文)</small>")
end
if args['asc++'] then
text:insert("<small>(繁體中文、日本漢字和韓國漢字)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['asc++']) .. "畫<small>(簡體中文)</small>")
end
if args['ascj'] then
text:insert("<small>(繁體中文)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['ascj']) .. "畫<small>(簡體中文和日本漢字)</small>")
end
if args['ascj+'] then
text:insert("<small>(繁體中文和韓國漢字)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['ascj+']) .. "畫<small>(簡體中文和日本漢字)</small>")
end
if args['asm'] then
text:insert("<small>(繁體中文)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['asm']) .. "畫<small>(中國大陸漢字和日本漢字)</small>")
end
if args['asmj'] then
text:insert("<small>(繁體中文)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['asmj']) .. "畫<small>(中國大陸漢字和日本漢字)</small>")
end
if args['asmj+'] then
text:insert("<small>(繁體中文和韓國漢字)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['asmj+']) .. "畫<small>(中國大陸漢字和日本漢字)</small>")
end
if args['asm+'] then
text:insert("<small>(繁體中文和日本漢字)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['asm+']) .. "畫<small>(中國大陸漢字)</small>")
end
if args['asm++'] then
text:insert("<small>(繁體中文、日本漢字和韓國漢字)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['asm++']) .. "畫<small>(中國大陸漢字)</small>")
end
if args['ascjk'] then
text:insert("<small>(繁體中文)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['ascjk']) .. "畫<small>(簡體中文、日本漢字和韓國漢字)</small>")
end
if args['asmjk'] then
text:insert("<small>(繁體中文)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['asmjk']) .. "畫<small>(中國大陸漢字、日本漢字和韓國漢字)</small>")
end
if args['asmjk+'] then
text:insert("<small>(臺灣繁體中文)</small>或" .. ("-{" .. args['rad'] .. "}-部" or '') .. '+' .. tonumber(args['asmjk+']) .. "畫<small>(中國大陸及香港漢字、日本漢字和韓國漢字)</small>")
end
text:insert(",共" .. (args['sn'] or '') .. "畫")
-- To do: fix handling of multiple additional stroke numbers;
-- search query:
-- hastemplate:"Module:zh-han" insource:/\|sn[cmjk][cmjk]?\+*=[^|]+\|sn[cmjk][cmjk]?\+*=[^|]+/
if args['sn'] ~= '1' then
-- text:insert('s')
end
if args['snj'] then
text:insert("<small>(中文)</small>")
end
if args['snc'] then
text:insert("<small>(繁體中文)</small>")
end
if args['snk'] then
text:insert("<small>(中文)</small>")
end
if args['snjk'] then
text:insert("<small>(中文)</small>")
end
if args['snj+'] then
text:insert("<small>(中文和韓國漢字)</small>")
end
if args['snk+'] then
text:insert("<small>(中文和日本漢字)</small>")
end
if args['snc+'] then
text:insert("<small>(繁體中文和日本漢字)</small>")
end
if args['snc++'] then
text:insert("<small>(繁體中文、日本漢字和韓國漢字)</small>")
end
if args['sncj'] then
text:insert("<small>(繁體中文)</small>")
end
if args['sncj+'] then
text:insert("<small>(繁體中文和韓國漢字)</small>")
end
if args['snm'] then
text:insert("<small>(繁體中文)</small>")
end
if args['snmj'] then
text:insert("<small>(繁體中文)</small>")
end
if args['snmj+'] then
text:insert("<small>(繁體中文和韓國漢字)</small>")
end
if args['snm+'] then
text:insert("<small>(繁體中文和日本漢字)</small>")
end
if args['snm++'] then
text:insert("<small>(繁體中文、日本漢字和韓國漢字)</small>")
end
if args['sncjk'] then
text:insert("<small>(繁體中文)</small>")
end
if args['snmjk'] then
text:insert("<small>(繁體中文)</small>")
end
if args['snmjk+'] then
text:insert("<small>(臺灣繁體中文)</small>")
end
-- Find parameters specifying additional stroke numbers and add notes for
-- them.
for param_name, value in pairs(args) do
if type(param_name) == "string" then
local letters = param_name:match("^sn(%l+)%+*$")
if letters then
if validate_letters(letters) then
if value and value ~= '' then
local label = {}
for letter in letters:gmatch(".") do
table.insert(label, codes[letter]) -- Already checked that letters are valid.
end
label = table.concat(label, "和")
text:insert("或" .. value .. "畫")
if value ~= '1' then
-- text:insert('s')
end
text:insert("" .. label .. "")
end
else
require("Module:debug").track('zh-han/incorrect stroke number parameter')
-- return error("Unrecognized stroke number parameter name " .. param_name .. ".")
end
end
end
end
if args['canj'] then
local canj = args['canj']
local canj_split = mw.text.split(canj,',')
for i = 1, #canj_split do
if canj_split[i]:match('^%u+$') then
canj_split[i] = canj_split[i]:gsub('[%(%)]','')
-- LOCALIZATION
canj_split[i] = canj_split[i]:gsub('[A-Z]',cangjie) .. '([[Appendix:倉頡索引/' .. canj_split[i]:sub(1,1) .. '|' .. canj_split[i] .. ']])'
else
return error('The value of "canj" parameter is invalid.')
end
end
text:insert(",[[Appendix:倉頡索引|倉頡碼]]:-{" .. table.concat(canj_split,'或') .. "}-")
if #canj_split > 1 then
categories:insert("[[Category:有多個倉頡碼的漢字]]")
end
end
if args['four'] then
local four = args['four']
local four_split = mw.text.split(four,',')
for i=1,#four_split do
if not four_split[i]:match('[<>]') then
four_split[i] = four_split[i]:gsub('(%d)(%d%d%d)%.?(%d?)','[[Appendix:四角號碼索引/%1|%1%2<sub>%3</sub>]]')
else
return error('The value of "four" parameter is invalid.')
end
end
text:insert(",[[Appendix:四角號碼索引|四角號碼]]:" .. table.concat(four_split,'或'))
if #four_split > 1 then
categories:insert("[[Category:有多個四角號碼的漢字]]")
end
end
if args['ids'] then
local ids = args['ids']
local ids_split = mw.text.split(ids,',')
for i=1, #ids_split do
if not ids_split[i]:match('[%[%]]') then
if find(ids_split[i], '^[⿲⿳](.)%1%1$') then
categories:insert('[[Category:三疊字]]')
end
if find(ids_split[i], '^[⿰⿱](.)%1$') then
categories:insert('[[Category:二疊字]]')
end
local before = {}
ids_split[i] = gsub(ids_split[i], "([⺀-⻳ -〿アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヰヱヲン㇀-㇣〇一-鿿㐀-䶿﨎﨏﨑﨓﨔﨟﨡﨣﨤﨧-﨩𠀀-𪛟𪜀-𮯠𰀀-𲎯])",
function (character)
if not before[character] then
before[character] = true
return "[[" .. character .. "]]"
else
return character
end
end)
ids_split[i] = ids_split[i]:gsub("^(.-)%f[%(%z](.*)",
function(m1, m2)
local m1 = m_links.embedded_language_links{term = m1, lang = mul, sc = Hani}
m1 = m_script_utils.tag_text(m1, mul, Hani)
local letters = {
G = '<span class="explain" title="中國大陸">陸</span>',
H = '<span class="explain" title="香港">港</span>',
T = '<span class="explain" title="臺灣">臺</span>',
J = '<span class="explain" title="日本">日</span>',
K = '<span class="explain" title="韓國">韓</span>',
V = '<span class="explain" title="越南">越</span>'
}
return m1 .. "<small>" .. m2:gsub(".", letters) .. "</small>"
end)
end
end
text:insert(",[[w:漢字部件|部件組合]]:-{" .. table.concat(ids_split,'或'):gsub('%(','('):gsub('%)',')') .. "}-")
if #ids_split > 1 then
categories:insert("[[Category:有多種組合描述字符的漢字]]")
end
end
text:insert(')')
if args['rad'] then
if mw.title.getCurrentTitle().nsText == '' then
categories:insert("[[Category:漢字字元|" .. sort_key .. "]]")
end
else
if mw.title.getCurrentTitle().nsText == '' then
categories:insert("[[Category:沒有rad參數的漢字]]")
end
end
local params_to_check = { "as", "rn", "sn", "canj" }
local sortkey = args['rad'] and "|" .. args['rad'] or ""
-- LOCALIZATION
if not args['ids'] or args['ids'] == '' then
categories:insert("[[Category:沒有表意文字描述字符的漢字" .. sortkey .. "]]")
end
if not args['four'] or args['four'] == '' then
categories:insert("[[Category:沒有四角號碼的漢字" .. sortkey .. "]]")
end
for _, param in pairs(params_to_check) do
if not args[param] or args[param] == '' then
categories:insert("[[Category:沒有" .. param .. "參數的漢字" .. sortkey .. "]]")
end
end
if type(args['sn']) == "string" and sub(args['sn'],1,1) == '0' then
return error('Please remove leading zeros from the "sn" parameter.')
end
check_translingual_only()
if (get_section(mw.title.getCurrentTitle():getContent(), "跨語言") or get_section(mw.title.getCurrentTitle():getContent(), "跨语言") or ""):match("%f[^%z\n\r]#[ \t]*%S") then
categories:insert("[[Category:有定義行的跨語言漢字" .. sortkey .. "]]")
end
return table.concat(text) .. table.concat(categories)
end
end
return export