Modul:PageTree: Unterschied zwischen den Versionen

K
27 Versionen von wikivoyage:Modul:PageTree importiert
K (24 Versionen von w:Modul:PageTree importiert)
K (27 Versionen von wikivoyage:Modul:PageTree importiert)
 
(2 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
--[=[ 2015-05-18
local PageTree = { suite  = "PageTree",
Module:pageTree
                  serial  = "2018-09-13",
                  item    = 56033297,
                  maxSub  = 10,
                  strings = { "segment",
                              "self",
                              "stamped",
                              "subpager",
                              "suppress" },
                  toggles = { "lazy",
                              "level",
                              "lineup",
                              "light",
                              "linked",
                              "limit",
                              "list" } }
--[=[
Module:PageTree
Rendering and administration of hierarchical wiki page structures
]=]
]=]
-- local globals
local Current = { maxSub = 10 }
local Sort    = false
local Strings = { "segment", "self", "stamped", "subpager", "suppress" }
local Toggles = { "lazy", "level", "lineup", "light", "linked", "limit",
                  "list" }




Zeile 39: Zeile 47:
     local lucky, r
     local lucky, r
     if s:byte( 1, 1 ) == 47 then    -- "/"
     if s:byte( 1, 1 ) == 47 then    -- "/"
         if Current.suite then
         if PageTree.suite then
             s = Current.suite .. s
             s = PageTree.suite .. s
         end
         end
     end
     end
Zeile 49: Zeile 57:
     return r
     return r
end -- facility()
end -- facility()
local function factory( apply )
    -- Clone read-only table
    --    apply  -- table, with basic data elements, read-only
    -- Returns message with markup
    local r = { }
    for k, v in pairs( apply ) do
        r[ k ] = v
    end -- for k, v
    return r
end -- factory()




Zeile 57: Zeile 78:
     -- Returns true if to be hidden
     -- Returns true if to be hidden
     local r = false
     local r = false
     for k, v in pairs( Current.hide ) do
     for k, v in pairs( PageTree.hide ) do
         if ask:match( v ) then
         if ask:match( v ) then
             r = true
             r = true
Zeile 65: Zeile 86:
     return r
     return r
end -- fade()
end -- fade()
local function failsafe( apply )
    -- Clone read-only table
    --    apply  -- table, with basic data elements, read-only
    -- Returns message with markup
    local r = { }
    for k, v in pairs( apply ) do
        r[ k ] = v
    end -- for k, v
    return r
end -- failsafe()




Zeile 87: Zeile 95:
     local r, s, title
     local r, s, title
     local n = 0
     local n = 0
     for k, v in pairs( Current.pages ) do
     for k, v in pairs( PageTree.pages ) do
         n = n + 1
         n = n + 1
         s = v.seed
         s = v.seed
Zeile 100: Zeile 108:
                                       "(-)" .. s )
                                       "(-)" .. s )
                     end
                     end
                 elseif Current.linked and
                 elseif PageTree.linked and
                       title.isRedirect then
                       title.isRedirect then
                     table.insert( redirect,
                     table.insert( redirect,
Zeile 139: Zeile 147:
     local r
     local r
     if adopt:byte( 1, 1 ) == 47 then    -- "/"
     if adopt:byte( 1, 1 ) == 47 then    -- "/"
         r = Current.start .. adopt:sub( 2 )
         r = PageTree.start .. adopt:sub( 2 )
     else
     else
         r = adopt
         r = adopt
Zeile 217: Zeile 225:
     -- Find parent page
     -- Find parent page
     --    ancestor  -- string, with page name
     --    ancestor  -- string, with page name
     -- Returns page name of parent, or Current.series
     -- Returns page name of parent, or PageTree.series
     local r = ancestor:match( "^(.+)/[^/]+$" )
     local r = ancestor:match( "^(.+)/[^/]+$" )
     if not r then
     if not r then
         r = ancestor:match( "^([^:]+:).+$" )
         r = ancestor:match( "^([^:]+:).+$" )
         if not r then
         if not r then
             r = Current.series
             r = PageTree.series
         end
         end
     end
     end
Zeile 240: Zeile 248:


local function features( apply, access )
local function features( apply, access )
     -- Fill Current.pages with elements
     -- Fill PageTree.pages with elements
     --    apply  -- table, with definitions, read-only
     --    apply  -- table, with definitions, read-only
     --    access  -- string, with relative path of module
     --    access  -- string, with relative path of module
Zeile 258: Zeile 266:
                 if type( v.seed ) == "string" then
                 if type( v.seed ) == "string" then
                     s = v.seed
                     s = v.seed
                     e = failsafe( v )
                     e = factory( v )
                 end
                 end
             end
             end
Zeile 264: Zeile 272:
             if type( v ) == "table" then
             if type( v ) == "table" then
                 s = k
                 s = k
                 e = failsafe( v )
                 e = factory( v )
             end
             end
         elseif k == true then    -- root
         elseif k == true then    -- root
             if Current.pages[ true ] then
             if PageTree.pages[ true ] then
                 bad[ "true" ] = "duplicated"
                 bad[ "true" ] = "duplicated"
             elseif type( v ) == "table" then
             elseif type( v ) == "table" then
                 if type( v.seed ) == "string" then
                 if type( v.seed ) == "string" then
                     Current.pages[ true ]          = failsafe( v )
                     PageTree.pages[ true ]          = factory( v )
                     Current.pages[ true ].children = { }
                     PageTree.pages[ true ].children = { }
                 else
                 else
                     bad[ "true" ] = "seed missing"
                     bad[ "true" ] = "seed missing"
Zeile 288: Zeile 296:
             end
             end
             if s then
             if s then
                 if not Current.pages[ s ] then
                 if not PageTree.pages[ s ] then
                     e.seed = s
                     e.seed = s
                     if e.super then
                     if e.super then
Zeile 298: Zeile 306:
                     end
                     end
                     e.children = { }
                     e.children = { }
                     Current.pages[ s ] = e
                     PageTree.pages[ s ] = e
                 end
                 end
             end
             end
Zeile 322: Zeile 330:


local function feed( access )
local function feed( access )
     -- Fill Current with data, if not yet set
     -- Fill PageTree with data, if not yet set
     --    access  -- string, with relative path of module
     --    access  -- string, with relative path of module
     -- Returns error message, if failed, or false, if fine
     -- Returns error message, if failed, or false, if fine
Zeile 329: Zeile 337:
         local s
         local s
         if type( r.maxSub ) == "number" then
         if type( r.maxSub ) == "number" then
             Current.maxSub = r.maxSub
             PageTree.maxSub = r.maxSub
         end
         end
         if type( r.stamp ) == "string" then
         if type( r.stamp ) == "string" then
             if Current.stamp then
             if PageTree.stamp then
                 if Current.stamp < r.stamp then
                 if PageTree.stamp < r.stamp then
                     Current.stamp = r.stamp
                     PageTree.stamp = r.stamp
                 end
                 end
             else
             else
                 Current.stamp = r.stamp
                 PageTree.stamp = r.stamp
             end
             end
         end
         end
Zeile 343: Zeile 351:
             s = mw.text.trim( r.start )
             s = mw.text.trim( r.start )
             if s ~= "" then
             if s ~= "" then
                 Current.start = s
                 PageTree.start = s
             end
             end
         end
         end
         if not Current.pages then
         if not PageTree.pages then
             Current.pages = { }
             PageTree.pages = { }
         end
         end
         if type( r.pages ) == "table" then
         if type( r.pages ) == "table" then
             if not Current.pages then
             if not PageTree.pages then
                 Current.pages = { }
                 PageTree.pages = { }
             end
             end
             s = features( r.pages, access )
             s = features( r.pages, access )
Zeile 394: Zeile 402:
         r = string.format( "%s %s", r, about.suffix )
         r = string.format( "%s %s", r, about.suffix )
     end
     end
     if Current.linked and type( about.shift ) == "string" then
     if PageTree.linked and type( about.shift ) == "string" then
         r = string.format( "%s <small>&#8594;[[%s]]</small>",
         r = string.format( "%s <small>&#8594;[[%s]]</small>",
                           r, fair( about.shift ) )
                           r, fair( about.shift ) )
     end
     end
     if Current.limit and type( about.protection ) == "string" then
     if PageTree.limit and type( about.protection ) == "string" then
         r = string.format( "%s %s",
         r = string.format( "%s %s",
                           r, fasten( about.protection ) )
                           r, fasten( about.protection ) )
Zeile 411: Zeile 419:
     --    adjust  -- string, to be standardized
     --    adjust  -- string, to be standardized
     -- Returns string with key
     -- Returns string with key
     if not Sort then
     if not PageTree.Sort then
         r, Sort = pcall( require, "Module:Sort" )
         r, PageTree.Sort = pcall( require, "Module:Sort" )
         if type( Sort ) == "table" then
         if type( PageTree.Sort ) == "table" then
             Sort = Sort.Sort()
             PageTree.Sort = PageTree.Sort.Sort()
         else
         else
             error( "Module:Sort not ready" )
             error( "Module:Sort not ready" )
         end
         end
     end
     end
     return string.upper( Sort.lex( adjust, "latin", false ) )
     return string.upper( PageTree.Sort.lex( adjust, "latin", false ) )
end -- filter()
end -- filter()


Zeile 466: Zeile 474:
     --    a2  -- string, with page name
     --    a2  -- string, with page name
     -- Returns true if a1 < a2
     -- Returns true if a1 < a2
     local e1 = Current.pages[ a1 ]
     local e1 = PageTree.pages[ a1 ]
     local e2 = Current.pages[ a2 ]
     local e2 = PageTree.pages[ a2 ]
     local r
     local r
     if e1.index then
     if e1.index then
Zeile 489: Zeile 497:
     --    ahead  -- string, with syntax in case of .lazy
     --    ahead  -- string, with syntax in case of .lazy
     local r
     local r
     if Current.lazy then
     if PageTree.lazy then
         r = ":"
         r = ":"
     else
     else
Zeile 515: Zeile 523:
         table.sort( above.children, firstly )
         table.sort( above.children, firstly )
         for i = 1, n do
         for i = 1, n do
             e = Current.pages[ above.children[ i ] ]
             e = PageTree.pages[ above.children[ i ] ]
             if e.list == false then
             if e.list == false then
                 let = Current.list
                 let = PageTree.list
             elseif Current.hide then
             elseif PageTree.hide then
                 let = not fade( e.seed )
                 let = not fade( e.seed )
             else
             else
Zeile 524: Zeile 532:
             end
             end
             if let then
             if let then
                local s
                 if not e.less then
                 if not e.less then
                     Current.item = Current.item + 1
                     PageTree.item = PageTree.item + 1
                     serial       = string.format( "%s_%d",
                     serial       = string.format( "%s_%d",
                                                  Current.serial,
                                                  PageTree.serial,
                                                  Current.item )
                                                  PageTree.item )
                     r = string.format( "%s\n<div %s %s %s>",
                     if table.maxn( e.children ) > 0 then
                                      r,
                        s = "mw-collapsible"
                                      "class='mw-collapsible'",
                        if amount >= already then
                                      "data-expandtext='[+]'",
                            s = s .. " mw-collapsed"
                                      "data-collapsetext='[-]'" )
                        end
                        r = string.format( "%s\n<div class='%s' %s %s>",
                                              r,
                                              s,
                                              "data-expandtext='[+]'",
                                              "data-collapsetext='[-]'" )
                        s = "</div>"
                    else
                        s = ""
                    end
                 end
                 end
                 r = string.format( "%s\n%s%s",
                 r = string.format( "%s\n%s%s",
                                   r, ahead, field( e, false ) )
                                   r,
                                  string.rep( ahead, amount ),
                                  field( e, false ) )
                 if not e.less then
                 if not e.less then
                     r = string.format( "%s\n<div %s>\n%s\n%s",
                    local style
                    if amount >= already then
                        style  = " style='display:none'"
                    else
                        style = ""
                    end
                     r = string.format( "%s\n<div %s%s>\n%s\n</div>%s",
                                       r,
                                       r,
--                                    span,
--                                    span,
                                       "class='mw-collapsible-content'",
                                       "class='mw-collapsible-content'",
                                       flip( ahead,
                                      style,
                                       flip( already,
                                            ahead,
                                             amount + 1,
                                             amount + 1,
                                             e,
                                             e ),
                                            already ),
                                       s )
                                       "</div></div>" )
                 end
                 end
             end
             end
Zeile 560: Zeile 587:
     --    acquire  -- string, with page name
     --    acquire  -- string, with page name
     if type( acquire ) == "string" then
     if type( acquire ) == "string" then
         local e = Current.pages[ acquire ]
         local e = PageTree.pages[ acquire ]
         local s = false
         local s = false
         if e then
         if e then
Zeile 574: Zeile 601:
                     e                        = { children = { },
                     e                        = { children = { },
                                                 seed    = acquire }
                                                 seed    = acquire }
                     Current.pages[ acquire ] = e
                     PageTree.pages[ acquire ] = e
                 end
                 end
                 e.super = s
                 e.super = s
Zeile 593: Zeile 620:
     local let = true
     local let = true
     local e
     local e
     for k, v in pairs( Current.pages ) do
     for k, v in pairs( PageTree.pages ) do
         if v.super == nil then
         if v.super == nil then
             flow( k )
             flow( k )
         elseif not Current.pages[ v.super ] then
         elseif not PageTree.pages[ v.super ] then
             flow( v.super )
             flow( v.super )
         end
         end
     end -- for k, v
     end -- for k, v
     for k, v in pairs( Current.pages ) do
     for k, v in pairs( PageTree.pages ) do
         if Current.level then
         if PageTree.level then
             let = ( not v.seed:find( "/" ) )
             let = ( not v.seed:find( "/" ) )
         end
         end
         if let and v.super then
         if let and v.super then
             e = Current.pages[ v.super ]
             e = PageTree.pages[ v.super ]
             if e then
             if e then
                 table.insert( e.children, k )
                 table.insert( e.children, k )
Zeile 630: Zeile 657:
         table.sort( above.children, firstly )
         table.sort( above.children, firstly )
         for i = 1, n do
         for i = 1, n do
             e    = Current.pages[ above.children[ i ] ]
             e    = PageTree.pages[ above.children[ i ] ]
             lift = ( all or above.long )
             lift = ( all or above.long )
             if e.list == false then
             if e.list == false then
                 let = Current.list
                 let = PageTree.list
             elseif Current.hide then
             elseif PageTree.hide then
                 let = not fade( e.seed )
                 let = not fade( e.seed )
             else
             else
Zeile 658: Zeile 685:
     local n      = 0
     local n      = 0
     local r, let
     local r, let
     for k, v in pairs( Current.pages ) do
     for k, v in pairs( PageTree.pages ) do
         let = true
         let = true
         if v.list == false  and
         if v.list == false  and
           ( not Current.list or v.loose or k == true ) then
           ( not PageTree.list or v.loose or k == true ) then
             let = false
             let = false
         elseif Current.level and v.seed:find( "/" ) then
         elseif PageTree.level and v.seed:find( "/" ) then
             let = false
             let = false
         elseif Current.hide then
         elseif PageTree.hide then
             let = not fade( v.seed )
             let = not fade( v.seed )
         end
         end
Zeile 672: Zeile 699:
                 v.show = nil
                 v.show = nil
             end
             end
             if Current.light then
             if PageTree.light then
                 local j, k = v.seed:find( Current.start )
                 local j, k = v.seed:find( PageTree.start )
                 if j == 1 then
                 if j == 1 then
                     v.show = v.seed:sub( k + 1 )
                     v.show = v.seed:sub( k + 1 )
Zeile 684: Zeile 711:
     if n > 0 then
     if n > 0 then
         local start
         local start
         local long = ( not Current.light )
         local long = ( not PageTree.light )
         if Current.lineup then
         if PageTree.lineup then
             start = " * "
             start = " * "
         else
         else
Zeile 717: Zeile 744:
         r = true
         r = true
     end
     end
     r = Current.pages[ r ]
     r = PageTree.pages[ r ]
     if r then
     if r then
         if type( Current.init ) == "number" then
         if type( PageTree.init ) == "number" then
             init = Current.init
             init = PageTree.init
             if Current.init < 1 then
             if PageTree.init < 1 then
                 init = 1
                 init = 1
             end
             end
Zeile 727: Zeile 754:
             init = 1
             init = 1
         end
         end
         if type( Current.serial ) ~= "string"
         if type( PageTree.serial ) ~= "string"
           or Current.serial == "" then
           or PageTree.serial == "" then
             Current.serial = "pageTree"
             PageTree.serial = "pageTree"
         end
         end
         Current.item = 0
         PageTree.item = 0
         r = flip( init,  flag( "#" ),  1,  r )
         r = flip( init,  flag( "*" ),  1,  r )
     else
     else
         r = false
         r = false
Zeile 745: Zeile 772:
     --    ancestor  -- string, with name of root element, or false
     --    ancestor  -- string, with name of root element, or false
     -- Returns string with story
     -- Returns string with story
     local sup = Current.self
     local sup = PageTree.self
     local higher, i, r
     local higher, i, r
     if ancestor then
     if ancestor then
         higher = Current.pages[ ancestor ]
         higher = PageTree.pages[ ancestor ]
         if type( higher ) == "table" then
         if type( higher ) == "table" then
             higher.super = false
             higher.super = false
         end
         end
     else
     else
         local point = Current.pages[ sup ]
         local point = PageTree.pages[ sup ]
         if not point then
         if not point then
             sup = true
             sup = true
         elseif point.list == false then
         elseif point.list == false then
             higher = Current.pages[ sup ]
             higher = PageTree.pages[ sup ]
             if type( higher ) == "table" then
             if type( higher ) == "table" then
                 if not higher.loose then
                 if not higher.loose then
Zeile 767: Zeile 794:
         end
         end
     end
     end
     for i = Current.maxSub, 0, -1 do
     for i = PageTree.maxSub, 0, -1 do
         higher = Current.pages[ sup ]
         higher = PageTree.pages[ sup ]
         if type( higher ) == "table" then
         if type( higher ) == "table" then
             higher.long = true
             higher.long = true
Zeile 798: Zeile 825:
     local n      = 1
     local n      = 1
     local reverse = { }
     local reverse = { }
     local sup    = Current.self
     local sup    = PageTree.self
     local r
     local r
     if type( sup ) == "string" and not sup:find( "/", 1, true ) then
     if type( sup ) == "string" and not sup:find( "/", 1, true ) then
         flow( sup )
         flow( sup )
         repeat
         repeat
             higher = Current.pages[ sup ]
             higher = PageTree.pages[ sup ]
             if type( higher ) == "table" then
             if type( higher ) == "table" then
                 sup          = higher.super
                 sup          = higher.super
Zeile 812: Zeile 839:
                 elseif sup then
                 elseif sup then
                     n = n + 1
                     n = n + 1
                     if n > Current.maxSub then
                     if n > PageTree.maxSub then
                         reverse[ n ] = { seed = "???????" }
                         reverse[ n ] = { seed = "???????" }
                         break    -- repeat
                         break    -- repeat
Zeile 867: Zeile 894:
         r = true
         r = true
     end
     end
     r = Current.pages[ r ]
     r = PageTree.pages[ r ]
     if r then
     if r then
         r = follow( flag( "#" ),  1,  r,  true )
         r = follow( flag( "#" ),  1,  r,  true )
Zeile 886: Zeile 913:
       type( args.service ) == "string"  and
       type( args.service ) == "string"  and
       type( args.suite ) == "string" then
       type( args.suite ) == "string" then
         Current.series  = args.series
         PageTree.series  = args.series
         Current.service = args.service
         PageTree.service = args.service
         Current.suite  = args.suite
         PageTree.suite  = args.suite
         if type( args.hide ) == "table" then
         if type( args.hide ) == "table" then
             Current.hide = args.hide
             PageTree.hide = args.hide
         elseif type( args.suppress ) == "string" then
         elseif type( args.suppress ) == "string" then
             Current.hide = { }
             PageTree.hide = { }
             table.insert( Current.hide, args.suppress )
             table.insert( PageTree.hide, args.suppress )
         end
         end
         if Current.series:match( "[:/]$" ) then
         if PageTree.series:match( "[:/]$" ) then
             Current.start = args.series
             PageTree.start = args.series
         else
         else
             Current.start = args.series .. "/"
             PageTree.start = args.series .. "/"
         end
         end
         r = feed( "/" .. Current.series )
         r = feed( "/" .. PageTree.series )
         if r then
         if r then
             r = fault( r )
             r = fault( r )
         else
         else
             local life = true
             local life = true
             if Current.service == "path"  or
             if PageTree.service == "path"  or
               Current.service == "subpages" then
               PageTree.service == "subpages" then
                 if args.self then
                 if args.self then
                     Current.self = args.self
                     PageTree.self = args.self
                 else
                 else
                     Current.page = mw.title.getCurrentTitle()
                     PageTree.page = mw.title.getCurrentTitle()
                     Current.self = Current.page.prefixedText
                     PageTree.self = PageTree.page.prefixedText
                 end
                 end
                 if not Current.pages[ Current.self ] then
                 if not PageTree.pages[ PageTree.self ] then
                     if type( Current.pages[ true ] ) == "table" then
                     if type( PageTree.pages[ true ] ) == "table" then
                         Current.self = true
                         PageTree.self = true
                     else
                     else
                         life = false
                         life = false
Zeile 922: Zeile 949:
             end
             end
             if life then
             if life then
                 if Current.service == "subpages" then
                 if PageTree.service == "subpages" then
                     r = formatSub( args.subpager, args.frame )
                     r = formatSub( args.subpager, args.frame )
                 elseif Current.service == "check" then
                 elseif PageTree.service == "check" then
                     Current.linked = args.linked
                     PageTree.linked = args.linked
                     r = failures()
                     r = failures()
                 else
                 else
                     for k, v in pairs( Toggles ) do
                     for k, v in pairs( PageTree.toggles ) do
                         Current[ v ] = args[ v ]
                         PageTree[ v ] = args[ v ]
                     end -- for k, v
                     end -- for k, v
                     if Current.service == "all" then
                     if PageTree.service == "all" then
                         r = formatAll()
                         r = formatAll()
                     else
                     else
Zeile 937: Zeile 964:
                         if type( args.segment ) == "string" then
                         if type( args.segment ) == "string" then
                             segment = fair( args.segment )
                             segment = fair( args.segment )
                             if not Current.pages[ segment ] then
                             if not PageTree.pages[ segment ] then
                                 Current.pages[ segment ] =
                                 PageTree.pages[ segment ] =
                                                     { seed    = segment,
                                                     { seed    = segment,
                                                       children = { },
                                                       children = { },
Zeile 946: Zeile 973:
                         end
                         end
                         fluent()
                         fluent()
                         if Current.service == "path" then
                         if PageTree.service == "path" then
                             r = formatPath( segment )
                             r = formatPath( segment )
                         elseif Current.service == "expand" then
                         elseif PageTree.service == "expand" then
                             r = formatExpand( segment, args )
                             r = formatExpand( segment, args )
                         else
                         else
                             if args.limit == "1"  or
                             if args.limit == "1"  or
                               args.limit == true then
                               args.limit == true then
                                 Current.limit = true
                                 PageTree.limit = true
                             end
                             end
                             r = formatTree( segment )
                             r = formatTree( segment )
                         end
                         end
                     end
                     end
                     if r and args.stamped and Current.stamp then
                     if r and args.stamped and PageTree.stamp then
                         local babel = mw.language.getContentLanguage()
                         local babel = mw.language.getContentLanguage()
                         local stamp = babel:formatDate( args.stamped,
                         local stamp = babel:formatDate( args.stamped,
                                                         Current.stamp )
                                                         PageTree.stamp )
                         r = stamp .. r
                         r = stamp .. r
                     end
                     end
Zeile 991: Zeile 1.018:
         local lucky
         local lucky
         params.frame = frame
         params.frame = frame
         for k, v in pairs( Strings ) do
         for k, v in pairs( PageTree.strings ) do
             if pars[ v ]  and  pars[ v ] ~= "" then
             if pars[ v ]  and  pars[ v ] ~= "" then
                 params[ v ] = pars[ v ]
                 params[ v ] = pars[ v ]
             end
             end
         end -- for k, v
         end -- for k, v
         for k, v in pairs( Toggles ) do
         for k, v in pairs( PageTree.toggles ) do
             if pars[ v ] then
             if pars[ v ] then
                 params[ v ] = ( pars[ v ] == "1" )
                 params[ v ] = ( pars[ v ] == "1" )
Zeile 1.013: Zeile 1.040:
     return r
     return r
end -- framed()
end -- framed()
PageTree.failsafe = function ( assert )
    -- 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 r
    local since = assert
    if since == "wikidata" then
        local item = PageTree.item
        since = false
        if type( item ) == "number"  and  item > 0 then
            local ent = mw.wikibase.getEntity( string.format( "Q%d",
                                                              item ) )
            if type( ent ) == "table" then
                local vsn = ent: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 <= PageTree.serial then
            r = PageTree.serial
        else
            r = false
        end
    end
    return r
end -- PageTree.failsafe()




Zeile 1.058: Zeile 1.122:
     --              .limit    -- show restrictions
     --              .limit    -- show restrictions
     local lucky, r = pcall( forward, args )
     local lucky, r = pcall( forward, args )
     return r or Current
     return r or PageTree
end -- p.test()
end -- p.test()
p.failsafe = function ( frame )
    -- Check or retrieve version information
    -- Precondition:
    --    frame  -- object; #invoke environment
    -- Postcondition:
    --    Return string with error message or ""
    -- Uses:
    --    PageTree.failsafe()
    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 PageTree.failsafe( since )  or  ""
end -- p.failsafe()


return p
return p