termrender 3.0.2__tar.gz → 4.0.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 (52) hide show
  1. {termrender-3.0.2 → termrender-4.0.0}/CHANGELOG.md +25 -0
  2. {termrender-3.0.2 → termrender-4.0.0}/PKG-INFO +2 -2
  3. {termrender-3.0.2 → termrender-4.0.0}/README.md +1 -1
  4. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/CLAUDE.md +1 -0
  5. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/__main__.py +1 -1
  6. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/parser.py +15 -4
  7. {termrender-3.0.2 → termrender-4.0.0}/tests/test_myst_gaps.py +5 -5
  8. {termrender-3.0.2 → termrender-4.0.0}/.github/workflows/publish.yml +0 -0
  9. {termrender-3.0.2 → termrender-4.0.0}/.gitignore +0 -0
  10. {termrender-3.0.2 → termrender-4.0.0}/CLAUDE.md +0 -0
  11. {termrender-3.0.2 → termrender-4.0.0}/LICENSE +0 -0
  12. {termrender-3.0.2 → termrender-4.0.0}/design.json +0 -0
  13. {termrender-3.0.2 → termrender-4.0.0}/pyproject.toml +0 -0
  14. {termrender-3.0.2 → termrender-4.0.0}/requirements.json +0 -0
  15. {termrender-3.0.2 → termrender-4.0.0}/scripts/build-mermaid-ascii.sh +0 -0
  16. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/__init__.py +0 -0
  17. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/_bin/mermaid-ascii-darwin-arm64 +0 -0
  18. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/_mermaid_bin.py +0 -0
  19. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/blocks.py +0 -0
  20. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/emit.py +0 -0
  21. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/layout.py +0 -0
  22. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/py.typed +0 -0
  23. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/CLAUDE.md +0 -0
  24. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/__init__.py +0 -0
  25. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/borders.py +0 -0
  26. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/charts.py +0 -0
  27. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/code.py +0 -0
  28. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/columns.py +0 -0
  29. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/diff.py +0 -0
  30. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/divider.py +0 -0
  31. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/mermaid.py +0 -0
  32. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/panel.py +0 -0
  33. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/quote.py +0 -0
  34. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/stat.py +0 -0
  35. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/table.py +0 -0
  36. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/text.py +0 -0
  37. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/timeline.py +0 -0
  38. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/renderers/tree.py +0 -0
  39. {termrender-3.0.2 → termrender-4.0.0}/src/termrender/style.py +0 -0
  40. {termrender-3.0.2 → termrender-4.0.0}/tests/__init__.py +0 -0
  41. {termrender-3.0.2 → termrender-4.0.0}/tests/test_charts.py +0 -0
  42. {termrender-3.0.2 → termrender-4.0.0}/tests/test_cli_contract.py +0 -0
  43. {termrender-3.0.2 → termrender-4.0.0}/tests/test_column_alignment.py +0 -0
  44. {termrender-3.0.2 → termrender-4.0.0}/tests/test_diff.py +0 -0
  45. {termrender-3.0.2 → termrender-4.0.0}/tests/test_inline_badge.py +0 -0
  46. {termrender-3.0.2 → termrender-4.0.0}/tests/test_linebreak.py +0 -0
  47. {termrender-3.0.2 → termrender-4.0.0}/tests/test_mermaid_compat.py +0 -0
  48. {termrender-3.0.2 → termrender-4.0.0}/tests/test_stat.py +0 -0
  49. {termrender-3.0.2 → termrender-4.0.0}/tests/test_tasklist.py +0 -0
  50. {termrender-3.0.2 → termrender-4.0.0}/tests/test_timeline.py +0 -0
  51. {termrender-3.0.2 → termrender-4.0.0}/tests/test_variable_colons.py +0 -0
  52. {termrender-3.0.2 → termrender-4.0.0}/uv.lock +0 -0
