termrender 3.0.0__tar.gz → 3.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.
- {termrender-3.0.0 → termrender-3.0.1}/CHANGELOG.md +13 -0
- {termrender-3.0.0 → termrender-3.0.1}/PKG-INFO +1 -1
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/__main__.py +42 -2
- {termrender-3.0.0 → termrender-3.0.1}/tests/test_cli_contract.py +36 -0
- {termrender-3.0.0 → termrender-3.0.1}/.github/workflows/publish.yml +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/.gitignore +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/CLAUDE.md +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/LICENSE +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/README.md +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/design.json +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/pyproject.toml +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/requirements.json +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/scripts/build-mermaid-ascii.sh +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/CLAUDE.md +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/__init__.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/_bin/mermaid-ascii-darwin-arm64 +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/_mermaid_bin.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/blocks.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/emit.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/layout.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/parser.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/py.typed +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/CLAUDE.md +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/__init__.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/borders.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/charts.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/code.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/columns.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/diff.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/divider.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/mermaid.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/panel.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/quote.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/stat.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/table.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/text.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/timeline.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/renderers/tree.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/src/termrender/style.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/tests/__init__.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/tests/test_charts.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/tests/test_column_alignment.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/tests/test_diff.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/tests/test_inline_badge.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/tests/test_linebreak.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/tests/test_mermaid_compat.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/tests/test_myst_gaps.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/tests/test_stat.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/tests/test_tasklist.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/tests/test_timeline.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/tests/test_variable_colons.py +0 -0
- {termrender-3.0.0 → termrender-3.0.1}/uv.lock +0 -0
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## v3.0.1 (2026-06-10)
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
- Spawn tmux render pane via absolute termrender path, not bare PATH name
|
|
9
|
+
([`993c646`](https://github.com/crouton-labs/termrender/commit/993c6463afc64b94b6dbbdbe6e69f7652feac500))
|
|
10
|
+
|
|
11
|
+
The tmux pane command baked a bare `termrender` token into split-window/ respawn-pane, so the
|
|
12
|
+
spawned pane resolved it via $PATH. A venv-only install (invoked by absolute path, not on PATH)
|
|
13
|
+
produced a pane that died instantly and silently. Build the pane command from termrender's own
|
|
14
|
+
absolute invocation (argv[0] when executable, else `python -m termrender`).
|
|
15
|
+
|
|
16
|
+
|
|
4
17
|
## v3.0.0 (2026-05-18)
|
|
5
18
|
|
|
6
19
|
### Chores
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: termrender
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.1
|
|
4
4
|
Summary: Rich terminal rendering of directive-flavored markdown
|
|
5
5
|
Project-URL: Homepage, https://github.com/CaptainCrouton89/termrender
|
|
6
6
|
Project-URL: Repository, https://github.com/CaptainCrouton89/termrender
|
|
@@ -4,6 +4,7 @@ import argparse
|
|
|
4
4
|
import json
|
|
5
5
|
import os
|
|
6
6
|
import sys
|
|
7
|
+
from pathlib import Path
|
|
7
8
|
from typing import Any, NoReturn
|
|
8
9
|
|
|
9
10
|
from termrender import render, TerminalError, DirectiveError
|
|
@@ -59,6 +60,23 @@ Branches
|
|
|
59
60
|
render render markdown to ANSI and print to stdout | use when producing output for display
|
|
60
61
|
check validate directive syntax without rendering | use when validating before rendering
|
|
61
62
|
watch live-render a file, updating on every save | use when monitoring a file interactively
|
|
63
|
+
|
|
64
|
+
Document format
|
|
65
|
+
Directive-flavored markdown. Triple-colon blocks carry attributes in {} and
|
|
66
|
+
nest arbitrarily; every block closes with a bare `:::`. Plain markdown
|
|
67
|
+
(headings, **bold**, *italic*, `code`, bullet/numbered lists) works
|
|
68
|
+
everywhere, including inside directives. Write structure, not box-drawing —
|
|
69
|
+
layout, padding, and guide lines are computed.
|
|
70
|
+
|
|
71
|
+
:::panel{title="" color=""} bordered box; color e.g. green|cyan|red
|
|
72
|
+
:::columns / :::col{width="N%"} side-by-side; col widths sum to 100%
|
|
73
|
+
:::tree{color=""} indentation → Unicode guide lines;
|
|
74
|
+
[x]=done [!]=warning status markers
|
|
75
|
+
:::callout{type=""} admonition; type success|warning|error|info
|
|
76
|
+
:::divider{label=""} labeled horizontal rule
|
|
77
|
+
:::code{lang=""} syntax-highlighted block (``` fences also work)
|
|
78
|
+
:::quote{author=""} attributed block quote
|
|
79
|
+
:::mermaid flowchart → ASCII (NOT ```mermaid fences)
|
|
62
80
|
"""
|
|
63
81
|
|
|
64
82
|
_DOC_RENDER_HELP = """\
|
|
@@ -325,6 +343,27 @@ def _cmd_doc_watch(args: argparse.Namespace) -> None:
|
|
|
325
343
|
sys.exit(EXIT_OK)
|
|
326
344
|
|
|
327
345
|
|
|
346
|
+
def _termrender_invocation() -> str:
|
|
347
|
+
"""Shell-quoted command prefix that invokes *this* termrender.
|
|
348
|
+
|
|
349
|
+
A tmux pane spawned via split-window/respawn-pane resolves a bare
|
|
350
|
+
``termrender`` token through ``$PATH``. When termrender lives only inside a
|
|
351
|
+
managed venv (e.g. invoked by absolute path), that bare name is not on PATH
|
|
352
|
+
and the spawned pane dies instantly and silently. Prefer the absolute path
|
|
353
|
+
of the running entrypoint (argv[0]) so the pane invokes the same binary;
|
|
354
|
+
fall back to ``python -m termrender`` when argv[0] is not a usable
|
|
355
|
+
executable.
|
|
356
|
+
"""
|
|
357
|
+
import shlex
|
|
358
|
+
|
|
359
|
+
argv0 = sys.argv[0] if sys.argv else ""
|
|
360
|
+
if argv0:
|
|
361
|
+
entry = Path(argv0).resolve()
|
|
362
|
+
if entry.is_file() and os.access(entry, os.X_OK):
|
|
363
|
+
return shlex.quote(str(entry))
|
|
364
|
+
return f"{shlex.quote(sys.executable)} -m termrender"
|
|
365
|
+
|
|
366
|
+
|
|
328
367
|
def _build_pane_cmd(
|
|
329
368
|
*,
|
|
330
369
|
watch: bool,
|
|
@@ -337,17 +376,18 @@ def _build_pane_cmd(
|
|
|
337
376
|
import shlex
|
|
338
377
|
|
|
339
378
|
cjk_flag = " --cjk" if cjk else ""
|
|
379
|
+
termrender = _termrender_invocation()
|
|
340
380
|
|
|
341
381
|
if watch:
|
|
342
382
|
# doc watch reads path as positional; use -- to guard against flag-looking paths
|
|
343
|
-
cmd = f"termrender doc watch --color on{cjk_flag} -- {shlex.quote(path)}"
|
|
383
|
+
cmd = f"{termrender} doc watch --color on{cjk_flag} -- {shlex.quote(path)}"
|
|
344
384
|
else:
|
|
345
385
|
effective_path = tmpfile if tmpfile else path
|
|
346
386
|
width_flag = f" --width {pane_width}" if pane_width is not None else ""
|
|
347
387
|
# doc render reads stdin — cat the file into it
|
|
348
388
|
cmd = (
|
|
349
389
|
f"cat {shlex.quote(effective_path)}"
|
|
350
|
-
f" | termrender doc render --color on{width_flag}{cjk_flag}"
|
|
390
|
+
f" | {termrender} doc render --color on{width_flag}{cjk_flag}"
|
|
351
391
|
f" | less -R; rm -f {shlex.quote(effective_path)}"
|
|
352
392
|
)
|
|
353
393
|
return cmd
|
|
@@ -332,3 +332,39 @@ def test_doc_render_rejects_unknown_flag():
|
|
|
332
332
|
assert r.returncode == 1
|
|
333
333
|
out = json.loads(r.stdout)
|
|
334
334
|
assert out["error"] == "bad_invocation"
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
# ---------------------------------------------------------------------------
|
|
338
|
+
# Pane command construction — must use an absolute termrender invocation, not a
|
|
339
|
+
# bare PATH-resolved name (a venv-only install is not on a spawned pane's PATH).
|
|
340
|
+
# ---------------------------------------------------------------------------
|
|
341
|
+
|
|
342
|
+
def test_build_pane_cmd_uses_absolute_invocation(monkeypatch, tmp_path):
|
|
343
|
+
import termrender.__main__ as m
|
|
344
|
+
|
|
345
|
+
fake = tmp_path / "termrender"
|
|
346
|
+
fake.write_text("#!/bin/sh\n")
|
|
347
|
+
fake.chmod(0o755)
|
|
348
|
+
monkeypatch.setattr(sys, "argv", [str(fake)])
|
|
349
|
+
|
|
350
|
+
watch_cmd = m._build_pane_cmd(
|
|
351
|
+
watch=True, path="/docs/a.md", cjk=False, pane_width=None, tmpfile=None,
|
|
352
|
+
)
|
|
353
|
+
assert str(fake.resolve()) in watch_cmd
|
|
354
|
+
assert watch_cmd.startswith(str(fake.resolve()) + " ") # absolute, not bare
|
|
355
|
+
assert " doc watch " in watch_cmd
|
|
356
|
+
|
|
357
|
+
render_cmd = m._build_pane_cmd(
|
|
358
|
+
watch=False, path="/docs/a.md", cjk=False, pane_width=80, tmpfile="/tmp/x.md",
|
|
359
|
+
)
|
|
360
|
+
assert str(fake.resolve()) in render_cmd
|
|
361
|
+
assert " doc render " in render_cmd
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def test_termrender_invocation_falls_back_to_python_m(monkeypatch):
|
|
365
|
+
import termrender.__main__ as m
|
|
366
|
+
|
|
367
|
+
monkeypatch.setattr(sys, "argv", [""])
|
|
368
|
+
inv = m._termrender_invocation()
|
|
369
|
+
assert "-m termrender" in inv
|
|
370
|
+
assert sys.executable in inv
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|