rich-gradient-cli 0.1.0__tar.gz → 0.3.0__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.
- rich_gradient_cli-0.3.0/PKG-INFO +153 -0
- rich_gradient_cli-0.1.0/PKG-INFO → rich_gradient_cli-0.3.0/README.md +47 -22
- rich_gradient_cli-0.3.0/pyproject.toml +59 -0
- rich_gradient_cli-0.3.0/pyproject.toml.orig +53 -0
- {rich_gradient_cli-0.1.0 → rich_gradient_cli-0.3.0}/src/rich_gradient_cli/__init__.py +55 -9
- rich_gradient_cli-0.3.0/src/rich_gradient_cli/common.py +189 -0
- rich_gradient_cli-0.3.0/src/rich_gradient_cli/gradient_command.py +139 -0
- {rich_gradient_cli-0.1.0 → rich_gradient_cli-0.3.0}/src/rich_gradient_cli/help.py +12 -1
- {rich_gradient_cli-0.1.0 → rich_gradient_cli-0.3.0}/src/rich_gradient_cli/markdown_command.py +49 -4
- {rich_gradient_cli-0.1.0 → rich_gradient_cli-0.3.0}/src/rich_gradient_cli/panel_command.py +52 -11
- rich_gradient_cli-0.3.0/src/rich_gradient_cli/renderable_commands.py +443 -0
- {rich_gradient_cli-0.1.0 → rich_gradient_cli-0.3.0}/src/rich_gradient_cli/rule_command.py +62 -0
- rich_gradient_cli-0.3.0/src/rich_gradient_cli/spectrum_command.py +82 -0
- {rich_gradient_cli-0.1.0 → rich_gradient_cli-0.3.0}/src/rich_gradient_cli/text_command.py +62 -1
- rich_gradient_cli-0.3.0/src/rich_gradient_cli/view_command.py +590 -0
- rich_gradient_cli-0.1.0/README.md +0 -88
- rich_gradient_cli-0.1.0/pyproject.toml +0 -31
- rich_gradient_cli-0.1.0/src/rich_gradient_cli/common.py +0 -87
- {rich_gradient_cli-0.1.0 → rich_gradient_cli-0.3.0}/src/rich_gradient_cli/__main__.py +0 -0
- {rich_gradient_cli-0.1.0 → rich_gradient_cli-0.3.0}/src/rich_gradient_cli/py.typed +0 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: rich-gradient-cli
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: CLI for printing text in gradient color using the rich-gradient library.
|
|
5
|
+
Author: Maxwell Ludden
|
|
6
|
+
Author-email: Maxwell Ludden <maxludden@me.com>
|
|
7
|
+
Requires-Dist: typer>=0.21.1
|
|
8
|
+
Requires-Dist: rich>=14.3.2
|
|
9
|
+
Requires-Dist: rich-color-ext>=0.1.9
|
|
10
|
+
Requires-Dist: rich-gradient>=0.3.9
|
|
11
|
+
Requires-Dist: mypy>=1.18.2 ; extra == 'dev'
|
|
12
|
+
Requires-Dist: pytest>=8.4.2 ; extra == 'dev'
|
|
13
|
+
Requires-Dist: ruff>=0.15.0 ; extra == 'dev'
|
|
14
|
+
Requires-Dist: mkdocstrings>=1.0.8 ; python_full_version >= '3.11' and extra == 'docs'
|
|
15
|
+
Requires-Dist: mkdocstrings-python>=2.0.2 ; python_full_version >= '3.11' and extra == 'docs'
|
|
16
|
+
Requires-Dist: zensical>=0.0.68 ; python_full_version >= '3.11' and extra == 'docs'
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Provides-Extra: docs
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# rich-gradient-cli
|
|
23
|
+
|
|
24
|
+
`rich-gradient-cli` is a CLI for [`rich-gradient`](https://github.com/maxludden/rich-gradient). The tool allows you to create colorful gradients in your terminal output, making it easier to visualize data or simply add some flair to your command-line applications.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
You can install rich-gradient-cli from PyPI
|
|
29
|
+
|
|
30
|
+
### uv (recommended)
|
|
31
|
+
|
|
32
|
+
```shell
|
|
33
|
+
uv add rich-gradient-cli
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### pip
|
|
37
|
+
|
|
38
|
+
```shell
|
|
39
|
+
pip install rich-gradient-cli
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
<video
|
|
45
|
+
src="docs/img/rich-gradient-cli-help.mp4"
|
|
46
|
+
controls
|
|
47
|
+
muted
|
|
48
|
+
loop>
|
|
49
|
+
</video>
|
|
50
|
+
|
|
51
|
+
### Print
|
|
52
|
+
|
|
53
|
+
To use the `rich-gradient-cli`, you can run the following command in your terminal:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
gradient print --colors 'red,#ff9900,#ffff00' "This is gradient text that starts red, transitions through orange, and ends in yellow\!"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+

|
|
60
|
+
|
|
61
|
+
### Gradient
|
|
62
|
+
|
|
63
|
+
Use `gradient` for the generic `rich-gradient` renderable, including highlight rules and animation:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
gradient gradient --colors 'magenta,cyan' --highlight-word error='bold white on red' "Highlight error text"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Spectrum
|
|
70
|
+
|
|
71
|
+
Inspect generated spectrum colors as a rich table, hex values, names, or CSV:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
gradient spectrum --hues 7 --seed 42
|
|
75
|
+
gradient spectrum --hues 7 --output hex
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Rich renderables
|
|
79
|
+
|
|
80
|
+
Wrap common Rich renderables in gradients without writing Python:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
gradient columns alpha beta gamma --colors 'red,blue'
|
|
84
|
+
gradient tree project src/app.py docs/index.md --colors 'lime,cyan'
|
|
85
|
+
gradient syntax pyproject.toml --lexer toml --line-numbers --colors 'yellow,magenta'
|
|
86
|
+
cat data.csv | gradient table - --colors 'cyan,magenta'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Rule
|
|
90
|
+
|
|
91
|
+
You can also create gradient rules using the `rule` command:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
gradient rule --colors 'blue,#00ff00,cyan' "Blue to Green to Cyan Rule"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+

|
|
98
|
+
|
|
99
|
+
### Panel
|
|
100
|
+
|
|
101
|
+
To create a gradient panel, you can use the `panel` command:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
gradient panel --colors "red,#ff9999" -t "Error" --title-style "bold #ffffff" --title-align left 'This is an error message with a red to pink gradient background.'
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+

|
|
108
|
+
|
|
109
|
+
### Markdown
|
|
110
|
+
|
|
111
|
+
You can also render Markdown with gradients:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
echo "# Hello\n\n- This is **bold**.\n- This is *italic*." | gradient markdown -
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+

|
|
118
|
+
|
|
119
|
+
### Rich-style viewing
|
|
120
|
+
|
|
121
|
+
Use `view` for `rich-cli`-style file rendering. It auto-detects Markdown, JSON, CSV/TSV, and syntax-highlighted source files; it also accepts `-` for stdin and `http://` or `https://` URLs.
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
gradient view README.md
|
|
125
|
+
gradient view pyproject.toml --lexer toml --line-numbers --guides
|
|
126
|
+
cat data.json | gradient view - --json --force-terminal
|
|
127
|
+
gradient view README.md --export-html readme.html
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Docs
|
|
131
|
+
|
|
132
|
+
Build and preview the documentation locally with Zensical (requires Python 3.11+; the `docs` extra is skipped on 3.10):
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
uv pip install -e ".[docs]"
|
|
136
|
+
zensical serve
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
<div align="center">
|
|
142
|
+
<a href="https://github.com/maxludden/maxludden" style="text-decoration:none; color:inherit;">
|
|
143
|
+
<p>Designed by Max Ludden</p>
|
|
144
|
+
</a>
|
|
145
|
+
<br />
|
|
146
|
+
<a href="https://github.com/maxludden/maxludden" style="text-decoration:none; color:inherit;">
|
|
147
|
+
<img
|
|
148
|
+
src="docs/img/MaxLogo.svg"
|
|
149
|
+
alt="Max Ludden's Logo"
|
|
150
|
+
width="20%"
|
|
151
|
+
/>
|
|
152
|
+
</a>
|
|
153
|
+
</div>
|
|
@@ -1,22 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.3
|
|
2
|
-
Name: rich-gradient-cli
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: CLI for printing text in gradient color using the rich-gradient library.
|
|
5
|
-
Author: Maxwell Ludden
|
|
6
|
-
Author-email: Maxwell Ludden <maxludden@me.com>
|
|
7
|
-
Requires-Dist: typer>=0.21.1
|
|
8
|
-
Requires-Dist: rich>=14.3.2
|
|
9
|
-
Requires-Dist: rich-color-ext>=0.1.9
|
|
10
|
-
Requires-Dist: rich-gradient>=0.3.9
|
|
11
|
-
Requires-Dist: ruff>=0.15.0
|
|
12
|
-
Requires-Dist: mkdocs>=1.6.0 ; extra == 'docs'
|
|
13
|
-
Requires-Dist: mkdocs-material>=9.5.0 ; extra == 'docs'
|
|
14
|
-
Requires-Dist: mkdocstrings>=0.25.0 ; extra == 'docs'
|
|
15
|
-
Requires-Dist: mkdocstrings-python>=1.10.0 ; extra == 'docs'
|
|
16
|
-
Requires-Python: >=3.14
|
|
17
|
-
Provides-Extra: docs
|
|
18
|
-
Description-Content-Type: text/markdown
|
|
19
|
-
|
|
20
1
|
# rich-gradient-cli
|
|
21
2
|
|
|
22
3
|
`rich-gradient-cli` is a CLI for [`rich-gradient`](https://github.com/maxludden/rich-gradient). The tool allows you to create colorful gradients in your terminal output, making it easier to visualize data or simply add some flair to your command-line applications.
|
|
@@ -39,6 +20,12 @@ pip install rich-gradient-cli
|
|
|
39
20
|
|
|
40
21
|
## Usage
|
|
41
22
|
|
|
23
|
+
<video
|
|
24
|
+
src="docs/img/rich-gradient-cli-help.mp4"
|
|
25
|
+
controls
|
|
26
|
+
muted
|
|
27
|
+
loop>
|
|
28
|
+
</video>
|
|
42
29
|
|
|
43
30
|
### Print
|
|
44
31
|
|
|
@@ -50,6 +37,33 @@ gradient print --colors 'red,#ff9900,#ffff00' "This is gradient text that starts
|
|
|
50
37
|
|
|
51
38
|

|
|
52
39
|
|
|
40
|
+
### Gradient
|
|
41
|
+
|
|
42
|
+
Use `gradient` for the generic `rich-gradient` renderable, including highlight rules and animation:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
gradient gradient --colors 'magenta,cyan' --highlight-word error='bold white on red' "Highlight error text"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Spectrum
|
|
49
|
+
|
|
50
|
+
Inspect generated spectrum colors as a rich table, hex values, names, or CSV:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
gradient spectrum --hues 7 --seed 42
|
|
54
|
+
gradient spectrum --hues 7 --output hex
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Rich renderables
|
|
58
|
+
|
|
59
|
+
Wrap common Rich renderables in gradients without writing Python:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
gradient columns alpha beta gamma --colors 'red,blue'
|
|
63
|
+
gradient tree project src/app.py docs/index.md --colors 'lime,cyan'
|
|
64
|
+
gradient syntax pyproject.toml --lexer toml --line-numbers --colors 'yellow,magenta'
|
|
65
|
+
cat data.csv | gradient table - --colors 'cyan,magenta'
|
|
66
|
+
```
|
|
53
67
|
|
|
54
68
|
### Rule
|
|
55
69
|
|
|
@@ -81,13 +95,24 @@ echo "# Hello\n\n- This is **bold**.\n- This is *italic*." | gradient markdown -
|
|
|
81
95
|
|
|
82
96
|

|
|
83
97
|
|
|
98
|
+
### Rich-style viewing
|
|
99
|
+
|
|
100
|
+
Use `view` for `rich-cli`-style file rendering. It auto-detects Markdown, JSON, CSV/TSV, and syntax-highlighted source files; it also accepts `-` for stdin and `http://` or `https://` URLs.
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
gradient view README.md
|
|
104
|
+
gradient view pyproject.toml --lexer toml --line-numbers --guides
|
|
105
|
+
cat data.json | gradient view - --json --force-terminal
|
|
106
|
+
gradient view README.md --export-html readme.html
|
|
107
|
+
```
|
|
108
|
+
|
|
84
109
|
## Docs
|
|
85
110
|
|
|
86
|
-
Build and preview the documentation locally with
|
|
111
|
+
Build and preview the documentation locally with Zensical (requires Python 3.11+; the `docs` extra is skipped on 3.10):
|
|
87
112
|
|
|
88
113
|
```bash
|
|
89
114
|
uv pip install -e ".[docs]"
|
|
90
|
-
|
|
115
|
+
zensical serve
|
|
91
116
|
```
|
|
92
117
|
|
|
93
118
|
|
|
@@ -99,7 +124,7 @@ mkdocs serve
|
|
|
99
124
|
<br />
|
|
100
125
|
<a href="https://github.com/maxludden/maxludden" style="text-decoration:none; color:inherit;">
|
|
101
126
|
<img
|
|
102
|
-
src="
|
|
127
|
+
src="docs/img/MaxLogo.svg"
|
|
103
128
|
alt="Max Ludden's Logo"
|
|
104
129
|
width="20%"
|
|
105
130
|
/>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "rich-gradient-cli"
|
|
3
|
+
version = "0.3.0"
|
|
4
|
+
description = "CLI for printing text in gradient color using the rich-gradient library."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"typer>=0.21.1",
|
|
9
|
+
"rich>=14.3.2",
|
|
10
|
+
"rich-color-ext>=0.1.9",
|
|
11
|
+
"rich-gradient>=0.3.9",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[[project.authors]]
|
|
15
|
+
name = "Maxwell Ludden"
|
|
16
|
+
email = "maxludden@me.com"
|
|
17
|
+
|
|
18
|
+
[project.optional-dependencies]
|
|
19
|
+
dev = [
|
|
20
|
+
"mypy>=1.18.2",
|
|
21
|
+
"pytest>=8.4.2",
|
|
22
|
+
"ruff>=0.15.0",
|
|
23
|
+
]
|
|
24
|
+
docs = [
|
|
25
|
+
"mkdocstrings>=1.0.8; python_version >= '3.11'",
|
|
26
|
+
"mkdocstrings-python>=2.0.2; python_version >= '3.11'",
|
|
27
|
+
"zensical>=0.0.68; python_version >= '3.11'",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.scripts]
|
|
31
|
+
gradient = "rich_gradient_cli:entrypoint"
|
|
32
|
+
|
|
33
|
+
[build-system]
|
|
34
|
+
requires = ["uv_build>=0.10.0,<0.11.0"]
|
|
35
|
+
build-backend = "uv_build"
|
|
36
|
+
|
|
37
|
+
[tool.mypy]
|
|
38
|
+
python_version = "3.10"
|
|
39
|
+
mypy_path = "typings"
|
|
40
|
+
files = [
|
|
41
|
+
"src",
|
|
42
|
+
"typings",
|
|
43
|
+
]
|
|
44
|
+
ignore_missing_imports = true
|
|
45
|
+
check_untyped_defs = true
|
|
46
|
+
|
|
47
|
+
[tool.ruff]
|
|
48
|
+
target-version = "py310"
|
|
49
|
+
src = [
|
|
50
|
+
"src",
|
|
51
|
+
"typings",
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
[tool.pylint.messages_control]
|
|
55
|
+
disable = [
|
|
56
|
+
"import-error",
|
|
57
|
+
"unused-argument",
|
|
58
|
+
"W0613",
|
|
59
|
+
]
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "rich-gradient-cli"
|
|
3
|
+
version = "0.3.0"
|
|
4
|
+
description = "CLI for printing text in gradient color using the rich-gradient library."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Maxwell Ludden", email = "maxludden@me.com" }
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"typer>=0.21.1",
|
|
12
|
+
"rich>=14.3.2",
|
|
13
|
+
"rich-color-ext>=0.1.9",
|
|
14
|
+
"rich-gradient>=0.3.9",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[project.optional-dependencies]
|
|
18
|
+
dev = [
|
|
19
|
+
"mypy>=1.18.2",
|
|
20
|
+
"pytest>=8.4.2",
|
|
21
|
+
"ruff>=0.15.0",
|
|
22
|
+
]
|
|
23
|
+
# Docs tooling (mkdocstrings>=1.0.8, zensical) requires Python >= 3.11; on 3.10 this extra installs nothing.
|
|
24
|
+
docs = [
|
|
25
|
+
"mkdocstrings>=1.0.8; python_version >= '3.11'",
|
|
26
|
+
"mkdocstrings-python>=2.0.2; python_version >= '3.11'",
|
|
27
|
+
"zensical>=0.0.68; python_version >= '3.11'",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.scripts]
|
|
31
|
+
gradient = "rich_gradient_cli:entrypoint"
|
|
32
|
+
|
|
33
|
+
[build-system]
|
|
34
|
+
requires = ["uv_build>=0.10.0,<0.11.0"]
|
|
35
|
+
build-backend = "uv_build"
|
|
36
|
+
|
|
37
|
+
[tool.mypy]
|
|
38
|
+
python_version = "3.10"
|
|
39
|
+
mypy_path = "typings"
|
|
40
|
+
files = ["src", "typings"]
|
|
41
|
+
ignore_missing_imports = true
|
|
42
|
+
check_untyped_defs = true
|
|
43
|
+
|
|
44
|
+
[tool.ruff]
|
|
45
|
+
target-version = "py310"
|
|
46
|
+
src = ["src", "typings"]
|
|
47
|
+
|
|
48
|
+
[tool.pylint.messages_control]
|
|
49
|
+
disable = [
|
|
50
|
+
"import-error",
|
|
51
|
+
"unused-argument",
|
|
52
|
+
"W0613"
|
|
53
|
+
]
|
|
@@ -3,17 +3,45 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import sys
|
|
6
|
+
from pathlib import Path
|
|
6
7
|
from typing import Any, Sequence
|
|
7
8
|
|
|
8
9
|
import click
|
|
9
10
|
import typer
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
from .
|
|
14
|
-
from .
|
|
15
|
-
from .
|
|
16
|
-
from .
|
|
12
|
+
if __package__ in {None, ""}:
|
|
13
|
+
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
|
14
|
+
from rich_gradient_cli.common import VERSION
|
|
15
|
+
from rich_gradient_cli.gradient_command import gradient_command
|
|
16
|
+
from rich_gradient_cli.help import RichTyperCommand, RichTyperGroup
|
|
17
|
+
from rich_gradient_cli.markdown_command import markdown_command
|
|
18
|
+
from rich_gradient_cli.panel_command import panel_command
|
|
19
|
+
from rich_gradient_cli.renderable_commands import (
|
|
20
|
+
columns_command,
|
|
21
|
+
syntax_command,
|
|
22
|
+
table_command,
|
|
23
|
+
tree_command,
|
|
24
|
+
)
|
|
25
|
+
from rich_gradient_cli.rule_command import rule_command
|
|
26
|
+
from rich_gradient_cli.spectrum_command import spectrum_command
|
|
27
|
+
from rich_gradient_cli.text_command import print_command
|
|
28
|
+
from rich_gradient_cli.view_command import view_command
|
|
29
|
+
else:
|
|
30
|
+
from .common import VERSION
|
|
31
|
+
from .gradient_command import gradient_command
|
|
32
|
+
from .help import RichTyperCommand, RichTyperGroup
|
|
33
|
+
from .markdown_command import markdown_command
|
|
34
|
+
from .panel_command import panel_command
|
|
35
|
+
from .renderable_commands import (
|
|
36
|
+
columns_command,
|
|
37
|
+
syntax_command,
|
|
38
|
+
table_command,
|
|
39
|
+
tree_command,
|
|
40
|
+
)
|
|
41
|
+
from .rule_command import rule_command
|
|
42
|
+
from .spectrum_command import spectrum_command
|
|
43
|
+
from .text_command import print_command
|
|
44
|
+
from .view_command import view_command
|
|
17
45
|
|
|
18
46
|
|
|
19
47
|
class DefaultTyperGroup(RichTyperGroup):
|
|
@@ -32,6 +60,7 @@ class DefaultTyperGroup(RichTyperGroup):
|
|
|
32
60
|
default_cmd_name: str = "print",
|
|
33
61
|
**kwargs: Any,
|
|
34
62
|
) -> None:
|
|
63
|
+
"""Initialize the group with a default command name fallback."""
|
|
35
64
|
super().__init__(
|
|
36
65
|
name=name,
|
|
37
66
|
commands=commands,
|
|
@@ -42,11 +71,12 @@ class DefaultTyperGroup(RichTyperGroup):
|
|
|
42
71
|
result_callback=result_callback,
|
|
43
72
|
**kwargs,
|
|
44
73
|
)
|
|
45
|
-
self.default_cmd_name = default_cmd_name
|
|
74
|
+
self.default_cmd_name: str = default_cmd_name
|
|
46
75
|
|
|
47
76
|
def resolve_command(
|
|
48
77
|
self, ctx: click.Context, args: list[str]
|
|
49
78
|
) -> tuple[str | None, click.Command | None, list[str]]:
|
|
79
|
+
"""Resolve the command, routing unknown input to the default command."""
|
|
50
80
|
if args:
|
|
51
81
|
cmd = self.get_command(ctx, args[0])
|
|
52
82
|
if cmd is None or args[0].startswith("-"):
|
|
@@ -60,7 +90,7 @@ app = typer.Typer(
|
|
|
60
90
|
add_completion=False,
|
|
61
91
|
help="Create gradient-rich text, panels, and markdown.",
|
|
62
92
|
rich_markup_mode="rich",
|
|
63
|
-
context_settings={"help_option_names": ["
|
|
93
|
+
context_settings={"help_option_names": ["--help"], "color": True},
|
|
64
94
|
)
|
|
65
95
|
|
|
66
96
|
|
|
@@ -86,11 +116,27 @@ def main(
|
|
|
86
116
|
|
|
87
117
|
|
|
88
118
|
app.command("print", cls=RichTyperCommand)(print_command)
|
|
119
|
+
app.command("gradient", cls=RichTyperCommand)(gradient_command)
|
|
120
|
+
app.command("columns", cls=RichTyperCommand)(columns_command)
|
|
89
121
|
app.command("panel", cls=RichTyperCommand)(panel_command)
|
|
90
122
|
app.command("rule", cls=RichTyperCommand)(rule_command)
|
|
91
123
|
app.command("markdown", cls=RichTyperCommand)(markdown_command)
|
|
124
|
+
app.command("spectrum", cls=RichTyperCommand)(spectrum_command)
|
|
125
|
+
app.command("syntax", cls=RichTyperCommand)(syntax_command)
|
|
126
|
+
app.command("table", cls=RichTyperCommand)(table_command)
|
|
127
|
+
app.command("tree", cls=RichTyperCommand)(tree_command)
|
|
128
|
+
app.command("view", cls=RichTyperCommand)(view_command)
|
|
92
129
|
|
|
93
130
|
|
|
94
131
|
cli = app
|
|
95
132
|
|
|
96
|
-
|
|
133
|
+
|
|
134
|
+
def entrypoint() -> None:
|
|
135
|
+
"""Run the Typer CLI application."""
|
|
136
|
+
app()
|
|
137
|
+
|
|
138
|
+
__all__ = ["app", "cli", "entrypoint"]
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
if __name__ == "__main__":
|
|
142
|
+
entrypoint()
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"""Shared helpers and configuration for the rich-gradient CLI."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any, List, Mapping, Optional, Sequence, cast
|
|
8
|
+
|
|
9
|
+
from rich.console import Console, RenderableType
|
|
10
|
+
from rich.padding import Padding
|
|
11
|
+
from rich.style import Style
|
|
12
|
+
from rich_gradient.animated_gradient import AnimatedGradient
|
|
13
|
+
from rich_gradient.gradient import Gradient
|
|
14
|
+
from rich_gradient.theme import GRADIENT_TERMINAL_THEME
|
|
15
|
+
|
|
16
|
+
console = Console()
|
|
17
|
+
try:
|
|
18
|
+
VERSION = version("rich-gradient-cli")
|
|
19
|
+
except PackageNotFoundError:
|
|
20
|
+
VERSION = "0.0.0"
|
|
21
|
+
|
|
22
|
+
HEADER_TEXT = (
|
|
23
|
+
"[#ff5500]r[/][#ff6f00]i[/][#ff8300]c[/]"
|
|
24
|
+
"[#ff9500]h[/][#ffa600]-[/][#ffb600]g[/][#ffc500]r[/]"
|
|
25
|
+
"[#ffd400]a[/][#ffe500]d[/][#fff400]i[/][#f9ff00]e[/]"
|
|
26
|
+
"[#e2ff00]n[/][#c8ff00]t[/][#a9ff00] [/][bold #fff]CLI[/]"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
FOOTER_TEXT = (
|
|
30
|
+
"[#ff5500]\U0001f308[/][#ff7400] [/][#ff8c00]h[/]"
|
|
31
|
+
"[#ffa100]t[/][#ffb500]t[/][#ffc700]p[/][#ffdc00]s[/]"
|
|
32
|
+
"[#ffef00]:[/][#fbff00]/[/][#dfff00]/[/][#bdff00]m[/]"
|
|
33
|
+
"[#9aff00]a[/][#73ff00]x[/][#2aff00]l[/][#00ff5c]u[/]"
|
|
34
|
+
"[#00ff83]d[/][#00ffa6]d[/][#00ffd1]e[/][#00fff3]n[/]"
|
|
35
|
+
"[#00f4ff].[/][#00e1ff]g[/][#00ccff]i[/][#00baff]t[/]"
|
|
36
|
+
"[#00a6ff]h[/][#2192ff]u[/][#3b81ff]b[/][#4c6cff].[/]"
|
|
37
|
+
"[#6061ff]i[/][#725bff]o[/][#8253ff]/[/][#9648ff]r[/]"
|
|
38
|
+
"[#a83bff]i[/][#c22eff]c[/][#e122ff]h[/][#fb0cff]-[/]"
|
|
39
|
+
"[#ff00e6]g[/][#ff00c6]r[/][#ff00a4]a[/][#ff0089]d[/]"
|
|
40
|
+
"[#ff0066]i[/][#ff004b]e[/][#ff0036]n[/][#ff0000]t[/]"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
USAGE_PREFIX = "[bold #00ff00]Usage:[/]"
|
|
45
|
+
USAGE_PROG_STYLE = "#af00ff"
|
|
46
|
+
USAGE_CMD_STYLE = "#0099ff"
|
|
47
|
+
USAGE_BRACKET_STYLE = "#ffffff"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def parse_colors(colors: Optional[str]) -> Optional[List[str]]:
|
|
51
|
+
"""Parse comma-separated color tokens into a list."""
|
|
52
|
+
if colors is None:
|
|
53
|
+
return None
|
|
54
|
+
return [c.strip() for c in colors.split(",") if c.strip()]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def parse_style(style: Optional[str]) -> Style:
|
|
58
|
+
"""Parse a Rich style string or return a null style."""
|
|
59
|
+
if style is None:
|
|
60
|
+
return Style.null()
|
|
61
|
+
return Style.parse(style)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def parse_mapping_options(values: Optional[Sequence[str]]) -> Optional[Mapping[str, str]]:
|
|
65
|
+
"""Parse repeated KEY=VALUE CLI options into a mapping."""
|
|
66
|
+
if not values:
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
parsed: dict[str, str] = {}
|
|
70
|
+
for value in values:
|
|
71
|
+
key, separator, item_value = value.partition("=")
|
|
72
|
+
key = key.strip()
|
|
73
|
+
item_value = item_value.strip()
|
|
74
|
+
if not separator or not key or not item_value:
|
|
75
|
+
raise ValueError(f"Expected KEY=VALUE, got {value!r}.")
|
|
76
|
+
parsed[key] = item_value
|
|
77
|
+
return parsed
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def parse_padding(padding: Optional[str]) -> int | tuple[int, ...] | None:
|
|
81
|
+
"""Parse Rich padding shorthand from a CLI string."""
|
|
82
|
+
if padding is None:
|
|
83
|
+
return None
|
|
84
|
+
|
|
85
|
+
parts = tuple(int(part) for part in padding.split(",") if part.strip())
|
|
86
|
+
if len(parts) not in {1, 2, 4}:
|
|
87
|
+
raise ValueError("Padding must contain 1, 2, or 4 comma-separated integers.")
|
|
88
|
+
if len(parts) == 1:
|
|
89
|
+
return parts[0]
|
|
90
|
+
return parts
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def export_svg(
|
|
94
|
+
renderable: RenderableType, svg_path: str, *, end: str = "\n", no_wrap: bool = False
|
|
95
|
+
) -> None:
|
|
96
|
+
"""Render a Rich renderable to an SVG file."""
|
|
97
|
+
svg_console = Console(record=True, force_terminal=True, color_system="truecolor")
|
|
98
|
+
padded = Padding(renderable, (1, 4))
|
|
99
|
+
svg_console.print(padded, end=end, no_wrap=no_wrap)
|
|
100
|
+
|
|
101
|
+
Path(svg_path).write_text(
|
|
102
|
+
svg_console.export_svg(
|
|
103
|
+
title="rich-gradient",
|
|
104
|
+
theme=GRADIENT_TERMINAL_THEME,
|
|
105
|
+
),
|
|
106
|
+
encoding="utf-8",
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def render_gradient_output(
|
|
111
|
+
renderable: RenderableType,
|
|
112
|
+
*,
|
|
113
|
+
colors: Optional[str] = None,
|
|
114
|
+
bgcolors: Optional[str] = None,
|
|
115
|
+
rainbow: bool = False,
|
|
116
|
+
hues: int = 5,
|
|
117
|
+
expand: bool = True,
|
|
118
|
+
justify: str = "left",
|
|
119
|
+
vertical_justify: str = "middle",
|
|
120
|
+
repeat_scale: float = 2.0,
|
|
121
|
+
highlight_words: Optional[Sequence[str]] = None,
|
|
122
|
+
highlight_regex: Optional[Sequence[str]] = None,
|
|
123
|
+
end: str = "\n",
|
|
124
|
+
animate: bool = False,
|
|
125
|
+
duration: Optional[float] = None,
|
|
126
|
+
svg: Optional[str] = None,
|
|
127
|
+
) -> None:
|
|
128
|
+
"""Render any Rich renderable through rich-gradient's Gradient wrapper."""
|
|
129
|
+
fg_list = parse_colors(colors)
|
|
130
|
+
bg_list = parse_colors(bgcolors)
|
|
131
|
+
highlight_word_map = parse_mapping_options(highlight_words)
|
|
132
|
+
highlight_regex_map = parse_mapping_options(highlight_regex)
|
|
133
|
+
|
|
134
|
+
if animate and svg:
|
|
135
|
+
raise ValueError("--svg is not supported with --animate.")
|
|
136
|
+
if animate and console.is_terminal is True:
|
|
137
|
+
animated = AnimatedGradient(
|
|
138
|
+
cast(Any, renderable),
|
|
139
|
+
colors=cast(Any, fg_list),
|
|
140
|
+
bg_colors=cast(Any, bg_list),
|
|
141
|
+
hues=hues,
|
|
142
|
+
rainbow=rainbow,
|
|
143
|
+
expand=expand,
|
|
144
|
+
justify=cast(Any, justify),
|
|
145
|
+
vertical_justify=cast(Any, vertical_justify),
|
|
146
|
+
repeat_scale=repeat_scale,
|
|
147
|
+
highlight_words=highlight_word_map,
|
|
148
|
+
highlight_regex=highlight_regex_map,
|
|
149
|
+
animate=True,
|
|
150
|
+
duration=duration,
|
|
151
|
+
)
|
|
152
|
+
animated.run()
|
|
153
|
+
return
|
|
154
|
+
|
|
155
|
+
gradient = Gradient(
|
|
156
|
+
cast(Any, renderable),
|
|
157
|
+
colors=cast(Any, fg_list),
|
|
158
|
+
bg_colors=cast(Any, bg_list),
|
|
159
|
+
hues=hues,
|
|
160
|
+
rainbow=rainbow,
|
|
161
|
+
expand=expand,
|
|
162
|
+
justify=cast(Any, justify),
|
|
163
|
+
vertical_justify=cast(Any, vertical_justify),
|
|
164
|
+
repeat_scale=repeat_scale,
|
|
165
|
+
highlight_words=highlight_word_map,
|
|
166
|
+
highlight_regex=highlight_regex_map,
|
|
167
|
+
)
|
|
168
|
+
if svg:
|
|
169
|
+
export_svg(gradient, svg, end=end)
|
|
170
|
+
return
|
|
171
|
+
console.print(gradient, end=end)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
__all__ = [
|
|
175
|
+
"VERSION",
|
|
176
|
+
"console",
|
|
177
|
+
"parse_colors",
|
|
178
|
+
"parse_mapping_options",
|
|
179
|
+
"parse_padding",
|
|
180
|
+
"parse_style",
|
|
181
|
+
"render_gradient_output",
|
|
182
|
+
"HEADER_TEXT",
|
|
183
|
+
"FOOTER_TEXT",
|
|
184
|
+
"USAGE_PREFIX",
|
|
185
|
+
"USAGE_PROG_STYLE",
|
|
186
|
+
"USAGE_CMD_STYLE",
|
|
187
|
+
"USAGE_BRACKET_STYLE",
|
|
188
|
+
"export_svg",
|
|
189
|
+
]
|