Modul:Vorlage:arXiv: Unterschied zwischen den Versionen

Aus FreeWiki
Zur Navigation springen Zur Suche springen
te>PerfektesChaos
(2018-02-01)
te>PerfektesChaos
(2019-05-12)
Zeile 1: Zeile 1:
 
local Export = { suite  = "arXiv",
 
local Export = { suite  = "arXiv",
                 serial = "2018-02-01" }
+
                 serial = "2019-05-12",
 +
                item  = 0 }
 
--[=[
 
--[=[
 
Template:arXiv
 
Template:arXiv
Zeile 142: Zeile 143:
  
 
Export.failsafe = function ( attempt )
 
Export.failsafe = function ( attempt )
     local since = attempt
+
    -- Retrieve versioning and check for compliance
 +
    -- Precondition:
 +
    --    assert  -- string, with required version or "wikidata",
 +
    --                or false
 +
    -- Postcondition:
 +
    --    Returns  string with appropriate version, or false
 +
     local since = assert
 
     local r
 
     local r
     if since then
+
     if since == "wikidata" then
         since = mw.text.trim( since )
+
        local item = Export.item
        if since == "" then
+
         since = false
          since = false
+
        if type( item ) == "number"  and  item > 0 then
 +
            local entity = mw.wikibase.getEntity( string.format( "Q%d",
 +
                                                                item ) )
 +
            if type( entity ) == "table" then
 +
                local vsn = entity:formatPropertyValues( "P348" )
 +
                if type( vsn ) == "table"  and
 +
                  type( vsn.value ) == "string" and
 +
                  vsn.value ~= "" then
 +
                    r = vsn.value
 +
                end
 +
            end
 
         end
 
         end
 
     end
 
     end
     if since then
+
     if not r then
         if since > Export.serial then
+
         if not since  or  since <= Export.serial then
             r = ""
+
             r = Export.serial
 
         else
 
         else
             r = Export.serial
+
             r = false
 
         end
 
         end
    else
 
        r = Export.serial
 
 
     end
 
     end
 
     return r
 
     return r
Zeile 372: Zeile 387:
 
                     r[ k ] = v
 
                     r[ k ] = v
 
                     k = false
 
                     k = false
                 elseif args.demo  or  faculty( args.NoCat ) then
+
                 elseif argsT.demo  or  faculty( argsT.NoCat ) then
 
                     Config.errCat  = false
 
                     Config.errCat  = false
 
                     Config.errHide = false
 
                     Config.errHide = false
Zeile 444: Zeile 459:
  
 
p.failsafe = function ( frame )
 
p.failsafe = function ( frame )
     return Export.failsafe( frame.args[ 1 ] )
+
     -- 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 Export.failsafe( since ) or  ""
 
end -- p.failsafe()
 
end -- p.failsafe()
  

Version vom 12. Mai 2019, 19:08 Uhr

local Export = { suite = "arXiv",

                serial = "2019-05-12",
                item   = 0 }

--[=[ Template:arXiv and other issues dealing with arXiv ID. ]=]


local Config = {

   self        = Export.suite,
   errCat      = false,
   errClass    = "error_arXiv",
   errClasses  = false,
   errHide     = false,
   errNS       = false,
   errConflict = { en = "Conflict in multiple parameters",
                   de = "Konflikt durch überbestimmte Parameter" },
   errInvalid  = { en = "Invalid:",
                   de = "Ungültig:" },
   errMissing  = { en = "Missing ID",
                   de = "ID fehlt" },
   errModule   = { en = "Library module missing:",
                   de = "Bibliotheksmodul fehlt:" },
   errUnkown   = { en = "Unkown parameter:",
                   de = "Parameter unbekannt:" },
   mode        = 0,
   showArticle = false

}


local function factory( apply )

   -- Localization of messages
   --     apply  -- string, with message key
   -- Returns message text; at least English
   local entry = Config[ apply ]
   local r
   if entry then
       -- TODO: page language
       r = entry[ mw.language.getContentLanguage():getCode() ]
       if not r then
           r = entry.en
       end
   else
       r = tostring( mw.html.create( "span" )
                            :addClass( "error" )
                            :wikitext( string.format( "????.%s.????",
                                                      apply ) ) )
   end
   return r

end -- factory()


local function faculty( adjust )

   -- Test template arg for boolean
   --     adjust  -- string or nil
   -- Returns boolean
   local r = false
   if adjust then
       r = mw.text.trim( adjust )
       if r ~= ""  and  r ~= "0" then
           r = true
       end
   end
   return r

end -- faculty()



local function fault( alert, about, frame )

   -- Format message with class="error" or similar
   --     alert  -- string, with message key
   --     about  -- string, with explanation
   --     frame  -- object
   -- Returns message with markup
   local scope = Config.errClass
   local story = factory( alert )
   local lucky, TemplUtl = pcall( require, "Module:TemplUtl" )
   local r, scope, style
   if type( TemplUtl ) == "table" then
       TemplUtl = TemplUtl.TemplUtl()
   end
   if Config.self then
       story = string.format( "%s * %s", Config.self, story )
   end
   if Config.errClasses then
       if scope then
           scope = string.format( "%s %s",
                                  scope, Config.errClasses )
       else
           scope = Config.errClasses
       end
   end
   if about then
       story = string.format( "%s %s", story, about )
   end
   if type( TemplUtl ) == "table" then
       r = TemplUtl.failure( story,
                             not Config.errHide,
                             scope,
                             frame )
   else
       r = tostring( mw.html.create( "span" )
                            :addClass( scope )
                            :addClass( "error" )
                            :wikitext( story ) )
   end
   if Config.errCat then
       if Config.errNS then
           local st = type( Config.errNS )
           local ns
           if not Config.title then
               Config.title = mw.title.getCurrentTitle()
           end
           ns = Config.title.namespace
           if st == "string" then
               local space  = string.format( ".*%%s%d%%s.*", ns )
               local spaces = string.format( " %s ", Config.errNS )
               if spaces:match( space ) then
                   Config.errNS = false
               end
           elseif st == "table" then
               for i = 1, #Config.errNS do
                   if Config.errNS[ i ] == ns then
                       Config.errNS = false
                       break    -- for i
                   end
               end -- for i
           end
       end
       if not Config.errNS then
           r = string.format( "%s", r, Config.errCat )
       end
   end
   return r

end -- fault()


Export.failsafe = function ( attempt )

   -- Retrieve versioning and check for compliance
   -- Precondition:
   --     assert  -- string, with required version or "wikidata",
   --                or false
   -- Postcondition:
   --     Returns  string with appropriate version, or false
   local since = assert
   local r
   if since == "wikidata" then
       local item = Export.item
       since = false
       if type( item ) == "number"  and  item > 0 then
           local entity = mw.wikibase.getEntity( string.format( "Q%d",
                                                                item ) )
           if type( entity ) == "table" then
               local vsn = entity:formatPropertyValues( "P348" )
               if type( vsn ) == "table"  and
                  type( vsn.value ) == "string" and
                  vsn.value ~= "" then
                   r = vsn.value
               end
           end
       end
   end
   if not r then
       if not since  or  since <= Export.serial then
           r = Export.serial
       else
           r = false
       end
   end
   return r

end -- Export.failsafe()


Export.fair = function ( arXiv )

   -- Analyze code, create URL
   --     arXiv  -- string, with arXiv ID
   -- Returns table
   --     .url
   --     .site      URL of repository
   --     .scope     thematic archive until 2007
   --     .since     yymm
   --     .serial    n
   --     .sequence  version number
   --     .signature identifier within scope
   --     .legacy    true: before 2007-04-01
   --     .legal     true: fine
   local r = { arXiv = arXiv,
               site  = "https://arxiv.org/abs/",
               url   = "https://arxiv.org/abs/" .. arXiv }
   local parts
   r.legal = arXiv:match( "^[-.0-9v]+$" )
   if r.legal then
       r.serial = arXiv
   else
       parts = mw.text.split( arXiv, "/", true )
       if #parts == 2  and  parts[ 2 ] ~= "" then
           r.scope  = parts[ 1 ]
           r.serial = parts[ 2 ]
           parts = mw.text.split( r.scope, ".", true )
           if #parts <= 2 then
               local p = mw.text.split( parts[ 1 ], "-", true )
               if #p <= 2 then
                   r.legal = p[ 1 ]:match( "^%l+$" )
                   if r.legal  and  #p == 2 then
                       r.legal = p[ 2 ]:match( "^%l+$" )
                   end
                   if r.legal  and  #parts == 2 then
                       r.legal = parts[ 2 ]:match( "^%l+$" )   or
                                 parts[ 2 ]:match( "^%u%u$" )
                   end
               end
           end
       end
   end
   if r.legal and r.serial then
       parts = mw.text.split( r.serial, "v", true )
       if #parts > 1 then
           r.serial   = parts[ 1 ]
           r.sequence = parts[ 2 ]
           r.legal    = ( #parts == 2   and
                          r.sequence:match( "^[1-9]%d*$" ) )
       end
       if r.legal then
           local split = "^([0129]%d)([01]%d)[.]?(%d+)$"
           local j, m, n = r.serial:match( split )
           r.legal = n
           if r.legal then
               r.since  = j .. m
               r.serial = n
               m        = tonumber( m )
               r.legal  = ( m <= 12 )
               if r.legal then
                   j = tonumber( j )
                   if j < 90 then
                       r.legal = ( j <= tonumber( os.date( "%y" ) ) )
                   end
                   if r.legal then
                       local k = 5
                       local scheme
                       r.legacy = ( j > 90   or
                                    j < 7    or
                                    ( j == 7  and  m < 4 ) )
                       if r.legacy then
                           k = 3
                       elseif j < 15 then
                           k = 4
                       end
                       n        = tonumber( n )
                       scheme   = string.format( "%%0%dd", k )
                       r.serial = string.format( scheme, n )
                       r.legal  = ( r.serial:len() == k )
                       if r.legacy  and  not r.scope then
                           r.legal = false
                       end
                   end
               end
           end
       end
   end
   if r.legal then
       r.signature = r.since
       if not r.legacy then
           r.signature = r.signature .. "."
       end
       r.signature = r.signature .. r.serial
       if r.sequence then
           r.signature = string.format( "%sv%s",
                                        r.signature, r.sequence )
       end
       if r.legacy then
           r.signature = string.format( "%s/%s", r.scope, r.signature )
       end
       r.url = r.signature
   else
       r.signature = arXiv
       r.url       = r.signature
   end
   r.url = r.site .. r.url
   return r

end -- Export.fair()


Export.features = function ( assign )

   -- Configure appearance
   --     assign  -- table, with components
   if type( assign ) == "table" then
       for k, v in pairs( assign ) do
           Config[ k ] = v
       end -- for k, v
   end

end -- Export.features()


Export.format = function ( arXiv )

   -- Format template request
   --     arXiv  -- table, with result of analysis
   -- May be influenced by Config.mode (0: standard appearance).
   -- Returns appropriate string
   local r
   if type( arXiv ) == "table" then
       local show
       if Config.mode == 0  or  true then
           if arXiv.scope   and  not arXiv.legacy then
               show = string.format( "%s [%s]",
                                     arXiv.signature, arXiv.scope )
           else
               show = arXiv.signature
           end
           r    = string.format( "[%s %s]", arXiv.url, show )
           show = "arxiv"
           if Config.showArticle then
               local title = mw.title.new( Config.showArticle )
               if not Config.title then
                   Config.title = mw.title.getCurrentTitle()
               end
               if not mw.title.equals( title, Config.title ) then
                   show = string.format( "arxiv",
                                         Config.showArticle )
               end
           end
           r = string.format( "%s:%s", show, r )
       end
       if not arXiv.legal then
           r = string.format( "%s %s %s",
                              r,
                              fault( "errInvalid", false, frame ),
                              arXiv.arXiv )
       end
   else
       r = "Module:Template:arXiv::format() no table arg"
   end
   return r

end -- Export.format()


-- Export local p = { }

p.main = function ( argsF, argsT, frame )

   -- Invocation
   --     argsF  -- table, with #invoke parameters, or false
   --     argsT  -- table, with template parameters
   --     frame  -- object, or nil
   -- Returns appropriate string, or table if argsF.mode = false
   local r
   if argsF then
       Config.errCat     = argsF.errCat
       Config.errClasses = argsF.errClasses
       Config.errHide    = faculty( argsF.errHide )
       Config.errNS      = argsF.errNS
       if argsF.mode ~= nil then
           Config.mode = argsF.mode
       end
       if argsF.showArticle ~= nil then
           if argsF.showArticle == "" then
               Config.showArticle = false
           else
               Config.showArticle = argsF.showArticle
           end
       end
   end
   if type( argsT ) == "table" then
       local unknown
       r = { }
       for k, v in pairs( argsT ) do
           s = type( k )
           if s == "number" then
               if ( k <= 2 ) then
                   r[ k ] = mw.text.trim( v )
                   k = false
               else
                   k = tostring( k )
               end
           elseif s == "string" then
               if k == "id"  or
                  k == "archive" then
                   r[ k ] = v
                   k = false
               elseif argsT.demo  or  faculty( argsT.NoCat ) then
                   Config.errCat  = false
                   Config.errHide = false
                   k = false
               end
           end
           if k then
               if not unknown then
                   unknown = { }
               end
               table.insert( unknown, k )
           end
       end -- for k, v
       if unknown then
           r = string.format( "'%s' in Template:arXiv",
                              table.concat( unknown, " " ) )
           r = fault( "errUnkown", r, frame )
       elseif ( r[ 1 ] and r.archive )  or
              ( r[ 2 ] and r.id )   then
           r = fault( "errConflict",
                      "1= ./. archive= | 2= ./. id=",
                      frame )
       else
           r[ 1 ] = ( r[ 1 ] or r.archive )
           r[ 2 ] = ( r[ 2 ] or r.id )
           if r[ 1 ] == "" then
               r[ 1 ] = false
           end
           if r[ 2 ] == "" then
               r[ 2 ] = false
           end
           if r[ 1 ] and r[ 2 ] then
               r[ 1 ] = string.format( "%s/%s", r[ 1 ], r[ 2 ] )
           elseif not r[ 1 ] then
               if r[ 2 ] then
                   r[ 1 ] = r[ 2 ]
               else
                   r = fault( "errMissing", false, frame )
               end
           end
       end
   else
       r = false
   end
   if type( r ) == "table" then
       r = Export.fair( r[ 1 ] )
       if Config.mode then
           r = Export.format( r )
       end
   end
   return r

end -- p.main()


p.f = function ( frame )

   local lucky, r
   Config.frame = frame
   lucky, r = pcall( p.main, frame.args, frame:getParent().args, frame )
   if not lucky then
       r = tostring( mw.html.create( "span" )
                            :addClass( "error" )
                            :wikitext( string.format( "%s * %s",
                                                      frame:getTitle(),
                                                      r ) ) )
   end
   return r

end -- p.f()


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 Export.failsafe( since )  or  ""

end -- p.failsafe()


p.arXiv = function ()

   return Export

end -- p.arXiv()

return p