Modul:Tutorial

Modul:Tutorial

Modul:Tutorial
Vorlagenprogrammierung Diskussionen Lua Unterseiten
Modul Deutsch English

Modul: Dokumentation

Diese Seite enthält Code in der Programmiersprache Lua. Einbindungszahl Cirrus


local Tutorial = { serial = "2018-03-18",
                   suite  = "Tutorial" }
--[=[
Support Tutorial tree
]=]



Tutorial.txt =
    { sequence = "bad page for page@Tutorial",
      slot     = "''Start of a trail.''",
      sole     = "''This page got currently no content assigned.''",
      sparse   = "''Nothing to say.''",
      start    = "Start",
      starter  = "Start trail",
      suite    = "All",
      summary0 = "'summary' missing",
      superior = "''Below all single pages are merged.''",
      survey   = "''Start page: [[%s|here]]''"
    }



local function faculty( args, arg )
    -- Retrieve boolean template arg
    --     args  -- (table)
    --     arg   -- (string, number)
    local r = args[ arg ]
    if r == ""  or  r == "0" then
        r = false
    end
    return r and true  or  false
end -- faculty()




local function fault( alert )
    -- Report problem
    --     alert  -- (string) message
    -- Returns: string
    local cat    = Tutorial.errCat   or ""
    local class  = Tutorial.errClass or ""
    local style  = Tutorial.errStyle or ""
    local show   = Tutorial.errText  or ""
    local suffix = type( alert )
    local e      = mw.html.create( "span" )
                          :addClass( "error" )
    local r
    if class ~= "" then
        e:addClass( class )
    end
    if style ~= "" then
        e:cssText( style )
    end
    if show == "" then
        show = "Error"
    end
    if suffix == "string" then
        show = string.format( "%s: %s", show, alert )
    elseif suffix == "number" then
        show = string.format( "%s %d", show, alert )
    end
    e:wikitext( show )
    r = tostring( e )
    if cat ~= "" then
        r = string.format( "%s[[Category:%s]]", r, cat )
    end
    return r
end -- fault()



Tutorial.facet = function ( access )
    -- Create page link with tooltip, if present
    --     access  -- (string) subpage
    -- Returns: string
    local swap = string.format( "%s:%s/%s",
                                Tutorial.page.nsText,
                                Tutorial.page.baseText,
                                access )
    local src, show = Tutorial.foreign( access )
    if show then
        -- TODO    plaintext show
        show = tostring( mw.html.create( "span" )
                                :attr( "title", show )
                                :wikitext( access ) )
    else
        show = access
    end
    return  string.format( "[[%s|%s]]", swap, show )
end -- Tutorial.facet()



Tutorial.facility = function ( appoint, at )
    -- Retrieve base page and subpage name
    --     appoint  -- module title and base page, page derived else
    --     at       -- page name, or nil
    -- Returns:
    --     1. module title and base page
    --     2. page name
    local r1, r2
    if appoint then
        r1 = appoint
    else
        local room = mw.site.namespaces[ Tutorial.page.namespace ]
        r1 = string.format( "%s:%s",
                            room.subject.name,
                            Tutorial.page.baseText )
    end
    if type( at ) == "string" then
        r2 = mw.text.trim( at )
        if r2 == "" then
            r2 = false
        end
    end
    if not r2 then
        r2 = Tutorial.page.subpageText
    end
    return  r1, r2
end -- Tutorial.facility()



Tutorial.fake = function ( album, at )
    -- Transclude content
    --     album  -- number of trail
    --     at     -- number of section
    -- Returns: (string) page content
    local trails = Tutorial.def.trails
    local sort   = Tutorial.page.subpageText
    local r
    if type( trails ) == "table" then
        local trail = trails[ album ]
        if type( trail ) == "table" then
            local start = trail[ 1 ]
            trail = trail[ 2 ]
            if type( start ) == "string"  and
               type( trail ) == "table" then
                local single = trail[ at ]
                start = mw.text.trim( start )
                if type( single ) == "string"  and
                   start ~= "" then
                    r = Tutorial.feed( start, single, trail, album, at )
                end
            end
        end
    end
    if r then
        sort = "§ " .. sort
    else
        r    = Tutorial.txt.sole
        sort = "# " .. sort
    end
    r = r .. Tutorial.fold( sort )
    return r
end -- Tutorial.fake()



