Module:StorySim
可在Module:StorySim/doc创建此模块的帮助文档
local p = {} local CNames = require('Module:StorySim/CName').CNames local getArgs = require('Module:Arguments').getArgs local Data = mw.loadData('Module:RotaenoStoryData/FullText') local asmCNames = {} local function writeCName(node,id) if asmCNames[id] and CNames[id] then return node:tag('span'):addClass('name changedName name_'..id) :tag('span'):wikitext(asmCNames[id]):done() :tag('span'):wikitext(CNames[id]):done(); elseif asmCNames[id] or CNames[id] then return node:tag('span'):addClass('name name_'..id):wikitext(asmCNames[id] or CNames[id]); else return node:tag('span'):addClass('name UnknownName name_'..id):wikitext(id); end end local function _generic_AppendLine(self,txt) self.curCNode:wikitext(txt); return self; end local function _generic_Reset(self) self.curNode = self.node:tag('div'):addClass('SimChild'); return self; end local _mtList = { ['Novel'] = {-- Novel WriteLine = function(self,txt,_) self.curCNode = self.curNode:tag('div'):wikitext(txt); return self; end; AppendLine = _generic_AppendLine, Reset = _generic_Reset }, ['Chat'] = {-- Chat WriteLine = function(self,txt,name) if name == self.lastName then self.left = self.left; else self.left = not self.left;end self.lastName = name; local n = self.curNode:tag('tr'); local l = n:tag('th'):addClass('L'); self.curCNode = n:tag('td'):wikitext(txt); local r = n:tag('th'):addClass('R'); if self.left then writeCName(l,name);self.curCNode:addClass('L') else writeCName(r,name);self.curCNode:addClass('R') end return self; end; AppendLine = _generic_AppendLine, Reset = function(self) if not self.init then self.init = true; self.left = false; self.curNode = self.node:tag('table'):addClass('SimChild'); else self.curNode:tag('tr'):tag('th'):attr('colspan',3):addClass('LineBreak'); end return self; end }, ['Dialogue'] = {-- Dialogue WriteLine = function(self,txt,name) local isThinking = false; if name=='' then isThinking = true;name='ilot';end local n = self.curNode:tag('tr'); if name == self.lastName then self.left = self.left; self.i = self.i + 1; self.NameNode:attr('rowspan',self.i) else local l = n:tag('th'):addClass('L');writeCName(l,name); self.NameNode = l; self.lastName = name; self.i = 1; end self.curCNode = n:tag('td'):wikitext(txt); if isThinking then self.curCNode:addClass('thinking');end return self; end; AppendLine = _generic_AppendLine, Reset = function(self) if not self.init then self.init = true; self.curNode = self.node:tag('table'):addClass('SimChild'); else self.curNode:tag('tr'):tag('th'):attr('colspan',2):addClass('LineBreak'); end;self.i = 1;self.lastName=nil;self.NameNode = nil; return self;end }, ['Fullscreen'] = {-- Fullscreen WriteLine = function(self,txt,_) self.curCNode = self.curNode:tag('div'):wikitext(txt); return self;end; AppendLine = _generic_AppendLine, Reset = _generic_Reset }, ['FullscreenImportant'] = {-- FullscreenImportant WriteLine = function(self,txt,_) self.curCNode = self.curNode:wikitext(txt); return self;end; AppendLine = _generic_AppendLine, Reset = _generic_Reset }, ['CgDialog'] = {-- CgDialog TBD WriteLine = function(self,txt,name) local N = self.curNode:tag('div'):addClass('DialogChild'); if name ~= '' then local n = N:tag('div');writeCName(n,name);end self.curCNode = N:tag('div'):wikitext(txt); if name == '' then self.curCNode:addClass('thinking');end return self; end; AppendLine = _generic_AppendLine, Reset = _generic_Reset }, ['ChapterTitle'] = {-- CT WriteLine = function(self,txt,_) local a,b = string.match(txt,'(.*)|(.*)'); if a and b then self.curNode:tag('div'):addClass('subTitle'):wikitext(a); self.curCNode = self.curNode:tag('div'):addClass('Title'):wikitext(b); else self.curCNode = self.curNode:tag('div'):addClass('onlyTitle'):wikitext(txt); end return self; end; AppendLine = _generic_AppendLine, Reset = _generic_Reset }, } --- @class Printer:table --- @field WriteLine fun(self:Printer,txt:string,name:string) --- @field AppendLine fun(self:Printer,txt:string) --- @field Reset fun(self:Printer) local _ = {} ---@param HTML any ---@param Type string ---@return Printer local function createPrinter(HTML,Type) return setmetatable( {node = HTML:tag('tr'):tag('td'):addClass('storySim type_'..tostring(Type))}, {__index = _mtList[Type]}):Reset(); end --[[ qMTPList = { Novel = 0, Chat = 1, -- 对话(d) Dialogue = 2, -- 对话(vn) Fullscreen = 3, -- 全屏文字(例子:c1开头) FullscreenImportant = 4, -- 左下角文字(例子:c2结尾) CgDialog = 5 -- 带cg的对话(例子:ss2) } dC_qTable = { ModifyTextPrinter = {0,5}, OverridePrintCommand = {1,5,6}, OverrideAppendLineBreakCommand = {2}, Wait = {3}, HidePrinter = {4}, ResetText = {5}, OverrideDisplayNameCommand = {6,5,6} } ]] local function reco(str) while true do local s,e,c,t = string.find(str,'<color=(.-)>(.-)</color>'); if s then str = string.sub(str,1,s-1) .. "<span class='Colored color_" .. c .. "' style='color:" .. c .. ";'>" .. t .. "</span>" .. string.sub(str,e+1) else break; end end while true do local s,e,c,t = string.find(str,'<size=(.-)>(.-)</size>'); if s then str = string.sub(str,1,s-1) .. string.format("<span class='Sized size_%s' style='font-size:%.3fem;'>",c,(tonumber(c)/36)) .. t .. "</span>" .. string.sub(str,e+1) else break; end end local s,_,c,t = string.find(str,'<indent=(.-)%%>(.*)'); if c then str = string.sub(str,1,s-1) .. string.format("<span class='Indented indent_%s' style='padding-left:%.3fem;'>",c,(tonumber(c)/5)) .. t .. "</span>" end return str; end -- Start -- local function makeInvokeFunc(funcName) return function(frame) local args = getArgs(frame) return p[funcName](args) end end p.main = makeInvokeFunc('_main') function p._main(args)-- 生成HTML的主函数 部分代码来源:[[Module:Songtable]] local id = args['name'] or args['story'] or args['id'] or args[2]; local d = Data[id]; if not d then error('找不到故事文本!!!');end --- 构建HTML --- local title = args[1] or args['title'] or "标题"; local box = mw.html.create("table"):addClass("rotable mw-collapsible mw-collapsed storyTable"); box:tag('tr'):tag('th'):tag('h4'):attr('id',id):wikitext(title); local cPID = 'Dialogue'; if d[1][1] == 0 then cPID = d[1][2];end local currentPrinter; local lastName = ''; local canAppend = false; -- local _i = 0; for _, t in ipairs(d) do -- _i = _i + 1; if t[1] == 0 then cPID = t[2]; currentPrinter=nil; canAppend=false; elseif t[1] == 1 then if not currentPrinter then currentPrinter = createPrinter(box,cPID);end if canAppend and t[3] == lastName then currentPrinter:AppendLine(reco(t[2] or '')); else currentPrinter:WriteLine(reco(t[2] or ''),t[3]);lastName = t[3]; end;canAppend=nil; elseif t[1] == 2 then if canAppend == nil then canAppend = true;end if canAppend then currentPrinter:AppendLine('<br>');end elseif t[1] == 3 then if canAppend == nil then canAppend = true;end elseif t[1] == 4 then canAppend = false; elseif t[1] == 5 then canAppend = false; currentPrinter:Reset(); elseif t[1] == 6 then if t[2] == '' then asmCNames[t[3]] = nil else asmCNames[t[3]] = t[2] end end end return tostring(box) end return p