diff --git a/CHANGELOG.md b/CHANGELOG.md index 01d4c3cca..153b24212 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - Added `App.batch_update` +- Added horizontal rule to Markdown ### Changed diff --git a/examples/dictionary.css b/examples/dictionary.css index 6bca8b9f5..151fa019d 100644 --- a/examples/dictionary.css +++ b/examples/dictionary.css @@ -8,9 +8,9 @@ Input { } #results { - width: auto; - min-height: 100%; - padding: 0 1; + width: 100%; + height: auto; + } #results-container { diff --git a/examples/dictionary.py b/examples/dictionary.py index 737bcb283..6a6f84d42 100644 --- a/examples/dictionary.py +++ b/examples/dictionary.py @@ -7,11 +7,10 @@ try: except ImportError: raise ImportError("Please install httpx with 'pip install httpx' ") -from rich.markdown import Markdown from textual.app import App, ComposeResult from textual.containers import Content -from textual.widgets import Static, Input +from textual.widgets import Input, Markdown class DictionaryApp(App): @@ -21,7 +20,7 @@ class DictionaryApp(App): def compose(self) -> ComposeResult: yield Input(placeholder="Search for a word") - yield Content(Static(id="results"), id="results-container") + yield Content(Markdown(id="results"), id="results-container") def on_mount(self) -> None: """Called when app starts.""" @@ -35,7 +34,7 @@ class DictionaryApp(App): asyncio.create_task(self.lookup_word(message.value)) else: # Clear the results - self.query_one("#results", Static).update() + await self.query_one("#results", Markdown).update("") async def lookup_word(self, word: str) -> None: """Looks up a word.""" @@ -45,7 +44,8 @@ class DictionaryApp(App): if word == self.query_one(Input).value: markdown = self.make_word_markdown(results) - self.query_one("#results", Static).update(Markdown(markdown)) + self.log(markdown) + await self.query_one("#results", Markdown).update(markdown) def make_word_markdown(self, results: object) -> str: """Convert the results in to markdown.""" diff --git a/src/textual/widgets/_markdown.py b/src/textual/widgets/_markdown.py index 50812dd9d..4c8bb5b16 100644 --- a/src/textual/widgets/_markdown.py +++ b/src/textual/widgets/_markdown.py @@ -198,6 +198,18 @@ class MarkdownH6(MarkdownHeader): """ +class MarkdownHorizontalRule(MarkdownBlock): + """A horizontal rule.""" + + DEFAULT_CSS = """ + MarkdownHorizontalRule { + border-bottom: heavy $primary; + height: 1; + padding-top: 1; + } + """ + + class MarkdownParagraph(MarkdownBlock): """A paragraph Markdown block.""" @@ -501,7 +513,7 @@ class Markdown(Widget): markdown = path.read_text(encoding="utf-8") except Exception: return False - await self.query("MarkdownBlock").remove() + await self.update(markdown) return True @@ -524,6 +536,8 @@ class Markdown(Widget): if token.type == "heading_open": block_id += 1 stack.append(HEADINGS[token.tag](id=f"block{block_id}")) + elif token.type == "hr": + output.append(MarkdownHorizontalRule()) elif token.type == "paragraph_open": stack.append(MarkdownParagraph()) elif token.type == "blockquote_open": @@ -627,7 +641,10 @@ class Markdown(Widget): await self.post_message( Markdown.TableOfContentsUpdated(table_of_contents, sender=self) ) - await self.mount(*output) + with self.app.batch_update(): + await self.query("MarkdownBlock").remove() + await self.mount(*output) + self.refresh(layout=True) class MarkdownTableOfContents(Widget, can_focus_children=True):