Vorlagenprogrammierung Diskussionen Lua Test Unterseiten
Modul Deutsch English

Modul: Dokumentation

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


local ISO15924 = { suite  = "ISO15924",
                   sub    = "maintain",
                   serial = "2019-11-12",
                   item   = 0,
                   main   = 71584769,
                   make   = 71840276 }
--[=[
Create pages to maintain ISO 15924 data
]=]
codeLua = { }



local follow = function ( assign )
    local r = { }
    for k, v in pairs( assign ) do
        table.insert( r, k )
    end -- for k, v
    table.sort( r )
    return r
end -- follow()



codeLua.start = [===[
local ISO15924 = { suite  = "%s",
                   sub    = "codes",
                   serial = "%s",
                   item   = %d,
                   main   = %d }
--[=[
ISO 15924 mw.loadData() with a snapshot of codes
]=]
local Failsafe = ISO15924

]===]



codeLua.suffix = [===[


local fresh = function ()
    -- Check for global update
    -- Returns: true, if matching global version; false, if not
    local r
    if mw.title.getCurrentTitle().namespace > 0  and
       type( Failsafe.item ) == "number"  and  Failsafe.item > 0 then
        local storage = string.format( "Q%d", Failsafe.item )
        local entity  = mw.wikibase.getEntity( storage )
        if type( entity ) == "table" then
            local seek =  Failsafe.serialProperty or "P348"
            local vsn  = entity:formatPropertyValues( seek )
            if type( vsn ) == "table"  and
               vsn.value == Failsafe.serial then
                r = true
            end
        end
    end
    return r or false
end -- fresh()


@.failsafe = @.serial
if mw.title.getCurrentTitle().namespace > 0 then
    @.last = fresh()
end
return @]===]



codeLua.full = function ( frame )
    -- Make Lua code for snapshot
    local collection, data, e, lucky, r, sub, support
    lucky, collection = pcall( mw.ext.data.get,
                               ISO15924.suite .. ".tab" )
    if type( collection ) == "table" then
        lucky, data = pcall( mw.loadData, "Module:ISO15924/commons" )
    else
        data = collection
    end
    if type( data ) == "table" then
        local stamp
        frame      = frame or mw.getCurrentFrame()
        stamp      = frame:callParserFunction( "#time", "c" )
        r          = string.format( codeLua.start,
                                    ISO15924.suite,
                                    stamp,
                                    ISO15924.make,
                                    ISO15924.main )
        collection = collection.data
        for i = 1, #collection do
            e       = collection[ i ]
            sub     = e[ 1 ]
            support = e[ 2 ]
            r = string.format( "%s\n%s.%s = {\n%s\n}",
                               r,
                               ISO15924.suite,
                               sub,
                               codeLua[ support ]( data[ sub ] ) )
        end -- for i
        r = r .. codeLua.suffix:gsub( "@", ISO15924.suite )
    else
        r = data
    end
    return r
end -- codeLua.full()



codeLua.boolean = function ( assign )
    local o = follow( assign )
    local r = ""
    local sep = ""
    local s
    for i = 1, #o do
        s = o[ i ]
        if ( assign[ s ] ) then
            r = string.format( "%s%s%s = true", r, sep, s )
            sep = ",\n"
        end
    end -- for i
    return r
end -- codeLua.boolean()



codeLua.ranges = function ( assign )
    local o = follow( assign )
    local r = ""
    local sep = ""
    local j, m, s, sss, v
    for i = 1, #o do
        s = o[ i ]
        v = assign[ s ]
        if s == "*" then
            s = "[\"*\"] "
        elseif #s == 3 then
            s = s .. " "
        end
        r = string.format( "%s%s%s = {", r, sep, s )
        if type( v ) == "table" then
            s = ""
            sss = ""
            for kk, vv in pairs( v ) do
                r = r .. s
                if type( vv ) == "table" then
                    j   = false
                    for kkk, vvv in pairs( vv ) do
                        if j then
                            if j < vvv then
                                m = vvv
                            else
                                m = j
                                j = vvv
                            end
                        else
                            j = vvv
                        end
                    end -- for kkk, vvv
                    r = string.format( "%s%s { 0x%X, 0x%X }",
                                       r, sss, j, m )
                    sss = ",\n        "
                end
            end -- for kk, vv
            s = ", "
        end
        r = r .. " }"
        sep = ",\n"
    end -- for i
    return r