Tutorial.father = function ( ancestor )
    -- Top page: link all trails
    --     ancestor  -- (string) supreme page
    -- Returns: (mw.html) <dl>, or nil
    local r
    if type( Tutorial.def.trails ) == "table" then
        local dl = mw.html.create( "dl" )
        local dd, ea, eg, et, ex, section, src, story, sum, trail
        story = string.format( "&#91;[[%s/%%s|%s]]&#93;",
                               ancestor,
                               Tutorial.txt.suite )
        for i = 1, #Tutorial.def.trails do
            trail = Tutorial.def.trails[ i ]
            if type( trail ) == "table" then
                section = trail[ 1 ]
                if type( section ) == "string" then
                    r = true
                    dl:newline()
                      :node( mw.html.create( "dt" )
                                    :wikitext( section ) )
                    src, sum = Tutorial.foreign( section )
                    if sum ~= section then
                        dl:newline()
                          :node( mw.html.create( "dd" )
                                        :wikitext( sum ) )
                    end
                    trail = trail[ 2 ]
                    if type( trail ) == "table" then
                        dd = mw.html.create( "dd" )
                        ea = mw.html.create( "small" )
                                    :wikitext( string.format( story,
                                                              section ) )
                        eg = mw.html.create( "span" )
                        Tutorial.forward( eg, i, 1, 1,
                                          Tutorial.txt.start,
                                          true )
                        et, ex = Tutorial.flip( ancestor, trail, i )
                        if et then
                            dd:newline()
                              :node( eg )
                              :newline()
                              :node( et )
                              :newline()
                              :node( ea )
                              :newline()
                              :node( ex )
                        end
                    end
                    dl:newline()
                      :node( dd )
                end
            end
        end -- i = 1, #Tutorial.def.trails
        if r then
            r = dl
        end
    end
    return r
end -- Tutorial.father()



Tutorial.features = function ( ancestor, all, album, attribute, ahead )
    -- List of direct links to trail subpages
    --     ancestor   -- (string) supreme page
    --     all        -- (table) subpages
    --     album      -- (number) trail
    --     attribute  -- (boolean) numbered list
    --     ahead      -- (boolean) show both name and summary
    -- Returns: (mw.html)
    local n = #all
    local r
    if n > 0 then
        local sequence = string.format( "[[%s/%d-%%d|%%s]]",
                                        ancestor,
                                        album )
        local ttips    = Tutorial.future( all, at, false, ancestor )
        local s, show
        if attribute then
            s = "ol"
        else
            s = "ul"
        end
        r = mw.html.create( s )
        for i = 1, #all do
            s = ttips[ i ]
            if ahead and s then
                show = string.format( sequence, i, all[ i ] )
                show = string.format( "%s &#8211; %s", show, s )
            else
                show = string.format( sequence,  i,  s or all[ i ] )
            end
            r:node( mw.html.create( "li" )
                           :wikitext( show ) )
        end -- i = 1, #all
    else
        r = mw.html.create( "span" )
                   :wikitext( Tutorial.txt.sparse )
    end
    return r
end -- Tutorial.features()



Tutorial.feed = function ( above, access, all, album, at )
    -- Equip page transclusion
    --     above   -- (string) start
    --     access  -- (string) subpage
    --     all     -- (table) subpages
    --     album   -- (number) trail
    --     at      -- (number) section
    -- Returns: (string), or nil
    local src, sum = Tutorial.foreign( access )
    local r
    if src then
        local box   = Tutorial.further( all, album, at )
        local start = Tutorial.facet( above )
        r = Tutorial.flat( sum, start, box )
        if type( Tutorial.pageSource ) == "table"  and
           type( Tutorial.pageSource.source ) == "string" then
            local e = mw.html.create( "div" )
                             :css( "clear",         "right" )
                             :css( "float",         "right" )
                             :css( "margin-top",    "-1em" )
                             :css( "margin-bottom", "1em" )
                             :css( "padding",       "2px" )
           if type( Tutorial.pageSource.class ) == "string" then
                e:addClass( Tutorial.pageSource.class )
            end
            if Tutorial.pageSource.loose then
                e:css( "display", "none" )
            end
            if type( Tutorial.pageSource.style ) == "string" then
                e:cssText( Tutorial.pageSource.style )
            end
            e:wikitext( string.format( "[[%s:%s/%s|%s]]",
                                       Tutorial.page.nsText,
                                       Tutorial.page.baseText,
                                       access,
                                       Tutorial.pageSource.source ) )
            r = string.format( "%s\n%s\n", r, tostring( e ) )
        end
        r = r .. Tutorial.frame:preprocess( src )
    end
    return r
end -- Tutorial.feed()



Tutorial.fence = function ( access )
    -- Retrieve page protection
    -- Precondition:
    --     access  -- (string) subpage
    -- Returns: (string) level sign
    local t = mw.title.new( string.format( "%s/%s",
                                           Tutorial.page.baseText,
                                           access ),
                            Tutorial.page.nsText )
    local r
    if t.exists then
        local p = t.protectionLevels
        if type( p ) == "table" then
            p = p.edit
            if type( p ) == "table" then
                for k, v in pairs( p ) do
                    if v == "editeditorprotected" then
                        r = "&frac34;"
                    elseif v == "autoconfirmed" then
                        r = "&frac12;"
                    elseif v == "sysop" then
                        r = "1"
                    end
                end -- for k, v
            end
        end
    end
    return r or "0"
