Modul:PageUtil

Aus FreeWiki
Version vom 12. November 2017, 12:51 Uhr von te>PerfektesChaos (2017-11-11)
Zur Navigation springen Zur Suche springen

local PageUtil = { suite = "PageUtil",

                  serial = "2017-11-11" };

--[=[ PageUtil ]=]


PageUtil.maxPages = 200


local function fault( alert, frame )

   -- Format message with class="error"
   --     alert  -- string, with message
   --     frame  -- object
   -- Returns message with markup
   local r = alert
   if frame then
       r = string.format( "%s * %s", frame:getTitle(), r )
   end
   r = string.format( "ERROR * %s", r )
   return r

end -- fault()


local function flat( adjust, assembly )

   -- Replace links to pages by inner links
   --     adjust    -- string, with text
   --     assembly  -- table, with page infos
   -- Returns adjusted string
   local r = adjust
   local seek, shift, source, subst
   for k, v in pairs( assembly ) do
       source = v[ 1 ]
       shift  = v[ 2 ]
       source = ":?" .. source:gsub( " ", "[_ ]+" )
                              :gsub( "[%.%(%)%*%?%+%-]", "%1" )
                     .. "%s*"
       seek   = "%[%[%s*" .. source .. "(#[^%]]*%]%])"
       subst  = "[[%1"
       r = r:gsub( seek, subst )
       seek  = "%[%[%s*" .. source .. "(%|[^%]]*%]%])"
       subst = "[[#" .. shift .. "%1"
       r = r:gsub( seek, subst )
       seek  = "%[%[%s*(" .. source .. "%]%])"
       subst = "[[#" .. shift .. "|%1"
       r = r:gsub( seek, subst )
   end -- for k, v
   return r

end -- flat()


local function fraction( access, frame )

   -- Retrieve text from section
   --     access  -- string, with request
   --     frame   -- object
   -- Returns content, or false
   -- Uses:
   --     mw.title.new() .exists
   local r
   local seek = "^(#lstx?):%s*%[%[([^%[|%]\n]+)%]%]%s*(%S.*)%s*$"
   local scope, source, section = access:match( seek )
   if source then
       local page = mw.title.new( source )
       source = page.prefixedText
       if page.exists then
           section = mw.text.trim( section )
           if section ~= "" then
               r = frame:callParserFunction{ name = scope,
                                             args = { source,
                                                      section } }
           end
       else

r = string.format( "

%s

",

                              source )
       end
   end
   return r

end -- fraction()


local function full( access, frame, alias, assembly )

   -- Retrieve text from page
   --     access    -- string, with page name
   --     frame     -- object
   --     alias     -- number, unique
   --     assembly  -- table, with page infos
   -- Returns string with content, or nil
   -- Uses:
   --     mw.title.new() .exists
   local page = mw.title.new( access )
   local r
   if page then
       if page.exists then
           local source  = page.prefixedText
           local segment = string.format( "PageUtilMerge-%d", alias )
           local seed
           if page.namespace == 0 then
               seed = ":" .. source
           else
               seed = source
           end
           r = frame:expandTemplate( { title = seed } )
           r = string.format( "\n%s", segment, r )
           table.insert( assembly,  { source, segment } )
       else

r = string.format( "

%s

",

                              page.prefixedText )
       end
   else

r = string.format( "

%s '%s'

",

                          "Unknown page", access )
   end
   return r

end -- full()


PageUtil.failsafe = function ( assert )

   local r
   if not assert  or  assert <= PageUtil.serial then
       r = PageUtil.serial
   else
       r = false
   end
   return r

end -- PageUtil.failsafe()


PageUtil.merge = function ( args, frame )

   -- Retrieve text
   --     args   -- table, with request
   --     frame  -- object, if available
   -- Returns string, with content
   local max = 0
   local r   = ""
   for k, v in pairs( args ) do
       if type( k ) == "number"  and
          k > max then
           max = k
       end
   end -- for k, v
   if max > 0 then
       local n     = 0
       local pages = {  { mw.title.getCurrentTitle().prefixedText,
                          "" }  }
       local mode, s, section, swallow
       if not frame then
           frame = mw.getCurrentFrame()
       end
       for i = 1, max do
           s = args[ i ]
           if s then
               swallow = s:match( "^%s*(#lstx?:[^\n]*%S)%s*$" )
               if swallow then
                   s = fraction( swallow, frame )
                   n = n + 1
               else
                   swallow = s:match( "^%s*%[%[([^%[|%]\n]+)%]%]%s*$" )
                   if swallow then
                       s = full( swallow, frame, i, pages )
                       n = n + 1
                   end
               end
               if s then
                   r = r .. mw.text.trim( s )
               end
               if n > PageUtil.maxPages then
                   s = string.format( "Too many pages (max. %d)",
                                      PageUtil.maxPages )
                   r = string.format( "%s\n\n%s",
                                      r,
                                      fault( s, frame ) )
                   break -- for i
               end
           end
       end -- for i
       r = flat( r, pages )
   end
   return r

end -- .merge()


-- Export local p = { }

function p.isRedirect()

   return mw.title.getCurrentTitle().isRedirect and "1"  or  "";

end -- p.isRedirect

p.merge = function ( frame )

   local lucky, r = pcall( PageUtil.merge, frame.args, frame )
   if not lucky then
       r = fault( r, frame )
   end
   return r

end

p.failsafe = function ( frame )

   -- Versioning interface
   local s = type( frame )
   local since
   if s == "table" then
       since = frame.args[ 1 ]
   elseif s == "string" then
       since = frame
   end
   if since then
       since = mw.text.trim( since )
       if since == "" then
           since = false
       end
   end
   return PageUtil.failsafe( since )  or  ""

end -- p.failsafe()

function p.PageUtil()

   return PageUtil

end

return p