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