- local module = {}
-
- local getArgs = require('Module:Arguments').getArgs
-
- --定义每次开头都是时间段而不是时间点
- --辅助处理trim
- function module.trim_step(text,patterns)
- for _,pattern in ipairs(patterns) do
- local b,e=text:find(pattern)
- if b then
- return true,string.sub(text,e+1)
- end
- end
- return false,text
- end
- function module.trim(text,patterns)
- local bool=true
- while bool do
- bool,text=module.trim_step(text,patterns)
- end
- return text
- end
- function module.trimCount(text,patterns)
- local bool=true
- local count=-1
- while bool do
- bool,text=module.trim_step(text,patterns)
- count=count+1
- end
- return text,count
- end
-
- --时间线/事件元表
- local timeLine={format={},analysis={}}
-
- function timeLine:timeSupply()--补足省略前缀时间
- if self.time~=nil then
- if timeLine.lastLine~=nil then
- --mw.log("time",self.time,self.time:getNumber())
- --mw.log("timeUse",timeLine.lastLine.time,timeLine.lastLine.time:getNumber())
- self.time:supply(timeLine.lastLine.time,true,false)
- --mw.log("totime",self.time,self.time:getNumber())
- --mw.log(self.time,self.time:compare(timeLine.lastLine.time),timeLine.lastLine.time)
- end
- elseif timeLine.lastLine then
- self.time=mw.clone(timeLine.lastLine.time)
- --mw.log(tostring(defaultTime).."--same--"..tostring(this))
- end
- end
- function timeLine.appendText(text)--为最后创建的timeLine追加文本
- if timeLine.lastLine then
- if timeLine.lastLine.text then
- timeLine.lastLine.text=timeLine.lastLine.text..timeLine.format.split..text
- else
- timeLine.lastLine.text=text
- end
- end
- return timeLine.lastLine
- end
- function timeLine.base(args)
- return setmetatable(args or {},timeLine)
- end
- timeLine.__index = timeLine
- function timeLine.title(titleLevel)
- assert(titleLevel,"标题层级不能为nil")
- return timeLine.base{titleLevel=titleLevel}
- end
- function timeLine.root()
- return timeLine.title(0)
- end
- function timeLine.create(withTimeText,parent)--带时间文本时间数字化·文本化函数
- assert(withTimeText~=nil and withTimeText~="","被分析文本不能为空")
- local titleLevel
- withTimeText,titleLevel=module.trimCount(withTimeText,timeLine.analysis.title)
- withTimeText=module.trim(withTimeText,timeLine.analysis.trim)
- withTimeText=module.trim(withTimeText,timeLine.analysis.sameTimeTable)
- local time,index=timeLine.getTime(withTimeText)
- if index==1 then
- time=nil
- end
- local text=module.trim(withTimeText:sub(index),timeLine.analysis.timeTextSplit)
- if #text+titleLevel==#withTimeText then--这是一行不具有时间效用的文本,实质为上一行文本的扩展部分。
- return timeLine.appendText(text)
- end
- local line=timeLine.base{time=time,text=text,titleLevel=titleLevel>0 and titleLevel}
- line:timeSupply()
- if parent then
- parent:insert(line)
- end
- timeLine.lastLine=line
- return line
- end
-
- function timeLine.titleMake(fulltime,level)--制作标题
- time=mw.clone(fulltime)
- --mw.log("->",timeLine.format.titleUnitList[level+timeLine.format.titleUnit-1],time)
- time:coverUnit(timeLine.format.titleUnitList[level+timeLine.format.titleUnit-1],true)
- if time:isEmpty() or time==fulltime then--没有可拆分信息
- return nil
- end
- local tag,range=time.accuracy:getMin()
- --mw.log(tag,range)
- local line=timeLine.title(timeLine.format.titleTopLevel+level-1)
- line.time=time
- return line
- end
- function timeLine:_insertTitile(newLine,index)--实际插入函数
- --mw.log("insert",self:currentlevel(),timeLine.format.titleLevel,self.titleLevel)
- if self.titleLevel and self:currentlevel()<timeLine.format.titleLevel then
- --mw.log("make",self:currentlevel()+1)
- local tl=timeLine.titleMake(newLine.time,self:currentlevel()+1)
- if not tl then--变成标题
- newLine.titleLevel=timeLine.format.titleTopLevel+self:currentlevel()
- newLine.parent=self
- table.insert(self,index,newLine)
- else
- tl.parent=self
- table.insert(self,index,tl)
- tl:_insertTitile(newLine,1)
- end
- else
- newLine.parent=self
- table.insert(self,index,newLine)
- end
- end
- function timeLine:move(otherLine,b,e)--辅助函数,转移数据
- --mw.log(tostring(self.time).."转移数据删除",b,e)
- e=e or b
- for i=b,e do--转移数据添加
- --mw.log("转移数据添加",i,self[i].time)
- otherLine:insert(self[i])
- end
- while e>=b do--转移数据删除
- --mw.log(self.time,"转移数据删除",e,self[e].time)
- table.remove(self,e)
- e=e-1
- end
- end
- function timeLine:_insert(newLine,index)--实际插入函数
- newLine.parent=self--记录父时间线
- table.insert(self,index,newLine)
- end
- function timeLine:insert(newLine)--插入时间函数
- local i=#self
- while i>=1 and newLine do
- local compareResult=newLine:compareTime(self[i])
- --mw.log(tostring(self[i].time).."-"..compareResult.."-"..tostring(newLine.time))
- if compareResult==timeLine.compareTime.inside then--包含,置入其内部
- --mw.log(tostring(self.time).."置入"..tostring(self[i].time).."数据"..tostring(newLine.time))
- newLine= self[i]:insert(newLine)
- elseif compareResult==timeLine.compareTime.equal then--相同。直接插入,这之后再处理
- break
- --if self:compare(newLine)~=timeLine.compare.equal then
- --newLine= self[i]:insert(newLine)--置入
- --else
- --break
- --end
- elseif compareResult==timeLine.compareTime.include then--需要转移数据
- local index=i-1
- while index>=1 and self[index]:compareTime(newLine)==timeLine.compareTime.inside do
- index=index-1
- end
- self:move(newLine,index+1,i)--转移数据的末端
- i=index
- break
- elseif compareResult~=timeLine.compareTime.before then--=timeCompare.before or compareResult==timeCompare.conflict then--越界或不正确(?),插入
- break
- end
- i=i-1
- --compareResult==timeCompare.after 继续
- end
- if not newLine then return end
- --mw.log(self.time,i+1,"追加数据",newLine.time)
- self:_insert(newLine,i+1)
- end
- function timeLine:currentlevel()--实际层数
- if self.parent then
- return self.parent:currentlevel()+1
- end
- return 0
- end
- function timeLine:level()--缩进层数
- if self.titleLevel then
- return 0
- end
- return self.parent:level()+1
- end
- timeLine.format.timeToText=function(self,time,parentTime)
- local tag=time:getMin()
- if parentTime and self.cut then
- time:coverRange(parentTime)
- end
- local timeText=time:format(self.pattern,self.ignore)
- if #timeText==0 then
- timeText=self.sameTimeTable[tag] or self.sameTimeTable[0]
- end
- return timeText
- end
- timeLine.format=setmetatable(timeLine.format,{--格式化输出文本
- __call=function(self,timeLine)
- local time=timeLine.time
- if not time then return nil end
- local timeText=self:timeToText(time,timeLine.parent and timeLine.parent.time)
- --mw.log(timeLine.time.from)
-
- if timeLine.titleLevel then
- local builder={string.rep(self.title,timeLine.titleLevel),timeText,string.rep(self.title,timeLine.titleLevel)}
- if timeLine.text and #timeLine.text>0 then
- table.insert(builder,timeLine.text)
- end
- return table.concat(builder)
- end
- local builder={self.preTime,timeText,self.afterTime}
-
- if self.alignLength>string.len(timeText) then
- local m,r=math.modf(self.alignLength/2-((#timeText+mw.ustring.len(timeText))/4))
- if m>=1 and r>0 then
- table.insert(builder," ")
- table.insert(builder,string.rep(" ",m-1))
- else
- table.insert(builder,string.rep(" ",m))
- end
- elseif self.alignLength>0 then
- table.insert(builder," ")
- end
- local level=timeLine:level()--
- table.insert(builder,1,string.rep(self.preRange,level))
- table.insert(builder,1,self.pre)
- table.insert(builder,timeLine.text)
- table.insert(builder,self.after)
- table.insert(builder,string.rep(self.afterRange,level))
- return table.concat(builder)
- end
- })
-
- function timeLine:insertText(withTimeText)--插入文本 解析为timeLine
- if withTimeText==nil or withTimeText=="" then return end
- return timeLine.create(withTimeText,self)
- end
- function timeLine:_sort()--整理
- local sameCount=0
- local index=#self
- while index>1 do
- if self[index].time==self[index-1].time then
- sameCount=sameCount+1
- else
- if sameCount>0 and self[index].time~=self.time then
- self:move(self[index],index+1,index+sameCount)
- end
- sameCount=0
- end
- index=index-1
- end
- if sameCount>0 and self[index].time~=self.time then
- self:move(self[index],index+1,index+sameCount)
- end
- for _,child in ipairs(self) do
- child:_sort()
- end
- end
- function timeLine:sort()--整理 同期排列
- if self.format.indentSameTime then
- self:_sort()
- end
- return self
- end
- function timeLine:toArgs(args)
- args=args or {}
- local text=self:format()
-
- args[#args+1]=text
- for _,child in ipairs(self) do
- child:toArgs(args)
- end
- return args
- end
- function timeLine:__tostring()
- return table.concat(self:toArgs(),timeLine.format.split)
- end
- module.timeLine=timeLine--供继承
-
- --参数预处理
- function module.preArgs_step(tab,state)
- while true do
- if state.gsplit[1] then
- local _f=state.gsplit[1]
- local value
- state.gsplit[3]=_f(state.gsplit[2],state.gsplit[3])
-
- if state.gsplit[3] then
- return state,state.gsplit[3]
- end
- end
- --下一个arg
- local arg=tab.args[state.index]
- if not arg then return nil end--结束遍历
- state.index=state.index+1
- state.gsplit={mw.text.gsplit(arg, tab.sentenceSplit)}
- end
- end
- function module.preArgs(args)--迭代器
- local tab={
- args=args,
- sentenceSplit=args.sentencesplit or args.ss or args["句段分割符"] or "\n",--识别用
- }
- local state={
- index=1,
- gsplit={},
- }
- return module.preArgs_step,tab,state
- end
- --主函数
- function module.timeModule(args)
- local from=args.from or args["原语言"]
- local to=args.to or args["目标语言"]
- local o_timezone=args.o_timezone or args.o_tz or args["原时区"]
- local c_timezone=args.c_timezone or args.c_tz or args["现时区"]
- local connect=args.timeformatrangesplit or args.tfrs or args["时间格式-时段连接符"] or "到"
- local timeModule=require("Module:模糊时间")
- timeModule.initialize(from,to,connect)
- return timeModule
- end
- function module.argsSet(args)--时间线参数设置
- --识别用
- timeLine.analysis.timeTextSplit={ "^%s", "^% ", }
- local filterAdd=function(tab,text)
- if text and text~="\t" and text~="\n" and text~="\r" and text~="\0" and text~="" then
- table.insert(tab,"^"..text)
- end
- end
- local timeTextSplit=args["time-textsplit"] or args.tts or args["时间-文本分割符"] or ","
- filterAdd(timeLine.analysis.timeTextSplit,timeTextSplit)
- timeLine.analysis.trim={ "^%s", "^% " }
- local bullet=args.bullet or args.b or args["项目符号"] or "\*"
- filterAdd(timeLine.analysis.trim,bullet)
- timeLine.analysis.title={}
- local timeTitle=args.timetitle or args.tt or args["时间标题符"] or "="
- filterAdd(timeLine.analysis.title,timeTitle)
- filterAdd(timeLine.analysis.timeTextSplit,timeTitle)
- timeLine.analysis.sameTimeTable={"^同期","^同年","^同月","^同日","^同时"}
- --格式化用
- timeLine.format.alignLength=tonumber(args.alignlength or args.al or args["对齐长度"]) or 0--18
- timeLine.format.pre=args.presentence or args.ps or args["文本前符"] or ""
- timeLine.format.after=args.aftersentence or args.as or args["文本后符"] or ""
- timeLine.format.preRange=args.prerange or args.pr or args["时段前符"] or bullet
- timeLine.format.afterRange=args.afterrange or args.ar or args["时段后符"] or ""
- timeLine.format.indentSameTime=((args.indentsametime or args.ist or args["时间格式-同时缩进"])~="false")--指示同时事件缩进
- timeLine.format.title=timeTitle
-
- timeLine.format.titleLevel=tonumber(args.titlelevel or args.tl or args["标题层级"]) --若有值,则为时间线增加分标题,值为增添的层数
- if timeLine.format.titleLevel then
- timeLine.format.titleTopLevel=tonumber(args.titletop or args.ttp or args["标题顶级层级"]) or 3 --最顶级的标题层级
- timeLine.format.titleUnit=tonumber(args.titleunit or args.tu or args["标题单位"]) or 3--需要标题化的最高层级单位,默认为year
- timeLine.format.titleUnitList=mw.text.split(args.titleunits or args.tus or args["标题单位表"] or "%C;%T;%Y;%M;%D;%H",";")
- timeLine._insert=timeLine._insertTitile
- else
- timeLine.format.titleLevel=nil
- end
- timeLine.format.split=args.sentencecontext or args.sc or args["句段连接符"] or "\n"--输出用
- timeLine.format.preTime=args.pretime or args.pt or args["时间前符"] or ""
- timeLine.format.afterTime=args.aftertime or args.at or args["时间后符"] or ","
-
- timeLine.format.cut=((args.timeformatcut or args.tfc or args["时间格式-省略"])~="false")--指示与父时间相同的步分省略
- timeLine.format.sameTimeTable={--用于识别与上一时段相同的时间--数字代表省略层级
- [0]="同期",
- ["year"]="同年",
- ["month"]="同月",
- ["day"]="同日",
- ["hour"]="同时",
- ["min"]="同时",
- ["second"]="同时"
- }
- timeLine.format.pattern=args.pattern or args["格式化字符串"] or "%Y%M%(Mi)%D%(Di)%H%I%S"
- timeLine.analysis.pattern= args.analysis_pattern or args.a_pattern or args["分析字符串"]
- if timeLine.analysis.pattern=="default" then
- timeLine.analysis.pattern=timeLine.format.pattern
- end
-
- local ignore=args.ignore or args["强制精确度"]
- if ignore=="nil" then
- timeLine.format.ignore=nil
- elseif ignore=="false" then
- timeLine.format.ignore=false
- else
- timeLine.format.ignore=true
- end
- local timeModule=module.timeModule(args)
- local totime=timeModule.toTime
- if timeLine.analysis.pattern then
- timeLine.getTime=function(text)
- return totime(text,timeLine.analysis.pattern)
- end
- else
- timeLine.getTime=totime
- end
- local time=timeModule.time
- timeLine.compareTime=setmetatable(mw.clone(time.compare),{--比较函数
- __call=function(self,timeLine1,timeLine2)
- --local bool,value=pcall( time.compare,timeLine1.time,timeLine2.time)
- return time.compare(timeLine1.time,timeLine2.time)
- end
- })
- end
- function module.toTimeLine(args)--转换为时间线
- module.argsSet(args)
- local root=timeLine.root()
- for _,sentence in module.preArgs(args) do
- root:insertText(sentence)
- end
-
- return root:sort()
- end
- function module.format(args)--函数:格式化参数table
- return module.toTimeLine(args):toArgs()
- end
- function module.toText(args)--函数:主要函数 转换为格式文本
- return tostring(module.toTimeLine(args))
- end
- function module.optionalArgsText(args)--获取可选参数文本
- local root={}
- for key,arg in pairs(args) do
- if type(key)~="number" then
- if key~="update" then
- table.insert(root,key.."="..arg)
- end
- end
- end
- return table.concat(root,"|")
- end
- function module.sortArgsSubst(args,name,fvalue)--返回排序参数后的模板,name指示模板名,fvalue指示sortargs的新值
- args.pre=nil
- args.after=nil
- args.pretime=nil
- args.aftertime=nil--避免重复问题
- if args.sortargs then
- args.sortargs=fvalue
- end--置为false
- if args["排列参数"] then
- args["排列参数"]=fvalue
- end--置为false
- local argsText=module.optionalArgsText(args)
- return "{{模板:"..name.."|"..argsText.."|\n"..module.toText(args).."\n}}"
- end
- function module.empty(args)--返回参数本身
- local sp=args.sentencecontext or args.sc or args["句段连接符"] or "\n"
- local t={}
- for _,arg in ipairs(args) do
- table.insert(t,arg)
- end
- return table.concat(t,sp)
- end
- function module._main(args, frame)--函数:主要函数
- local sortArgs=args["排列参数"] or args.sortargs or args.sort--排序参数,需要配合subst使用
- if sortArgs then
- if sortArgs=="false" then
- return module.empty(args)
- elseif sortArgs=="once" then
- return module.sortArgsSubst(args,"时间线",nil)
- else
- return module.sortArgsSubst(args,"时间线","false")
- end
- end
- return module.toText(args)
- end
-
- function module.main(frame)--函数:主要函数
- local args = getArgs(frame)
- return module._main(args, frame)
- end
-
- --[[function module.test()
- return module.main({"1年4月,吃饭饭","*1年2月,睡觉觉","1年4月,打豆豆","1年到1年,吃喝睡玩","同年4月,洗澡澡"})
- end]]--
-
-
- return module