end -- Tutorial.fence()



Tutorial.fenced = function ( album, at, access )
    -- Retrieve page group protection
    -- Precondition:
    --     album   -- number of trail
    --     at      -- number of section
    --     access  -- (string) subpage
    -- Returns: (string) both levels
    return string.format( "%s,%s",
                          Tutorial.fence( string.format( "%d-%d",
                                                         album, at ) ),
                          Tutorial.fence( access ) )
end -- Tutorial.fenced()



Tutorial.fetch = function ( appoint, allow )
    -- Attach config or tree module
    -- Precondition:
    --     appoint  -- module title, "config" if "", page derived else
    --     allow    -- (boolean) suppress error message
    -- Returns: (table) with library, or (string) error message
    local suite = appoint
    local got, lucky, r, source
    if not Tutorial.page then
        Tutorial.page = mw.title.getCurrentTitle()
    end
    if type( suite ) == "string" then
        suite = mw.text.trim( suite )
        if suite == "" then
            suite = false
        end
    else
        suite = string.format( "%s:%s",
                               Tutorial.page.nsText,
                               Tutorial.page.baseText )
    end
    if suite then
        source = string.format( "Module:%s/%s",
                                Tutorial.suite, suite )
        lucky, got = pcall( require, source )
        if type( got ) == "table" then
            r = got
            if type( got[ suite ] ) == "function" then
                r = got[ suite ]()
            end
        end
        if type( r ) ~= "table" then
            if allow then
                r = ""
            else
                r = string.format( "%s invalid", source )
            end
        end
    end
    source = string.format( "Module:%s/config", Tutorial.suite )
    lucky, got = pcall( require, source )
    if type( got ) == "table" then
        for k, v in pairs( got ) do
            if type( v ) == "table" then
                if not Tutorial[ k ] then
                    Tutorial[ k ] = { }
                end
                if type( Tutorial[ k ] ) == "table" then
                    local t = Tutorial[ k ]
                     for kk, vv in pairs( v ) do
                         t[ kk ] = vv
                     end -- for kk, vv
                end
            else
                Tutorial[ k ] = v
            end
        end -- for k, v
    end
    return r
end -- Tutorial.fetch()



Tutorial.field = function ( access, add )
    -- Create box
    --     access  -- 2nd headline, string, or nil
    --     add     -- action area, mw.html <div>, or nil
    -- Returns: (string) box
    local bas = Tutorial.def
    local btm = bas.bottom
    local css = bas.style
    local f   = function ()
                    local r = mw.html.create( "td" )
                    if type( css.fgc ) == "string" then
                        r:css( "border-top-color", "#" .. css.fgc )
                         :css( "border-top-style", "solid" )
                         :css( "border-top-width", "1px" )
                    end
                    return r
                end -- f()
    local tbl = mw.html.create( "table" )
                       :addClass( "wikiTutorial" )
                       :attr( "role", "navigation" )
                       :css( "float",         "right !important" )
                       :css( "margin-left",   "1em !important" )
                             -- mobile resets first float table (infobox)
                       :css( "margin-bottom", "1em" )
    local te  = mw.html.create( "th" )
    if type( css.bgc ) == "string" then
        tbl:css( "background-color", "#" .. css.bgc )
    end
    if type( css.fgc ) == "string" then
        tbl:css( "color", "#" .. css.fgc )
    end
    if type( css.border ) == "table" then
        if type( css.fgc ) == "string" then
           tbl:css( "border-color", "#" .. css.fgc )
        end
        if type( css.border.style ) == "string" then
           tbl:css( "border-style", css.border.style )
        end
        if type( css.border.width ) == "string" then
           tbl:css( "border-width", css.border.width )
        end
    end
    if type( css.icon ) == "string" then
        local size
        if type( css.size ) == "string" then
            size = css.size:match( "^(%d+)px$" )
            if size then
                size = tonumber( size ) + 4
                size = string.format( "%dpx", size )
            else
                size = css.size
            end
        else
            size = "15px"
        end
        te:wikitext( string.format( "[[File:%s|%s]]",
                                    css.icon,
                                    size ) )
    end
    if type( bas.show ) == "string" then
       local e = mw.html.create( "span" )
                        :css( "margin-left", "5px" )
       local s = bas.supreme
       if type( s ) == "string" then
           s = string.format( "[[%s|%s]]", s, bas.show )
       else
           s = bas.show
       end
       e:wikitext( s )
        if type( css.size ) == "string" then
            e:css( "font-size", css.size )
        end
        te:node( e )
    end
    te:css( "padding-left", "4px" )
      :css( "padding-right", "4px" )
      :css( "text-align", "left" )
    tbl:newline()
       :node( mw.html.create( "tr" )
                     :node( te ) )
    if type( access ) == "string" then
        tbl:newline()
           :node( mw.html.create( "tr" )
                         :node( f():wikitext( access ) ) )
    end
    if type( add ) == "table" then
        tbl:newline()
           :node( mw.html.create( "tr" )
                         :node( f():node( add ) ) )
    end
    if type( btm ) == "table" then
        te = f()
        if type( btm.service ) == "string" then
            local s
            if type( btm.show ) == "string" then
                s = "|" .. btm.show
            else
                s = ""
            end
            te:wikitext( string.format( "[[%s%s]]",
                                        btm.service,
                                        s ) )
        elseif type( btm.show ) == "string" then
            te:wikitext( btm.show )
        end
        tbl:newline()
           :node( mw.html.create( "tr" )
                         :node( te ) )
    end
    return tostring( tbl )
