Module:Chessboard mxn

Από τη Βικιπαίδεια, την ελεύθερη εγκυκλοπαίδεια
Documentation icon Τεκμηρίωση module[δημιουργία]
local p = {}
local gr_used = false
local solid_board = nil

function chessboard(args, size, rows, cols, rev, trans, lightdark, altprefix, letters, numbers, header, footer, align, clear)
    function colchar( col ) --το στίγμα='ς' και το δίγαμμα='f' συμπληρώνουν το 25ο και 26ο γράμμα του αγγλικού αλφαβήτου για λόγους συμβατότητας
        return (col <= 26) and mw.ustring.sub( 'αβγδεζηθικλμνξοπρστυφχψωςf', col, col )
            or mw.ustring.sub( "αβγδεζηθικλμνξοπρστυφχψωςf", math.floor((col-1)/26), math.floor((col-1)/26) )
            .. mw.ustring.sub( "αβγδεζηθικλμνξοπρστυφχψωςf", col-math.floor((col-1)/26)*26, col-math.floor((col-1)/26)*26 )
    end
    function image_square( pc, row, col, size, t, flip, altprefix )
        local piecenames_u = {
            p = 'πιόνι',                    --σ (Τα 'δθλους' είναι δεσμευμένα για πιθανή μελλοντική χρήση)
            r = 'πύργος',                   --π
            n = 'ίππος',                    --ι
            b = 'αξιωματικός',              --α
            q = 'βασίλισσα',                --β
            k = 'βασιλιάς',                 --ρ
            a = 'αρχιεπίσκοπος',            --ς ή πριγκίπισσα, αρχηγός (princess, chief)
            c = 'καγκελάριος',              --κ ή αυτοκράτειρα (empress)
            z = 'πρωταθλητής',              --ω (champion)
            w = 'μάγος',                    --μ ή κιρίν (wizard, kirin)
            t = 'τρελλός',                  --τ ή τζόκερ, υπεριππότης (fool, joker, superknight)
            h = 'ανεστραμμένο πιόνι',       --η ή αντιπιόνι, λοχίας (anti-pawn, sergeant, berolina pawn)
            m = 'ανεστραμμένος πύργος',     --ζ ή βεζίρης, τανκ, καταπέλτης (wazir, dabbaba, tank)
            s = 'ανεστραμμένος ίππος',      --ν ή καμήλα, ζέβρα, φοίνικας, μονόκερος (camel, zebra, phoenix, unicorn, nightrider, knigthmare)
            s1= 'βάρκα',                    --ψ (boat)
            e = 'ανεστραμμένος αξιωματικός',--ξ ή ελέφαντας (elephant, alfil, ferz)
            e1= 'ελέφαντας',                --ε (elephant)
            g = 'ανεστραμμένη βασίλισσα',   --γ ή αμαζόνα, ακρίδα (amazon, grasshopper, hopper)
            f = 'ανεστραμμένος βασιλιάς',   --φ ή πρίγκιπας, άνθρωπος, πολίτης, θνητός (prince, mann, commoner)
            G = 'καμηλοπάρδαλη',            -- ή κιρίν (giraffe, kirin)
            U = 'μονόκερος',                -- (unicorn)
            Z = 'ζέβρα'                     -- (zebra)
            }
        local symnames = {
            xx = 'μαύρο χι',                --χχ
            ox = 'λευκό χι',                --οχ
            xo = 'μαύρος κύκλος',           --χο
            oo = 'λευκός κύκλος',           --οο
            ud = 'τόξο πάνω-κάτω',          --τ0
            dl = 'τόξο κάτω-αριστερά',      --τ1
            da = 'τόξο κάτω',               --τ2
            dr = 'τόξο κάτω-δεξιά',         --τ3
            la = 'τόξο αριστερά',           --τ4
            lr = 'τόξο αριστερά-δεξιά',     --τ5
            ra = 'τόξο δεξιά',              --τ6
            ul = 'τόξο πάνω-αριστερά',      --τ7
            ua = 'τόξο πάνω',               --τ8
            ur = 'τόξο πάνω-δεξιά',         --τ9
            db = 'τόξο πάνω-δεξιά και κάτω-αριστερά',
            dw = 'τόξο πάνω-αριστερά και κάτω-δεξιά',
            x0 = 'μηδέν',                   --χ0
            x1 = 'ένα',                     --χ1
            x2 = 'δύο',                     --χ2
            x3 = 'τρία',                    --χ3
            x4 = 'τέσσερα',                 --χ4
            x5 = 'πέντε',                   --χ5
            x6 = 'έξι',                     --χ6
            x7 = 'επτά',                    --χ7
            x8 = 'οκτώ',                    --χ8
            x9 = 'εννιά',                   --χ9
            O0 = 'μαύρη μάρκα',             --Ο0
            O1 = 'λευκή μάρκα',             --Ο1
            O2 = 'κόκκινη μάρκα',           --Ο2
            O3 = 'πράσινη μάρκα',           --Ο3
            O4 = 'μπλε μάρκα',              --Ο4
            O5 = 'κυανή μάρκα',             --Ο5
            O6 = 'κίτρινη μάρκα',           --Ο6
            O7 = 'ροζ μάρκα',               --Ο7
            O8 = 'καφέ μάρκα',              --Ο8
            O9 = 'μωβ μάρκα',               --Ο9
            j0 = 'μαύρο πούλι',             --Π0
            j1 = 'λευκό πούλι',             --Π1
            D0 = 'μαύρη ντάμα',             --Δ0
            D1 = 'λευκή ντάμα',             --Δ1
            HL = 'επισημασμένο'             --ΕΠ
            }
        local colornames_m = {
            l = 'λευκός',                   --α
            d = 'μαύρος',                   --σ
            L = 'επισημασμένος λευκός',     --Λ (με περίγραμμα)
            D = 'επισημασμένος μαύρος',     --Μ (με περίγραμμα)
            r = 'κόκκινος',                 --κ
            g = 'πράσινος',                 --π
            b = 'μπλε',                     --ε
            y = 'κίτρινος'                  --ι
            }
        local colornames_f = {
            l = 'λευκή',                    --α
            d = 'μαύρη',                    --σ
            L = 'επισημασμένη λευκή',       --Λ (με περίγραμμα)
            D = 'επισημασμένη μαύρη',       --Μ (με περίγραμμα)
            r = 'κόκκινη',                  --κ
            g = 'πράσινη',                  --π
            b = 'μπλε',                     --ε
            y = 'κίτρινη'                   --ι
            }
        local colornames_u = {
            l = 'λευκό',                    --λ
            d = 'μαύρο',                    --μ
            L = 'επισημασμένο λευκό',       --Λ (με περίγραμμα)
            D = 'επισημασμένο μαύρο',       --Μ (με περίγραμμα)
            r = 'κόκκινο',                  --κ
            g = 'πράσινο',                  --π
            b = 'μπλε',                     --ε
            y = 'κίτρινο'                   --ι
            }
        function colornames( color, piece )
            if mw.ustring.find( 'ph', piece, 1 ) then
                return colornames_u[color]
            elseif mw.ustring.find( 'qgGZ', piece, 1 ) or ( piece:match( 's' ) and mw.ustring.find( 'rgby', color, 1 ) ) then
                return colornames_f[color]
            else
                return colornames_m[color]
            end
        end
        function piecenames( color, piece )
            local p = piece
            if piece:match( 's' ) or piece:match( 'e' ) then
                if solid_board or mw.ustring.find( 'rgby', color, 1 ) then
                    p = p .. '1' --βάρκα ή ελέφαντας
                end
            end
            return piecenames_u[p]
        end
        function convert_color( color )
            if color == '' then
                return ''
            else
                local i = mw.ustring.find( 'λμΛΜκπει', color, 1 ) --λευκά, μαύρα, κόκκινα, πράσινα, μπλε, κίτρινα (τα κεφαλαία με περίγραμμα)
                if ( i ) then
                    return mw.ustring.sub( 'ldLDrgby', i, i )     --light, dark,  red,     green,   blue, yellow
                else
                    return color
                end
            end
        end
        function convert_piece( piece )
            if piece == '' then
                return ''
            else
                local i = mw.ustring.find( 'σπιαβρςκωμτηζξεvψγφ', piece, 1 ) --τα 'ολθδυς' είναι δεσμευμένα
                if ( i ) then
                    gr_used = true
                    return mw.ustring.sub( 'prnbqkaczwthmeessgf', i, i ) --τα 'dijlouvxy' είναι δεσμευμένα
                else
                    return piece
                end
            end
        end
        local piece = mw.ustring.gsub( pc, '^.*(%w)(%w).*$', '%1' ) or ''
        local color = mw.ustring.gsub( pc, '^.*(%w)(%w).*$', '%2' ) or ''
        local tmp = piece .. color
        local alt = altprefix .. colchar( col ) .. row .. ' '
        local idf = 'Chess '
        local idx = mw.ustring.find( 'τ0 τ1 τ2 τ3 τ4 τ5 τ6 τ7 τ8 τ9 χχ χο οχ οο Π0 Π1 Δ0 Δ1 ΕΠ',
            ( piece == '' and 'x' or piece ) .. ( color == '' and 'x' or color ), 1 )

        if idx then
            piece = mw.ustring.sub( 'ud dl da dr la lr ra ul ua ur xx xo ox oo j0 j1 D0 D1 HL', idx, idx )
            color = mw.ustring.sub( 'ud dl da dr la lr ra ul ua ur xx xo ox oo j0 j1 D0 D1 HL', idx + 1, idx + 1 )
        else
            idx = mw.ustring.find( '0123456789', ( color == '' and 'x' or color ), 1 )
            if idx then
                if piece:match( 'χ' ) then piece = 'x' elseif piece:match( 'Ο' ) then piece = 'O' else idx = nil end
            end
            if ( idx == nil ) then
                piece = convert_piece( piece )
                color = convert_color( color )
            end
        end
        if idx then gr_used = true end
        idx = mw.ustring.find( 'LD', ( color == '' and 'x' or color ), 1 ) --δεν υπάρχουν διάφανα επισημασμένα
           or mw.ustring.find( 'j0 j1 D0 D1 O0 O1 O2 O3 O4 O5 O6 O7 O8 O9',
           ( piece == '' and 'x' or piece ) .. ( color == '' and 'x' or color ), 1 ) --δεν υπάρχουν διάφανα για αυτά
        if t and ( idx == nil ) then
            idx = 't'
        elseif solid_board then
            idx = ( piece == '' ) and 'g' or 'l'
        else
            idx = ( ( (row + col + flip) % 2 ) == 0 ) and 'd' or 'l'
        end
        if piecenames_u[piece] and colornames_u[color] then
            alt = alt .. colornames( color, piece ) .. ' ' .. piecenames( color, piece )
            if color:match( 'b' ) then
                idx = 'g' --δεν υπάρχουν διάφανα μπλε
            elseif color:match( 'r' ) or color:match( 'g' ) or color:match( 'y' ) then
                idx = t and 't' or 'g' --π.χ. κόκκινος βασιλιάς: Chess krt45.svg | Chess krg45.svg
            end
        else
            alt = alt .. ( symnames[piece .. color] or tmp )
        end
        return string.format( '[[File:%s%s%s%s45.svg|%dx%dpx|alt=%s|%s]]', idf, piece, color, idx, size, size, alt, alt )
    end

    function letters_row( rev, num_lt, num_rt, cols )
        local res = '<tr style="vertical-align:middle">'
            .. ( num_lt and '<td style="padding:0; vertical-align:inherit"></td>' or '' )
            .. '<td style="padding:0; vertical-align:inherit; height:18px">'
        for k = 1, cols do
            res = res .. colchar(rev and (cols - k + 1) or k) .. '</td><td style="padding:0; vertical-align:inherit">'
        end
        res = res .. '</td>' .. ( num_lt and '<td style="padding:0; vertical-align:inherit"></td>' or '' ) .. '</tr>'
        return res
    end

    local flip = lightdark and 1 or 0
    local letters_tp = letters:match('both') or letters:match('top')
    local letters_bt = letters:match('both') or letters:match('bottom')
    local numbers_lt = numbers:match('both') or numbers:match('left')
    local numbers_rt = numbers:match('both') or numbers:match('right')
    local width = cols * size + 2
    if ( numbers_lt ) then width = width + 18 end
    if ( numbers_rt ) then width = width + 18 end

    local b = ''
    local caption = ''

    if ( letters_tp ) then b = b .. letters_row(rev, numbers_lt, numbers_rt, cols) .. '\n' end
    for trow = 1,rows do
        local row = rev and trow or (rows - trow + 1)
        b = b .. '<tr style="vertical-align:middle">'
        if ( numbers_lt ) then b = b .. '<td style="padding:0; vertical-align:inherit; width:18px">' .. row .. '</td>' end
        for tcol = 1,cols do
            local col = rev and (cols - tcol + 1) or tcol
            local idx = cols*(rows - row) + col + 2
            if (args[idx] == nil) then args[idx] = '  ' end
            local img = image_square(args[idx]:match('%w%w') or '', row, col, size, trans, flip, altprefix )
            local bg = ( solid_board or (((trow + tcol + flip) % 2) == 0) ) and '#ffce9e' or '#d18b47'
            b = b .. '<td style="padding:0; vertical-align:inherit; background-color: ' .. bg .. ';">' .. img .. '</td>'
        end
        if ( numbers_rt ) then b = b .. '<td style="padding:0; vertical-align:inherit; width:18px">' .. row .. '</td>' end
    end
    if ( letters_bt ) then b = b .. letters_row(rev, numbers_lt, numbers_rt, cols) .. '\n' end

    if footer:match('^%s*$')
    then
    else    
        caption = '<div class="thumbcaption">' .. footer .. '</div>\n'
    end
    b = '<table cellpadding=0 cellspacing=0 style="line-height: 0; background:white; font-size:88%; border:1px #b0b0b0 solid;'
        .. 'padding:0; margin:auto">\n' .. b .. '\n</table>[[Κατηγορία:Σελίδες που χρησιμοποιούν σκακιστικό πρότυπο '
        .. ( gr_used and 'με' or 'χωρίς' ) .. ' ελληνική σημειογραφία]]'
    
    if noframe then
        return b
    else
        return '<div class="thumb ' .. align .. '" style="clear:' .. clear .. '; text-align:center;">'
        .. header .. '\n<div class="thumbinner" style="width:' .. width .. 'px;">\n' 
        .. b .. '\n' .. caption .. '</div></div>'
    end
    
