Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-rich for openSUSE:Factory checked in at 2023-06-04 00:11:45 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-rich (Old) and /work/SRC/openSUSE:Factory/.python-rich.new.15902 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-rich" Sun Jun 4 00:11:45 2023 rev:24 rq:1090265 version:13.4.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-rich/python-rich.changes 2023-05-09 13:06:16.924643948 +0200 +++ /work/SRC/openSUSE:Factory/.python-rich.new.15902/python-rich.changes 2023-06-04 00:11:47.237241585 +0200 @@ -1,0 +2,8 @@ +Thu Jun 1 06:05:31 UTC 2023 - Johannes Kastl <ka...@b1-systems.de> + +- update to 13.4.1: + * Fixed typing extensions import in markdown #2979 +- update to 13.4.0: + * Added support for tables in Markdown #2977 + +------------------------------------------------------------------- Old: ---- rich-13.3.5.tar.gz New: ---- rich-13.4.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-rich.spec ++++++ --- /var/tmp/diff_new_pack.EA0BFj/_old 2023-06-04 00:11:47.893245506 +0200 +++ /var/tmp/diff_new_pack.EA0BFj/_new 2023-06-04 00:11:47.901245555 +0200 @@ -17,10 +17,9 @@ # -%define skip_python2 1 %{?sle15_python_module_pythons} Name: python-rich -Version: 13.3.5 +Version: 13.4.1 Release: 0 Summary: A Python library for rich text and beautiful formatting in the terminal License: MIT ++++++ rich-13.3.5.tar.gz -> rich-13.4.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rich-13.3.5/PKG-INFO new/rich-13.4.1/PKG-INFO --- old/rich-13.3.5/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 +++ new/rich-13.4.1/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: rich -Version: 13.3.5 +Version: 13.4.1 Summary: Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal Home-page: https://github.com/Textualize/rich License: MIT diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rich-13.3.5/pyproject.toml new/rich-13.4.1/pyproject.toml --- old/rich-13.3.5/pyproject.toml 2023-04-27 16:16:26.977654500 +0200 +++ new/rich-13.4.1/pyproject.toml 2023-05-31 19:15:37.644099200 +0200 @@ -2,7 +2,7 @@ name = "rich" homepage = "https://github.com/Textualize/rich" documentation = "https://rich.readthedocs.io/en/latest/" -version = "13.3.5" +version = "13.4.1" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" authors = ["Will McGugan <willmcgu...@gmail.com>"] license = "MIT" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rich-13.3.5/rich/markdown.py new/rich-13.4.1/rich/markdown.py --- old/rich-13.3.5/rich/markdown.py 2023-01-27 17:26:35.442798900 +0100 +++ new/rich-13.4.1/rich/markdown.py 2023-05-31 19:25:32.484368000 +0200 @@ -1,10 +1,18 @@ from __future__ import annotations +import sys from typing import ClassVar, Dict, Iterable, List, Optional, Type, Union from markdown_it import MarkdownIt from markdown_it.token import Token +if sys.version_info >= (3, 8): + from typing import get_args +else: + from typing_extensions import get_args # pragma: no cover + +from rich.table import Table + from . import box from ._loop import loop_first from ._stack import Stack @@ -223,6 +231,117 @@ yield Rule(style=style) +class TableElement(MarkdownElement): + """MarkdownElement corresponding to `table_open`.""" + + def __init__(self) -> None: + self.header: TableHeaderElement | None = None + self.body: TableBodyElement | None = None + + def on_child_close( + self, context: "MarkdownContext", child: "MarkdownElement" + ) -> bool: + if isinstance(child, TableHeaderElement): + self.header = child + elif isinstance(child, TableBodyElement): + self.body = child + else: + raise RuntimeError("Couldn't process markdown table.") + return False + + def __rich_console__( + self, console: Console, options: ConsoleOptions + ) -> RenderResult: + table = Table(box=box.SIMPLE_HEAVY) + + assert self.header is not None + assert self.header.row is not None + for column in self.header.row.cells: + table.add_column(column.content) + + assert self.body is not None + for row in self.body.rows: + row_content = [element.content for element in row.cells] + table.add_row(*row_content) + + yield table + + +class TableHeaderElement(MarkdownElement): + """MarkdownElement corresponding to `thead_open` and `thead_close`.""" + + def __init__(self) -> None: + self.row: TableRowElement | None = None + + def on_child_close( + self, context: "MarkdownContext", child: "MarkdownElement" + ) -> bool: + assert isinstance(child, TableRowElement) + self.row = child + return False + + +class TableBodyElement(MarkdownElement): + """MarkdownElement corresponding to `tbody_open` and `tbody_close`.""" + + def __init__(self) -> None: + self.rows: list[TableRowElement] = [] + + def on_child_close( + self, context: "MarkdownContext", child: "MarkdownElement" + ) -> bool: + assert isinstance(child, TableRowElement) + self.rows.append(child) + return False + + +class TableRowElement(MarkdownElement): + """MarkdownElement corresponding to `tr_open` and `tr_close`.""" + + def __init__(self) -> None: + self.cells: List[TableDataElement] = [] + + def on_child_close( + self, context: "MarkdownContext", child: "MarkdownElement" + ) -> bool: + assert isinstance(child, TableDataElement) + self.cells.append(child) + return False + + +class TableDataElement(MarkdownElement): + """MarkdownElement corresponding to `td_open` and `td_close` + and `th_open` and `th_close`.""" + + @classmethod + def create(cls, markdown: "Markdown", token: Token) -> "MarkdownElement": + style = str(token.attrs.get("style" "")) or "" + + justify: JustifyMethod + if "text-align:right" in style: + justify = "right" + elif "text-align:center" in style: + justify = "center" + elif "text-align:left" in style: + justify = "left" + else: + justify = "default" + + assert justify in get_args(JustifyMethod) + return cls(justify=justify) + + def __init__(self, justify: JustifyMethod) -> None: + self.content: TextType = "" + self.justify = justify + + def on_text(self, context: "MarkdownContext", text: TextType) -> None: + plain = text.plain if isinstance(text, Text) else text + style = text.style if isinstance(text, Text) else "" + self.content = Text( + plain, justify=self.justify, style=context.style_stack.current + ) + + class ListElement(MarkdownElement): """A list element.""" @@ -426,6 +545,12 @@ "ordered_list_open": ListElement, "list_item_open": ListItem, "image": ImageItem, + "table_open": TableElement, + "tbody_open": TableBodyElement, + "thead_open": TableHeaderElement, + "tr_open": TableRowElement, + "td_open": TableDataElement, + "th_open": TableDataElement, } inlines = {"em", "strong", "code", "s"} @@ -440,7 +565,7 @@ inline_code_lexer: Optional[str] = None, inline_code_theme: Optional[str] = None, ) -> None: - parser = MarkdownIt().enable("strikethrough") + parser = MarkdownIt().enable("strikethrough").enable("table") self.markup = markup self.parsed = parser.parse(markup) self.code_theme = code_theme @@ -557,6 +682,7 @@ if should_render: if new_line: yield _new_line_segment + yield from console.render(element, context.options) elif self_closing: # SELF-CLOSING tags (e.g. text, code, image) context.stack.pop() @@ -580,7 +706,6 @@ if __name__ == "__main__": # pragma: no cover - import argparse import sys @@ -652,6 +777,7 @@ else: with open(args.path, "rt", encoding="utf-8") as markdown_file: markdown_body = markdown_file.read() + markdown = Markdown( markdown_body, justify="full" if args.justify else "left",