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
|
## Unreleased
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Added `parser_factory` argument to `Markdown` and `MarkdownViewer` constructors https://github.com/Textualize/textual/pull/2075
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Dropped "loading-indicator--dot" component style from LoadingIndicator https://github.com/Textualize/textual/pull/2050
|
- Dropped "loading-indicator--dot" component style from LoadingIndicator https://github.com/Textualize/textual/pull/2050
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from pathlib import Path, PurePath
|
from pathlib import Path, PurePath
|
||||||
from typing import Iterable
|
from typing import Iterable, Callable
|
||||||
|
|
||||||
from markdown_it import MarkdownIt
|
from markdown_it import MarkdownIt
|
||||||
from rich import box
|
from rich import box
|
||||||
@@ -541,6 +541,7 @@ class Markdown(Widget):
|
|||||||
name: str | None = None,
|
name: str | None = None,
|
||||||
id: str | None = None,
|
id: str | None = None,
|
||||||
classes: str | None = None,
|
classes: str | None = None,
|
||||||
|
parser_factory: Callable[[], MarkdownIt] | None = None,
|
||||||
):
|
):
|
||||||
"""A Markdown widget.
|
"""A Markdown widget.
|
||||||
|
|
||||||
@@ -549,9 +550,11 @@ class Markdown(Widget):
|
|||||||
name: The name of the widget.
|
name: The name of the widget.
|
||||||
id: The ID of the widget in the DOM.
|
id: The ID of the widget in the DOM.
|
||||||
classes: The CSS classes of the widget.
|
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)
|
super().__init__(name=name, id=id, classes=classes)
|
||||||
self._markdown = markdown
|
self._markdown = markdown
|
||||||
|
self._parser_factory = parser_factory
|
||||||
|
|
||||||
class TableOfContentsUpdated(Message, bubble=True):
|
class TableOfContentsUpdated(Message, bubble=True):
|
||||||
"""The table of contents was updated."""
|
"""The table of contents was updated."""
|
||||||
@@ -606,7 +609,11 @@ class Markdown(Widget):
|
|||||||
"""
|
"""
|
||||||
output: list[MarkdownBlock] = []
|
output: list[MarkdownBlock] = []
|
||||||
stack: 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()
|
content = Text()
|
||||||
block_id: int = 0
|
block_id: int = 0
|
||||||
@@ -831,6 +838,7 @@ class MarkdownViewer(VerticalScroll, can_focus=True, can_focus_children=True):
|
|||||||
name: str | None = None,
|
name: str | None = None,
|
||||||
id: str | None = None,
|
id: str | None = None,
|
||||||
classes: str | None = None,
|
classes: str | None = None,
|
||||||
|
parser_factory: Callable[[], MarkdownIt] | None = None,
|
||||||
):
|
):
|
||||||
"""Create a Markdown Viewer object.
|
"""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.
|
name: The name of the widget.
|
||||||
id: The ID of the widget in the DOM.
|
id: The ID of the widget in the DOM.
|
||||||
classes: The CSS classes of the widget.
|
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)
|
super().__init__(name=name, id=id, classes=classes)
|
||||||
self.show_table_of_contents = show_table_of_contents
|
self.show_table_of_contents = show_table_of_contents
|
||||||
self._markdown = markdown
|
self._markdown = markdown
|
||||||
|
self._parser_factory = parser_factory
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def document(self) -> Markdown:
|
def document(self) -> Markdown:
|
||||||
@@ -882,7 +892,7 @@ class MarkdownViewer(VerticalScroll, can_focus=True, can_focus_children=True):
|
|||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield MarkdownTableOfContents()
|
yield MarkdownTableOfContents()
|
||||||
yield Markdown()
|
yield Markdown(parser_factory=self._parser_factory)
|
||||||
|
|
||||||
def on_markdown_table_of_contents_updated(
|
def on_markdown_table_of_contents_updated(
|
||||||
self, message: Markdown.TableOfContentsUpdated
|
self, message: Markdown.TableOfContentsUpdated
|
||||||
|
|||||||
Reference in New Issue
Block a user