@@ -1,6 +1,31 @@
1
1
  # CHANGELOG
2
2
 
3
3
 
4
+ ## v4.0.0 (2026-07-06)
5
+
6
+ ### Features
7
+
8
+ - **mermaid**: Also route ```mermaid fences through the mermaid renderer
9
+ ([`99a8017`](https://github.com/crouton-labs/termrender/commit/99a801783d719125505eef2dc1194e2e418ed025))
10
+
11
+ BREAKING CHANGE: partially reverses 083f590. A fenced code block whose info string is `mermaid`
12
+ (e.g. GFM ````mermaid```` fences used by GitHub and most docs/agents unaware of the :::mermaid
13
+ directive) now renders as an ASCII mermaid diagram, same as :::mermaid. Any other language tag
14
+ still falls through to a plain CODE block; the :::mermaid directive is unchanged.
15
+
16
+ Root-caused: the reported bug (fences render as raw source, not a diagram) was not a regression or
17
+ missing binary — the vendored mermaid-ascii binary and subprocess pipeline both work correctly. It
18
+ was 083f590's deliberate, documented breaking change dropping fence support. Human chose to extend
19
+ support back to fences rather than close as working-as-intended.
20
+
21
+ ### Breaking Changes
22
+
23
+ - **mermaid**: Partially reverses 083f590. A fenced code block whose info string is `mermaid` (e.g.
24
+ GFM ````mermaid```` fences used by GitHub and most docs/agents unaware of the :::mermaid
25
+ directive) now renders as an ASCII mermaid diagram, same as :::mermaid. Any other language tag
26
+ still falls through to a plain CODE block; the :::mermaid directive is unchanged.
27
+
28
+
4
29
  ## v3.0.2 (2026-06-17)
5
30
 
6
31
  ### Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: termrender
3
- Version: 3.0.2
3
+ Version: 4.0.0
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
@@ -408,7 +408,7 @@ Horizontal rules with optional centered labels.
408
408
 
409
409
  ### Mermaid diagrams
410
410
 
411
- Renders mermaid flowcharts as ASCII art via [mermaid-ascii](https://github.com/mermaid-js/mermaid-ascii). Mermaid uses the `:::mermaid` directive backtick fences (`` ```mermaid ``) are treated as plain code blocks.
411
+ Renders mermaid flowcharts as ASCII art via [mermaid-ascii](https://github.com/mermaid-js/mermaid-ascii). Use the `:::mermaid` directive, or a standard GFM ` ```mermaid ` fenced code block both render the same diagram.
412
412
 
413
413
  **Input:**
414
414
  ```markdown
@@ -380,7 +380,7 @@ Horizontal rules with optional centered labels.
380
380
 
381
381
  ### Mermaid diagrams
382
382
 
383
- Renders mermaid flowcharts as ASCII art via [mermaid-ascii](https://github.com/mermaid-js/mermaid-ascii). Mermaid uses the `:::mermaid` directive backtick fences (`` ```mermaid ``) are treated as plain code blocks.
383
+ Renders mermaid flowcharts as ASCII art via [mermaid-ascii](https://github.com/mermaid-js/mermaid-ascii). Use the `:::mermaid` directive, or a standard GFM ` ```mermaid ` fenced code block both render the same diagram.
384
384
 
385
385
  **Input:**
386
386
  ```markdown
@@ -1,2 +1,3 @@
1
1
  - **Nesting is by colon count** (`parser.py`, since `4a501d9`): an outer directive must use strictly MORE colons than the directive nested inside it — `::::columns` (4) wraps `:::col` (3); a leaf closes with a bare run of its own colon count. Equal-colon nesting is a `syntax_error` (the closer matches the wrong opener). Mirrors MyST colon fences. All docs/examples must follow this — `termrender doc check` is the gate.
2
2
  - **QUOTE** height gets `+1` only when `author` or `by` attr is set. Using any other key (`attribution`, `source`) silently omits the extra line — the renderer's attribution line is clipped.
3
+ - **``` mermaid fences and `:::mermaid` both produce `BlockType.MERMAID`** (`parser.py::_convert_ast`, block_code handling): a fenced code block whose info string's first word is `mermaid` (case-insensitive) is special-cased to `BlockType.MERMAID` instead of `BlockType.CODE`, so GFM-style ``` ```mermaid ``` docs render the same as the directive form. This was a deliberate reversal of `083f590` (which had dropped fence support); any other language tag still falls through to a plain CODE block.
@@ -78,7 +78,7 @@ Document format
78
78
  :::divider{label=""} labeled horizontal rule
79
79
  :::code{lang=""} syntax-highlighted block (``` fences also work)
80
80
  :::quote{author=""} attributed block quote
81
- :::mermaid flowchart → ASCII (NOT ```mermaid fences)
81
+ :::mermaid flowchart → ASCII (``` mermaid fences also work)
82
82
  """
83
83
 
84
84
  _DOC_RENDER_HELP = """\
@@ -303,10 +303,21 @@ def _convert_ast(nodes: list[dict], _depth: int = 0) -> list[Block]:
303
303
  elif ntype == "block_code":
304
304
  raw = node.get("raw", "")
305
305
  info = node.get("attrs", {}).get("info", "")
306
- blocks.append(Block(
307
- type=BlockType.CODE,
308
- attrs={"lang": info, "source": raw},
309
- ))
306
+ # A ```mermaid fence is GFM's standard way to tag a mermaid diagram
307
+ # (GitHub, and most docs/agents that don't know this project's
308
+ # :::mermaid directive, use this form) — route it through the
309
+ # mermaid renderer same as :::mermaid, instead of a plain code panel.
310
+ lang = info.split()[0].lower() if info.split() else ""
311
+ if lang == "mermaid":
312
+ blocks.append(Block(
313
+ type=BlockType.MERMAID,
314
+ attrs={"source": raw},
315
+ ))
316
+ else:
317
+ blocks.append(Block(
318
+ type=BlockType.CODE,
319
+ attrs={"lang": info, "source": raw},
320
+ ))
310
321
 
311
322
  elif ntype == "list":
312
323
  ordered = node.get("attrs", {}).get("ordered", False)
@@ -7,7 +7,7 @@ from termrender.parser import parse, _strip_options
7
7
 
8
8
 
9
9
  class TestMermaidDirective(unittest.TestCase):
10
- """:::mermaid is the only fence form for mermaid diagrams."""
10
+ """:::mermaid and ```mermaid fences both produce mermaid diagrams."""
11
11
 
12
12
  def test_basic_mermaid_directive(self):
13
13
  """:::mermaid\ngraph LR\nA-->B\n::: → BlockType.MERMAID"""
@@ -26,12 +26,12 @@ class TestMermaidDirective(unittest.TestCase):
26
26
  self.assertIn("graph LR", block.attrs["source"])
27
27
  self.assertNotIn(":title:", block.attrs["source"])
28
28
 
29
- def test_backtick_mermaid_is_plain_code_block(self):
30
- """```mermaid is no longer a mermaid block it renders as a code block."""
29
+ def test_backtick_mermaid_is_mermaid_block(self):
30
+ """```mermaid fences route through the mermaid renderer, same as :::mermaid."""
31
31
  doc = parse("```mermaid\ngraph LR\nA-->B\n```")
32
32
  block = doc.children[0]
33
- self.assertEqual(block.type, BlockType.CODE)
34
- self.assertEqual(block.attrs.get("lang"), "mermaid")
33
+ self.assertEqual(block.type, BlockType.MERMAID)
34
+ self.assertIn("graph LR", block.attrs["source"])
35
35
 
36
36
  def test_backtick_directive_is_plain_code_block(self):
37
37
  """```{panel} is no longer a directive — it renders as a code block."""
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes