mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Allow customizing the markdown parser (#2075)
* Allow customizing the markdown parser
For instance, code using Markdown might wish to create a markdown
parser that does not parse embedded HTML:
```py
def parser_factory():
parser = MarkdownIt("gfm-like")
parser.options["html"] = False
return parser
```
* blacken
* Implement requested changes
* fix AttributeError
This commit is contained in:
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
- Added `parser_factory` argument to `Markdown` and `MarkdownViewer` constructors https://github.com/Textualize/textual/pull/2075
|
||||
|
||||
### Changed
|
||||
|
||||
- Dropped "loading-indicator--dot" component style from LoadingIndicator https://github.com/Textualize/textual/pull/2050
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path, PurePath
|
||||
from typing import Iterable
|
||||
from typing import Iterable, Callable
|
||||
|
||||
from markdown_it import MarkdownIt
|
||||
from rich import box
|
||||
@@ -541,6 +541,7 @@ class Markdown(Widget):
|
||||
name: str | None = None,
|
||||
id: str | None = None,
|
||||
classes: str | None = None,
|
||||
parser_factory: Callable[[], MarkdownIt] | None = None,
|
||||
):
|
||||
"""A Markdown widget.
|
||||
|
||||
@@ -549,9 +550,11 @@ class Markdown(Widget):
|
||||
name: The name of the widget.
|
||||
id: The ID of the widget in the DOM.
|
||||
classes: The CSS classes of the widget.
|
||||
parser_factory: A factory function to return a configured MarkdownIt instance. If `None`, a "gfm-like" parser is used.
|
||||
"""
|
||||
super().__init__(name=name, id=id, classes=classes)
|
||||
self._markdown = markdown
|
||||
self._parser_factory = parser_factory
|
||||
|
||||
class TableOfContentsUpdated(Message, bubble=True):
|
||||
"""The table of contents was updated."""
|
||||
@@ -606,7 +609,11 @@ class Markdown(Widget):
|
||||
"""
|
||||
output: list[MarkdownBlock] = []
|
||||
stack: list[MarkdownBlock] = []
|
||||
parser = MarkdownIt("gfm-like")
|
||||
parser = (
|
||||
MarkdownIt("gfm-like")
|
||||
if self._parser_factory is None
|
||||
else self._parser_factory()
|
||||
)
|
||||
|
||||
content = Text()
|
||||
block_id: int = 0
|
||||
@@ -831,6 +838,7 @@ class MarkdownViewer(VerticalScroll, can_focus=True, can_focus_children=True):
|
||||
name: str | None = None,
|
||||
id: str | None = None,
|
||||
classes: str | None = None,
|
||||
parser_factory: Callable[[], MarkdownIt] | None = None,
|
||||
):
|
||||
"""Create a Markdown Viewer object.
|
||||
|
||||
@@ -840,10 +848,12 @@ class MarkdownViewer(VerticalScroll, can_focus=True, can_focus_children=True):
|
||||
name: The name of the widget.
|
||||
id: The ID of the widget in the DOM.
|
||||
classes: The CSS classes of the widget.
|
||||
parser_factory: A factory function to return a configured MarkdownIt instance. If `None`, a "gfm-like" parser is used.
|
||||
"""
|
||||
super().__init__(name=name, id=id, classes=classes)
|
||||
self.show_table_of_contents = show_table_of_contents
|
||||
self._markdown = markdown
|
||||
self._parser_factory = parser_factory
|
||||
|
||||
@property
|
||||
def document(self) -> Markdown:
|
||||
@@ -882,7 +892,7 @@ class MarkdownViewer(VerticalScroll, can_focus=True, can_focus_children=True):
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield MarkdownTableOfContents()
|
||||
yield Markdown()
|
||||
yield Markdown(parser_factory=self._parser_factory)
|
||||
|
||||
def on_markdown_table_of_contents_updated(
|
||||
self, message: Markdown.TableOfContentsUpdated
|
||||
|
||||
Reference in New Issue
Block a user