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