Documentation for this module may be created at Module:Sandbox/Thoken/Algor/doc
--[=[ {{#invoke <module name>|Gang|Toronto|3}} [(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="%[%[[CcKk]at[eé]gor[yi][ae]-:(.-)[|#%]]"
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<n do n=n-1
local text=wikitext(title)
if not text then out=out.."[["..title.."]], ''dead end''\n:"; -- if <red link, ...>
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