end -- Tutorial.field()



Tutorial.find = function ( at )
    -- Retrieve trail lessons
    --     at  -- trail name
    -- Returns:
    --     (table) or nil
    --     (number) trail
    local r1, r2
    for i = 1, #Tutorial.def.trails do
        trail = Tutorial.def.trails[ i ]
        if type( trail ) == "table" then
            if trail[ 1 ] == at then
                r1 = trail[ 2 ]
                r2 = i
                break -- i = 1, #Tutorial.def.trails
            end
        end
    end -- i = 1, #Tutorial.def.trails
    return r1, r2
end -- Tutorial.find()



Tutorial.flat = function ( about, above, add )
    -- Single content page
    --     about  -- summary
    --     above  -- trail start, if in trail
    --     add    -- action area, mw.html <div>, or nil
    -- Returns: (string)
    local css = Tutorial.def.style
    local e   = mw.html.create( "div" )
    local r   = Tutorial.field( above, add )
    e:wikitext( about )
    if type( css ) == "table" then
        if type( css.bgc ) == "string" then
            e:css( "background-color", "#" .. css.bgc )
        end
        if type( css.fgc ) == "string" then
            e:css( "color", "#" .. css.fgc )
        end
        if type( css.h1 ) == "table" then
            for k, v in pairs( css.h1 ) do
                e:css( k, v )
            end -- for k, v
        end
    end
    r = string.format( "%s\n%s%s",
                       r,
                       tostring( e ),
                       Tutorial.fold( Tutorial.page.subpageText ) )
    return r
end -- Tutorial.flat()



Tutorial.flip = function ( ancestor, all, album )
    -- Create trail extension for survey
    --     ancestor  -- (string) supreme page
    --     all       -- (table) subpages
    --     album     -- (number) trail
    -- Returns:
    --     (mw.html) toggle <span>, or nil
    --     (mw.html) list <div>, or nil
    local r1 = mw.html.create( "span" )
                      :css( "margin-left", "2em" )
                      :css( "margin-right", "2em" )
    local r2 = mw.html.create( "div" )
    Tutorial.flipper( r1,  string.format( "tutorial-%d", album ) )
    r2:attr( "id",
             string.format( "mw-customcollapsible-tutorial-%d", album ) )
      :addClass( "mw-collapsible mw-collapsed" )
      :css( "display", "none" )
      :newline()
      :node( Tutorial.features( ancestor, all, album, false, true ) )
    return r1, r2
end -- Tutorial.flip()



Tutorial.flipper = function ( apply, assign )
    -- Create toggle
    --     apply    -- (mw.html)
    --     assign   -- (string) ID
    local sel  = "nomobile"
                 -- mobile no collapsible yet
                 -- derive from .client-nojs display:none
    local sign = "mw-customtoggle"
    sel = string.format( "%s %s-%s %s-%s-show %s-%s-hide",
                         sel, sign, assign, sign, assign, sign, assign )
    apply:addClass( sel )
         :newline()
         :node( Tutorial.flipflop( true, assign ) )
         :newline()
         :node( Tutorial.flipflop( false, assign ) )
end -- Tutorial.flipper()



Tutorial.flipflop = function ( activate, assign )
    -- Create single toggle image
    --     activate  -- (boolean) more (down), or not
    --     assign    -- (string) ID, or nil
    -- Returns: (mw.html), or (string) if not
    local j       = 16
    local support = mw.ustring.char( 43, 47, 8722 )
    local sign    = "OOjs UI icon caret%s.svg"
    local r, s
    if activate then
        s = "Down"
    else
        s = "Up"
    end
    r = string.format( "[[File:%s|%dpx|link=#top|alt=|%s]]",
                       string.format( sign, s ),  j,  support )
    if assign then
        if activate then
            s = "show"
        else
            s = "hide"
        end
        r = mw.html.create( "span" )
                   :addClass( "mw-collapsible" )
                   :attr( "id",
                          string.format( "mw-customcollapsible-%s-%s",
                                         assign, s ) )
                   :wikitext( r )
        if not activate then
            r:addClass( "mw-collapsed" )
             :css( "display", "none" )
        end
    end
    return r
end -- Tutorial.flipflop()