end -- codeLua.ranges()



codeLua.reverse = function ( frame, around )
    -- Make Lua code for unicode ranges of script table
    local data, scripts = ISO15924.fetchUnicodeMap()
    local r
    if type( data ) == "table" then
        local e, s, sep, stamp
        if around then
            if not frame then
                frame = mw.getCurrentFrame()
            end
            stamp = frame:callParserFunction( "#time", "c" )
        end
        for i = 1, #data do
            sep = ""
            if s then
                s = s .. ",\n"
            else
                s = ""
            end
            e = data[ i ]
            s = string.format( "%s{ 0x%05X, 0x%05X, { ",
                               s, e[ 1 ], e[ 2 ] )
            for k = 3, #e do
                s   = string.format( "%s%s\"%s\"", s, sep, e[ k ] )
                sep = ", "
            end -- for k
            s = s .. " } }"
        end -- for i
        if around then
            e = "-- mw.loadData() table\n" ..
                "-- scripting systems for unicode range\n" ..
                "return {\n" ..
                "suite    = \"%s\",\n" ..
                "sub      = \"%s\",\n" ..
                "failsafe = \"%s\",\n" ..
                "commons  = \"%s\",\n" ..
                "reverse  = {\n%s\n}\n};"
            r = string.format( e,
                               ISO15924.suite,
                               "reverse",
                               stamp,
                               scripts,
                               s )
        else
            r = s
        end
    else
        r = data
    end
    return r
end -- codeLua.reverse()



codeLua.strings = function ( assign )
    local o = follow( assign )
    local r = ""
    local sep = ""
    local s, v
    for i = 1, #o do
        s = o[ i ]
        v = assign[ s ]
        if s == "or" then
            s = "[\"or\"]"
        elseif #s == 3 then
            s = s .. "   "
        elseif #s == 2 then
            s = s .. "    "
        end
        r = string.format( "%s%s%s = { ", r, sep, s )
        if type( v ) == "table" then
            s = ""
            for kk, vv in pairs( v ) do
                r = string.format( "%s%s\"%s\"", r, s, vv )
                s = ", "
            end -- for kk, vv
        end
        r = r .. " }"
        sep = ",\n"
    end -- for k, v
    return r
end -- codeLua.strings()



ISO15924.fetchUnicodeJSON = function ()
    -- Make JSON code for unicode ranges of script table
    local data, scripts = ISO15924.fetchUnicodeMap()
    local r
    if type( data ) == "table" then
        local e, s, sep
        for i = 1, #data do
            sep = ""
            if s then
                s = s .. ",\n"
            else
                s = ""
            end
            e = data[ i ]
            s = string.format( "%s[ \"%05X\", \"%05X\", \"",
                               s, e[ 1 ], e[ 2 ] )
            for k = 3, #e do
                s   = string.format( "%s%s%s", s, sep, e[ k ] )
                sep = " "
            end -- for k
            s = s .. "\" ]"
        end -- for i
        r = string.format( "[\n%s\n]", s )
    else
        r = data
    end
    return r
end -- ISO15924.fetchUnicodeJSON()



