markrender 1.1.0__tar.gz → 1.1.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.
- {markrender-1.1.0/markrender.egg-info → markrender-1.1.1}/PKG-INFO +183 -97
- markrender-1.1.1/README.md +459 -0
- {markrender-1.1.0 → markrender-1.1.1}/markrender/_version.py +2 -2
- {markrender-1.1.0 → markrender-1.1.1}/markrender/colors.py +27 -1
- {markrender-1.1.0 → markrender-1.1.1}/markrender/formatters.py +3 -12
- {markrender-1.1.0 → markrender-1.1.1}/markrender/renderer.py +6 -4
- {markrender-1.1.0 → markrender-1.1.1/markrender.egg-info}/PKG-INFO +183 -97
- {markrender-1.1.0 → markrender-1.1.1}/markrender.egg-info/SOURCES.txt +1 -0
- {markrender-1.1.0 → markrender-1.1.1}/markrender.egg-info/scm_file_list.json +1 -0
- markrender-1.1.1/tests/test_dim_mode.py +119 -0
- {markrender-1.1.0 → markrender-1.1.1}/tests/test_regressions.py +2 -1
- markrender-1.1.0/README.md +0 -373
- {markrender-1.1.0 → markrender-1.1.1}/.gitignore +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/LICENSE +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/MANIFEST.in +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/check_truecolor.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/examples/basic_usage.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/examples/complete_showcase.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/examples/definition_lists.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/examples/footnotes.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/examples/highlights.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/examples/link_highlighting.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/examples/mermaid_diagrams.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/examples/new_features_demo.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/examples/progress_bars.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/examples/streaming_demo.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/examples/theme_showcase.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/examples/v1_0_7_showcase.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/markrender/__init__.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/markrender/__main__.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/markrender/cli.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/markrender/config.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/markrender/parser.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/markrender/themes.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/markrender.egg-info/dependency_links.txt +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/markrender.egg-info/entry_points.txt +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/markrender.egg-info/requires.txt +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/markrender.egg-info/top_level.txt +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/pyproject.toml +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/requirements.txt +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/setup.cfg +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/setup.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/test.md +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/tests/test_colors.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/tests/test_formatters.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/tests/test_parser.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/tests/test_renderer.py +0 -0
- {markrender-1.1.0 → markrender-1.1.1}/tests/test_versioning.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: markrender
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.1
|
|
4
4
|
Summary: Professional terminal markdown renderer for streaming LLM responses
|
|
5
5
|
Author: Praneeth Gandodi
|
|
6
6
|
License: MIT
|
|
@@ -34,14 +34,14 @@ Dynamic: license-file
|
|
|
34
34
|
|
|
35
35
|
**Professional Terminal Markdown Renderer for Streaming LLM Responses**
|
|
36
36
|
|
|
37
|
-
MarkRender
|
|
37
|
+
MarkRender renders markdown in the terminal. It is built for streaming output, so you can hand it a complete string or feed it chunks from an LLM as they arrive. Syntax highlighting, themes, tables, and the rest work the same either way, without reprinting content that is already on screen.
|
|
38
38
|
|
|
39
39
|
## Features
|
|
40
40
|
|
|
41
41
|
- **Streaming Support** - Designed for chunk-by-chunk LLM response rendering
|
|
42
42
|
- **7 Themes** - github-dark, monokai, dracula, nord, one-dark, solarized-dark, solarized-light
|
|
43
43
|
- **Syntax Highlighting** - Powered by Pygments with 500+ languages
|
|
44
|
-
- **Dim Mode** - Render content in
|
|
44
|
+
- **Dim Mode** - Render "thinking" content in a single muted gray
|
|
45
45
|
- **Theme Preview** - Preview all themes with sample content via CLI
|
|
46
46
|
- **Line Numbers** - Optional line numbers in code blocks
|
|
47
47
|
- **Tables** - Table rendering with borders and overflow truncation
|
|
@@ -55,183 +55,269 @@ MarkRender is a Python library that renders markdown in terminals, designed for
|
|
|
55
55
|
|
|
56
56
|
## Installation
|
|
57
57
|
|
|
58
|
+
MarkRender is on PyPI:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install markrender
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
That installs the library and the `markrender` command. Check that it worked:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
markrender --version
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Upgrade an existing install with:
|
|
71
|
+
|
|
58
72
|
```bash
|
|
59
|
-
pip install
|
|
73
|
+
pip install --upgrade markrender
|
|
60
74
|
```
|
|
61
75
|
|
|
62
|
-
|
|
76
|
+
If you want to work on MarkRender itself, clone the repo and install it in editable mode instead:
|
|
63
77
|
|
|
64
78
|
```bash
|
|
65
79
|
git clone https://github.com/Praneeth-Gandodi/markrender.git
|
|
66
80
|
cd markrender
|
|
67
|
-
pip install -e .
|
|
81
|
+
pip install -e ".[dev]"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Command Line
|
|
85
|
+
|
|
86
|
+
Render a file:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
markrender README.md
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Read markdown from stdin:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
cat notes.md | markrender
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
On PowerShell:
|
|
99
|
+
|
|
100
|
+
```powershell
|
|
101
|
+
Get-Content notes.md -Raw | markrender
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Pick a theme:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
markrender --theme dracula notes.md
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Adjust code blocks:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
markrender --no-line-numbers notes.md
|
|
114
|
+
markrender --code-background notes.md
|
|
115
|
+
markrender --no-stream-code notes.md
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Set a fixed width when the terminal reports the wrong size, or when the output goes somewhere else:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
markrender --width 80 notes.md
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Force color when piping into another program, a log file, or CI:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
markrender --force-color notes.md | less -R
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
List the theme names:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
markrender --list-themes
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Preview every theme with sample content:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
markrender --preview-themes
|
|
68
140
|
```
|
|
69
141
|
|
|
70
|
-
|
|
142
|
+
Running `markrender` with no file and nothing piped in prints an error and exits.
|
|
143
|
+
|
|
144
|
+
### Options
|
|
145
|
+
|
|
146
|
+
| Option | Description |
|
|
147
|
+
|--------|-------------|
|
|
148
|
+
| `--theme NAME` | Color theme (default: `github-dark`) |
|
|
149
|
+
| `--no-line-numbers` | Hide line numbers in code blocks |
|
|
150
|
+
| `--code-background` | Show a background behind code blocks |
|
|
151
|
+
| `--width N` | Wrap at a fixed width instead of the terminal width |
|
|
152
|
+
| `--no-stream-code` | Render code blocks in one pass instead of line by line |
|
|
153
|
+
| `--force-color` | Emit colors even when the output is not a terminal |
|
|
154
|
+
| `--list-themes` | Print available themes and exit |
|
|
155
|
+
| `--preview-themes` | Render sample markdown in every theme and exit |
|
|
156
|
+
| `-v`, `--version` | Print the version and exit |
|
|
157
|
+
|
|
158
|
+
CLI flags override values from a config file. See [Configuration](#configuration).
|
|
159
|
+
|
|
160
|
+
## Python API
|
|
161
|
+
|
|
162
|
+
### Render a string
|
|
71
163
|
|
|
72
164
|
````python
|
|
73
165
|
from markrender import MarkdownRenderer
|
|
74
166
|
|
|
75
|
-
# Create renderer with default theme
|
|
76
167
|
renderer = MarkdownRenderer()
|
|
77
168
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
# Hello World
|
|
169
|
+
markdown = """
|
|
170
|
+
# Hello
|
|
81
171
|
|
|
82
|
-
|
|
172
|
+
Some **bold** text, some *italic* text, and `inline code`.
|
|
83
173
|
|
|
84
174
|
```python
|
|
85
175
|
def hello():
|
|
86
176
|
print("Hello from MarkRender!")
|
|
87
177
|
```
|
|
88
178
|
|
|
89
|
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
- [x] Completed task
|
|
93
|
-
- [ ] Pending task
|
|
179
|
+
- A list item
|
|
180
|
+
- [x] A finished task
|
|
181
|
+
- [ ] A pending task
|
|
94
182
|
"""
|
|
95
183
|
|
|
96
|
-
renderer.render(
|
|
184
|
+
renderer.render(markdown)
|
|
97
185
|
renderer.finalize()
|
|
98
186
|
````
|
|
99
187
|
|
|
100
|
-
|
|
188
|
+
`render()` writes output as it parses, and `finalize()` flushes whatever is still buffered. For a string you already have, call them one after the other.
|
|
101
189
|
|
|
102
|
-
|
|
190
|
+
### Streaming LLM responses
|
|
103
191
|
|
|
104
192
|
```python
|
|
105
193
|
from markrender import MarkdownRenderer
|
|
106
194
|
from openai import OpenAI
|
|
107
195
|
|
|
108
196
|
client = OpenAI()
|
|
109
|
-
renderer = MarkdownRenderer(theme=
|
|
197
|
+
renderer = MarkdownRenderer(theme="github-dark")
|
|
110
198
|
|
|
111
199
|
stream = client.chat.completions.create(
|
|
112
|
-
model="gpt-
|
|
200
|
+
model="gpt-4o",
|
|
113
201
|
messages=[{"role": "user", "content": "Explain quantum computing"}],
|
|
114
|
-
stream=True
|
|
202
|
+
stream=True,
|
|
115
203
|
)
|
|
116
204
|
|
|
117
205
|
for chunk in stream:
|
|
118
|
-
|
|
119
|
-
if
|
|
120
|
-
renderer.render(
|
|
206
|
+
text = chunk.choices[0].delta.content
|
|
207
|
+
if text:
|
|
208
|
+
renderer.render(text)
|
|
121
209
|
|
|
122
210
|
renderer.finalize()
|
|
123
211
|
```
|
|
124
212
|
|
|
125
|
-
|
|
213
|
+
The renderer keeps partial lines and open blocks in an internal buffer, so chunks can split anywhere: mid-word, mid-table, or in the middle of a code fence. Feed every chunk and call `finalize()` once when the stream ends.
|
|
126
214
|
|
|
127
|
-
|
|
215
|
+
### Dim mode
|
|
128
216
|
|
|
129
|
-
|
|
130
|
-
from markrender import MarkdownRenderer
|
|
131
|
-
|
|
132
|
-
renderer = MarkdownRenderer()
|
|
217
|
+
`render()` takes a `dim_mode` argument, which draws that chunk as plain muted gray. Formatting colors, bold, and syntax highlighting are dropped so the whole block reads like thinking text instead of competing with the answer:
|
|
133
218
|
|
|
134
|
-
|
|
135
|
-
renderer.render("
|
|
136
|
-
|
|
137
|
-
# Dim/reduced color rendering
|
|
138
|
-
renderer.render("This content is dimmed and less prominent", dim_mode=True)
|
|
219
|
+
```python
|
|
220
|
+
renderer.render("Let me think about this...", dim_mode=True)
|
|
221
|
+
renderer.render("Here is the answer.", dim_mode=False)
|
|
139
222
|
```
|
|
140
223
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
Preview all available themes from the CLI:
|
|
224
|
+
Dim mode applies per call, so you can turn it on and off while streaming.
|
|
144
225
|
|
|
145
|
-
|
|
146
|
-
markrender --preview-themes
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
## Themes
|
|
226
|
+
### Custom output
|
|
150
227
|
|
|
151
|
-
|
|
228
|
+
By default output goes to stdout. Pass any text stream with `output`:
|
|
152
229
|
|
|
153
230
|
```python
|
|
154
|
-
|
|
155
|
-
'github-dark', # GitHub's dark theme (default)
|
|
156
|
-
'monokai', # Popular Monokai theme
|
|
157
|
-
'dracula', # Dracula theme
|
|
158
|
-
'nord', # Nord color palette
|
|
159
|
-
'one-dark', # Atom One Dark
|
|
160
|
-
'solarized-dark', # Solarized Dark
|
|
161
|
-
'solarized-light' # Solarized Light
|
|
162
|
-
]
|
|
231
|
+
from markrender import MarkdownRenderer
|
|
163
232
|
|
|
164
|
-
|
|
233
|
+
with open("rendered.txt", "w", encoding="utf-8") as log:
|
|
234
|
+
renderer = MarkdownRenderer(output=log, force_color=True)
|
|
235
|
+
renderer.render("# Saved to a file\n")
|
|
236
|
+
renderer.finalize()
|
|
165
237
|
```
|
|
166
238
|
|
|
167
|
-
|
|
239
|
+
Color detection still looks at stdout, so set `force_color=True` if you want ANSI colors in the file.
|
|
168
240
|
|
|
169
|
-
|
|
170
|
-
markrender --list-themes
|
|
171
|
-
```
|
|
241
|
+
### Constructor options
|
|
172
242
|
|
|
173
|
-
|
|
243
|
+
| Parameter | Default | Description |
|
|
244
|
+
|-----------|---------|-------------|
|
|
245
|
+
| `theme` | `"github-dark"` | Theme name |
|
|
246
|
+
| `code_background` | `False` | Draw a background behind code blocks |
|
|
247
|
+
| `line_numbers` | `True` | Show line numbers in code blocks |
|
|
248
|
+
| `inline_code_color` | theme default | ANSI color code for inline code |
|
|
249
|
+
| `width` | auto-detect | Wrap width in characters |
|
|
250
|
+
| `force_color` | `False` | Emit color even when the output is not a TTY |
|
|
251
|
+
| `stream_code` | `True` | Render code lines as they arrive |
|
|
252
|
+
| `output` | `sys.stdout` | Stream to write to |
|
|
253
|
+
| `use_config` | `True` | Load a config file if one is found |
|
|
254
|
+
| `config` | `None` | Pass a `RendererConfig` directly |
|
|
174
255
|
|
|
175
|
-
|
|
256
|
+
Custom inline code color uses the `rgb` helper:
|
|
176
257
|
|
|
177
258
|
```python
|
|
178
259
|
from markrender import MarkdownRenderer
|
|
179
260
|
from markrender.colors import rgb
|
|
180
261
|
|
|
181
262
|
renderer = MarkdownRenderer(
|
|
182
|
-
theme=
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
inline_code_color=rgb(255, 100, 200), # Custom inline code color
|
|
186
|
-
width=100, # Terminal width (auto-detect by default)
|
|
187
|
-
force_color=False, # Force color output
|
|
188
|
-
stream_code=True # Stream code lines as they arrive
|
|
263
|
+
theme="monokai",
|
|
264
|
+
inline_code_color=rgb(255, 100, 200),
|
|
265
|
+
width=100,
|
|
189
266
|
)
|
|
190
267
|
```
|
|
191
268
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
- **theme** (str): Color theme name (default: `'github-dark'`)
|
|
195
|
-
- **code_background** (bool): Show background in code blocks (default: `False`)
|
|
196
|
-
- **line_numbers** (bool): Show line numbers in code blocks (default: `True`)
|
|
197
|
-
- **inline_code_color** (str): Custom ANSI color code for inline code (default: theme default)
|
|
198
|
-
- **width** (int): Terminal width in characters (default: auto-detect)
|
|
199
|
-
- **force_color** (bool): Force color output even if terminal does not support it (default: `False`)
|
|
200
|
-
- **stream_code** (bool): Render code lines as they arrive instead of buffering (default: `True`)
|
|
201
|
-
- **output** (file): Output stream (default: `sys.stdout`)
|
|
269
|
+
## Configuration
|
|
202
270
|
|
|
203
|
-
|
|
271
|
+
MarkRender reads a TOML config file if one exists. It checks these locations in order and uses the first match:
|
|
204
272
|
|
|
205
|
-
|
|
206
|
-
markrender
|
|
207
|
-
markrender
|
|
208
|
-
cat file.md | markrender
|
|
209
|
-
markrender --preview-themes
|
|
210
|
-
markrender --list-themes
|
|
211
|
-
markrender --no-line-numbers --code-background file.md
|
|
212
|
-
markrender --width 80 --force-color file.md
|
|
213
|
-
```
|
|
273
|
+
1. `.markrender.toml` in the current directory
|
|
274
|
+
2. `~/.markrender/config.toml`
|
|
275
|
+
3. `~/.config/markrender/config.toml`
|
|
214
276
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
MarkRender supports TOML configuration files. Place a `.markrender.toml` in your current directory or `~/.markrender/config.toml`:
|
|
277
|
+
Example `.markrender.toml`:
|
|
218
278
|
|
|
219
279
|
```toml
|
|
220
280
|
[theme]
|
|
221
|
-
name = "
|
|
281
|
+
name = "dracula"
|
|
222
282
|
|
|
223
283
|
[rendering]
|
|
224
|
-
code_background =
|
|
225
|
-
line_numbers =
|
|
284
|
+
code_background = true
|
|
285
|
+
line_numbers = false
|
|
226
286
|
|
|
227
287
|
[output]
|
|
228
|
-
|
|
288
|
+
width = 100
|
|
229
289
|
force_color = false
|
|
230
290
|
|
|
231
291
|
[features]
|
|
232
|
-
stream_code =
|
|
292
|
+
stream_code = false
|
|
233
293
|
```
|
|
234
294
|
|
|
295
|
+
Values are applied in this order, from highest to lowest priority:
|
|
296
|
+
|
|
297
|
+
1. Arguments passed to `MarkdownRenderer(...)`
|
|
298
|
+
2. The config file
|
|
299
|
+
3. Built-in defaults
|
|
300
|
+
|
|
301
|
+
Only non-`None` arguments override the config, so `MarkdownRenderer()` picks up your file settings. Pass `use_config=False` to ignore config files entirely.
|
|
302
|
+
|
|
303
|
+
## Themes
|
|
304
|
+
|
|
305
|
+
| Theme | Notes |
|
|
306
|
+
|-------|-------|
|
|
307
|
+
| `github-dark` | GitHub's dark theme (default) |
|
|
308
|
+
| `monokai` | Classic Monokai palette |
|
|
309
|
+
| `dracula` | Dracula palette |
|
|
310
|
+
| `nord` | Nord palette |
|
|
311
|
+
| `one-dark` | Atom One Dark |
|
|
312
|
+
| `solarized-dark` | Solarized Dark |
|
|
313
|
+
| `solarized-light` | Solarized Light |
|
|
314
|
+
|
|
315
|
+
```python
|
|
316
|
+
renderer = MarkdownRenderer(theme="dracula")
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
See the names from the CLI with `markrender --list-themes`, or render a sample in each theme with `markrender --preview-themes`.
|
|
320
|
+
|
|
235
321
|
## Supported Markdown Features
|
|
236
322
|
|
|
237
323
|
### Headings
|