termrender 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.
Files changed (37) hide show
  1. termrender-0.3.0/.github/workflows/publish.yml +48 -0
  2. termrender-0.3.0/CHANGELOG.md +119 -0
  3. termrender-0.3.0/CLAUDE.md +64 -0
  4. termrender-0.3.0/PKG-INFO +473 -0
  5. termrender-0.3.0/README.md +445 -0
  6. termrender-0.3.0/design.json +408 -0
  7. {termrender-0.1.0 → termrender-0.3.0}/pyproject.toml +20 -2
  8. termrender-0.3.0/requirements.json +590 -0
  9. termrender-0.3.0/src/termrender/CLAUDE.md +57 -0
  10. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/__init__.py +6 -1
  11. termrender-0.3.0/src/termrender/__main__.py +278 -0
  12. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/blocks.py +1 -0
  13. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/emit.py +4 -1
  14. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/layout.py +44 -10
  15. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/parser.py +63 -8
  16. termrender-0.3.0/src/termrender/renderers/CLAUDE.md +54 -0
  17. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/renderers/borders.py +18 -7
  18. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/renderers/divider.py +5 -2
  19. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/renderers/mermaid.py +16 -2
  20. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/renderers/quote.py +3 -3
  21. termrender-0.3.0/src/termrender/renderers/table.py +95 -0
  22. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/renderers/tree.py +22 -5
  23. termrender-0.3.0/src/termrender/style.py +253 -0
  24. termrender-0.3.0/tests/__init__.py +0 -0
  25. termrender-0.3.0/tests/test_column_alignment.py +138 -0
  26. termrender-0.1.0/.github/workflows/publish.yml +0 -23
  27. termrender-0.1.0/PKG-INFO +0 -26
  28. termrender-0.1.0/src/termrender/__main__.py +0 -46
  29. termrender-0.1.0/src/termrender/style.py +0 -147
  30. {termrender-0.1.0 → termrender-0.3.0}/.gitignore +0 -0
  31. {termrender-0.1.0 → termrender-0.3.0}/LICENSE +0 -0
  32. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/py.typed +0 -0
  33. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/renderers/__init__.py +0 -0
  34. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/renderers/code.py +0 -0
  35. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/renderers/columns.py +0 -0
  36. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/renderers/panel.py +0 -0
  37. {termrender-0.1.0 → termrender-0.3.0}/src/termrender/renderers/text.py +0 -0