Tutorial.focus = function ( at, about, appoint )
    -- Retrieve page name of particular lesson in trail
    --     at       -- page name, or nil
    --     about    -- lesson name, or nil (means first in trail)
    --     appoint  -- module title and base page, page derived else
    -- Returns: (string)
    local suite, start = Tutorial.facility( appoint, at )
    local r, trail
    for i = 1, #Tutorial.def.trails do
        trail = Tutorial.def.trails[ i ]
        if type( trail ) == "table"  and
           type( trail[ 2 ] ) == "table"  and
           ( trail[ 1 ] == start  or
             trail[ 2 ][ 1 ] == start ) then
            if about then
                trail = trail[ 2 ]
                for k = 1, #trail do
                    if trail[ k ] == about then
                        r = string.format( "%s/%d-%d", suite, i, k )
                        break -- k = 1, #trail
                    end
                end -- k = 1, #trail
            else
                r = string.format( "%s/%d-1", suite, i )
            end
            break -- i = 1, #Tutorial.def.trails
        end
    end -- i = 1, #Tutorial.def.trails
    if not r then
        local t
        if about then
            t = mw.title.new( string.format( "%s/%s",
                                             Tutorial.page.baseText,
                                             about ),
                              Tutorial.page.nsText )
            if t.exists then
                r = t.prefixedText
            end
        end
        if not r then
            t = mw.title.new( Tutorial.page.baseText,
                              Tutorial.page.nsText )
            r = t.prefixedText
        end
    end
    return r
end -- Tutorial.focus()



Tutorial.fold = function ( align )
    -- Create DEFAULTSORT and Category
    --     align  -- sortkey
    -- Returns:
    --     (string) may be empty
    local r
    if type( Tutorial.def.cat ) == "string" then
        local s = Tutorial.frame:callParserFunction( "DEFAULTSORT",
                                                     align )
        r = string.format( "\n[[Category:%s]]", Tutorial.def.cat )
    else
        r = ""
    end
    return r
end -- Tutorial.fold()



Tutorial.folder = function ()
    -- Create maintenance survey
    -- Returns:
    --     (mw.html)
    local r
    if type( Tutorial.def.trails ) == "table" then
        local dl     = mw.html.create( "dl" )
        local e      = mw.html.create( "span" )
        local room   = mw.site.namespaces[ Tutorial.page.namespace ]
        local story  = "[[%s:%s/%%s|%%s]]"
        local single = "[[%s:%s/%%d-%%d|%%d]]. " .. story .. " %s %%s %s"
        local stitch = "[[%s:%s/%%d-%%d|@]]/[[%s:%s/%%s|@]] %%s"
        local section, src, strict, sum, trail, ttips
        e:css( "font-size",   "smaller" )
         :css( "margin-left", "2em" )
         :newline()
         :wikitext( string.format( stitch,
                                   room.talk.name,
                                   Tutorial.page.baseText,
                                   room.talk.name,
                                   Tutorial.page.baseText ) )
        single = string.format( single,
                                Tutorial.page.nsText,
                                Tutorial.page.baseText,
                                Tutorial.page.nsText,
                                Tutorial.page.baseText,
                                mw.ustring.char( 8211 ),
                                tostring( e ) )
        story  = string.format( story,
                                Tutorial.page.nsText,
                                Tutorial.page.baseText )
        for i = 1, #Tutorial.def.trails do
            trail = Tutorial.def.trails[ i ]
            if type( trail ) == "table" then
                section = trail[ 1 ]
                if type( section ) == "string" then
                    r   = true
                    src = string.format( story, section, section )
                    e   = mw.html.create( "span" )
                    e:css( "font-size",   "smaller" )
                     :css( "margin-left", "2em" )
                     :newline()
                     :wikitext( string.format( "[[%s:%s/%s|@]]",
                                               room.talk.name,
                                               Tutorial.page.baseText,
                                               section ) )
                    dl:newline()
                      :node( mw.html.create( "dt" )
                                    :wikitext( src )
                                    :node( e ) )
                    src, sum = Tutorial.foreign( section )
                    if sum ~= section then
                        dl:newline()
                          :node( mw.html.create( "dd" )
                                        :wikitext( sum ) )
                    end
                    trail = trail[ 2 ]
                    if type( trail ) == "table" then
                        ttips = Tutorial.future( trail )
                        for k = 1, #trail do
                            strict = Tutorial.fenced( i, k, trail[ k ] )
                            src    = string.format( single,
                                                    i, k, k,
                                                    trail[ k ],
                                                    trail[ k ],
                                                    ttips[ k ],
                                                    k, k,
                                                    trail[ k ],
                                                    strict )
                            dl:newline()
                              :node( mw.html.create( "dd" )
                                            :wikitext( src ) )
                        end -- k = 1, #trail
                    end
                end
            end
        end -- i = 1, #Tutorial.def.trails
        if r then
            r = dl
        end
    end
    return r
end -- Tutorial.folder()



