mdview-tui 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: mdview-tui
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: CLI tool to view markdown files in the terminal.
|
|
5
|
+
Author: Shunichiro Nomura
|
|
6
|
+
Author-email: Shunichiro Nomura <nomura@space.t.u-tokyo.ac.jp>
|
|
7
|
+
Classifier: Programming Language :: Python
|
|
8
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
10
|
+
Classifier: Typing :: Typed
|
|
11
|
+
Requires-Dist: rich>=14.3.3
|
|
12
|
+
Requires-Dist: textual[syntax]>=8.2.2
|
|
13
|
+
Requires-Dist: typer>=0.24.1
|
|
14
|
+
Requires-Python: >=3.14
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# mdview
|
|
18
|
+
|
|
19
|
+
This is a thin wrapper around Textual's Markdown widget to view markdown files in the terminal.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
uv tool install mdview-tui
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
mdview <markdown-file>
|
|
31
|
+
```
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "mdview-tui"
|
|
3
|
+
version = "0.0.1"
|
|
4
|
+
description = "CLI tool to view markdown files in the terminal."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.14"
|
|
7
|
+
authors = [
|
|
8
|
+
{ name = "Shunichiro Nomura", email = "nomura@space.t.u-tokyo.ac.jp" },
|
|
9
|
+
]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Programming Language :: Python",
|
|
12
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
13
|
+
"Programming Language :: Python :: 3.14",
|
|
14
|
+
"Typing :: Typed",
|
|
15
|
+
]
|
|
16
|
+
dependencies = [
|
|
17
|
+
"rich>=14.3.3",
|
|
18
|
+
"textual[syntax]>=8.2.2",
|
|
19
|
+
"typer>=0.24.1",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.scripts]
|
|
23
|
+
mdview = "mdview_tui:main"
|
|
24
|
+
|
|
25
|
+
[dependency-groups]
|
|
26
|
+
dev = [
|
|
27
|
+
"pre-commit>=4.2.0",
|
|
28
|
+
{ include-group = "ruff" },
|
|
29
|
+
{ include-group = "test" },
|
|
30
|
+
{ include-group = "typing" },
|
|
31
|
+
]
|
|
32
|
+
ruff = ["ruff>=0.11.13"]
|
|
33
|
+
test = [
|
|
34
|
+
"pytest>=9.0.0",
|
|
35
|
+
# "coverage>=7.8.2", # If you use coverage
|
|
36
|
+
]
|
|
37
|
+
typing = [
|
|
38
|
+
"basedpyright>=1.36.2",
|
|
39
|
+
"mypy>=1.16.1",
|
|
40
|
+
"ty>=0.0.8",
|
|
41
|
+
{ include-group = "test" },
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[build-system]
|
|
45
|
+
requires = ["uv_build>=0.11,<0.12"]
|
|
46
|
+
build-backend = "uv_build"
|
|
47
|
+
|
|
48
|
+
[tool.mypy]
|
|
49
|
+
strict = true
|
|
50
|
+
|
|
51
|
+
[tool.pytest]
|
|
52
|
+
addopts = [
|
|
53
|
+
"--capture=no",
|
|
54
|
+
"--color=yes",
|
|
55
|
+
"--log-cli-level=INFO",
|
|
56
|
+
"--strict-markers",
|
|
57
|
+
"--verbose",
|
|
58
|
+
"--verbose",
|
|
59
|
+
"-ra", # show extra test summary info for all tests except passed tests
|
|
60
|
+
]
|
|
61
|
+
minversion = "9.0"
|
|
62
|
+
testpaths = ["tests"]
|
|
63
|
+
|
|
64
|
+
[tool.ruff]
|
|
65
|
+
line-length = 120
|
|
66
|
+
|
|
67
|
+
[tool.ruff.lint]
|
|
68
|
+
select = ["ALL"]
|
|
69
|
+
# Modify the following rules according to your preferences
|
|
70
|
+
ignore = [
|
|
71
|
+
# "PLR2004", # magic numbers
|
|
72
|
+
"S101", # use of assert
|
|
73
|
+
"G", # logging format
|
|
74
|
+
# "ANN101", # missing type annotation for self in method
|
|
75
|
+
# "ANN102", # missing type annotation for cls in classmethod
|
|
76
|
+
# "D100", # missing docstring in public module
|
|
77
|
+
# "D101", # missing docstring in public class
|
|
78
|
+
# "D102", # missing docstring in public method
|
|
79
|
+
# "D103", # missing docstring in public function
|
|
80
|
+
# "D104", # missing docstring in public package
|
|
81
|
+
# "D105", # missing docstring in magic method
|
|
82
|
+
# "D107", # missing docstring in __init__
|
|
83
|
+
"D203", # 1 blank line required before class docstring
|
|
84
|
+
"D213", # multi-line docstring summary should start at the second line
|
|
85
|
+
# "PGH003", # Use specific rule codes when ignoring type issues
|
|
86
|
+
# "RET505", # Unnecessary `else` after `return` statement
|
|
87
|
+
"ANN401", # Dynamically typed expressions (typing.Any) are disallowed
|
|
88
|
+
# "D401", # First line should be in imperative mood
|
|
89
|
+
"TD002", # Missing author in TODO
|
|
90
|
+
"TD003", # add link on issue into TODO
|
|
91
|
+
# "PLR0913", # Too many arguments to function call
|
|
92
|
+
# "D407", # Missing dashed underline after section
|
|
93
|
+
# "ERA001", # Commented out code
|
|
94
|
+
"FIX002", # Fixme comment
|
|
95
|
+
# "S311", # suspicious-non-cryptographic-random-usage
|
|
96
|
+
# "EM101", # raw-string-in-exception
|
|
97
|
+
# "TRY003", # Avoid specifying long messages outside the exception class
|
|
98
|
+
# "UP040", # uses `TypeAlias` annotation instead of the `type` keyword. This is to be compatible with griffe.
|
|
99
|
+
]
|
|
100
|
+
unfixable = [
|
|
101
|
+
"F401", # Prevent auto-fix for unused imports
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
[tool.ruff.lint.per-file-ignores]
|
|
105
|
+
"tests/**.py" = [
|
|
106
|
+
"D", # Docstring
|
|
107
|
+
"INP001", # implicit-namespace-package
|
|
108
|
+
"ANN201", # missing-return-type-undocumented-public-function
|
|
109
|
+
"S101", # use of assert
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
[tool.uv]
|
|
113
|
+
exclude-newer = "7 days"
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""mdview_tui is a terminal-based markdown viewer built with Textual."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path # noqa: TC003
|
|
4
|
+
from typing import Annotated
|
|
5
|
+
|
|
6
|
+
import typer
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
|
|
9
|
+
from .app import MarkdownViewerApp
|
|
10
|
+
|
|
11
|
+
err_console = Console(stderr=True)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _main(
|
|
15
|
+
file: Annotated[
|
|
16
|
+
Path,
|
|
17
|
+
typer.Argument(help="Path to the markdown file to view."),
|
|
18
|
+
],
|
|
19
|
+
) -> None:
|
|
20
|
+
"""View markdown files in the terminal."""
|
|
21
|
+
if not file.exists():
|
|
22
|
+
err_console.print(f"[bold red]Error:[/] File not found: [yellow]{file}[/]")
|
|
23
|
+
raise typer.Exit(code=1)
|
|
24
|
+
if not file.is_file():
|
|
25
|
+
err_console.print(f"[bold red]Error:[/] Not a file: [yellow]{file}[/]")
|
|
26
|
+
raise typer.Exit(code=1)
|
|
27
|
+
text = file.read_text()
|
|
28
|
+
MarkdownViewerApp(text, title=str(file)).run()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def main() -> None:
|
|
32
|
+
"""Entry point for the mdview_tui application."""
|
|
33
|
+
typer.run(_main)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""MarkdownViewerApp Textual application for viewing markdown content in the terminal."""
|
|
2
|
+
|
|
3
|
+
from textual.app import App, ComposeResult
|
|
4
|
+
from textual.binding import Binding
|
|
5
|
+
from textual.widgets import Footer, Markdown
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class MarkdownViewerApp(App):
|
|
9
|
+
"""A Textual application for viewing markdown content in the terminal."""
|
|
10
|
+
|
|
11
|
+
BINDINGS = [ # noqa: RUF012
|
|
12
|
+
Binding("q", "quit", "Quit"),
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
CSS = """
|
|
16
|
+
Markdown {
|
|
17
|
+
layout: stream;
|
|
18
|
+
padding: 0 2;
|
|
19
|
+
}
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
theme = "tokyo-night"
|
|
23
|
+
|
|
24
|
+
def __init__(self, text: str, title: str = "Markdown") -> None:
|
|
25
|
+
"""Initialize the MarkdownViewerApp with the given markdown text and title."""
|
|
26
|
+
super().__init__()
|
|
27
|
+
self._text = text
|
|
28
|
+
self._title = title
|
|
29
|
+
|
|
30
|
+
def compose(self) -> ComposeResult:
|
|
31
|
+
"""Compose the UI components for the application."""
|
|
32
|
+
yield Markdown(self._text)
|
|
33
|
+
yield Footer()
|
|
34
|
+
|
|
35
|
+
def on_mount(self) -> None:
|
|
36
|
+
"""Set the application title on mount."""
|
|
37
|
+
self.title = self._title
|