User:Testdrill/sandbox/Module:Test

local p = {} function chessboard(args, size, rev, letters, numbers, header, footer, align, clear)   function image_square( pc, row, col, size )        local colornames = { l = 'white', d = 'black' }        local piecenames = {             p = 'pawn',             r = 'rook',             n = 'knight',             b = 'bishop',             q = 'queen',             k = 'king',             a = 'archbishop',            c = 'chancelor',             z = 'champion',             w = 'wizard',             t = 'fool',             h = 'upside-down pawn',             m = 'upside-down rook',             s = 'upside-down knight',             f = 'upside-down king',              e = 'upside-down bishop',             g = 'upside-down queen',            }        local symnames = {             xx = 'black cross',             ox = 'white cross',             xo = 'black circle',             oo = 'white circle',            ul = 'up-left arrow',             ua = 'up arrow',             ur = 'up-right arrow',             la = 'left arrow',             ra = 'right arrow',            dl = 'down-left arrow',             da = 'down arrow',             dr = 'down-right arrow',             lr = 'left-right arrow',             ud = 'up-down arrow',            x0 = 'zero',             x1 = 'one',             x2 = 'two',             x3 = 'three',             x4 = 'four',             x5 = 'five',             x6 = 'six',             x7 = 'seven',             x8 = 'eight',             x9 = 'nine',        }         function colchar( col )             return ( 'abcdefgh' ):sub( col, col )         end         local color = mw.ustring.gsub( pc, '^.*(%w)(%w).*$', '%2' ) or         local piece = mw.ustring.gsub( pc, '^.*(%w)(%w).*$', '%1' ) or         local alt = colchar( col ) .. row .. ' '       if colornames[color] and piecenames[piece] then            alt = alt .. colornames[color] .. ' ' .. piecenames[piece]       else            alt = alt .. ( symnames[piece .. color] or piece .. ' ' .. color )       end         return string.format( , piece, color, size, size, alt, alt )    end     function letters_row( rev, num_lt, num_rt )        local td = ''        local legends = 'abcdefgh'        local l = mw.text.split( rev and legends:reverse or legends,  )        return '\n'                 .. ( num_lt and ' ' or '' )                .. td               .. table.concat( l, ' ' .. td )                .. ' '               .. ( num_rt and '  ' or '' )                .. '\n '   end    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 = 8 * 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 ) .. '\n' end   b = b .. ''   if ( numbers_lt ) then b = b .. '' .. (rev and 1 or 8) .. ' ' end   b = b .. ' '   b = b .. string.format( , 8 * size, 8 * size )   for trow = 1,8 do        local row = rev and trow or ( 9 - trow )        for tcol = 1,8 do            local col = rev and ( 9 - tcol ) or tcol            local piece = args[8 * ( 8 - row ) + col + 2] or             if piece:match( '%w%w' ) then               local img = image_square(piece:match('%w%w'), row, col, size )               b = b .. string.format(                  ' %s \n',                    ( trow - 1 ) * size, ( tcol - 1 ) * size, img )            end        end    end    b = b .. ' '    if ( numbers_rt ) then b = b .. '' .. (rev and 1 or 8) .. ' ' end   if ( numbers_lt or numbers_rt ) then       for trow = 2, 8 do          local row = rev and trow or ( 9 - trow )          b = b .. ''         if ( numbers_lt ) then b = b .. '' .. row .. ' ' end         if ( numbers_rt ) then b = b .. '' .. row .. ' ' end         b = b .. ' \n'      end    end    if ( letters_bt ) then b = b .. letters_row( rev, numbers_lt, numbers_rt ) .. '\n' end    if footer:match( '^%s*$' )    then    else            caption = ' ' .. footer .. ' \n'   end     return ' '        .. header .. '\n \n'        .. ' \n' .. caption .. ' 'end function convertFenToArgs( fen )    -- converts FEN notation to 64 entry 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 resend function convertArgsToFen( args, offset )    function nullOrWhitespace( s ) return not s or s:match( '^%s*(.-)%s*$' ) ==  end    function piece( s )         return nullOrWhitespace( s ) and 1        or s:gsub( '%s*(%a)(%a)%s*', function( a, b ) return b == 'l' and a:upper or a end )    end     local res =     offset = offset or 0    for row = 1, 8 do        for file = 1, 8 do            res = res .. piece( args[8*(row - 1) + file + offset] )       end        if row < 8 then res = res .. '/' end   end    return mw.ustring.gsub(res, '1+', function( s ) return #s end )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 letters = ( args.letters or pargs.letters or 'both' ):lower     local numbers = ( args.numbers or pargs.numbers or 'both' ):lower     local header = args[2] or pargs[2] or     local footer = args[67] or pargs[67] 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 fen = args.fen or pargs.fen     size = mw.ustring.match( size, '[%d]+' ) or '26' -- remove px from size    if (fen) then        align = args.align or pargs.align or 'tright'        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, reverse, letters, numbers, header, footer, align, clear )    end    if args[3] then        return chessboard(args, size, reverse, letters, numbers, header, footer, align, clear)    else        return chessboard(pargs, size, reverse, letters, numbers, header, footer, align, clear)    endend function p.fen2ascii(frame)    --     local b = convertFenToArgs( frame.args.fen )    local res = '|=\n'    local offset = 2    for row = 1,8 do        local n = (9 - row)        res = res .. n .. ' |' ..            table.concat(b, '|', 8*(row-1) + 1 + offset, 8*(row-1) + 8 + offset) .. '|=\n'   end    res = mw.ustring.gsub( res,'\| \|', '|  |' )    res = mw.ustring.gsub( res,'\| \|', '|  |' )    res = res .. '  a  b  c  d  e  f  g  h'    return resend function p.ascii2fen( frame )    --     return convertArgsToFen( frame.args, frame.args.offset or 1 )end return p