Tutorial.foreign = function ( access, above )
    -- Retrieve page and summary
    --     access  -- (string) subpage
    --     above   -- (string) supreme page, or nil
    -- Returns:
    --     (string)  source, or nil
    --     (string)  summary
    local page, source, sum, title
    if above then
        title = mw.title.new( above )
    else
        title = Tutorial.page
    end
    page   = mw.title.makeTitle( title.nsText,
                                 string.format( "%s/%s",
                                                title.baseText,
                                                access ) )
    source = page:getContent()
    if source then
        if not Tutorial.patSummary then
            Tutorial.patSummary = string.format( "%s%s%s%s%s",
                                                 "%{%{%s*#invoke:%s*",
                                                 "Tutorial%s*",
                                                 "|%s*s%l+%s*",
                                                 "|%s*summary%s*=%s*",
                                                 "([^%}]+)%s*%}%}" )
        end
        sum = source:match( Tutorial.patSummary )
        if sum then
            sum = mw.text.trim( sum )
        end
    end
    return source,  sum or access
end -- Tutorial.foreign()



Tutorial.forward = function ( apply, album, at, advance, about, alter )
    -- Arrow button (horizontal)
    --     apply    -- (mw.html) section
    --     album    -- (number) trail, or false
    --     at       -- (number) target section, or false
    --     advance  -- (number) 1: rightward -- -1: left -- 0: start
    --     about    -- (string) tooltip, or false
    --     alter    -- (boolean) true: small
    local e = mw.html.create( "div" )
    local j, k, m, s, src
    if advance == -1 then
        s = " left"
    elseif advance == 0 then
        s = ""
    else
        s = " right"
    end
    if alter then
        m = 9
        j = 1
        k = 2
    else
        m = 24
        j = 3
        k = 4
    end
    apply:css( "margin",   string.format( "%dpx", j ) )
    s   = string.format( "File:White triangle%s.svg", s )
    src = string.format( "[[%s|%dpx|link=%%s]]", s, m )
    if at then
        local btn = mw.html.create( "span" )
        btn:addClass( "mw-ui-button mw-ui-progressive" )
           :css( "padding",  string.format( "%dpx", k ) )
           :css( "min-width", "0" )
           :wikitext( string.format( src, "" ) )
        if album then
            local f = function ( allow, at, arrow )
                          local wrap = mw.html.create( "span" )
                          wrap:wikitext( string.format( "[%s %s]",
                                                        at, arrow ) )
                          if allow then
                              wrap:addClass( "nomobile" )
                          else
                              wrap:addClass( "mobile" )
                                  :css( "display", "none" )
                          end
                          apply:node( wrap )
                      end
            local show
            s = string.format( "%d-%d", album, at )
            btn:attr( "title",  about or s )
            s = string.format( "%s:%s/%s",
                               Tutorial.page.nsText,
                               Tutorial.page.baseText,
                               s )
            s = tostring( mw.uri.canonicalUrl( s ) )
            apply:addClass( "plainlinks" )
                 :attr( "role", "button" )
            show = tostring( btn )
            f( true, s, show )
            s = s:gsub( "(//%l+%.)", "%1m." )
            f( false, s, show )
        else
            btn:attr( "title", "Demo" )
            apply:node( btn )
        end
        apply:css( "background-color", "#3366CC" )    -- fallback
    else
        src = string.format( src, "|&#215;" )
        apply:css( "background-color", "#B0B0B0" )
             :css( "padding",  string.format( "%dpx", k ) )
             :wikitext( src )
    end
end -- Tutorial.forward()



Tutorial.full = function ( at )
    -- Collect all trail page contents
    --     at  -- trail name
    -- Returns: (string) collection, or nil
    local r, trail
    for i = 1, #Tutorial.def.trails do
        trail = Tutorial.def.trails[ i ]
        if type( trail ) == "table" then
            if trail[ 1 ] == at then
                if type( trail[ 2 ] ) == "table" then
                    trail = trail[ 2 ]
                    if type( trail ) == "table" then
                        local src, sum = Tutorial.foreign( at )
                        local e, m, n, s
                        e = mw.html.create( "div" )
                                   :css( "clear", "both" )
                                   :css( "margin-top", "1em" )
                                   :css( "margin-bottom", "1em" )
                                   :wikitext( Tutorial.txt.superior )
                        r = string.format( "%s\n%s\n%s\n__TOC__",
                                           Tutorial.flat( at ),
                                           sum,
                                           tostring( e ) )
                        for k = 1, #trail do
                            s = trail[ k ]
                            if type( s ) == "string" then
                                s2, sum = Tutorial.foreign( s )
                                if type( s2 ) == "string" then
                                    m, n = s2:find( "}}\n?[^\n]+\n" )
                                    if n then
                                        s  = s2:sub( 1,  n - 1 )
                                        s2 = s2:sub( n )
                                    else
                                        s  = s2
                                        s2 = ""
                                    end
                                    s2 = s:gsub( "'''", "" ) .. s2
                                    s  = Tutorial.frame:preprocess( s2 )
                                    e  = mw.html.create( "h2" )
                                                :wikitext( sum )
                                    r  = string.format( "%s\n%s\n%s",
                                                        r,
                                                        tostring( e ),
                                                        s )
                                end
                            end
                        end -- k = 1, #trail
                    end
                end
                break -- i = 1, #all
            end
        end
    end -- i = 1, #Tutorial.def.trails
    return r
