Skip to content

[0] is being considered a markup tag #5768

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
kuhnchris opened this issue Apr 25, 2025 · 2 comments
Open

[0] is being considered a markup tag #5768

kuhnchris opened this issue Apr 25, 2025 · 2 comments

Comments

@kuhnchris
Copy link

kuhnchris commented Apr 25, 2025

Have you checked closed issues? (https://github.com/Textualize/textual/issues?q=is%3Aissue+is%3Aclosed) Yes

Have you checked against the most recent version of Textual? (https://pypi.org/search/?q=textual) Yes

The bug

  • Trying to create a Static with markup=True with predefined text "[0] Hello World".
    => Crash

  • Trying to escape the text results in a non-escaped string.
    => Crash

According to McGugan:

[0] shouldn't be considered a tag and shouldn't need escaping. If it is throwing a markup error, that is a bug. Please file an issue.

Error:

MarkupError: Expected markup style value (found '0] Hello World!').

MRE:

from textual.app import App
from textual.widgets import Footer, Static
from textual.markup import escape
class TextualApp(App):

    DEFAULT_CSS = """
    /* any needed CSS  here */
    """

    def compose(self):
        yield Static(escape("[0] Hello World!"))
        yield Footer()

    # code that causes a bug here

textual diagnose:

<!-- This is valid Markdown, please paste the following directly in to a GitHub issue -->
# Textual Diagnostics

## Versions

| Name    | Value  |
|---------|--------|
| Textual | 3.1.1  |
| Rich    | 14.0.0 |

## Python

| Name           | Value                                |
|----------------|--------------------------------------|
| Version        | 3.12.9                               |
| Implementation | CPython                              |
| Compiler       | GCC 13.2.1 20240309                  |
| Executable     | /home/kuhnchris/test/venv/bin/python |

## Operating System

| Name    | Value                                             |
|---------|---------------------------------------------------|
| System  | Linux                                             |
| Release | 6.12.21-0-lts                                     |
| Version | #1-Alpine SMP PREEMPT_DYNAMIC 2025-04-01 11:09:17 |

## Terminal

| Name                 | Value          |
|----------------------|----------------|
| Terminal Application | *Unknown*      |
| TERM                 | xterm-256color |
| COLORTERM            | truecolor      |
| FORCE_COLOR          | *Not set*      |
| NO_COLOR             | *Not set*      |

## Rich Console options

| Name           | Value                |
|----------------|----------------------|
| size           | width=289, height=98 |
| legacy_windows | False                |
| min_width      | 1                    |
| max_width      | 289                  |
| is_terminal    | True                 |
| encoding       | utf-8                |
| max_height     | 98                   |
| justify        | None                 |
| overflow       | None                 |
| no_wrap        | False                |
| highlight      | None                 |
| markup         | None                 |
| height         | None                 |

Technical workaround:
(by David Fokkema)

import re

escape("[1]", _escape=re.compile(r"(\\*)(\[[a-z0-9#/@][^[]*?])").sub)

(by kuhnchris)

outputText.replace("[", "\\[")

Full Stack log (textual run --dev):

fullStackTrace.txt

Copy link

We found the following entries in the FAQ which you may find helpful:

Feel free to close this issue if you found an answer in the FAQ. Otherwise, please give us a little time to review.

This is an automated reply, generated by FAQtory

@python-and-novella
Copy link
Contributor

The uppercase also should be considered:

from textual.app import App
from textual.widgets import Static
from textual.markup import escape
import re

class MyApp(App):
    def on_mount(self):
        self.widgets = [ 
                Static(escape('[0 W] Hello World!',re.compile(r'(\\*)(\[[0-9a-zA-Z#/@][^[]*?])').sub)),
            ]
        self.mount_all(self.widgets)

if __name__ == '__main__':
    app = MyApp()
    app.run()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants