How to keep whitespace formatting

I am trying to print out a chessboard inside a streamlit message. I am trying to print it inside a code block, but the whitespaces don’t align as in the terminal. Is there any way to solve this issue?

This is how the chessboard now looks inside the chat:
This is how the chessboard now looks inside the chat

This is an example of what I am trying to print out

Thank you all in advance

It’s a bit tough to test what you’re experiencing without some sample code, but this code seems to work fine

import streamlit as st


# Define a function to generate a text-and-unicode representation of a chess board
def generate_chessboard():
    # Unicode characters for each type of chess piece
    pieces = {
        "K": "\u2654",  # White King
        "Q": "\u2655",  # White Queen
        "R": "\u2656",  # White Rook
        "B": "\u2657",  # White Bishop
        "N": "\u2658",  # White Knight
        "P": "\u2659",  # White Pawn
        "k": "\u265A",  # Black King
        "q": "\u265B",  # Black Queen
        "r": "\u265C",  # Black Rook
        "b": "\u265D",  # Black Bishop
        "n": "\u265E",  # Black Knight
        "p": "\u265F",  # Black Pawn
        ".": " ",  # Empty square
    }

    # Define the board layout as a list of strings, where each string represents a row
    # A couple of pieces have been moved for demonstration
    board_layout = [
        "r n b q k b n r",
        "p p p p . p p p",
        ". . . . . . . .",
        ". . . . p . . .",
        ". . . . P . . .",
        ". . . . . . . .",
        "P P P P . P P P",
        "R N B Q K B N R",
    ]

    # Generate the formatted board as a string
    board_str = ""
    for i, row in enumerate(reversed(board_layout)):
        board_str += f'{8 - i} {" ".join([pieces[piece] for piece in row.split()])}\n'

    board_str += "  a b c d e f g h"

    return board_str


# Generate and print the chessboard
chessboard_str = generate_chessboard()
print(chessboard_str)
st.code(chessboard_str)

I think the issue is the monospace font that st.code defaults to. In my case, @blackary’s code shows unaligned pieces:

I think I might be close to a solution.
I think the problem with using monospace alone is that whitespaces don’t have the same width as other characters. Therefore, it would be optimal to replace whitespaces with

<span style="width: 1ch;"> </span> in order to let it have the same width as other characters.

st.code does not have unsafe_allow_html, so I tried putting the chessboard between a bloc of three backticks and using st.write. I set unsafe_allow_html=True and replaced whitespaces inside the code block, but now I get the whole HTML as text within the code block. This is because, for some reason, β€œ&lt” and β€œ&gt” are put in the HTML instead of the tags.
I guess, it is not possible to insert HTML inside a code block, but at the same time I need a code block in order to preserve the whitespaces.
However, thank you a lot for your previous answers. Do you have any idea on how I could move on?
Thanks

Could you try adding something like this

st.markdown(
    """
<style>
    code {
        font-family: "Courier New", monospace !important;
    }
            """,
    unsafe_allow_html=True,
)

That should override the default font that code blocks use, which might solve the issue.

I suspect:

  • It depends on the fonts you happen to have available on your machine, which is why you both are seeing something different from me
  • The actual issue is likely the width of the unicode piece characters in the particular font, not the spaces themselves

But those are just suspicions. If the first one is true, then switching the font to some different monospace font might work.

You are on the right track there.

I will add that you will need to set up a font that actually supports the chess piece characters. Otherwise they will default to whatever font is available that do have them implemented, not necessarily a monospaced font.

An array in st.latex or a regular html table could be used as an alternative:

import streamlit as st
with st.chat_message("user"):

    st.latex(
        r"""
        \def\arraystretch{1.5}
        \begin{array}{c|c:c:c:c:c:c:c:c}
        & a & b & c & d & e & f & g & h \\ \hline
        1 & β™” & β™” & β™” & β™” & β™” & β™” & β™” & β™” \\ \hdashline
        2 & β™™ & β™™ & β™™ & β™™ & β™™ & β™™ & β™™ & β™™ \\ \hdashline
        3 & \\ \hdashline
        4 & \\ \hdashline
        5 & \\ \hdashline
        6 & \\ \hdashline
        7 & β™ŸοΈŽ & β™ŸοΈŽ & β™ŸοΈŽ & β™ŸοΈŽ & β™ŸοΈŽ & β™ŸοΈŽ & β™ŸοΈŽ & β™ŸοΈŽ \\ \hdashline
        8 & β™› & β™› & β™› & β™› & β™› & β™› & β™› & β™› 
        \end{array}
        """)
    

I absolutely did not think about using latex! Thank you a lot!

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.