end -- Tutorial.full()



Tutorial.further = function ( all, album, at )
    -- Trail navigation
    --     all     -- (table) subpages
    --     album   -- (number) trail
    --     at      -- (number) section
    -- Returns: (mw.html)
    local before = mw.html.create( "div" )
    local down   = mw.html.create( "div" )
    local pop    = mw.html.create( "div" )
    local post   = mw.html.create( "div" )
    local row    = mw.html.create( "div" )
    local r      = mw.html.create( "div" )
    local ul     = mw.html.create( "ul" )
    local ttips  = Tutorial.future( all, at )
    local e, m, s, support, t
    if at > 1 then
        m       = at - 1
        support = ttips[ m ]
    end
    before:css( "float", "left" )
    Tutorial.forward( before, album, m, -1, support )
    if at < #all then
        m       = at + 1
        support = ttips[ m ]
    else
        m = false
    end
    post:css( "float", "right" )
    Tutorial.forward( post, album, m, 1, support )
    row:node( before )
       :node( post )
    Tutorial.flipper( down, "tutorial" )
    if at > 1 then
        local beg = mw.html.create( "div" )
                           :css( "float", "left" )
        Tutorial.forward( beg, album, 1, 0, Tutorial.txt.starter, true )
        down = mw.html.create( "div" )
                      :node( beg )
                      :newline()
                      :node( down )
    end
    pop:attr( "id", "mw-customcollapsible-tutorial" )
       :addClass( "mw-collapsible mw-collapsed" )
       :addClass( "mobile" )
       :css( "display",    "none" )
       :css( "clear",      "both" )
       :css( "text-align", "left" )
       :newline()
    for i = 1, #all do
        s = all[ i ]
        e = mw.html.create( "span" )
        if i == at then
            e:css( "font-weight", "bold" )
        else
            t = mw.html.create( "span" )
                  :attr( "title", ttips[ i ] )
                  :wikitext( s )
            s = string.format( "[[%s:%s/%d-%d|%s]]",
                               Tutorial.page.nsText,
                               Tutorial.page.baseText,
                               album,
                               i,
                               tostring( t ) )
        end
        ul:node( mw.html.create( "li" )
                        :node( e:wikitext( s ) ) )
          :newline()
    end -- i = 1, #all
    pop:node( ul )
    r:css( "text-align", "center" )
     :node( row )
     :newline()
     :node( mw.html.create( "div" )
                   :css( "clear", "both" ) )
     :newline()
     :node( down )
     :newline()
     :node( pop )
    return r
end -- Tutorial.further()



Tutorial.future = function ( all, already, another, above )
    -- Retrieve tooltips
    --     all       -- (table) subpages
    --     already   -- (number) trail
    --     another   -- (string) text if already, or nil
    --     above     -- (string) supreme page, or nil
    -- Returns: (table)
    local r = { }
    local d, s, sub
    for i = 1, #all do
        if i == already then
            s = another or "'''&lt;*&gt;'''"
        else
            sub = all[ i ]
            d, s = Tutorial.foreign( sub, above )
        end
        -- TODO    plaintext
        table.insert( r, s )
    end -- i = 1, #all
    return r
end -- Tutorial.future()



-- Export
local p = { }

p.begin = function ( frame )
    -- Retrieve page name of first lesson in trail
    --     1 -- title part of trail or first page
    --     2 -- Wikipedia:Tutorial, or derive from page name
    local t = frame.args[ 2 ]
    local r = Tutorial.fetch( t )
    if type( r ) == "table" then
        Tutorial.def   = r
        Tutorial.frame = frame
        r              = Tutorial.focus( frame.args[ 1 ], false, t )
    end
    return r
end -- p.begin



p.gadget = function ( frame )
    -- Retrieve GUI elements
    local def = Tutorial.fetch( frame.args[ 1 ] )
    local r   = mw.html.create( "span" )
    if type( def ) == "table" then
        local sel = frame.args[ 2 ]
        Tutorial.def = def
        if sel == "go" then
            Tutorial.forward( r, false, true, 1, false, true )
        elseif sel == "top" then
            Tutorial.forward( r, false, true, 0, false, true )
        elseif sel == "expand" then
            r:wikitext( Tutorial.flipflop( true ) )
             :wikitext( Tutorial.flipflop( false ) )
        end
    end
    return r
end -- p.gadget



