| 此模块基于Lua语言实现,依赖以下模块: |
此模块可以在Lua阶段实现字词转换,但不支持手工转换。
--[[
Module:ZhConversion - Lua 实现的汉字转换模块
本模块提供使用 MediaWiki 转换表的汉字变体转换功能
(ZhConversion.php 兼容)
支持:
- to_cn: zh-cn
- to_hans: zh-hans
- to_tw: zh-tw
- to_hk: zh-hk
- to_hant: zh-hant
转换策略(按优先级):
1. 全站转换表(MediaWiki:Conversiontable/* 页面)
2. MediaWiki 内建转换(ZhConversion.php)
]]
local p = {}
local siteTableCache = {}
-- 加载内建转换表(从数据文件)
local BUILTIN_TABLES = mw.loadData('Module:ZhConversion/data')
-- 辅助函数:合并转换表
local function merge(a, b)
for k, v in pairs(b) do
a[k] = v
end
end
-- 加载全站转换表(覆盖内建表)
local function loadConversionTable(variant)
if siteTableCache[variant] then
return siteTableCache[variant]
end
-- 初始化转换表
local merged_table = {}
-- 1. 加载内建转换表(mwtable)
-- 由于 zh-tw/zh-hk/zh-cn 是 zh-hant/zh-hans 的扩展,需要合并
if variant == 'zh-tw' then
if BUILTIN_TABLES['zh-hant'] then merge(merged_table, BUILTIN_TABLES['zh-hant']) end
if BUILTIN_TABLES['zh-tw'] then merge(merged_table, BUILTIN_TABLES['zh-tw']) end
elseif variant == 'zh-hk' then
if BUILTIN_TABLES['zh-hant'] then merge(merged_table, BUILTIN_TABLES['zh-hant']) end
if BUILTIN_TABLES['zh-hk'] then merge(merged_table, BUILTIN_TABLES['zh-hk']) end
elseif variant == 'zh-cn' then
if BUILTIN_TABLES['zh-hans'] then merge(merged_table, BUILTIN_TABLES['zh-hans']) end
if BUILTIN_TABLES['zh-cn'] then merge(merged_table, BUILTIN_TABLES['zh-cn']) end
else
-- 其他变体直接使用内建表
if BUILTIN_TABLES[variant] then
merge(merged_table, BUILTIN_TABLES[variant])
end
end
-- 2. 加载全站转换表页面(覆盖内建表)
local title = mw.title.makeTitle('MediaWiki', 'Conversiontable/' .. variant)
if title and title.exists then
local content = title:getContent()
if content then
-- 解析转换规则格式:*原文=>转换后; (可能带 // 注释)
for line in content:gmatch('[^\n]+') do
-- 移除前导 * 和空格
line = line:gsub('^%s*%*%s*', '')
-- 移除末尾注释(// 之后的内容)
line = line:gsub('%s*//.*$', '')
-- 移除末尾分号和空格
line = line:gsub('[;%s]+$', '')
-- 匹配 "原文=>转换后" 格式
local original, converted = line:match('^([^%s;]+)%s*=>%s*(.+)$')
if original and converted then
original = original:gsub('^%s+', ''):gsub('%s+$', '')
converted = converted:gsub('^%s+', ''):gsub('%s+$', '')
if original ~= '' and converted ~= '' then
merged_table[original] = converted
end
end
end
end
end
siteTableCache[variant] = merged_table
return siteTableCache[variant]
end
-- 字符逐个转换(与内建 ZhConversion.php 行为一致)
-- 按最长优先匹配,正确处理多字符转换
local function _language_cvt(str, cvt_table)
if not cvt_table or next(cvt_table) == nil then
return str -- 如果没有转换表则返回原文
end
-- 计算最长的转换键长度
local max_length = 1
for key in pairs(cvt_table) do
if #key > max_length then
max_length = #key
end
end
-- 按字符码点处理字符串
local source = {}
for cp in mw.ustring.gcodepoint(str) do
table.insert(source, mw.ustring.char(cp))
end
local result = {}
local strlen = #source
local i = 1
while i <= strlen do
local changed = false
-- 尝试最长匹配(从 max_length 递减到 1)
for ji = 1, max_length do
local j = max_length - ji
if i + j <= strlen then
local check_str = table.concat(source, nil, i, i + j)
if cvt_table[check_str] then
table.insert(result, cvt_table[check_str])
i = i + j
changed = true
break
end
end
end
-- 如果没有匹配则保留原字符
if not changed then
table.insert(result, source[i])
end
i = i + 1
end
return table.concat(result)
end
--[[ 公开函数 ]]
-- 辅助函数:处理参数
local function get_input_string(input)
if type(input) == 'table' then
return (input.args or {})[1] or input[1] or ''
elseif type(input) ~= 'string' then
return tostring(input)
end
return input
end
function p.to_cn(input)
local text = get_input_string(input)
return _language_cvt(text, loadConversionTable('zh-cn'))
end
function p.to_hans(input)
local text = get_input_string(input)
return _language_cvt(text, loadConversionTable('zh-hans'))
end
function p.to_tw(input)
local text = get_input_string(input)
return _language_cvt(text, loadConversionTable('zh-tw'))
end
function p.to_hk(input)
local text = get_input_string(input)
return _language_cvt(text, loadConversionTable('zh-hk'))
end
function p.to_hant(input)
local text = get_input_string(input)
return _language_cvt(text, loadConversionTable('zh-hant'))
end
-- 通用转换函数
function p.convert(input, variant)
local text = get_input_string(input)
return _language_cvt(text, loadConversionTable(variant))
end
return p