ISO15924.fetchUnicodeMap = function ()
    -- Make table for unicode ranges of script table
    local lucky, data = pcall( mw.loadData,
                               "Module:ISO15924/commons" )
    local r, scripts
    if type( data ) == "table" then
        if type( data.unicodes ) == "table" then
            local unicodes = data.unicodes
            local bib
            lucky, bib = pcall( require, "Module:ISO15924" )
            if type( bib ) == "table" then
                local ranges = { }
                bib = bib.ISO15924()
                for s, v in pairs( unicodes ) do
                    if #s == 4  and
                       s:match( "^%u%l%l%l$" )  and
                       type( v ) == "table" then
                        bib.Unicode.merge( ranges, unicodes, s, true )
                    end
                end -- for s, v
                r = ISO15924.fixUnicodeRanges( bib, ranges )
            else
                r = bib
            end
        else
            r = "ISO15924/commons .unicodes not found"
        end
        scripts = data.failsafe
    else
        r = data
    end
    return r, scripts
end -- ISO15924.fetchUnicodeMap()



ISO15924.fixUnicodeRanges = function ( access, assign )
    -- Unify sequence table of ranges
    -- Precondition:
    --     access  -- table, with library
    --     assign  -- table, with sequence table of ranges
    -- Postcondition:
    --     Returns unified table
    local r = assign
    local k = #r
    local before, current, living, plus
    access.Unicode.sort( r )
    while k > 1 do
        before  = r[ k - 1 ]
        current = r[ k ]
        if before[ 2 ] > current[ 2 ] then
            plus = { current[ 2 ] + 1,  before[ 2 ] }
            for i = 3, #before do
                table.insert( plus, before[ i ] )
            end -- for i
            before[ 2 ] = current[ 2 ]
            r[ k - 1 ]  = before
            table.insert( r,  k + 1,  plus )
            living = true
        elseif before[ 2 ] >= current[ 1 ]  and
               before[ 2 ] < current[ 2 ]  and
               before[ 1 ] < current[ 1 ] then
            plus = { before[ 2 ] + 1,  current[ 2 ] }
            for i = 3, #current do
                table.insert( plus, current[ i ] )
            end -- for i
            current[ 2 ] = before[ 2 ]
            r[ k ]       = current
            table.insert( r,  k + 1,  plus )
            living = true
        elseif before[ 1 ] < current[ 1 ]  and
               before[ 2 ] == current[ 2 ] then
            for i = 3, #before do
                table.insert( current, before[ i ] )
            end -- for i
            r[ k ]      = current
            before[ 2 ] = current[ 1 ] - 1
            r[ k - 1 ]  = before
        elseif before[ 1 ] == current[ 1 ]  and
               before[ 2 ] == current[ 2 ] then
            for i = 3, #current do
                table.insert( before, current[ i ] )
            end -- for i
            r[ k - 1 ] = before
            table.remove( r, k )
        end
        k = k - 1
    end -- while
    if living then
        r = ISO15924.fixUnicodeRanges( access, r )
    else
        for k = 1, #r do
            current = r[ k ]
            if #current > 3 then
                plus   = { current[ 1 ],  current[ 2 ] }
                before = { }
                for i = 3, #current do
                    table.insert( before, current[ i ] )
                end -- for i
                table.sort( before )
                for i = 1, #before do
                    if i == 1  or
                       before[ i ]  ~=  before[ i - 1 ] then
                        table.insert( plus, before[ i ] )
                    end
                end -- for i
                r[ k ] = plus
            end
        end -- for k
    end
    return r
end -- ISO15924.fixUnicodeRanges()



ISO15924.failsafe = ISO15924.serial



-- Export
local p = { }

p.fetchUnicodeJSON = function ( frame )
    return ISO15924.fetchUnicodeJSON ()
end -- p.fetchUnicodeJSON()

p.fetchLua = function ( frame )
    return codeLua.full( frame )
end -- p.fetchLua()

p.fetchUnicodeLua = function ( frame )
    return codeLua.reverse( frame, true )
end -- p.fetchUnicodeLua()

p.ISO15924 = function ()
    return ISO15924
end -- p.ISO15924

return p