From f4672b6e7394aa240d8f091076c758422c9349e0 Mon Sep 17 00:00:00 2001 From: John <37978984+johnridesabike@users.noreply.github.com> Date: Sat, 14 Jul 2018 09:04:21 -0400 Subject: [PATCH 1/7] Initial commit for html.py --- chess/html.py | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 chess/html.py diff --git a/chess/html.py b/chess/html.py new file mode 100644 index 000000000..26978a737 --- /dev/null +++ b/chess/html.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +# This file is an addition to the python-chess library. +# Copyright (C) 2018 John Jackson +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# NOTE: This file is currently in a beta, proof-of-concept stage. + +import chess + +TABLE_HEAD = """""" +TABLE_HEAD_COORDS = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + ++ + + + +""" +TABLE_ROW_HEAD = """""" +TABLE_ROW_COORDS = """""" +TABLE_DATA = """ +""" +TABLE_ROW_FOOT = """""" +TABLE_FOOT = """
ABCDEFGH
ABCDEFGH
{rank} + {attack}{symbol} +
""" + +def piece(piece: chess.Piece): + return piece.unicode_symbol().encode('ascii', 'xmlcharrefreplace').decode() + + +def board(board: chess.Board, squares=[], flipped=False, coordinates=True, + lastmove=None, check=None): + HTML = TABLE_HEAD + if coordinates: + HTML += TABLE_HEAD_COORDS + if flipped: + rank_names = chess.RANK_NAMES + else: + rank_names = chess.RANK_NAMES[::-1] + for rank in rank_names: + HTML += TABLE_ROW_HEAD + if coordinates: + HTML += TABLE_ROW_COORDS.format(rank=rank) + for file in chess.FILE_NAMES: + square = chess.square(chess.FILE_NAMES.index(file), + chess.RANK_NAMES.index(rank)) + data = {'square': chess.square_name(square), 'piece_name': '', + 'color': '', 'symbol': '', 'attack': '', 'check': '', + 'lastmove': ''} + if square in squares: + data['attack'] = 'X' + if square == check: + data['check'] = 'check' + if lastmove and square in [lastmove.from_square, + lastmove.to_square]: + data['lastmove'] = 'lastmove' + if square in board.piece_map(): + piece_obj = board.piece_map()[square] + data['symbol'] = piece(piece_obj) + data['color'] = chess.COLOR_NAMES[piece_obj.color] + data['piece_name'] = chess.PIECE_NAMES[piece_obj.piece_type] + HTML += TABLE_DATA.format(**data) + if coordinates: + HTML += TABLE_ROW_COORDS.format(rank=rank) + HTML += TABLE_ROW_FOOT + HTML += TABLE_FOOT + return HTML From 57f4683d5f79e15da2c4b25ba36c302af3abe8f1 Mon Sep 17 00:00:00 2001 From: John <37978984+johnridesabike@users.noreply.github.com> Date: Sat, 14 Jul 2018 13:56:51 -0400 Subject: [PATCH 2/7] tweaks --- chess/html.py | 83 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/chess/html.py b/chess/html.py index 26978a737..c007393b7 100644 --- a/chess/html.py +++ b/chess/html.py @@ -14,37 +14,39 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . +"""A module for python-chess which outputs an HTML table of a board. -# NOTE: This file is currently in a beta, proof-of-concept stage. +This file is currently in a beta, proof-of-concept stage. +""" import chess -TABLE_HEAD = """""" +TABLE_HEAD = """
""" TABLE_HEAD_COORDS = """ - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + + @@ -56,30 +58,42 @@ """ TABLE_ROW_HEAD = """""" TABLE_ROW_COORDS = """""" -TABLE_DATA = """ +TABLE_ATTACK = """×""" +TABLE_DATA = """ """ TABLE_ROW_FOOT = """""" TABLE_FOOT = """
ABCDEFGHabcdefgh
ABCDEFGHabcdefgh
{rank} - {attack}{symbol} -{attack}{symbol}
""" def piece(piece: chess.Piece): + """Renders the given :class:`chess.Piece` as HTML escaped unicode. + """ return piece.unicode_symbol().encode('ascii', 'xmlcharrefreplace').decode() def board(board: chess.Board, squares=[], flipped=False, coordinates=True, lastmove=None, check=None): - HTML = TABLE_HEAD + """ + Renders a board with pieces and/or selected squares as an HTML table. + + :param board: A :class:`chess.BaseBoard` for a chessboard with pieces or + ``None`` (the default) for a chessboard without pieces. + :param squares: A :class:`chess.SquareSet` with selected squares. + :param flipped: Pass ``True`` to flip the board. + :param coordinates: Pass ``False`` to disable coordinates in the margin. + :param lastmove: A :class:`chess.Move` to be highlighted. + :param check: A square to be marked as check. + """ + html = TABLE_HEAD if coordinates: - HTML += TABLE_HEAD_COORDS + html += TABLE_HEAD_COORDS if flipped: rank_names = chess.RANK_NAMES else: rank_names = chess.RANK_NAMES[::-1] for rank in rank_names: - HTML += TABLE_ROW_HEAD + html += TABLE_ROW_HEAD if coordinates: - HTML += TABLE_ROW_COORDS.format(rank=rank) + html += TABLE_ROW_COORDS.format(rank=rank) for file in chess.FILE_NAMES: square = chess.square(chess.FILE_NAMES.index(file), chess.RANK_NAMES.index(rank)) @@ -87,9 +101,7 @@ def board(board: chess.Board, squares=[], flipped=False, coordinates=True, 'color': '', 'symbol': '', 'attack': '', 'check': '', 'lastmove': ''} if square in squares: - data['attack'] = 'X' - if square == check: - data['check'] = 'check' + data['attack'] = TABLE_ATTACK if lastmove and square in [lastmove.from_square, lastmove.to_square]: data['lastmove'] = 'lastmove' @@ -98,9 +110,14 @@ def board(board: chess.Board, squares=[], flipped=False, coordinates=True, data['symbol'] = piece(piece_obj) data['color'] = chess.COLOR_NAMES[piece_obj.color] data['piece_name'] = chess.PIECE_NAMES[piece_obj.piece_type] - HTML += TABLE_DATA.format(**data) + if square == check: + data['check'] = 'check' + elif (board.is_check() and piece_obj.piece_type == chess.KING + and board.turn == piece_obj.color): + data['check'] = 'check' + html += TABLE_DATA.format(**data) if coordinates: - HTML += TABLE_ROW_COORDS.format(rank=rank) - HTML += TABLE_ROW_FOOT - HTML += TABLE_FOOT - return HTML + html += TABLE_ROW_COORDS.format(rank=rank) + html += TABLE_ROW_FOOT + html += TABLE_FOOT + return html From 229bbbe705aabbd38bdb9874613cb89b068fbf9e Mon Sep 17 00:00:00 2001 From: John <37978984+johnridesabike@users.noreply.github.com> Date: Sat, 14 Jul 2018 23:07:16 -0400 Subject: [PATCH 3/7] Better organization and documentation. --- chess/html.py | 188 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 138 insertions(+), 50 deletions(-) diff --git a/chess/html.py b/chess/html.py index c007393b7..23bcc46f1 100644 --- a/chess/html.py +++ b/chess/html.py @@ -14,55 +14,131 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -"""A module for python-chess which outputs an HTML table of a board. - -This file is currently in a beta, proof-of-concept stage. -""" +"""A module for python-chess which outputs an HTML table of a board.""" import chess -TABLE_HEAD = """""" -TABLE_HEAD_COORDS = """ - - - - - - - - - - - - +HTML_HEAD = """ + + + python-chess output + + + +""" +DEFAULT_CSS = """.chess_board { + font-size:4em; + font-family: sans-serif; + border-collapse: collapse; + border-spacing: 0; + margin-left: auto; + margin-right: auto; +} +.chess_board .piece { + color:#000; + display:block; + height:1.25em; + width:1.25em; + position:relative; + text-decoration:none; +} +.chess_board td { + background: rgba(209, 139, 71, 1); + height:1.25em; + width:1.25em; + padding: 0; + text-align:center; + vertical-align:middle; +} +.chess_board td.lastmove { + background: #aaa23b; +} +.chess_board tr:nth-child(odd) td:nth-child(even), +.chess_board tr:nth-child(even) td:nth-child(odd) { + background:rgba(255, 206, 158, 1); +} +.chess_board tr:nth-child(odd) td:nth-child(even).lastmove, +.chess_board tr:nth-child(even) td:nth-child(odd).lastmove { + background: #cdd16a; +} +.chess_board th { + background: transparent; + height:2.5em; + width:2.5em; + padding: 0; + text-align:center; + vertical-align:middle; + font-weight: normal; + font-size:.5em; + text-transform: uppercase; +} +.chess_board .check { + background: -moz-radial-gradient(center, ellipse cover, rgba(255,0,0,1) 0%, rgba(231,0,0,0.5) 50%, rgba(158,0,0,0) 100%); + background: -webkit-radial-gradient(center, ellipse cover, rgba(255,0,0,1) 0%,rgba(231,0,0,0.5) 50%,rgba(158,0,0,0) 100%); + background: radial-gradient(ellipse at center, rgba(255,0,0,1) 0%,rgba(231,0,0,0.5) 50%,rgba(158,0,0,0) 100%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff0000', endColorstr='#009e0000',GradientType=1 ); +} +.chess_board .attack { + position: absolute; + z-index: 999; + display: block; + width: 1.25em; + height: 1.25em; +} +""" +TABLE_START = """
abcdefgh
+""" +TABLE_HEAD_COORDS = """++++ + + + + + + + + + + + + + - - - - - - - - - - - - - +""" +TABLE_BODY_START = """ +""" +TABLE_ROW_START = """ +""" +TABLE_ROW_COORDS = """ +""" +TABLE_DATA = """ +""" +TABLE_ATTACK = """×""" +TABLE_PIECE = """{symbol}""" +TABLE_ROW_END = """ +""" +TABLE_BODY_END = """ +""" +TABLE_FOOT_COORDS = """ + + + + + + + + + + + + -- - - - """ -TABLE_ROW_HEAD = """""" -TABLE_ROW_COORDS = """""" -TABLE_ATTACK = """×""" -TABLE_DATA = """ +TABLE_END = """
abcdefgh
abcdefgh
{rank}{attack}{piece}
abcdefgh
{rank}{attack}{symbol}
""" -TABLE_ROW_FOOT = """""" -TABLE_FOOT = """""" def piece(piece: chess.Piece): """Renders the given :class:`chess.Piece` as HTML escaped unicode. @@ -71,9 +147,8 @@ def piece(piece: chess.Piece): def board(board: chess.Board, squares=[], flipped=False, coordinates=True, - lastmove=None, check=None): - """ - Renders a board with pieces and/or selected squares as an HTML table. + lastmove=None, check=None, snippet=True, style=None): + """Renders a board with pieces and/or selected squares as an HTML table. :param board: A :class:`chess.BaseBoard` for a chessboard with pieces or ``None`` (the default) for a chessboard without pieces. @@ -82,16 +157,25 @@ def board(board: chess.Board, squares=[], flipped=False, coordinates=True, :param coordinates: Pass ``False`` to disable coordinates in the margin. :param lastmove: A :class:`chess.Move` to be highlighted. :param check: A square to be marked as check. + :param snippet: Pass ``False`` to return a complete HTML document. + :param style: A CSS stylesheet to include in the HTML document. Has no effect if ``snippet`` is ``True``. """ - html = TABLE_HEAD + if snippet: + html = TABLE_START + else: + if not style: + style = DEFAULT_CSS + html = HTML_HEAD.format(style=style) + html += TABLE_START if coordinates: html += TABLE_HEAD_COORDS if flipped: rank_names = chess.RANK_NAMES else: rank_names = chess.RANK_NAMES[::-1] + html += TABLE_BODY_START for rank in rank_names: - html += TABLE_ROW_HEAD + html += TABLE_ROW_START if coordinates: html += TABLE_ROW_COORDS.format(rank=rank) for file in chess.FILE_NAMES: @@ -99,7 +183,7 @@ def board(board: chess.Board, squares=[], flipped=False, coordinates=True, chess.RANK_NAMES.index(rank)) data = {'square': chess.square_name(square), 'piece_name': '', 'color': '', 'symbol': '', 'attack': '', 'check': '', - 'lastmove': ''} + 'lastmove': '', 'piece': ''} if square in squares: data['attack'] = TABLE_ATTACK if lastmove and square in [lastmove.from_square, @@ -115,9 +199,13 @@ def board(board: chess.Board, squares=[], flipped=False, coordinates=True, elif (board.is_check() and piece_obj.piece_type == chess.KING and board.turn == piece_obj.color): data['check'] = 'check' + data['piece'] = TABLE_PIECE.format(**data) html += TABLE_DATA.format(**data) if coordinates: html += TABLE_ROW_COORDS.format(rank=rank) - html += TABLE_ROW_FOOT - html += TABLE_FOOT + html += TABLE_ROW_END + html += TABLE_BODY_END + if coordinates: + html += TABLE_FOOT_COORDS + html += TABLE_END return html From c193e8a1df4bf51ffe63e4af75ec9b4aaab1305f Mon Sep 17 00:00:00 2001 From: John <37978984+johnridesabike@users.noreply.github.com> Date: Sat, 14 Jul 2018 23:23:35 -0400 Subject: [PATCH 4/7] Better organization and documentation. --- chess/html.py | 188 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 138 insertions(+), 50 deletions(-) diff --git a/chess/html.py b/chess/html.py index c007393b7..23bcc46f1 100644 --- a/chess/html.py +++ b/chess/html.py @@ -14,55 +14,131 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -"""A module for python-chess which outputs an HTML table of a board. - -This file is currently in a beta, proof-of-concept stage. -""" +"""A module for python-chess which outputs an HTML table of a board.""" import chess -TABLE_HEAD = """""" -TABLE_HEAD_COORDS = """ - - - - - - - - - - - - +HTML_HEAD = """ + + + python-chess output + + + +""" +DEFAULT_CSS = """.chess_board { + font-size:4em; + font-family: sans-serif; + border-collapse: collapse; + border-spacing: 0; + margin-left: auto; + margin-right: auto; +} +.chess_board .piece { + color:#000; + display:block; + height:1.25em; + width:1.25em; + position:relative; + text-decoration:none; +} +.chess_board td { + background: rgba(209, 139, 71, 1); + height:1.25em; + width:1.25em; + padding: 0; + text-align:center; + vertical-align:middle; +} +.chess_board td.lastmove { + background: #aaa23b; +} +.chess_board tr:nth-child(odd) td:nth-child(even), +.chess_board tr:nth-child(even) td:nth-child(odd) { + background:rgba(255, 206, 158, 1); +} +.chess_board tr:nth-child(odd) td:nth-child(even).lastmove, +.chess_board tr:nth-child(even) td:nth-child(odd).lastmove { + background: #cdd16a; +} +.chess_board th { + background: transparent; + height:2.5em; + width:2.5em; + padding: 0; + text-align:center; + vertical-align:middle; + font-weight: normal; + font-size:.5em; + text-transform: uppercase; +} +.chess_board .check { + background: -moz-radial-gradient(center, ellipse cover, rgba(255,0,0,1) 0%, rgba(231,0,0,0.5) 50%, rgba(158,0,0,0) 100%); + background: -webkit-radial-gradient(center, ellipse cover, rgba(255,0,0,1) 0%,rgba(231,0,0,0.5) 50%,rgba(158,0,0,0) 100%); + background: radial-gradient(ellipse at center, rgba(255,0,0,1) 0%,rgba(231,0,0,0.5) 50%,rgba(158,0,0,0) 100%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff0000', endColorstr='#009e0000',GradientType=1 ); +} +.chess_board .attack { + position: absolute; + z-index: 999; + display: block; + width: 1.25em; + height: 1.25em; +} +""" +TABLE_START = """
abcdefgh
+""" +TABLE_HEAD_COORDS = """++++ + + + + + + + + + + + + + - - - - - - - - - - - - - +""" +TABLE_BODY_START = """ +""" +TABLE_ROW_START = """ +""" +TABLE_ROW_COORDS = """ +""" +TABLE_DATA = """ +""" +TABLE_ATTACK = """×""" +TABLE_PIECE = """{symbol}""" +TABLE_ROW_END = """ +""" +TABLE_BODY_END = """ +""" +TABLE_FOOT_COORDS = """ + + + + + + + + + + + + -- - - - """ -TABLE_ROW_HEAD = """""" -TABLE_ROW_COORDS = """""" -TABLE_ATTACK = """×""" -TABLE_DATA = """ +TABLE_END = """
abcdefgh
abcdefgh
{rank}{attack}{piece}
abcdefgh
{rank}{attack}{symbol}
""" -TABLE_ROW_FOOT = """""" -TABLE_FOOT = """""" def piece(piece: chess.Piece): """Renders the given :class:`chess.Piece` as HTML escaped unicode. @@ -71,9 +147,8 @@ def piece(piece: chess.Piece): def board(board: chess.Board, squares=[], flipped=False, coordinates=True, - lastmove=None, check=None): - """ - Renders a board with pieces and/or selected squares as an HTML table. + lastmove=None, check=None, snippet=True, style=None): + """Renders a board with pieces and/or selected squares as an HTML table. :param board: A :class:`chess.BaseBoard` for a chessboard with pieces or ``None`` (the default) for a chessboard without pieces. @@ -82,16 +157,25 @@ def board(board: chess.Board, squares=[], flipped=False, coordinates=True, :param coordinates: Pass ``False`` to disable coordinates in the margin. :param lastmove: A :class:`chess.Move` to be highlighted. :param check: A square to be marked as check. + :param snippet: Pass ``False`` to return a complete HTML document. + :param style: A CSS stylesheet to include in the HTML document. Has no effect if ``snippet`` is ``True``. """ - html = TABLE_HEAD + if snippet: + html = TABLE_START + else: + if not style: + style = DEFAULT_CSS + html = HTML_HEAD.format(style=style) + html += TABLE_START if coordinates: html += TABLE_HEAD_COORDS if flipped: rank_names = chess.RANK_NAMES else: rank_names = chess.RANK_NAMES[::-1] + html += TABLE_BODY_START for rank in rank_names: - html += TABLE_ROW_HEAD + html += TABLE_ROW_START if coordinates: html += TABLE_ROW_COORDS.format(rank=rank) for file in chess.FILE_NAMES: @@ -99,7 +183,7 @@ def board(board: chess.Board, squares=[], flipped=False, coordinates=True, chess.RANK_NAMES.index(rank)) data = {'square': chess.square_name(square), 'piece_name': '', 'color': '', 'symbol': '', 'attack': '', 'check': '', - 'lastmove': ''} + 'lastmove': '', 'piece': ''} if square in squares: data['attack'] = TABLE_ATTACK if lastmove and square in [lastmove.from_square, @@ -115,9 +199,13 @@ def board(board: chess.Board, squares=[], flipped=False, coordinates=True, elif (board.is_check() and piece_obj.piece_type == chess.KING and board.turn == piece_obj.color): data['check'] = 'check' + data['piece'] = TABLE_PIECE.format(**data) html += TABLE_DATA.format(**data) if coordinates: html += TABLE_ROW_COORDS.format(rank=rank) - html += TABLE_ROW_FOOT - html += TABLE_FOOT + html += TABLE_ROW_END + html += TABLE_BODY_END + if coordinates: + html += TABLE_FOOT_COORDS + html += TABLE_END return html From d1e66765a300ac2a7e11e9159d09f8c04b38bae8 Mon Sep 17 00:00:00 2001 From: John <37978984+johnridesabike@users.noreply.github.com> Date: Sat, 14 Jul 2018 23:25:34 -0400 Subject: [PATCH 5/7] tweak --- chess/html.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/chess/html.py b/chess/html.py index 23bcc46f1..a5bdb8fce 100644 --- a/chess/html.py +++ b/chess/html.py @@ -31,8 +31,6 @@ font-family: sans-serif; border-collapse: collapse; border-spacing: 0; - margin-left: auto; - margin-right: auto; } .chess_board .piece { color:#000; From 1cd686cfc9bd05a35e6e0a6ce3fce7793b39b253 Mon Sep 17 00:00:00 2001 From: John <37978984+johnridesabike@users.noreply.github.com> Date: Sun, 15 Jul 2018 18:44:05 -0400 Subject: [PATCH 6/7] Added documentation and made tweaks to the code. --- chess/html.py | 48 ++++++---- docs/html.rst | 11 +++ docs/scholars_mate.html | 196 ++++++++++++++++++++++++++++++++++++++++ examples/html_output.py | 33 +++++++ 4 files changed, 269 insertions(+), 19 deletions(-) create mode 100644 docs/html.rst create mode 100644 docs/scholars_mate.html create mode 100644 examples/html_output.py diff --git a/chess/html.py b/chess/html.py index a5bdb8fce..7eed25e3e 100644 --- a/chess/html.py +++ b/chess/html.py @@ -26,7 +26,7 @@ """ -DEFAULT_CSS = """.chess_board { +DEFAULT_STYLE = """.chess_board { font-size:4em; font-family: sans-serif; border-collapse: collapse; @@ -114,8 +114,8 @@ """ TABLE_DATA = """{attack}{piece} """ -TABLE_ATTACK = """×""" -TABLE_PIECE = """{symbol}""" +HTML_ATTACK = """×""" +HTML_PIECE = """{symbol}""" TABLE_ROW_END = """ """ TABLE_BODY_END = """ @@ -140,11 +140,20 @@ def piece(piece: chess.Piece): """Renders the given :class:`chess.Piece` as HTML escaped unicode. + + >>> import chess + >>> import chess.html + >>> + >>> chess.html.piece(chess.Piece.from_symbol("R")) # doctest: +SKIP + '' """ - return piece.unicode_symbol().encode('ascii', 'xmlcharrefreplace').decode() + symb = piece.unicode_symbol().encode('ascii', 'xmlcharrefreplace').decode() + data = {'symbol': symb, 'color': chess.COLOR_NAMES[piece.color], + 'name': chess.PIECE_NAMES[piece.piece_type]} + return HTML_PIECE.format(**data) -def board(board: chess.Board, squares=[], flipped=False, coordinates=True, +def board(board: chess.Board, *, squares=[], flipped=False, coordinates=True, lastmove=None, check=None, snippet=True, style=None): """Renders a board with pieces and/or selected squares as an HTML table. @@ -157,12 +166,21 @@ def board(board: chess.Board, squares=[], flipped=False, coordinates=True, :param check: A square to be marked as check. :param snippet: Pass ``False`` to return a complete HTML document. :param style: A CSS stylesheet to include in the HTML document. Has no effect if ``snippet`` is ``True``. + + >>> import chess + >>> import chess.html + >>> + >>> board = chess.Board("8/8/8/8/4N3/8/8/8 w - - 0 1") + >>> squares = board.attacks(chess.E4) + >>> html = chess.html.board(board=board, squares=squares, snippet=False) # doctest: +SKIP + >>> with open('output.html', 'w') as f: + >>> f.write(html) """ if snippet: html = TABLE_START else: if not style: - style = DEFAULT_CSS + style = DEFAULT_STYLE html = HTML_HEAD.format(style=style) html += TABLE_START if coordinates: @@ -179,25 +197,17 @@ def board(board: chess.Board, squares=[], flipped=False, coordinates=True, for file in chess.FILE_NAMES: square = chess.square(chess.FILE_NAMES.index(file), chess.RANK_NAMES.index(rank)) - data = {'square': chess.square_name(square), 'piece_name': '', - 'color': '', 'symbol': '', 'attack': '', 'check': '', - 'lastmove': '', 'piece': ''} + data = {'square': chess.square_name(square), 'attack': '', + 'check': '', 'lastmove': '', 'piece': ''} if square in squares: - data['attack'] = TABLE_ATTACK + data['attack'] = HTML_ATTACK if lastmove and square in [lastmove.from_square, lastmove.to_square]: data['lastmove'] = 'lastmove' if square in board.piece_map(): - piece_obj = board.piece_map()[square] - data['symbol'] = piece(piece_obj) - data['color'] = chess.COLOR_NAMES[piece_obj.color] - data['piece_name'] = chess.PIECE_NAMES[piece_obj.piece_type] + data['piece'] = piece(board.piece_map()[square]) if square == check: - data['check'] = 'check' - elif (board.is_check() and piece_obj.piece_type == chess.KING - and board.turn == piece_obj.color): - data['check'] = 'check' - data['piece'] = TABLE_PIECE.format(**data) + data['piece'] = data['piece'].replace('not-check', 'check') html += TABLE_DATA.format(**data) if coordinates: html += TABLE_ROW_COORDS.format(rank=rank) diff --git a/docs/html.rst b/docs/html.rst new file mode 100644 index 000000000..102164769 --- /dev/null +++ b/docs/html.rst @@ -0,0 +1,11 @@ +HTML rendering +============= + +The :mod:`chess.html` module renders pieces and boards as HTML code. Depending +on your needs, HTML can be an alternative to SVG used by :mod:`chess.svg`. +`You can view a comparison of the HTML and SVG here `_. + + +.. autofunction:: chess.html.piece + +.. autofunction:: chess.html.board diff --git a/docs/scholars_mate.html b/docs/scholars_mate.html new file mode 100644 index 000000000..17aa58aef --- /dev/null +++ b/docs/scholars_mate.html @@ -0,0 +1,196 @@ +python-chess output +

HTML Table Output

+++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
abcdefgh
88
77
66
55
44
33
22
11
abcdefgh
+
+

SVG Output

aabbccddeeffgghh1122334455667788
Generated by + python-chess/examples/html_output.py
+ \ No newline at end of file diff --git a/examples/html_output.py b/examples/html_output.py new file mode 100644 index 000000000..a8378d7f6 --- /dev/null +++ b/examples/html_output.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +"""Renders scholar's mate in the file `scholars_mate.html`.""" + +import chess +import chess.html +import chess.svg + +def main(): + board = chess.Board() + chess.Move.from_uci("a8a1") in board.legal_moves + board.push_san("e4") + board.push_san("e5") + board.push_san("Qh5") + board.push_san("Nc6") + board.push_san("Bc4") + board.push_san("Nf6") + board.push_san("Qxf7") + table = chess.html.board(board, lastmove=board.peek(), + check=board.pieces(chess.KING,chess.BLACK).pop()) + svg = chess.svg.board(board, lastmove=board.peek(), size=800, + check=board.pieces(chess.KING,chess.BLACK).pop()) + html = """python-chess output +

HTML Table Output

{1}
+

SVG Output

{2}
Generated by + python-chess/examples/html_output.py
+ """.format(chess.html.DEFAULT_STYLE, table, svg) + with open('scholars_mate.html', 'w') as f: + f.write(html) + +if __name__ == '__main__': + main() From 4029dae641094ecb3dcbfd4b83a6f5bd2a949113 Mon Sep 17 00:00:00 2001 From: John <37978984+johnridesabike@users.noreply.github.com> Date: Mon, 23 Jul 2018 10:33:00 -0400 Subject: [PATCH 7/7] Lowercase'd table headings for consistency. --- chess/html.py | 1 - docs/scholars_mate.html | 2 -- 2 files changed, 3 deletions(-) diff --git a/chess/html.py b/chess/html.py index 7eed25e3e..c3d99f551 100644 --- a/chess/html.py +++ b/chess/html.py @@ -68,7 +68,6 @@ vertical-align:middle; font-weight: normal; font-size:.5em; - text-transform: uppercase; } .chess_board .check { background: -moz-radial-gradient(center, ellipse cover, rgba(255,0,0,1) 0%, rgba(231,0,0,0.5) 50%, rgba(158,0,0,0) 100%); diff --git a/docs/scholars_mate.html b/docs/scholars_mate.html index 17aa58aef..4c8d116c1 100644 --- a/docs/scholars_mate.html +++ b/docs/scholars_mate.html @@ -42,7 +42,6 @@ vertical-align:middle; font-weight: normal; font-size:.5em; - text-transform: uppercase; } .chess_board .check { background: -moz-radial-gradient(center, ellipse cover, rgba(255,0,0,1) 0%, rgba(231,0,0,0.5) 50%, rgba(158,0,0,0) 100%); @@ -193,4 +192,3 @@

SVG Output

aabbccddeeffgghh1122334455667788
- \ No newline at end of file