p.index = function ( frame )
    -- List all trails or lessons (main or maintenance page)
    local r = Tutorial.fetch()
    if type( r ) == "table" then
        local sel = frame.args[ 1 ]
        Tutorial.def   = r
        Tutorial.frame = frame
        if  frame.args.mode == "main"  or  not sel then
            sel = sel or Tutorial.page.prefixedText
            r   = Tutorial.father( sel )
        elseif sel == "trail" then
            local t2 = Tutorial.page.subpageText:match( "^(%d+)%-%d+$" )
            local t1
            if t2 then
                if type( Tutorial.def.trails ) == "table" then
                    t2  = tonumber( t2 )
                    sel = Tutorial.def.trails[ t2 ]
                    if type( sel ) == "table"  and
                       type( sel[ 2 ] ) == "table" then
                        t1 = sel[ 2 ]
                    end
                end
            else
                t1, t2 = Tutorial.find( Tutorial.page.subpageText )
            end
            if type( t1 ) == "table" then
                local less = faculty( frame.args, "less" )
                sel = string.format( "%s:%s",
                                     Tutorial.page.nsText,
                                     Tutorial.page.baseText )
                r   = Tutorial.features( sel, t1, t2, true, not less )
            else
                local e = mw.html.create( "div" )
                e:css( "clear", "both" )
                 :css( "margin-top", "1em" )
                 :css( "margin-bottom", "1em" )
                 :wikitext( string.format( Tutorial.txt.survey,
                                           Tutorial.focus() ) )
                r = tostring( e )
            end
        elseif sel == "maintain" then
            r = Tutorial.folder()
        end
    end
    return r or ""
end -- p.index



p.isVirtual = function ()
    -- Is this a virtual page?
    local r = Tutorial.page.subpageText:find( "^%d+%-%d+$" )
    if faculty( frame.args, "not" ) then
        r = not r
    end
    if r then
        r = "1"
    else
        r = ""
    end
    return r
end -- p.isVirtual



p.page = function ( frame )
    -- Virtual lesson page
    local r = Tutorial.fetch()
    if type( r ) == "table" then
        Tutorial.def = r
        local k, i = Tutorial.page.subpageText:match( "^(%d+)%-(%d+)$" )
        if k then
            Tutorial.frame = frame
            r = Tutorial.fake( tonumber( k ),  tonumber( i ) )
        else
            r = fault( Tutorial.txt.sequence )
        end
    else
        r = fault( r )
    end
    return r
end -- p.page



p.redirect = function ( frame )
    -- Retrieve page name of particular lesson in trail
    --     1 -- title part of trail or first page
    --     2 -- lesson
    --     3 -- Wikipedia:Tutorial, or derive from page name
    local t = frame.args[ 3 ]
    local r
    if t then
        Tutorial.page = mw.title.new( t )
    end
    r = Tutorial.fetch()
    if type( r ) == "table" then
        Tutorial.def   = r
        Tutorial.frame = frame
        r              = Tutorial.focus( frame.args[ 1 ],
                                         frame.args[ 2 ],
                                         t )
    end
    return r
end -- p.redirect



p.single = function ( frame )
    -- Single content page
    local r = Tutorial.fetch( false, true )
    if type( r ) == "table" then
        Tutorial.def = r
        local summary = frame.args.summary or ""
        if summary == "" then
            r = fault( Tutorial.txt.summary0 )
        else
            local parent = frame:getParent()
            Tutorial.frame = frame
            if parent:getTitle()  ==  Tutorial.page.prefixedText then
                r = Tutorial.flat( summary )
            else
                r = ""
            end
        end
    elseif r ~= "" then
        r = fault( r )
    end
    return r
end -- p.single



p.start = function ( frame )
    -- Start page of a trail
    local r = Tutorial.fetch()
    if type( r ) == "table" then
        local summary = frame.args.summary or ""
        if summary == "" then
            r = fault( Tutorial.txt.summary0 )
        else
            local sort
            Tutorial.def   = r
            Tutorial.frame = frame
            if type( Tutorial.def.trails ) == "table" then
                r = Tutorial.full( Tutorial.page.subpageText )
            end
            if r then
                sort = "* "
            else
                r    = Tutorial.txt.slot
                sort = "? "
            end
            r = r .. Tutorial.fold( sort .. Tutorial.page.subpageText )
        end
    else
        r = fault( r )
    end
    return r
end -- p.start



p.style = function ( frame )
    -- Retrieve standard style
    -- Parameter
    --     1 -- Wikipedia:Tutorial
    --     2 -- bgc, icon, ...
    local def = Tutorial.fetch( frame.args[ 1 ] )
    local r
    if type( def ) == "table" then
        def = def[ "style" ]
        if type( def ) == "table" then
            r = def[ frame.args[ 2 ] ]
        end
    end
    return r or ""
end -- p.style



p.failsafe = function ()
    return Tutorial.serial
end -- p.failsafe

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.