end

function convertFenToArgs( fen )
    -- converts FEN notation to an array of positions, offset by 2
    local res = {' ', ' '}
    -- Loop over rows, which are delimited by /
    for srow in string.gmatch("/" .. fen, "/%w+") do
        -- Loop over all letters and numbers in the row
        for piece in srow:gmatch( "%w" ) do
            if (piece:match("%d")) then
                -- if a digit
                for k=1,piece do
                    table.insert(res,' ')
                end
            else 
                -- not a digit
                local color = piece:match( '%u' ) and 'l' or 'd'
                piece = piece:lower()
                table.insert(res, piece .. color )
            end
        end
    end

    return res
end

function p.board(frame)
    local args = frame.args
    local pargs = frame:getParent().args
    local size = (args.size or pargs.size) or '26'
    local reverse = (args.reverse or pargs.reverse or '' ):lower() == "true"
    local trans = (args.transparent or pargs.transparent or '' ):lower() == "true"
    local lightdark = (args.lightdark or pargs.lightdark or '' ):lower() == "swap"
    local altprefix = args.altprefix or pargs.altprefix or ''
    local rows = args.rows or pargs.rows or 8
    local cols = args.cols or pargs.cols or 8
    local letters = ( args.letters or pargs.letters or 'both' ):lower() 
    local numbers = ( args.numbers or pargs.numbers or 'both' ):lower() 
    local header = mw.ustring.gsub( args[2] or pargs[2] or '', '^%s*(.-)%s*$', '%1' )
    local footer = args[3 + rows*cols] or pargs[3 + rows*cols] or ''
    local align = ( args[1] or pargs[1] or 'tright' ):lower()
    local clear = ( args.clear or pargs.clear ) or ( align:match('tright') and 'right' or 'none' )
    local noframe = (args.noframe or pargs.noframe or ''):lower() == "true"
    local fen = args.fen or pargs.fen

    size = mw.ustring.match(size, '[%d]+') or '26' -- remove px from size
    solid_board = ( tonumber( size ) >= 100 ) and true or false
    if solid_board then
        size = ( tonumber( size ) == 100 ) and '26' or tostring( tonumber( size ) - 100)
    end
    if (fen) then
        align = ( args.align or pargs.align or 'tright' ):lower()
        clear = ( args.clear or pargs.clear ) or ( align:match('tright') and 'right' or 'none' )
        header = args.header or pargs.header or ''
        footer = args.footer or pargs.footer or ''
        return chessboard(convertFenToArgs( fen ), size, rows, cols, reverse, trans, lightdark, altprefix, letters, numbers, header, footer, align, clear, noframe)
    end
    if args[3] then
        return chessboard(args, size, rows, cols, reverse, trans, lightdark, altprefix, letters, numbers, header, footer, align, clear, noframe)
    else
        return chessboard(pargs, size, rows, cols, reverse, trans, lightdark, altprefix, letters, numbers, header, footer, align, clear, noframe)
    end
    
end

return p