Module:Sandbox/Thoken/Algor

Source: Wikipedia, the free encyclopedia.
--[=[ {{#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:" --&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
    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