Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-rich-rst for openSUSE:Factory
checked in at 2026-07-06 12:31:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-rich-rst (Old)
and /work/SRC/openSUSE:Factory/.python-rich-rst.new.1982 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-rich-rst"
Mon Jul 6 12:31:33 2026 rev:3 rq:1363829 version:2.1.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-rich-rst/python-rich-rst.changes
2026-06-30 15:13:34.004312213 +0200
+++
/work/SRC/openSUSE:Factory/.python-rich-rst.new.1982/python-rich-rst.changes
2026-07-06 12:34:02.462954279 +0200
@@ -1,0 +2,9 @@
+Sun Jul 5 09:11:56 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to version 2.1.0:
+ * Add -S/--save-html and -d/--debug CLI flags
+ * Improved error messages and help text
+ * Expanded test coverage and CI automation
+ * No runtime dependency changes
+
+-------------------------------------------------------------------
Old:
----
rich_rst-2.0.2.tar.gz
New:
----
rich_rst-2.1.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-rich-rst.spec ++++++
--- /var/tmp/diff_new_pack.V0VkXc/_old 2026-07-06 12:34:03.742998751 +0200
+++ /var/tmp/diff_new_pack.V0VkXc/_new 2026-07-06 12:34:03.746998890 +0200
@@ -17,7 +17,7 @@
Name: python-rich-rst
-Version: 2.0.2
+Version: 2.1.0
Release: 0
Summary: A beautiful reStructuredText renderer for rich
License: MIT
++++++ rich_rst-2.0.2.tar.gz -> rich_rst-2.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/rich_rst-2.0.2/MANIFEST.in
new/rich_rst-2.1.0/MANIFEST.in
--- old/rich_rst-2.0.2/MANIFEST.in 1970-01-01 01:00:00.000000000 +0100
+++ new/rich_rst-2.1.0/MANIFEST.in 2026-07-05 04:59:22.000000000 +0200
@@ -0,0 +1 @@
+include tests/conftest.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/rich_rst-2.0.2/PKG-INFO new/rich_rst-2.1.0/PKG-INFO
--- old/rich_rst-2.0.2/PKG-INFO 2026-06-25 19:23:36.880336300 +0200
+++ new/rich_rst-2.1.0/PKG-INFO 2026-07-05 04:59:26.450120400 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: rich-rst
-Version: 2.0.2
+Version: 2.1.0
Summary: A beautiful reStructuredText renderer for rich
Author-email: Wasi Master <[email protected]>
License-Expression: MIT
@@ -30,14 +30,16 @@
Requires-Dist: pygments>=2.0.0
Provides-Extra: docs
Requires-Dist: docutils; extra == "docs"
-Requires-Dist: rich; extra == "docs"
-Requires-Dist: rich_rst; extra == "docs"
Requires-Dist: sphinx; extra == "docs"
Requires-Dist: sphinx_copybutton; extra == "docs"
Requires-Dist: sphinx_rtd_theme; extra == "docs"
Provides-Extra: tests
Requires-Dist: pytest; extra == "tests"
Requires-Dist: pytest-cov; extra == "tests"
+Provides-Extra: dev
+Requires-Dist: ruff; extra == "dev"
+Requires-Dist: mypy; extra == "dev"
+Requires-Dist: pre-commit; extra == "dev"
Dynamic: license-file
@@ -116,7 +118,7 @@
python -m rich_rst --help
```
-Useful flags include `--code-theme`, `--show-line-numbers`, `--guess-lexer`,
`--default-lexer`, `--show-errors`, `--admonition-style`, `--save-html`,
`--html-theme`, `--list-html-themes`, `--output`, and `--version`.
+Useful flags include ``--code-theme``, ``--show-line-numbers``,
``--guess-lexer``, ``--default-lexer``, ``--show-errors``,
``--admonition-style``, ``-S/--save-html``, ``--html-theme``,
``--list-html-themes``, ``--output``, ``--debug``, and ``--version``.
## Compatibility
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/rich_rst-2.0.2/README.md new/rich_rst-2.1.0/README.md
--- old/rich_rst-2.0.2/README.md 2026-05-16 02:44:55.000000000 +0200
+++ new/rich_rst-2.1.0/README.md 2026-07-05 04:59:22.000000000 +0200
@@ -74,7 +74,7 @@
python -m rich_rst --help
```
-Useful flags include `--code-theme`, `--show-line-numbers`, `--guess-lexer`,
`--default-lexer`, `--show-errors`, `--admonition-style`, `--save-html`,
`--html-theme`, `--list-html-themes`, `--output`, and `--version`.
+Useful flags include ``--code-theme``, ``--show-line-numbers``,
``--guess-lexer``, ``--default-lexer``, ``--show-errors``,
``--admonition-style``, ``-S/--save-html``, ``--html-theme``,
``--list-html-themes``, ``--output``, ``--debug``, and ``--version``.
## Compatibility
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/rich_rst-2.0.2/pyproject.toml
new/rich_rst-2.1.0/pyproject.toml
--- old/rich_rst-2.0.2/pyproject.toml 2026-06-25 19:23:20.000000000 +0200
+++ new/rich_rst-2.1.0/pyproject.toml 2026-07-05 04:59:22.000000000 +0200
@@ -6,7 +6,7 @@
[project]
name = "rich-rst"
-version = "2.0.2"
+version = "2.1.0"
description = "A beautiful reStructuredText renderer for rich"
readme = "README.md"
license = "MIT"
@@ -45,8 +45,6 @@
[project.optional-dependencies]
docs = [
"docutils",
- "rich",
- "rich_rst",
"sphinx",
"sphinx_copybutton",
"sphinx_rtd_theme"
@@ -55,6 +53,11 @@
"pytest",
"pytest-cov"
]
+dev = [
+ "ruff",
+ "mypy",
+ "pre-commit"
+]
[tool.setuptools]
@@ -70,3 +73,22 @@
omit = [
"rich_rst/_vendor/*",
]
+
+[tool.ruff]
+line-length = 100
+target-version = "py38"
+exclude = [
+ "rich_rst/_vendor",
+ ".venv",
+ "build",
+ "dist",
+]
+
+[tool.ruff.lint]
+select = ["E", "W", "F", "I", "N", "UP", "YTT", "ASYNC", "TRIO", "C4", "RUF"]
+
+[tool.mypy]
+ignore_missing_imports = true
+warn_unused_ignores = true
+exclude = ["rich_rst/_vendor"]
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/rich_rst-2.0.2/rich_rst/__main__.py
new/rich_rst-2.1.0/rich_rst/__main__.py
--- old/rich_rst-2.0.2/rich_rst/__main__.py 2026-05-16 02:45:05.000000000
+0200
+++ new/rich_rst-2.1.0/rich_rst/__main__.py 2026-07-05 04:59:22.000000000
+0200
@@ -1,35 +1,30 @@
import argparse
+import logging
import sys
from typing import Tuple
-from rich.panel import Panel
+
from rich.console import Console
-from rich_rst import RestructuredText, __version__
-from rich.terminal_theme import TerminalTheme, DEFAULT_TERMINAL_THEME,
MONOKAI, NIGHT_OWLISH, DIMMED_MONOKAI
-from rich.traceback import install
+from rich.panel import Panel
+from rich.terminal_theme import (
+ DIMMED_MONOKAI,
+ DEFAULT_TERMINAL_THEME,
+ MONOKAI,
+ NIGHT_OWLISH,
+ TerminalTheme,
+)
from rich.text import Text
+from rich.traceback import install
-def rgb(r: int, g: int, b: int) -> Tuple[int, int, int]:
- """
- Function to represent color in RGB format.
+from rich_rst import RestructuredText, __version__
- Parameters
- ----------
- r : int
- Red color value.
- g : int
- Green color value.
- b : int
- Blue color value.
-
- Returns
- -------
- tuple
- A tuple representing the RGB color.
- """
+log = logging.getLogger(__name__)
+
+
+def rgb(r: int, g: int, b: int) -> Tuple[int, int, int]:
+ """Represent color in RGB format."""
return (r, g, b)
-# Named HTML export themes available via --html-theme
_DRACULA_TERMINAL_THEME = TerminalTheme(
rgb(40, 42, 54),
rgb(248, 248, 242),
@@ -66,28 +61,113 @@
def parse_arguments() -> argparse.Namespace:
"""Parse command line arguments."""
- parser = argparse.ArgumentParser(description="Render reStructuredText to
the console with rich-rst")
- parser.add_argument("--version", action="version", version=__version__)
- parser.add_argument("path", metavar="PATH", nargs="?", default=None,
help="path to file, or - for stdin")
- parser.add_argument("-c", "--force-color", dest="force_color",
action="store_true", default=None, help="force color for non-terminals")
- parser.add_argument("-e", "--encoding", dest="encoding", type=str,
default="utf-8", help="encoding for file (default: utf-8)")
- parser.add_argument("-w", "--width", type=int, dest="width", default=None,
help="width of output (default will auto-detect)")
- parser.add_argument("-hw", "--html-width", type=str, dest="html_width",
default="1675px", help="width of html output (default: 1675px)")
- parser.add_argument("-t", "--code-theme", dest="code_theme", type=str,
default="monokai", help="pygments code theme")
- parser.add_argument("--show-line-numbers", action="store_true",
dest="show_line_numbers", default=False, help="show line numbers for
syntax-highlighted code blocks")
- parser.add_argument("-html", "--save-html", type=str,
dest="html_filename", default=False, help="save to html")
- parser.add_argument("-r", "--wrap", dest="word_wrap", action="store_true",
default=False, help="word wrap long lines")
- parser.add_argument("-s", "--soft-wrap", action="store_true",
dest="soft_wrap", default=False, help="enable soft wrapping mode")
- parser.add_argument("-gl", "--guess-lexer", action="store_true",
dest="guess_lexer", default=False, help="Whether to guess the lexer for code
blocks without specified language")
- parser.add_argument("-dl", "--default-lexer", type=str,
dest="default_lexer", default="python", help="The default lexer for code blocks
without specified language if no lexer could be guessed or found")
- parser.add_argument("-se", "--show-errors", action="store_true",
dest="show_errors", default=False, help="Whether to show errors or not")
+ parser = argparse.ArgumentParser(
+ description="Render reStructuredText to the console with rich-rst"
+ )
+ parser.add_argument("--version", action="version", version=f"%(prog)s
{__version__}")
+ parser.add_argument(
+ "path",
+ metavar="PATH",
+ nargs="?",
+ default=None,
+ help="path to file, or - for stdin",
+ )
+ parser.add_argument(
+ "-c",
+ "--force-color",
+ dest="force_color",
+ action="store_true",
+ help="force color for non-terminals",
+ )
+ parser.add_argument(
+ "-e",
+ "--encoding",
+ dest="encoding",
+ type=str,
+ default="utf-8",
+ help="encoding for file (default: utf-8)",
+ )
+ parser.add_argument(
+ "-w",
+ "--width",
+ type=int,
+ dest="width",
+ default=None,
+ help="width of output (default will auto-detect)",
+ )
+ parser.add_argument(
+ "-hw",
+ "--html-width",
+ type=str,
+ dest="html_width",
+ default="1675px",
+ help="width of html output (default: 1675px)",
+ )
+ parser.add_argument(
+ "-t",
+ "--code-theme",
+ dest="code_theme",
+ type=str,
+ default="monokai",
+ help="pygments code theme (default: monokai)",
+ )
+ parser.add_argument(
+ "--show-line-numbers",
+ action="store_true",
+ dest="show_line_numbers",
+ help="show line numbers in code blocks",
+ )
+ parser.add_argument(
+ "-S",
+ "--save-html",
+ type=str,
+ dest="html_filename",
+ default=None,
+ help="export rendered output to HTML file",
+ )
+ parser.add_argument(
+ "-r",
+ "--wrap",
+ dest="word_wrap",
+ action="store_true",
+ help="enable word wrapping for long lines",
+ )
+ parser.add_argument(
+ "-s",
+ "--soft-wrap",
+ action="store_true",
+ dest="soft_wrap",
+ help="enable soft wrapping mode",
+ )
+ parser.add_argument(
+ "-gl",
+ "--guess-lexer",
+ action="store_true",
+ dest="guess_lexer",
+ help="guess lexer for code blocks without language",
+ )
+ parser.add_argument(
+ "-dl",
+ "--default-lexer",
+ type=str,
+ dest="default_lexer",
+ default="python",
+ help="default lexer if no lexer found (default: python)",
+ )
+ parser.add_argument(
+ "-se",
+ "--show-errors",
+ action="store_true",
+ dest="show_errors",
+ help="display reStructuredText parsing errors",
+ )
parser.add_argument(
"--admonition-style",
dest="admonition_style",
type=str,
default="panel",
choices=["panel", "compact"],
- help="How to render admonitions (default: panel)",
+ help="rendering style for admonitions (default: panel)",
)
parser.add_argument(
"--html-theme",
@@ -95,129 +175,190 @@
type=str,
default="dracula",
choices=list(_HTML_THEMES),
- help="colour theme for --save-html output (default: dracula)",
+ help="color theme for HTML export (default: dracula)",
)
parser.add_argument(
"--list-html-themes",
action="store_true",
dest="list_html_themes",
- default=False,
help="list available HTML export themes and exit",
)
parser.add_argument(
- "-o", "--output",
+ "-o",
+ "--output",
dest="output",
type=str,
default=None,
- help="write rendered plain-text output to FILE instead of stdout",
+ help="write plain-text output to FILE instead of stdout",
)
+ parser.add_argument(
+ "-d",
+ "--debug",
+ action="store_true",
+ dest="debug",
+ help="enable debug logging",
+ )
+
args = parser.parse_args()
- # PATH is only optional when --list-html-themes is used.
+
if not args.list_html_themes and args.path is None:
parser.error("the following arguments are required: PATH")
+
return args
+
def main() -> int:
- """The main function."""
+ """Main entry point."""
args = parse_arguments()
+ if args.debug:
+ logging.basicConfig(level=logging.DEBUG)
+ log.debug("Debug mode enabled")
+
if args.list_html_themes:
for name in sorted(_HTML_THEMES):
print(name)
return 0
- # PATH is required at this point (parse_arguments already validated it)
-
- # NOTE: CSS braces must be doubled ({{ / }}) so that Rich's internal
- # code_format.format(...) call treats them as literal characters.
- # args.html_width is spliced in with a plain str.replace to avoid
- # adding a third round of brace escaping.
- CONSOLE_HTML_FORMAT = """\
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <style>
- {stylesheet}
- body {{
- color: {foreground};
- background-color: {background};
- max-width: HTML_WIDTH_PLACEHOLDER
- }}
- pre {{
- white-space: pre-wrap; /* Since CSS 2.1 */
- white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
- white-space: -pre-wrap; /* Opera 4-6 */
- white-space: -o-pre-wrap; /* Opera 7 */
- word-wrap: break-word; /* Internet Explorer 5.5+ */
- }}
- ::-moz-selection {{
- background: #44475a;
- }}
- ::selection {{
- background: #44475a;
- }}
- </style>
- </head>
- <body>
- <pre style="font-family:ui-monospace,'Fira Code',Menlo,'DejaVu Sans
Mono',consolas,'Courier New',monospace"><code>{code}</code></pre>
- </body>
- </html>
- """.replace("HTML_WIDTH_PLACEHOLDER", args.html_width)
+ html_format = (
+ """\
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<style>
+{stylesheet}
+body {{
+ color: {foreground};
+ background-color: {background};
+ max-width: HTML_WIDTH_PLACEHOLDER
+}}
+pre {{
+ white-space: pre-wrap;
+ white-space: -moz-pre-wrap;
+ white-space: -pre-wrap;
+ white-space: -o-pre-wrap;
+ word-wrap: break-word;
+}}
+::-moz-selection {{
+ background: #44475a;
+}}
+::selection {{
+ background: #44475a;
+}}
+</style>
+</head>
+<body>
+ <pre style="font-family:ui-monospace,'Fira Code',Menlo,'DejaVu Sans
Mono',consolas,'Courier New',monospace"><code>{code}</code></pre>
+</body>
+</html>
+"""
+ ).replace("HTML_WIDTH_PLACEHOLDER", args.html_width)
record = bool(args.html_filename) or bool(args.output)
console = Console(force_terminal=args.force_color, width=args.width,
record=record)
- if args.path == "-":
- code = sys.stdin.read()
- else:
- try:
+
+ try:
+ if args.path == "-":
+ log.debug("Reading from stdin")
+ code = sys.stdin.read()
+ else:
+ log.debug(f"Reading file: {args.path}")
with open(args.path, "rt", encoding=args.encoding) as file_handle:
code = file_handle.read()
- except OSError as error:
- console.print(
- Panel(
- Text(
- f"Could not read {args.path!r}.\n\n"
- "Check that the file exists and that you have
permission to read it.\n"
- f"{error}",
- ),
- title="Input File Error",
- )
+ except OSError as e:
+ console.print(
+ Panel(
+ Text(
+ f"[bold red]Error reading file[/bold red]\n\n"
+ f"Path: {args.path!r}\n"
+ f"Reason: {e.strerror}\n\n"
+ "Check that the file exists and you have read permission."
+ ),
+ title="[bold]File Error[/bold]",
+ style="red",
)
- return 1
- rst = RestructuredText(
- code,
- code_theme=args.code_theme,
- show_line_numbers=args.show_line_numbers,
- guess_lexer=args.guess_lexer,
- default_lexer=args.default_lexer,
- show_errors=args.show_errors,
- filename=args.path if args.path != "-" else "<stdin>",
- admonition_style=args.admonition_style,
- )
- if args.output:
- # Render to a file instead of stdout.
- console.print(rst, soft_wrap=args.soft_wrap)
- text_output = console.export_text()
- try:
+ )
+ if args.debug:
+ log.exception("File read error")
+ return 1
+
+ try:
+ log.debug("Parsing reStructuredText")
+ rst = RestructuredText(
+ code,
+ code_theme=args.code_theme,
+ show_line_numbers=args.show_line_numbers,
+ guess_lexer=args.guess_lexer,
+ default_lexer=args.default_lexer,
+ show_errors=args.show_errors,
+ filename=args.path if args.path != "-" else "<stdin>",
+ admonition_style=args.admonition_style,
+ )
+ except Exception as e:
+ console.print(
+ Panel(
+ Text(
+ f"[bold red]Error parsing reStructuredText[/bold red]\n\n"
+ f"[yellow]{type(e).__name__}[/yellow]: {e}"
+ ),
+ title="[bold]Parse Error[/bold]",
+ style="red",
+ )
+ )
+ if args.debug:
+ log.exception("Parse error")
+ return 1
+
+ try:
+ if args.output:
+ log.debug(f"Writing output to: {args.output}")
+ console.print(rst, soft_wrap=args.soft_wrap)
+ text_output = console.export_text()
with open(args.output, "w", encoding="utf-8") as out_fh:
out_fh.write(text_output)
- except OSError as error:
- Console().print(
- Panel(
- Text(f"Could not write to {args.output!r}.\n{error}"),
- title="Output File Error",
- )
+ else:
+ console.print(rst, soft_wrap=args.soft_wrap)
+
+ if args.html_filename:
+ log.debug(f"Exporting HTML to: {args.html_filename}")
+ html_theme = _HTML_THEMES.get(args.html_theme,
_DRACULA_TERMINAL_THEME)
+ console.save_html(
+ args.html_filename, theme=html_theme, code_format=html_format
)
- return 1
- else:
- console.print(rst, soft_wrap=args.soft_wrap)
-
- if args.html_filename:
- html_theme = _HTML_THEMES.get(args.html_theme, _DRACULA_TERMINAL_THEME)
- console.save_html(args.html_filename, theme=html_theme,
code_format=CONSOLE_HTML_FORMAT)
+ except OSError as e:
+ console.print(
+ Panel(
+ Text(
+ f"[bold red]Error writing output[/bold red]\n\n"
+ f"Path: {args.output or args.html_filename!r}\n"
+ f"Reason: {e.strerror}"
+ ),
+ title="[bold]Output Error[/bold]",
+ style="red",
+ )
+ )
+ if args.debug:
+ log.exception("Output write error")
+ return 1
+ except Exception as e:
+ console.print(
+ Panel(
+ Text(
+ f"[bold red]Error during export[/bold red]\n\n"
+ f"[yellow]{type(e).__name__}[/yellow]: {e}"
+ ),
+ title="[bold]Export Error[/bold]",
+ style="red",
+ )
+ )
+ if args.debug:
+ log.exception("Export error")
+ return 1
+
return 0
+
if __name__ == "__main__":
install()
- raise SystemExit(main())
+ sys.exit(main())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/rich_rst-2.0.2/rich_rst.egg-info/PKG-INFO
new/rich_rst-2.1.0/rich_rst.egg-info/PKG-INFO
--- old/rich_rst-2.0.2/rich_rst.egg-info/PKG-INFO 2026-06-25
19:23:36.000000000 +0200
+++ new/rich_rst-2.1.0/rich_rst.egg-info/PKG-INFO 2026-07-05
04:59:26.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: rich-rst
-Version: 2.0.2
+Version: 2.1.0
Summary: A beautiful reStructuredText renderer for rich
Author-email: Wasi Master <[email protected]>
License-Expression: MIT
@@ -30,14 +30,16 @@
Requires-Dist: pygments>=2.0.0
Provides-Extra: docs
Requires-Dist: docutils; extra == "docs"
-Requires-Dist: rich; extra == "docs"
-Requires-Dist: rich_rst; extra == "docs"
Requires-Dist: sphinx; extra == "docs"
Requires-Dist: sphinx_copybutton; extra == "docs"
Requires-Dist: sphinx_rtd_theme; extra == "docs"
Provides-Extra: tests
Requires-Dist: pytest; extra == "tests"
Requires-Dist: pytest-cov; extra == "tests"
+Provides-Extra: dev
+Requires-Dist: ruff; extra == "dev"
+Requires-Dist: mypy; extra == "dev"
+Requires-Dist: pre-commit; extra == "dev"
Dynamic: license-file
@@ -116,7 +118,7 @@
python -m rich_rst --help
```
-Useful flags include `--code-theme`, `--show-line-numbers`, `--guess-lexer`,
`--default-lexer`, `--show-errors`, `--admonition-style`, `--save-html`,
`--html-theme`, `--list-html-themes`, `--output`, and `--version`.
+Useful flags include ``--code-theme``, ``--show-line-numbers``,
``--guess-lexer``, ``--default-lexer``, ``--show-errors``,
``--admonition-style``, ``-S/--save-html``, ``--html-theme``,
``--list-html-themes``, ``--output``, ``--debug``, and ``--version``.
## Compatibility
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/rich_rst-2.0.2/rich_rst.egg-info/SOURCES.txt
new/rich_rst-2.1.0/rich_rst.egg-info/SOURCES.txt
--- old/rich_rst-2.0.2/rich_rst.egg-info/SOURCES.txt 2026-06-25
19:23:36.000000000 +0200
+++ new/rich_rst-2.1.0/rich_rst.egg-info/SOURCES.txt 2026-07-05
04:59:26.000000000 +0200
@@ -1,4 +1,5 @@
LICENSE
+MANIFEST.in
README.md
pyproject.toml
rich_rst/__init__.py
@@ -51,11 +52,13 @@
rich_rst/_vendor/docutils/utils/urischemes.py
rich_rst/_vendor/docutils/writers/__init__.py
rich_rst/_vendor/docutils/writers/null.py
+tests/conftest.py
tests/test_admonitions.py
tests/test_api.py
tests/test_block_elements.py
tests/test_code_blocks.py
tests/test_directives.py
+tests/test_edge_cases.py
tests/test_inline_markup.py
tests/test_lists.py
tests/test_main.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/rich_rst-2.0.2/rich_rst.egg-info/requires.txt
new/rich_rst-2.1.0/rich_rst.egg-info/requires.txt
--- old/rich_rst-2.0.2/rich_rst.egg-info/requires.txt 2026-06-25
19:23:36.000000000 +0200
+++ new/rich_rst-2.1.0/rich_rst.egg-info/requires.txt 2026-07-05
04:59:26.000000000 +0200
@@ -1,10 +1,13 @@
rich>=12.0.0
pygments>=2.0.0
+[dev]
+ruff
+mypy
+pre-commit
+
[docs]
docutils
-rich
-rich_rst
sphinx
sphinx_copybutton
sphinx_rtd_theme
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/rich_rst-2.0.2/tests/conftest.py
new/rich_rst-2.1.0/tests/conftest.py
--- old/rich_rst-2.0.2/tests/conftest.py 1970-01-01 01:00:00.000000000
+0100
+++ new/rich_rst-2.1.0/tests/conftest.py 2026-07-05 04:59:22.000000000
+0200
@@ -0,0 +1,60 @@
+"""
+Shared pytest fixtures for the rich-rst test suite.
+
+``make_visitor``
+ Parses RST text via docutils (full transform pipeline) and returns a
+ walked :class:`RSTVisitor`. Use this for structural assertions
+ (renderable types, panel titles, span counts, …).
+
+``render_text``
+ Renders RST markup through the public :class:`RestructuredText` API and
+ returns the exported plain text. Use this for content / output assertions.
+"""
+from pathlib import Path
+import sys
+
+ROOT = Path(__file__).resolve().parents[1]
+if str(ROOT) not in sys.path:
+ sys.path.insert(0, str(ROOT))
+
+from rich_rst._vendor import docutils
+import rich_rst._vendor.docutils.core
+import pytest
+from rich.console import Console
+
+from rich_rst import RestructuredText, RSTVisitor
+
+
[email protected]
+def make_visitor():
+ """Factory fixture: parse RST and return a walked RSTVisitor."""
+ def _make(rst_text, **kwargs):
+ document = docutils.core.publish_doctree(
+ rst_text,
+ settings_overrides={"report_level": 69, "halt_level": 69},
+ )
+ console = Console(force_terminal=True, width=120, record=True)
+ visitor = RSTVisitor(
+ document,
+ console=console,
+ code_theme="monokai",
+ show_line_numbers=False,
+ guess_lexer=False,
+ default_lexer="python",
+ **kwargs,
+ )
+ document.walkabout(visitor)
+ return visitor
+
+ return _make
+
+
[email protected]
+def render_text():
+ """Factory fixture: render RST markup and return plain text output."""
+ def _render(markup, **kwargs):
+ console = Console(force_terminal=True, width=120, record=True)
+ console.print(RestructuredText(markup, **kwargs))
+ return console.export_text()
+
+ return _render
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/rich_rst-2.0.2/tests/test_edge_cases.py
new/rich_rst-2.1.0/tests/test_edge_cases.py
--- old/rich_rst-2.0.2/tests/test_edge_cases.py 1970-01-01 01:00:00.000000000
+0100
+++ new/rich_rst-2.1.0/tests/test_edge_cases.py 2026-07-05 04:59:22.000000000
+0200
@@ -0,0 +1,196 @@
+"""Edge case and smoke tests for rich-rst."""
+import tempfile
+from pathlib import Path
+
+import pytest
+
+from rich_rst import RestructuredText
+
+
+class TestEdgeCases:
+ """Test edge cases and unusual inputs."""
+
+ def test_empty_document(self):
+ """Test rendering an empty document."""
+ rst = RestructuredText("")
+ # Should not raise
+ assert rst is not None
+
+ def test_very_long_line(self):
+ """Test handling of very long lines without wrapping."""
+ long_line = "x" * 5000
+ rst = RestructuredText(f"This is a very long line:\n\n{long_line}")
+ # Should not raise
+ assert rst is not None
+
+ def test_deeply_nested_lists(self):
+ """Test handling of deeply nested lists."""
+ doc = """
+List
+====
+
+- Level 1
+
+ - Level 2
+
+ - Level 3
+
+ - Level 4
+
+ - Level 5
+"""
+ rst = RestructuredText(doc)
+ assert rst is not None
+
+ def test_unicode_content(self):
+ """Test rendering Unicode content."""
+ doc = """
+Unicode Test
+============
+
+This document contains Unicode: 你好 مرحبا こんにちは 🚀 ♠️
+
+- List with emoji 🎉
+- More emoji 🔥
+"""
+ rst = RestructuredText(doc)
+ assert rst is not None
+
+ def test_special_characters_in_code(self):
+ """Test code blocks with special characters."""
+ doc = r'''
+Code Example
+============
+
+.. code-block:: python
+
+ # Special chars: <>&"'
+ x = "special: \n\t\r"
+ regex = r"[a-z]+\d{3}"
+'''
+ rst = RestructuredText(doc)
+ assert rst is not None
+
+ def test_malformed_markup_with_errors_hidden(self):
+ """Test that malformed markup doesn't crash when errors are hidden."""
+ doc = """
+Bad Markup
+==========
+
+`Unclosed link <http://example.com
+`Another unclosed link
+
+.. unknown-directive::
+ This directive doesn't exist
+"""
+ rst = RestructuredText(doc, show_errors=False)
+ assert rst is not None
+
+ def test_large_table(self):
+ """Test rendering of a large table."""
+ rows = "\n".join([f"| Cell {i},{j} | Cell {i},{j+1} |" for i in
range(50) for j in range(0, 10, 2)])
+ doc = f"""
+Large Table
+===========
+
++----------+----------+
+| Header 1 | Header 2 |
++==========+==========+
+{rows}
++----------+----------+
+"""
+ rst = RestructuredText(doc)
+ assert rst is not None
+
+ def test_multiple_code_themes(self):
+ """Test with different code themes."""
+ doc = """
+Code
+====
+
+.. code-block:: python
+
+ print("hello")
+"""
+ for theme in ["monokai", "fruity", "vim", "native"]:
+ rst = RestructuredText(doc, code_theme=theme)
+ assert rst is not None
+
+ def test_encoding_edge_cases(self):
+ """Test with various special encoding scenarios."""
+ doc = "Café\nNaïve\nResuméé"
+ rst = RestructuredText(doc)
+ assert rst is not None
+
+ def test_document_with_only_whitespace(self):
+ """Test document with only whitespace."""
+ doc = " \n\n \n\t\n "
+ rst = RestructuredText(doc)
+ assert rst is not None
+
+ def test_mixed_indentation(self):
+ """Test document with mixed tabs and spaces."""
+ doc = "Heading\n=======\n\n\tTabbed line\n Spaced line\n\t Mixed"
+ rst = RestructuredText(doc)
+ assert rst is not None
+
+
+class TestHTMLExport:
+ """Test HTML export functionality."""
+
+ def test_html_export_basic(self):
+ """Test basic HTML export."""
+ doc = "Title\n=====\n\nParagraph with **bold**."
+ rst = RestructuredText(doc)
+ assert rst is not None
+
+ def test_html_export_with_code(self):
+ """Test HTML export with code blocks."""
+ doc = """
+Code
+====
+
+.. code-block:: python
+
+ def hello():
+ print("world")
+"""
+ rst = RestructuredText(doc)
+ assert rst is not None
+
+ def test_html_export_with_images(self):
+ """Test HTML export with image directives."""
+ doc = """
+Images
+======
+
+.. image:: /path/to/image.png
+ :alt: Alternative text
+ :width: 100px
+"""
+ rst = RestructuredText(doc, show_errors=False)
+ assert rst is not None
+
+
+class TestCliEdgeCases:
+ """Test CLI edge cases."""
+
+ def test_stdin_rendering(self, tmp_path):
+ """Test that stdin input can be rendered."""
+ from rich_rst.__main__ import RestructuredText as CliRST
+
+ doc = "Test\n====\n\nContent"
+ rst = CliRST(doc)
+ assert rst is not None
+
+ def test_temp_file_encoding(self, tmp_path):
+ """Test file with non-default encoding."""
+ test_file = tmp_path / "test.rst"
+ content = "Tëst\n====\n\nWïth spëcial chärs"
+ test_file.write_text(content, encoding="utf-8")
+
+ from rich_rst.__main__ import RestructuredText as CliRST
+
+ with open(test_file, encoding="utf-8") as f:
+ rst = CliRST(f.read())
+ assert rst is not None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/rich_rst-2.0.2/tests/test_main.py
new/rich_rst-2.1.0/tests/test_main.py
--- old/rich_rst-2.0.2/tests/test_main.py 2026-04-03 18:24:35.000000000
+0200
+++ new/rich_rst-2.1.0/tests/test_main.py 2026-07-05 04:59:22.000000000
+0200
@@ -29,8 +29,8 @@
captured = capsys.readouterr()
assert exit_code == 1
- assert "Input File Error" in captured.out
- assert f"Could not read {path!r}." in captured.out
+ assert "File Error" in captured.out
+ assert f"Path: {path!r}" in captured.out
assert "Check that the file exists" in captured.out
assert "Traceback" not in captured.out