@@ -0,0 +1,48 @@
1
+ name: Release & Publish
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ permissions:
8
+ contents: write
9
+ id-token: write
10
+
11
+ jobs:
12
+ release:
13
+ runs-on: ubuntu-latest
14
+ outputs:
15
+ released: ${{ steps.semrel.outputs.released }}
16
+ tag: ${{ steps.semrel.outputs.tag }}
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ with:
20
+ fetch-depth: 0
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.12"
24
+ - uses: python-semantic-release/python-semantic-release@v9
25
+ id: semrel
26
+ with:
27
+ github_token: ${{ secrets.GITHUB_TOKEN }}
28
+ git_committer_name: "github-actions[bot]"
29
+ git_committer_email: "github-actions[bot]@users.noreply.github.com"
30
+
31
+ publish:
32
+ needs: release
33
+ if: needs.release.outputs.released == 'true'
34
+ runs-on: ubuntu-latest
35
+ environment: pypi
36
+ permissions:
37
+ id-token: write
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+ with:
41
+ fetch-depth: 0
42
+ ref: ${{ needs.release.outputs.tag }}
43
+ - uses: actions/setup-python@v5
44
+ with:
45
+ python-version: "3.12"
46
+ - run: pip install build
47
+ - run: python -m build
48
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,119 @@
1
+ # CHANGELOG
2
+
3
+
4
+ ## v0.3.0 (2026-04-05)
5
+
6
+ ### Documentation
7
+
8
+ - Update CLAUDE.md notes for mermaid, tmux, and layout
9
+ ([`9e104d5`](https://github.com/CaptainCrouton89/termrender/commit/9e104d5ee7bad9a57902e79586c02b0e8d80c589))
10
+
11
+ ### Features
12
+
13
+ - **cli**: Auto-size tmux pane to fit rendered content
14
+ ([`91f0414`](https://github.com/CaptainCrouton89/termrender/commit/91f0414d0bf8bfbe4d7167159b928ed9c736db74))
15
+
16
+ - **mermaid**: Pass width and vertical padding to mermaid-ascii
17
+ ([`96145c2`](https://github.com/CaptainCrouton89/termrender/commit/96145c2789a52a4d94e9bc5f4adf7f3a88d8501f))
18
+
19
+ - **table**: Auto-wrap cell content when columns overflow
20
+ ([`0fae56f`](https://github.com/CaptainCrouton89/termrender/commit/0fae56f8f00260c3263671df9a63a5bea17820bb))
21
+
22
+ When a table exceeds available width, cells now wrap text within their proportionally-shrunk column
23
+ widths instead of overflowing. Layout height calculation updated to account for multi-line cells.
24
+
25
+
26
+ ## v0.2.1 (2026-04-05)
27
+
28
+ ### Bug Fixes
29
+
30
+ - **mermaid**: Undo double-encoded UTF-8 from mermaid-ascii output
31
+ ([`9e0560c`](https://github.com/CaptainCrouton89/termrender/commit/9e0560ce46b6dc3f90d2d716a97780713e5e5e53))
32
+
33
+ mermaid-ascii misinterprets UTF-8 bytes as Latin-1 and re-encodes, corrupting multi-byte characters
34
+ (e.g. → renders as â<U+0086><U+0092>). Apply latin-1 round-trip to recover original UTF-8 in both
35
+ layout and renderer subprocess call sites.
36
+
37
+ ### Documentation
38
+
39
+ - Add tmux pane lifecycle and --check interaction notes to CLAUDE.md
40
+ ([`9400092`](https://github.com/CaptainCrouton89/termrender/commit/9400092e507d470acb97ac5a17b66fcf0e9aa2f6))
41
+
42
+
43
+ ## v0.2.0 (2026-04-05)
44
+
45
+ ### Bug Fixes
46
+
47
+ - Handle zero-width and emoji presentation chars in visual width calculation
48
+ ([`d0bb8dc`](https://github.com/CaptainCrouton89/termrender/commit/d0bb8dcfa5ca0d2c16d78a1d7f81825231b9cb59))
49
+
50
+ _char_width now returns 0 for combining marks and format characters (ZWJ, variation selectors).
51
+ visual_len handles VS16 emoji presentation sequences by promoting the preceding character to width
52
+ 2. Fixes panel border misalignment when content contains emoji or special Unicode.
53
+
54
+ - **docs**: Update README output examples to match actual rendered output
55
+ ([`de6d0cc`](https://github.com/CaptainCrouton89/termrender/commit/de6d0ccfd8a60aca20f2b2659a313f8d8c87d853))
56
+
57
+ ### Chores
58
+
59
+ - Add README, design specs, and project CLAUDE.md files
60
+ ([`93ac358`](https://github.com/CaptainCrouton89/termrender/commit/93ac35857981c549797a9359573cacea1478b3ad))
61
+
62
+ - Derive version from git tags via hatch-vcs
63
+ ([`33595a0`](https://github.com/CaptainCrouton89/termrender/commit/33595a0b64363e445b90c9df135a50a4652e2bae))
64
+
65
+ ### Continuous Integration
66
+
67
+ - Auto-release and publish via conventional commits
68
+ ([`80a456b`](https://github.com/CaptainCrouton89/termrender/commit/80a456b7301c57f2fd2b0cd30622b78f2d4b931e))
69
+
70
+ Replace manual GitHub release trigger with python-semantic-release. On push to main, conventional
71
+ commits are analyzed to determine version bumps (feat→minor, fix→patch) and publish to PyPI
72
+ automatically.
73
+
74
+ ### Documentation
75
+
76
+ - Update README token count and expand CLAUDE.md implementation notes
77
+ ([`1f70a53`](https://github.com/CaptainCrouton89/termrender/commit/1f70a5352cbced30219012dbede7040c6ac97457))
78
+
79
+ ### Features
80
+
81
+ - Add CJK ambiguous-width support, strict directive parsing, and rendering fixes
82
+ ([`c000883`](https://github.com/CaptainCrouton89/termrender/commit/c0008835d66b721b0a09c7a34dde11d08b3d3d94))
83
+
84
+ - Add emoji presentation and East Asian ambiguous-width character handling with --cjk flag and
85
+ TERMRENDER_CJK env var - All renderers (borders, divider, quote, tree) now compute box-drawing
86
+ character widths dynamically via visual_len - Parser raises DirectiveError on unclosed or stray
87
+ ::: directives instead of silently degrading - Fix column width distribution to correctly account
88
+ for inter-column gaps - Support 'author' as alias for 'by' attribute on quote blocks
89
+
90
+ - Add GFM table rendering with box-drawing borders
91
+ ([`c3b61cd`](https://github.com/CaptainCrouton89/termrender/commit/c3b61cdd659fdb782089cbca2fd3f74b18486605))
92
+
93
+ Enable mistune table plugin, parse table AST into TABLE blocks, and render with box-drawing
94
+ characters. Supports left/center/right column alignment, bold headers, auto-sized columns, and
95
+ proportional overflow distribution.
96
+
97
+ - **cli**: Add --tmux pane output, --check validation, and structured error handling
98
+ ([`36b52ee`](https://github.com/CaptainCrouton89/termrender/commit/36b52eed9701cd0acd363db2d0fa3d277244c8b0))
99
+
100
+ - --tmux renders in a new tmux side pane via split-window, piped through less -R - --check validates
101
+ directive syntax without rendering (exit 0/2) - Structured _error() helper with fix/hint guidance
102
+ on stderr - Named exit codes (EXIT_OK, EXIT_INPUT, EXIT_SYNTAX, EXIT_TERMINAL) - Expanded epilog
103
+ with full directive reference, nesting examples, and env docs - Dynamic version from
104
+ importlib.metadata (hatch-vcs) - Updated CLAUDE.md to document --check behavior and fix recursion
105
+ depth note
106
+
107
+ - **cli**: Improve help output with examples, version flag, and tty detection
108
+ ([`cb3e7e2`](https://github.com/CaptainCrouton89/termrender/commit/cb3e7e2752ae860e5c3cbd4c4f1627e925a9c431))
109
+
110
+ ### Testing
111
+
112
+ - Add column alignment and visual width tests
113
+ ([`f8b6099`](https://github.com/CaptainCrouton89/termrender/commit/f8b60998625977b10dd4697f8e772d80125cb9ce))
114
+
115
+ Covers showpiece rendering, column line width consistency, status marker visual widths (text vs
116
+ emoji presentation), and panel border alignment.
117
+
118
+
119
+ ## v0.1.0 (2026-04-04)
@@ -0,0 +1,64 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## What this is
6
+
7
+ termrender renders directive-flavored markdown to ANSI terminal output. LLM agents describe layout with `:::directives` (panels, columns, trees, callouts, etc.) and termrender produces styled terminal output. Public API: `from termrender import render`.
8
+
9
+ ## Commands
10
+
11
+ ```bash
12
+ # Install in dev mode
13
+ pip install -e .
14
+
15
+ # Run tests
16
+ pytest tests/
17
+ pytest tests/test_column_alignment.py::TestColumnAlignment::test_showpiece_renders_without_error
18
+
19
+ # Run the CLI
20
+ python -m termrender <file.md>
21
+ echo ':::panel{title="Hi"}\nHello\n:::' | python -m termrender
22
+
23
+ # Build
24
+ python -m build
25
+ ```
26
+
27
+ No linter or formatter is configured.
28
+
29
+ ## Architecture
30
+
31
+ Three-stage pipeline: **parse → layout → emit**.
32
+
33
+ 1. **Parse** (`parser.py`) — Two-pass: regex extracts `:::directives` first, then mistune v3 processes markdown segments. Produces a tree of `Block` dataclasses (`blocks.py`).
34
+ 2. **Layout** (`layout.py`) — Two-pass, order is load-bearing: `resolve_width()` top-down, then `resolve_height()` bottom-up. Width must resolve first because height calls `wrap_text(text, width)`.
35
+ 3. **Emit** (`emit.py`) — Walks the block tree and dispatches to renderer functions in `renderers/`.
36
+
37
+ Entry points:
38
+ - **Library**: `__init__.py:render()` — parse → layout → emit
39
+ - **CLI**: `__main__.py:main()` — argparse with `--width`, `--no-color`, `--check`, `--cjk`, `--tmux`. Exit codes: 0=ok, 1=input, 2=syntax, 3=terminal.
40
+
41
+ ### Renderers (`src/termrender/renderers/`)
42
+
43
+ Two signatures (not type-enforced):
44
+ - **Leaf**: `render(block, color) -> list[str]` — divider, tree
45
+ - **Container**: `render(block, color, render_child) -> list[str]` — panel, quote, code, columns, callout, table, text, mermaid
46
+
47
+ `borders.py` is a shared utility, not a renderer. Its `render_box(content_lines, width, ...)` takes **total** width (including borders), not content width.
48
+
49
+ ### Style (`style.py`)
50
+
51
+ `visual_len()` measures display width accounting for ANSI escapes, emoji, CJK, and combining marks. `wrap_text()` uses `len()` internally (known bug: CJK overflow). `_ambiguous_width` is global mutable state with no reset path — set via `set_ambiguous_width()` or `TERMRENDER_CJK` env var.
52
+
53
+ ## Conventions
54
+
55
+ - **Commits**: conventional commits (`feat:`, `fix:`, `chore:`, etc.). `feat` → minor, `fix`/`perf` → patch. Auto-released via python-semantic-release on main.
56
+ - **Version**: derived from git tags via hatch-vcs (no version in pyproject.toml).
57
+ - **Python**: 3.10+.
58
+
59
+ ## Supplementary CLAUDE.md files
60
+
61
+ - `src/termrender/CLAUDE.md` — parser, layout, mermaid, nesting, and `--check`/`--tmux` implementation gotchas
62
+ - `src/termrender/renderers/CLAUDE.md` — renderer contracts, `render_box` width semantics, EAW edge cases
63
+
64
+ Read these before modifying layout, parsing, or renderer code.