Module:Sandbox/Thoken/Algor

--[=[ [(console:) =p.Gang{"Toronto",3}] writes a random link chain by   selecting randomly a single wikilink at page "Toronto", continuing to do the same at the page linked, then at that next page linked, and so on. the number determines the length of the chain. ]=]

local Attributes=function(text,title) local coord_pattern="{{[Cc]oord|([0-9]-)|-([0-9]-)|-([0-9%.]-)|([NS])|([0-9]-)|-([0-9]-)|-([0-9%.]-)|([EWO])[|}]" local infobox_pattern="{{Infobox.-|%s-lat_-d%s-=%s-([0-9]-)%s-|-%s-lat-_-m%s-=-%s-([0-9]-)%s-|-%s-lat-_-s%s-=-%s-([0-9%.]-)%s-|%s-lat_-NS%s-=%s-([NS]).-|%s-long_-d%s-=%s-([0-9]-)%s-|-%s-long-_-m%s-=-%s-([0-9]-)%s-|-%s-long-_-s%s-=-%s-([0-9%.]-)%s-|%s-long_-EW%s-=%s-([EW])%s-|.*" local pattern={}; pattern[1]=coord_pattern; pattern[2]=infobox_pattern local cat_pattern="%[%#%" Cats=function(text) local i,sr=0 local p,q,cat=text:find(cat_pattern,-999) while p and i<4 do           if i==0 then sr="" end if cat:lower~=title:lower then sr=sr..cat..", "; i=i+1 end p,q,cat=text:find(cat_pattern,q) end if 0<i then sr=sr:sub(1,-3) end return sr   end local sr="" local i,sc=1 repeat text:gsub(pattern[i],function(...) sc={...} end) i=i+1 until sc or not pattern[i] local cch,j={"°","′","″"},1 if sc then for _,v in ipairs(sc) do if tonumber(v) then sr=sr..v..cch[j]; j=j+1 elseif v~="" then sr=sr..v.." "; j=1 end end end sd=Cats(text) if sd then if sc then sr=sr:sub(1,-2).."; " end sr=sr..sd   else sd=Cats(mw.getCurrentFrame:preprocess(text)) if sd then sr=sr..""..sd.."" end end return sr end

Stack=function(starttable) -- table stack, one item push/pop local Stack={ push=function(self,v) self[#self+1]=v end, pop=function(self) assert(0<#self,"Stack empty on pop, out of service") return table.remove(self) end } return setmetatable(starttable or {},{__index=Stack}) end

local TitleStack=function return Stack{"Wikipedia","K","Little Red Rooster"} end

local RandPageChain={} RandPageChain.Gang=function(frame) local function wikitext(title) return mw.title.new(title,0):getContent,title end local osc=os.clock math.randomseed(math.floor(math.abs(math.floor(osc*10e3+0.5)-osc*10e3)*10e3+0.5)) if frame==mw.getCurrentFrame then args=frame:getParent.args else args=frame or {} end local title_pattern="%[%[([^:]-)[|#%]]" -- not matching titles containing a colon TS=TitleStack local title=tostring(args[1]) -- 'nil' is legal title if title=="" then title=TS:pop end local n=tonumber(args[2]) or 5 local out=""; local debuglog=":gang '"..title.."', "..n.."\n:" while 0 repeat text,title=wikitext(TS:pop) until text end out=out..n.." "..title.."".." \t "..Attributes(text,title).."\n:" -- local k,pos=0,{} local p,q=text:find(title_pattern) while p do     k=k+1; pos[k]=p   --debuglog=debuglog..k..":"..p.." "..capture.."\n:" p,q=text:find(title_pattern,q) end if 0<k then title=text:match(title_pattern,pos[math.random(k)]) if 5<k then TS:push(text:match(title_pattern,pos[math.random(k)])) end if 20<k then TS:push(text:match(title_pattern,pos[math.random(k)])) end else title=TS:pop end end return debuglog..out.."break" end return RandPageChain