2023年政策修订增补工作正在进行中,欢迎参与!
Module:组字
跳转到导航
跳转到搜索
local p={}
p.parse=function(frame)
local parseTable=mw.loadData("Module:组字/ParseTable")
local function buildTree(str, index)
-- 递归下降
index=index or 1
str=str or ""
if mw.ustring.len(str) < index then return nil, index end
local chr=mw.ustring.sub(str, index, index)
local data={}
data.head=chr
if parseTable[chr] then
data.body={}
local nexti=index+1
for i=1,parseTable[chr].length do
data.body[i], nexti=buildTree(str, nexti)
if not data.body[i] then break end
end
return data, nexti
else
return data, index+1
end
end
local function setSize(tree, x, y, width, height)
-- 计算尺寸
if type(tree)~="table" then return end
tree.x=x
tree.y=y
tree.width=width
tree.height=height
if not tree.body then return end
local szt=parseTable[tree.head]
if not szt then return end
for i=1,szt.length do
setSize(tree.body[i], szt.x[i]*width+x, szt.y[i]*height+y, szt.width[i]*width, szt.height[i]*height)
end
end
local function plainize(tree)
local arr={}
if type(tree)~="table" then return end
if tree.body then
for i=1,#(tree.body) do
local sarr=plainize(tree.body[i])
for k,v in ipairs(sarr) do
table.insert(arr, v)
end
end
elseif not parseTable[tree.head] then
table.insert(arr, {
text=tree.head,
width=tree.width,
height=tree.height,
left=tree.x,
top=tree.y,
})
end
return arr
end
local function make_text(text, unit, gw, gh)
local ts=mw.html.create("span")
if type(text)~="table" then return ts end
ts:css("display", "inline-block")
ts:css("position", "absolute")
ts:css("top", tostring(text.top) .. unit)
ts:css("left", tostring(text.left) .. unit)
ts:css("width", tostring(gw) .. unit)
ts:css("height", tostring(gh) .. unit)
ts:css("transform", "scale(" .. tostring(text.width/gw) .. "," .. tostring(text.height/gh) .. ")" )
ts:css("transform-origin", "0% 0%")
ts:addClass("combination-text")
ts:wikitext(text.text)
return ts
end
local function make_frame(texts, width, height, unit)
if type(texts)~="table" then return end
local text=mw.html.create("span")
text:css("display", "inline-block")
--text:css("overflow", "hidden")
text:css("position", "relative")
text:css("width", tostring(width) .. unit)
text:css("height", tostring(height) .. unit)
--text:css("top", tostring(height*5/6) .. unit)
--text:css("left", tostring(width/12) .. unit)
text:css("font-size", tostring((height+width)/2) .. unit)
--local place=mw.html.create("span")
--place:css("display", "inline-block")
--place:css("position", "absolute")
--place:css("z-index", "-1")
--text:node(place)
for k,v in ipairs(texts) do
text:node(make_text(v, unit, width, height))
end
return text
end
local function emit_html(tree, unit)
local arr=plainize(tree)
return tostring(make_frame(arr, tree.width, tree.height, unit))
end
local str=frame.args[1]
if not str then return end
local size=tonumber(frame.args[2]) or 24
local unit=frame.args[3] or "px"
local chrdata=buildTree(str, 1)
setSize(chrdata, 0, 0, size, size)
--do return mw.dumpObject(plainize(chrdata)) end
return emit_html(chrdata, unit)
end
return p