streamlit icon indicating copy to clipboard operation
streamlit copied to clipboard

Rendering of HTML tables in Markdown is whitespace-sensitive

Open enrico-stauss opened this issue 6 months ago • 5 comments

Checklist

  • [X] I have searched the existing issues for similar issues.
  • [X] I added a very descriptive title to this issue.
  • [X] I have provided sufficient information below to help reproduce this issue.

Summary

AFAIK, HTML should be Whitespace insensitive. I encountered some issues with auto-generated Markdown that contain HTML tables when rendering with the st.markdown(..., unsafe_allow_html=True) that, funnily enough, don't appear when using st.write.

You'll find a MWE attached. Note the newline after <colgroup>

Reproducible Code Example

Open in Streamlit Cloud

import streamlit as st


TABLE_CORRECT = """
TEXT

<table class="- topic/table table frame-all" style="width:100%;">
<colgroup>
<col style="width: 50%">
<col style="width: 50%">
</colgroup>

  <thead class="- topic/thead thead">
    <tr class="- topic/row">
      <th id="header1" class="- topic/entry entry colsep-1 rowsep-1">
        Property
      </th>
      <th id="header2" class="- topic/entry entry colsep-1 rowsep-1">
        Description
      </th>
    </tr>
  </thead>
  <tbody class="- topic/tbody tbody">
    <tr class="- topic/row">
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header1">
        ExampleProperty1
      </td>
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header2">
        Description of ExampleProperty1
      </td>
    </tr>
    <tr class="- topic/row">
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header1">
        ExampleProperty2
      </td>
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header2">
        Description of ExampleProperty2
      </td>
    </tr>
    <tr class="- topic/row">
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header1">
        ExampleProperty3
      </td>
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header2">
        Description of ExampleProperty3
      </td>
    </tr>
    <tr class="- topic/row">
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header1">
        ExampleProperty4
      </td>
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header2">
        Description of ExampleProperty4
      </td>
    </tr>
  </tbody>
</table>
"""

TABLE_FAULTY_1 = """
TEXT

<table class="- topic/table table frame-all" style="width:100%;">
<colgroup>

<col style="width: 50%">
<col style="width: 50%">
</colgroup>

  <thead class="- topic/thead thead">
    <tr class="- topic/row">
      <th id="header1" class="- topic/entry entry colsep-1 rowsep-1">
        Property
      </th>
      <th id="header2" class="- topic/entry entry colsep-1 rowsep-1">
        Description
      </th>
    </tr>
  </thead>
  <tbody class="- topic/tbody tbody">
    <tr class="- topic/row">
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header1">
        ExampleProperty1
      </td>
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header2">
        Description of ExampleProperty1
      </td>
    </tr>
    <tr class="- topic/row">
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header1">
        ExampleProperty2
      </td>
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header2">
        Description of ExampleProperty2
      </td>
    </tr>
    <tr class="- topic/row">
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header1">
        ExampleProperty3
      </td>
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header2">
        Description of ExampleProperty3
      </td>
    </tr>
    <tr class="- topic/row">
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header1">
        ExampleProperty4
      </td>
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header2">
        Description of ExampleProperty4
      </td>
    </tr>
  </tbody>
</table>
"""

TABLE_FAULTY_2 = """
TEXT

<table class="- topic/table table frame-all" style="width:100%;">
<colgroup>

    <col style="width: 50%">
    <col style="width: 50%">
</colgroup>

  <thead class="- topic/thead thead">
    <tr class="- topic/row">
      <th id="header1" class="- topic/entry entry colsep-1 rowsep-1">
        Property
      </th>
      <th id="header2" class="- topic/entry entry colsep-1 rowsep-1">
        Description
      </th>
    </tr>
  </thead>
  <tbody class="- topic/tbody tbody">
    <tr class="- topic/row">
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header1">
        ExampleProperty1
      </td>
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header2">
        Description of ExampleProperty1
      </td>
    </tr>
    <tr class="- topic/row">
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header1">
        ExampleProperty2
      </td>
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header2">
        Description of ExampleProperty2
      </td>
    </tr>
    <tr class="- topic/row">
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header1">
        ExampleProperty3
      </td>
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header2">
        Description of ExampleProperty3
      </td>
    </tr>
    <tr class="- topic/row">
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header1">
        ExampleProperty4
      </td>
      <td class="- topic/entry entry colsep-1 rowsep-1" headers="header2">
        Description of ExampleProperty4
      </td>
    </tr>
  </tbody>
</table>
"""

st.markdown(TABLE_CORRECT, unsafe_allow_html=True)
st.markdown(TABLE_FAULTY_1, unsafe_allow_html=True)
st.markdown(TABLE_FAULTY_2, unsafe_allow_html=True)

Steps To Reproduce

Just launch the code I provided as streamlit app, you'll see what I described

Expected Behavior

No response

Current Behavior

No response

Is this a regression?

  • [ ] Yes, this used to work in a previous version.

Debug info

  • Streamlit version: 1.37.0
  • Python version: 3.10.11
  • Operating System: Windows
  • Browser: Chrome

Additional Information

No response

enrico-stauss avatar Aug 20 '24 14:08 enrico-stauss