Module:Sandbox/Fred Gandt/chessDemo
Appearance
local p = {}
local getArgs = require( 'Module:Arguments' ).getArgs
local function replace( s, p, r )
return mw.ustring.gsub( s, p, r )
end
local function collapseWhitespace( s )
return replace( s, '%s*', '' )
end
local function toLower( s )
return mw.ustring.lower( s )
end
local function collapseToLower( s )
return toLower( collapseWhitespace( s ) )
end
local function splitter( s, d, p )
return mw.text.split( s, d, p or false )
end
local function join( t, d )
return table.concat( t, d or '' )
end
local function firstUpper( p )
p = toLower( p )
if p ~= 'pawn' then
if p ~= 'knight' then
return mw.ustring.upper( splitter( p, '' )[ 1 ] )
end
return 'N'
end
return ''
end
local function removeAlphas( s )
if s and #s > 0 then
local r = replace( s, '%D', '' )
if #r > 0 then
return r
end
end
return nil
end
local function finder( hs, n )
return mw.ustring.find( toLower( hs ), n )
end
local function buildDemo( configuration )
local function eD()
return mw.html.create( 'div' )
end
local function eP()
return mw.html.create( 'p' )
end
local function eB()
return mw.html.create( 'b' )
end
local function addSpan( n, s )
local se = mw.html.create( 'span' )
se:wikitext( s )
n:node( se )
end
local i = 0
local W = 'w"|'
local B = 'b"|'
local aN = '\n|'
local tR = aN .. '-'
local aS = '</span>'
local aP = '<span class="cd-persp-'
local rC = aN .. 'class="cd-square-'
local aW = aN .. aP .. 'w">'
local aB = aS .. aP .. 'b">'
local a = join( { aN, aW, 'a', aB, 'h', aS, aW, 'b', aB, 'g', aS, aW, 'c', aB, 'f', aS, aW, 'd', aB,
'e', aS, aW, 'e', aB, 'd', aS, aW, 'f', aB, 'c', aS, aW, 'g', aB, 'b', aS, aW, 'h', aB, 'a', aS, aN } )
local r = join( { rC, B, rC, W, rC, B, rC, W, rC, B, rC, W, rC, B } )
local rW = rC .. W .. r
local rB = r .. rC .. W
local T = join( { '\n{|cellpadding="0" cellspacing="0"', a, tR,
aW, '8', aB, '1', aS, rW, aW, '8', aB, '1', aS, tR, aW, '7', aB, '2', aS, rB, aW, '7', aB, '2', aS, tR,
aW, '6', aB, '3', aS, rW, aW, '6', aB, '3', aS, tR, aW, '5', aB, '4', aS, rB, aW, '5', aB, '4', aS, tR,
aW, '4', aB, '5', aS, rW, aW, '4', aB, '5', aS, tR, aW, '3', aB, '6', aS, rB, aW, '3', aB, '6', aS, tR,
aW, '2', aB, '7', aS, rW, aW, '2', aB, '7', aS, tR, aW, '1', aB, '8', aS, rB, aW, '1', aB, '8', aS, tR,
a, aN, '}' } )
local peice
local board = eD()
local fallback = eD()
local chessDemo = eD()
local interface = eD()
local borderfix = eD()
chessDemo:attr( 'data-data', mw.text.jsonEncode( configuration.instructions ) )
chessDemo:attr( 'class', 'chessDemo' )
:addClass( 'cd-border' )
:css( { float = configuration.float,
clear = configuration.clear,
width = configuration.width.master .. 'px'
} )
if configuration.notation.notes and configuration.notation.float then
chessDemo:addClass( 'cd-notation-' .. configuration.notation.float )
end
if configuration.title then
local n = eP()
n:attr( 'class', 'cd-title' )
:wikitext( configuration.title )
chessDemo:node( n )
end
if configuration.info then
local n = eP()
n:attr( 'class', 'cd-information' )
:wikitext( configuration.info )
chessDemo:node( n )
end
interface:attr( 'class', 'cd-interface' )
if configuration.orientation then
interface:addClass( 'cd-persp-b' )
end
borderfix:attr( 'class', 'cd-border' )
:css( 'font-size', configuration.width.board .. 'px' )
board:attr( 'class', 'cd-board' )
:addClass( 'noprint' )
while i < #configuration.setup do
i = i + 1
peice = eD()
peice:attr( 'class', configuration.setup[ i ] )
board:node( peice )
end
fallback:attr( 'class', 'cd-fallback' )
:wikitext( '[[File:Ajedrez animación en passant.gif|' .. configuration.width.img .. 'x' .. configuration.width.img .. 'px]]' )
board:node( fallback )
borderfix:wikitext( T )
:node( board )
interface:node( borderfix )
if configuration.instructions.controls then
local controls = eD()
controls:attr( 'class', 'cd-controls' )
interface:node( controls )
end
chessDemo:node( interface )
if configuration.notation.notes then
local n
local c
local m
local be
local note
local pe = eP()
local notes = {}
local alternator = 1
local notewrap = eD()
local notation = eD()
local nnp = { '...', '.' }
local columns = configuration.notation.columns
local notecount = configuration.notation.numbering
if configuration.blackfirst then
alternator = 0
nnp = { '.', '...' }
end
notation:attr( 'class', 'cd-notation' )
pe:attr( 'class', 'cd-title' )
:wikitext( 'Notation' )
notation:node( pe )
if configuration.notation.collapsible then
notation:addClass( 'mw-collapsible' )
if configuration.notation.collapsed then
notation:addClass( 'mw-collapsed' )
end
notewrap:attr( 'class', 'mw-collapsible-content' )
end
for index, value in ipairs( configuration.notation.notes ) do
n = value[ 1 ]
c = value[ 2 ]
m = index % 2
if not note then
be = eB()
note = eP()
note:node( be )
if columns then
notes[ #notes + 1 ] = note
else
notewrap:node( note )
end
if notecount then
be:wikitext( tostring( notecount ) .. nnp[ m + 1 ] )
end
end
if c then
note:tag( 'br' )
addSpan( note, c )
note = nil
end
if m == alternator then
addSpan( be, n .. ' ' )
else
addSpan( be, n )
if notecount then
notecount = notecount + 1
end
note = nil
end
end
if columns then
columns = tonumber( columns )
local column
local created = 0
local notespercolumn = math.ceil( #notes / columns )
for index, value in ipairs( notes ) do
if ( index - 1 ) % notespercolumn == 0 then
column = eD()
column:css( 'width', configuration.notation.width .. 'px' )
notewrap:node( column )
created = created + 1
end
column:node( value )
end
if created < columns then
chessDemo:css( 'width', tostring( tonumber( configuration.width.master ) - ( tonumber( configuration.notation.width ) + 20 ) ) .. 'px' )
end
elseif configuration.notation.float then
notewrap:css( 'width', configuration.notation.width .. 'px' )
end
notation:node( notewrap )
chessDemo:node( notation )
end
chessDemo:wikitext( '[[Category:Pages using Template chessDemo]]' )
return tostring( chessDemo )
end
local function _getDemo( args )
local pC = 'cd-piece-'
local pF = 'cd-file-'
local pR = 'cd-rank-'
local pR1 = pR .. '1'
local pR2 = pR .. '2'
local pR7 = pR .. '7'
local pR8 = pR .. '8'
local pB = pC .. 'black'
local pW = pC .. 'white'
local configuration = {
width = {
master = '204',
board = '20',
img = '160'
},
clear = args.clear or 'both',
float = args.float or 'right',
title = args.title,
info = args.information,
setup = {
join( { pB, ' ', pC, 'R ', pF, 'a ', pR8 } ), join( { pB, ' ', pF, 'a ', pR7 } ),
join( { pB, ' ', pC, 'N ', pF, 'b ', pR8 } ), join( { pB, ' ', pF, 'b ', pR7 } ),
join( { pB, ' ', pC, 'B ', pF, 'c ', pR8 } ), join( { pB, ' ', pF, 'c ', pR7 } ),
join( { pB, ' ', pC, 'Q ', pF, 'd ', pR8 } ), join( { pB, ' ', pF, 'd ', pR7 } ),
join( { pB, ' ', pC, 'K ', pF, 'e ', pR8 } ), join( { pB, ' ', pF, 'e ', pR7 } ),
join( { pB, ' ', pC, 'B ', pF, 'f ', pR8 } ), join( { pB, ' ', pF, 'f ', pR7 } ),
join( { pB, ' ', pC, 'N ', pF, 'g ', pR8 } ), join( { pB, ' ', pF, 'g ', pR7 } ),
join( { pB, ' ', pC, 'R ', pF, 'h ', pR8 } ), join( { pB, ' ', pF, 'h ', pR7 } ),
join( { pW, ' ', pF, 'a ', pR2 } ), join( { pW, ' ', pC, 'R ', pF, 'a ', pR1 } ),
join( { pW, ' ', pF, 'b ', pR2 } ), join( { pW, ' ', pC, 'N ', pF, 'b ', pR1 } ),
join( { pW, ' ', pF, 'c ', pR2 } ), join( { pW, ' ', pC, 'B ', pF, 'c ', pR1 } ),
join( { pW, ' ', pF, 'd ', pR2 } ), join( { pW, ' ', pC, 'Q ', pF, 'd ', pR1 } ),
join( { pW, ' ', pF, 'e ', pR2 } ), join( { pW, ' ', pC, 'K ', pF, 'e ', pR1 } ),
join( { pW, ' ', pF, 'f ', pR2 } ), join( { pW, ' ', pC, 'B ', pF, 'f ', pR1 } ),
join( { pW, ' ', pF, 'g ', pR2 } ), join( { pW, ' ', pC, 'N ', pF, 'g ', pR1 } ),
join( { pW, ' ', pF, 'h ', pR2 } ), join( { pW, ' ', pC, 'R ', pF, 'h ', pR1 } )
},
orientation = args.orientation,
notation = {
numbering = 1,
columns = removeAlphas( args.columns )
},
instructions = {
speed = removeAlphas( args.speed ) or '2',
autostart = args.autostart or false,
blackfirst = false,
controls = true,
moves = {}
}
}
configuration.instructions.setup = configuration.setup
if args.initial then
local i = removeAlphas( args.initial )
if i then
configuration.instructions.initial = tonumber( i )
end
else
configuration.instructions.initial = 0
end
if args.controls then
if finder( args.controls, '^min' ) then
configuration.instructions.controls = 'min'
elseif finder( args.controls, '^med' ) then
configuration.instructions.controls = 'med'
else
configuration.instructions.controls = false
configuration.instructions.autostart = true
end
end
if args.width then
local width = removeAlphas( args.width )
if width then
width = tonumber( width )
if width >= 200 then
configuration.width.master = tostring( width + 4 )
configuration.width.board = tostring( width / 10 )
configuration.width.img = tostring( ( width / 10 ) * 8 )
end
end
end
if not args.notation or ( args.notation and args.notation ~= 'hidden' ) then
local columns = tonumber( configuration.notation.columns or '1' )
configuration.notation.notes = {}
configuration.notation.width = tostring( ( math.floor( tonumber( configuration.width.master ) / columns ) - 20 ) + math.floor( 20 / columns ) )
if args.notation == 'collapsible' or args.notation == 'collapsed' then
configuration.notation.collapsible = true
if args.notation == 'collapsed' then
configuration.notation.collapsed = true
end
elseif args.notation then
configuration.notation.float = args.notation
configuration.notation.width = removeAlphas( args.columnwidth ) or '120'
configuration.width.master = tostring( tonumber( configuration.width.master ) + ( tonumber( configuration.notation.width ) * columns ) + ( 20 * columns ) )
end
if args.numbering then
local numbering = removeAlphas( args.numbering )
if numbering then
configuration.notation.numbering = tonumber( numbering )
else
configuration.notation.numbering = nil
end
end
end
for index, value in ipairs( args ) do
local splitarg = splitter( value, '\n', true )
local fromto = splitter( splitarg[ 1 ], '%s+' )
local to = replace( fromto[ 2 ], 'O', '0' )
configuration.instructions.moves[ #configuration.instructions.moves + 1 ] = {
fromto[ 1 ],
to
}
if configuration.notation.notes then
configuration.notation.notes[ #configuration.notation.notes + 1 ] = {
mw.text.trim( to .. ' ' .. ( fromto[ 3 ] or '' ) ),
splitarg[ 2 ]
}
end
end
if args.setup then
local bits = {}
local color = ''
local piece = ''
local pieces = {}
local coords = {}
local firstmovefrom = configuration.instructions.moves[ 1 ][ 1 ]
local splitarg = splitter( args.setup, ',%s*' )
for index, value in ipairs( splitarg ) do
bits = splitter( value, '%s+' )
color = toLower( bits[ 1 ] )
if #bits == 3 then
piece = pC .. firstUpper( bits[ 2 ] ) .. ' '
coords = splitter( toLower( bits[ 3 ] ), '' )
else
piece = ''
coords = splitter( toLower( bits[ 2 ] ), '' )
end
if configuration.blackfirst == nil and join( coords ) == firstmovefrom then
configuration.blackfirst = color == 'black'
configuration.instructions.blackfirst = configuration.blackfirst
end
pieces[ #pieces + 1 ] = join( { pC, color, ' ', piece, pF, join( coords, ' ' .. pR ) } )
end
configuration.setup = pieces
configuration.instructions.setup = pieces
end
return buildDemo( configuration )
end
local function _getNotation( args )
local arg = ''
local move = ''
if args.castle then
arg = args.castle
move = move .. '0-0'
if arg == 'queenside' then
move = move .. '-0'
end
elseif args.to then
if args.from then
move = move .. collapseToLower( args.from ) .. ' '
end
if args.piece then
move = move .. firstUpper( args.piece )
end
move = move .. collapseToLower( args.disambiguation or '' )
if args.capture then
move = move .. 'x'
end
move = move .. collapseToLower( args.to )
if args.enpassant then
move = move .. 'e.p.'
end
if args.promotion then
arg = firstUpper( args.promotion )
if #arg > 0 then
move = move .. '=' .. arg
end
end
end
if args.check then
if toLower( args.check ) == 'mate' then
move = move .. '#'
else
move = move .. '+'
end
end
move = move .. collapseWhitespace( args.punctuation or '' )
if args.gamescore then
arg = toLower( args.gamescore )
move = move .. ' '
if arg == 'white' then
move = move .. '1–0'
elseif arg == 'black' then
move = move .. '0–1'
else
move = move .. '½–½'
end
end
if args.comment then
move = move .. '\n' .. args.comment
end
return move
end
function p.getNotation( frame )
return _getNotation( getArgs( frame:getParent().args ) )
end
function p.getDemo( frame )
local args = getArgs( frame:getParent().args )
if mw.isSubsting() then
local r = {}
for key, value in pairs( args ) do
if not tonumber( key ) then
r[ #r + 1 ] = key .. ' = ' .. value
end
end
for index, value in ipairs( args ) do
r[ #r + 1 ] = tostring( index ) .. ' = ' .. value
end
return '{{User:Fred Gandt/sandbox/chessDemo\n| ' .. join( r, '\n| ' ) .. '\n}}'
end
return _getDemo( args )
end
return p