termaid 0.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.
Files changed (233) hide show
  1. termaid-0.1.1/.github/workflows/ci.yml +29 -0
  2. termaid-0.1.1/.github/workflows/publish.yml +22 -0
  3. termaid-0.1.1/.gitignore +10 -0
  4. termaid-0.1.1/CHANGELOG.md +34 -0
  5. termaid-0.1.1/CONTRIBUTING.md +73 -0
  6. termaid-0.1.1/LICENSE +21 -0
  7. termaid-0.1.1/PKG-INFO +416 -0
  8. termaid-0.1.1/README.md +390 -0
  9. termaid-0.1.1/demo/demo.tape +44 -0
  10. termaid-0.1.1/demo/flowchart.mmd +6 -0
  11. termaid-0.1.1/demo/gitgraph.mmd +10 -0
  12. termaid-0.1.1/demo/sequence.mmd +13 -0
  13. termaid-0.1.1/demo/termaid-demo.gif +0 -0
  14. termaid-0.1.1/pyproject.toml +40 -0
  15. termaid-0.1.1/src/termaid/__init__.py +178 -0
  16. termaid-0.1.1/src/termaid/__main__.py +4 -0
  17. termaid-0.1.1/src/termaid/cli.py +129 -0
  18. termaid-0.1.1/src/termaid/graph/__init__.py +4 -0
  19. termaid-0.1.1/src/termaid/graph/model.py +185 -0
  20. termaid-0.1.1/src/termaid/graph/shapes.py +22 -0
  21. termaid-0.1.1/src/termaid/layout/__init__.py +3 -0
  22. termaid-0.1.1/src/termaid/layout/grid.py +879 -0
  23. termaid-0.1.1/src/termaid/model/__init__.py +0 -0
  24. termaid-0.1.1/src/termaid/model/blockdiagram.py +30 -0
  25. termaid-0.1.1/src/termaid/model/classdiagram.py +47 -0
  26. termaid-0.1.1/src/termaid/model/erdiagram.py +41 -0
  27. termaid-0.1.1/src/termaid/model/gitgraph.py +30 -0
  28. termaid-0.1.1/src/termaid/model/sequence.py +66 -0
  29. termaid-0.1.1/src/termaid/output/__init__.py +3 -0
  30. termaid-0.1.1/src/termaid/output/rich.py +202 -0
  31. termaid-0.1.1/src/termaid/output/text.py +16 -0
  32. termaid-0.1.1/src/termaid/output/widget.py +42 -0
  33. termaid-0.1.1/src/termaid/parser/__init__.py +4 -0
  34. termaid-0.1.1/src/termaid/parser/blockdiagram.py +299 -0
  35. termaid-0.1.1/src/termaid/parser/classdiagram.py +255 -0
  36. termaid-0.1.1/src/termaid/parser/erdiagram.py +246 -0
  37. termaid-0.1.1/src/termaid/parser/flowchart.py +796 -0
  38. termaid-0.1.1/src/termaid/parser/gitgraph.py +328 -0
  39. termaid-0.1.1/src/termaid/parser/sequence.py +249 -0
  40. termaid-0.1.1/src/termaid/parser/statediagram.py +203 -0
  41. termaid-0.1.1/src/termaid/parser/tokens.py +53 -0
  42. termaid-0.1.1/src/termaid/py.typed +0 -0
  43. termaid-0.1.1/src/termaid/renderer/__init__.py +3 -0
  44. termaid-0.1.1/src/termaid/renderer/blockdiagram.py +463 -0
  45. termaid-0.1.1/src/termaid/renderer/canvas.py +254 -0
  46. termaid-0.1.1/src/termaid/renderer/charset.py +130 -0
  47. termaid-0.1.1/src/termaid/renderer/classdiagram.py +724 -0
  48. termaid-0.1.1/src/termaid/renderer/draw.py +662 -0
  49. termaid-0.1.1/src/termaid/renderer/erdiagram.py +497 -0
  50. termaid-0.1.1/src/termaid/renderer/gitgraph.py +414 -0
  51. termaid-0.1.1/src/termaid/renderer/sequence.py +860 -0
  52. termaid-0.1.1/src/termaid/renderer/shapes/__init__.py +456 -0
  53. termaid-0.1.1/src/termaid/renderer/themes.py +87 -0
  54. termaid-0.1.1/src/termaid/routing/__init__.py +3 -0
  55. termaid-0.1.1/src/termaid/routing/pathfinder.py +156 -0
  56. termaid-0.1.1/src/termaid/routing/router.py +281 -0
  57. termaid-0.1.1/tests/__init__.py +0 -0
  58. termaid-0.1.1/tests/conftest.py +119 -0
  59. termaid-0.1.1/tests/fixtures/blockdiagram/basic.mmd +3 -0
  60. termaid-0.1.1/tests/fixtures/blockdiagram/col_span.mmd +4 -0
  61. termaid-0.1.1/tests/fixtures/blockdiagram/grid.mmd +4 -0
  62. termaid-0.1.1/tests/fixtures/blockdiagram/links.mmd +4 -0
  63. termaid-0.1.1/tests/fixtures/classdiagram/annotation.mmd +12 -0
  64. termaid-0.1.1/tests/fixtures/classdiagram/basic.mmd +6 -0
  65. termaid-0.1.1/tests/fixtures/classdiagram/inheritance.mmd +10 -0
  66. termaid-0.1.1/tests/fixtures/classdiagram/relationships.mmd +8 -0
  67. termaid-0.1.1/tests/fixtures/erdiagram/attributes.mmd +12 -0
  68. termaid-0.1.1/tests/fixtures/erdiagram/basic.mmd +3 -0
  69. termaid-0.1.1/tests/fixtures/erdiagram/dashed.mmd +3 -0
  70. termaid-0.1.1/tests/fixtures/erdiagram/multiple_entities.mmd +4 -0
  71. termaid-0.1.1/tests/fixtures/expected/all_shapes.txt +45 -0
  72. termaid-0.1.1/tests/fixtures/expected/ampersand_both.txt +13 -0
  73. termaid-0.1.1/tests/fixtures/expected/backlink_complex.txt +13 -0
  74. termaid-0.1.1/tests/fixtures/expected/bidir_dotted.txt +5 -0
  75. termaid-0.1.1/tests/fixtures/expected/bidir_labeled.txt +5 -0
  76. termaid-0.1.1/tests/fixtures/expected/bidir_td.txt +13 -0
  77. termaid-0.1.1/tests/fixtures/expected/bidir_thick.txt +5 -0
  78. termaid-0.1.1/tests/fixtures/expected/bidirectional.txt +5 -0
  79. termaid-0.1.1/tests/fixtures/expected/blockdiagram/basic.txt +7 -0
  80. termaid-0.1.1/tests/fixtures/expected/blockdiagram/col_span.txt +14 -0
  81. termaid-0.1.1/tests/fixtures/expected/blockdiagram/grid.txt +14 -0
  82. termaid-0.1.1/tests/fixtures/expected/blockdiagram/links.txt +7 -0
  83. termaid-0.1.1/tests/fixtures/expected/branching.txt +13 -0
  84. termaid-0.1.1/tests/fixtures/expected/chain.txt +5 -0
  85. termaid-0.1.1/tests/fixtures/expected/classdiagram/annotation.txt +21 -0
  86. termaid-0.1.1/tests/fixtures/expected/classdiagram/basic.txt +10 -0
  87. termaid-0.1.1/tests/fixtures/expected/classdiagram/inheritance.txt +20 -0
  88. termaid-0.1.1/tests/fixtures/expected/classdiagram/relationships.txt +19 -0
  89. termaid-0.1.1/tests/fixtures/expected/comments.txt +5 -0
  90. termaid-0.1.1/tests/fixtures/expected/cycle.txt +7 -0
  91. termaid-0.1.1/tests/fixtures/expected/diamond.txt +23 -0
  92. termaid-0.1.1/tests/fixtures/expected/dotted_arrow.txt +5 -0
  93. termaid-0.1.1/tests/fixtures/expected/duplicate_labels.txt +13 -0
  94. termaid-0.1.1/tests/fixtures/expected/empty_graph.txt +5 -0
  95. termaid-0.1.1/tests/fixtures/expected/erdiagram/attributes.txt +20 -0
  96. termaid-0.1.1/tests/fixtures/expected/erdiagram/basic.txt +19 -0
  97. termaid-0.1.1/tests/fixtures/expected/erdiagram/dashed.txt +12 -0
  98. termaid-0.1.1/tests/fixtures/expected/erdiagram/multiple_entities.txt +12 -0
  99. termaid-0.1.1/tests/fixtures/expected/fan_in.txt +13 -0
  100. termaid-0.1.1/tests/fixtures/expected/fan_out.txt +13 -0
  101. termaid-0.1.1/tests/fixtures/expected/flowchart_keyword.txt +5 -0
  102. termaid-0.1.1/tests/fixtures/expected/gitgraph/cherry_pick.txt +7 -0
  103. termaid-0.1.1/tests/fixtures/expected/gitgraph/feature_branch.txt +7 -0
  104. termaid-0.1.1/tests/fixtures/expected/gitgraph/linear.txt +4 -0
  105. termaid-0.1.1/tests/fixtures/expected/gitgraph/tags.txt +4 -0
  106. termaid-0.1.1/tests/fixtures/expected/gitgraph/tb_direction.txt +18 -0
  107. termaid-0.1.1/tests/fixtures/expected/graph_bt.txt +25 -0
  108. termaid-0.1.1/tests/fixtures/expected/graph_rl.txt +5 -0
  109. termaid-0.1.1/tests/fixtures/expected/labeled_edges.txt +13 -0
  110. termaid-0.1.1/tests/fixtures/expected/large_graph.txt +53 -0
  111. termaid-0.1.1/tests/fixtures/expected/long_labels.txt +7 -0
  112. termaid-0.1.1/tests/fixtures/expected/mermaid_comprehensive.txt +13 -0
  113. termaid-0.1.1/tests/fixtures/expected/mixed_arrow_styles.txt +5 -0
  114. termaid-0.1.1/tests/fixtures/expected/multiple_links.txt +21 -0
  115. termaid-0.1.1/tests/fixtures/expected/no_arrow_dotted.txt +5 -0
  116. termaid-0.1.1/tests/fixtures/expected/no_arrow_solid.txt +5 -0
  117. termaid-0.1.1/tests/fixtures/expected/no_arrow_thick.txt +5 -0
  118. termaid-0.1.1/tests/fixtures/expected/node_with_label.txt +5 -0
  119. termaid-0.1.1/tests/fixtures/expected/parallelogram.txt +5 -0
  120. termaid-0.1.1/tests/fixtures/expected/self_ref_with_edge.txt +5 -0
  121. termaid-0.1.1/tests/fixtures/expected/self_reference.txt +5 -0
  122. termaid-0.1.1/tests/fixtures/expected/semicolons.txt +5 -0
  123. termaid-0.1.1/tests/fixtures/expected/sequence/arrows.txt +16 -0
  124. termaid-0.1.1/tests/fixtures/expected/sequence/autonumber.txt +12 -0
  125. termaid-0.1.1/tests/fixtures/expected/sequence/basic.txt +12 -0
  126. termaid-0.1.1/tests/fixtures/expected/sequence/multiline_notes.txt +19 -0
  127. termaid-0.1.1/tests/fixtures/expected/sequence/nested_blocks.txt +22 -0
  128. termaid-0.1.1/tests/fixtures/expected/sequence/notes.txt +16 -0
  129. termaid-0.1.1/tests/fixtures/expected/sequence/participant_kinds.txt +14 -0
  130. termaid-0.1.1/tests/fixtures/expected/sequence/self_message.txt +12 -0
  131. termaid-0.1.1/tests/fixtures/expected/simple_lr.txt +5 -0
  132. termaid-0.1.1/tests/fixtures/expected/simple_tb.txt +13 -0
  133. termaid-0.1.1/tests/fixtures/expected/simple_td.txt +13 -0
  134. termaid-0.1.1/tests/fixtures/expected/single_node.txt +5 -0
  135. termaid-0.1.1/tests/fixtures/expected/statediagram/basic.txt +21 -0
  136. termaid-0.1.1/tests/fixtures/expected/statediagram/choice.txt +31 -0
  137. termaid-0.1.1/tests/fixtures/expected/statediagram/composite.txt +28 -0
  138. termaid-0.1.1/tests/fixtures/expected/statediagram/start_end.txt +29 -0
  139. termaid-0.1.1/tests/fixtures/expected/subgraph_basic.txt +12 -0
  140. termaid-0.1.1/tests/fixtures/expected/subgraph_nested.txt +27 -0
  141. termaid-0.1.1/tests/fixtures/expected/subgraph_three_levels.txt +24 -0
  142. termaid-0.1.1/tests/fixtures/expected/subgraph_two_separate.txt +12 -0
  143. termaid-0.1.1/tests/fixtures/expected/subgraph_with_labels.txt +12 -0
  144. termaid-0.1.1/tests/fixtures/expected/thick_arrow.txt +5 -0
  145. termaid-0.1.1/tests/fixtures/expected/three_nodes_inline.txt +5 -0
  146. termaid-0.1.1/tests/fixtures/expected/trapezoid.txt +5 -0
  147. termaid-0.1.1/tests/fixtures/expected/two_roots.txt +13 -0
  148. termaid-0.1.1/tests/fixtures/expected/unicode_labels.txt +5 -0
  149. termaid-0.1.1/tests/fixtures/flowcharts/all_shapes.mmd +7 -0
  150. termaid-0.1.1/tests/fixtures/flowcharts/ampersand_both.mmd +2 -0
  151. termaid-0.1.1/tests/fixtures/flowcharts/backlink_complex.mmd +6 -0
  152. termaid-0.1.1/tests/fixtures/flowcharts/bidir_dotted.mmd +2 -0
  153. termaid-0.1.1/tests/fixtures/flowcharts/bidir_labeled.mmd +2 -0
  154. termaid-0.1.1/tests/fixtures/flowcharts/bidir_td.mmd +2 -0
  155. termaid-0.1.1/tests/fixtures/flowcharts/bidir_thick.mmd +2 -0
  156. termaid-0.1.1/tests/fixtures/flowcharts/bidirectional.mmd +2 -0
  157. termaid-0.1.1/tests/fixtures/flowcharts/branching.mmd +2 -0
  158. termaid-0.1.1/tests/fixtures/flowcharts/chain.mmd +2 -0
  159. termaid-0.1.1/tests/fixtures/flowcharts/comments.mmd +5 -0
  160. termaid-0.1.1/tests/fixtures/flowcharts/cycle.mmd +2 -0
  161. termaid-0.1.1/tests/fixtures/flowcharts/diamond.mmd +4 -0
  162. termaid-0.1.1/tests/fixtures/flowcharts/dotted_arrow.mmd +2 -0
  163. termaid-0.1.1/tests/fixtures/flowcharts/duplicate_labels.mmd +3 -0
  164. termaid-0.1.1/tests/fixtures/flowcharts/empty_graph.mmd +2 -0
  165. termaid-0.1.1/tests/fixtures/flowcharts/fan_in.mmd +2 -0
  166. termaid-0.1.1/tests/fixtures/flowcharts/fan_out.mmd +2 -0
  167. termaid-0.1.1/tests/fixtures/flowcharts/flowchart_keyword.mmd +3 -0
  168. termaid-0.1.1/tests/fixtures/flowcharts/graph_bt.mmd +2 -0
  169. termaid-0.1.1/tests/fixtures/flowcharts/graph_rl.mmd +2 -0
  170. termaid-0.1.1/tests/fixtures/flowcharts/labeled_edges.mmd +3 -0
  171. termaid-0.1.1/tests/fixtures/flowcharts/large_graph.mmd +17 -0
  172. termaid-0.1.1/tests/fixtures/flowcharts/long_labels.mmd +2 -0
  173. termaid-0.1.1/tests/fixtures/flowcharts/mermaid_comprehensive.mmd +5 -0
  174. termaid-0.1.1/tests/fixtures/flowcharts/mixed_arrow_styles.mmd +4 -0
  175. termaid-0.1.1/tests/fixtures/flowcharts/multiple_links.mmd +2 -0
  176. termaid-0.1.1/tests/fixtures/flowcharts/no_arrow_dotted.mmd +2 -0
  177. termaid-0.1.1/tests/fixtures/flowcharts/no_arrow_solid.mmd +2 -0
  178. termaid-0.1.1/tests/fixtures/flowcharts/no_arrow_thick.mmd +2 -0
  179. termaid-0.1.1/tests/fixtures/flowcharts/node_with_label.mmd +2 -0
  180. termaid-0.1.1/tests/fixtures/flowcharts/parallelogram.mmd +2 -0
  181. termaid-0.1.1/tests/fixtures/flowcharts/self_ref_with_edge.mmd +2 -0
  182. termaid-0.1.1/tests/fixtures/flowcharts/self_reference.mmd +2 -0
  183. termaid-0.1.1/tests/fixtures/flowcharts/semicolons.mmd +2 -0
  184. termaid-0.1.1/tests/fixtures/flowcharts/simple_lr.mmd +2 -0
  185. termaid-0.1.1/tests/fixtures/flowcharts/simple_tb.mmd +2 -0
  186. termaid-0.1.1/tests/fixtures/flowcharts/simple_td.mmd +2 -0
  187. termaid-0.1.1/tests/fixtures/flowcharts/single_node.mmd +2 -0
  188. termaid-0.1.1/tests/fixtures/flowcharts/subgraph_basic.mmd +5 -0
  189. termaid-0.1.1/tests/fixtures/flowcharts/subgraph_nested.mmd +8 -0
  190. termaid-0.1.1/tests/fixtures/flowcharts/subgraph_three_levels.mmd +8 -0
  191. termaid-0.1.1/tests/fixtures/flowcharts/subgraph_two_separate.mmd +8 -0
  192. termaid-0.1.1/tests/fixtures/flowcharts/subgraph_with_labels.mmd +8 -0
  193. termaid-0.1.1/tests/fixtures/flowcharts/thick_arrow.mmd +2 -0
  194. termaid-0.1.1/tests/fixtures/flowcharts/three_nodes_inline.mmd +2 -0
  195. termaid-0.1.1/tests/fixtures/flowcharts/trapezoid.mmd +2 -0
  196. termaid-0.1.1/tests/fixtures/flowcharts/two_roots.mmd +3 -0
  197. termaid-0.1.1/tests/fixtures/flowcharts/unicode_labels.mmd +2 -0
  198. termaid-0.1.1/tests/fixtures/gitgraph/cherry_pick.mmd +6 -0
  199. termaid-0.1.1/tests/fixtures/gitgraph/feature_branch.mmd +9 -0
  200. termaid-0.1.1/tests/fixtures/gitgraph/linear.mmd +4 -0
  201. termaid-0.1.1/tests/fixtures/gitgraph/tags.mmd +4 -0
  202. termaid-0.1.1/tests/fixtures/gitgraph/tb_direction.mmd +7 -0
  203. termaid-0.1.1/tests/fixtures/sequence/arrows.mmd +7 -0
  204. termaid-0.1.1/tests/fixtures/sequence/autonumber.mmd +6 -0
  205. termaid-0.1.1/tests/fixtures/sequence/basic.mmd +5 -0
  206. termaid-0.1.1/tests/fixtures/sequence/multiline_notes.mmd +5 -0
  207. termaid-0.1.1/tests/fixtures/sequence/nested_blocks.mmd +9 -0
  208. termaid-0.1.1/tests/fixtures/sequence/notes.mmd +5 -0
  209. termaid-0.1.1/tests/fixtures/sequence/participant_kinds.mmd +8 -0
  210. termaid-0.1.1/tests/fixtures/sequence/self_message.mmd +5 -0
  211. termaid-0.1.1/tests/fixtures/statediagram/basic.mmd +4 -0
  212. termaid-0.1.1/tests/fixtures/statediagram/choice.mmd +6 -0
  213. termaid-0.1.1/tests/fixtures/statediagram/composite.mmd +7 -0
  214. termaid-0.1.1/tests/fixtures/statediagram/start_end.mmd +4 -0
  215. termaid-0.1.1/tests/test_blockdiagram.py +178 -0
  216. termaid-0.1.1/tests/test_classdiagram.py +254 -0
  217. termaid-0.1.1/tests/test_cli.py +81 -0
  218. termaid-0.1.1/tests/test_edge_styles.py +266 -0
  219. termaid-0.1.1/tests/test_erdiagram.py +221 -0
  220. termaid-0.1.1/tests/test_gitgraph.py +423 -0
  221. termaid-0.1.1/tests/test_integration.py +343 -0
  222. termaid-0.1.1/tests/test_layout.py +143 -0
  223. termaid-0.1.1/tests/test_parser.py +332 -0
  224. termaid-0.1.1/tests/test_parser_comprehensive.py +347 -0
  225. termaid-0.1.1/tests/test_renderer.py +167 -0
  226. termaid-0.1.1/tests/test_routing.py +143 -0
  227. termaid-0.1.1/tests/test_sequence.py +706 -0
  228. termaid-0.1.1/tests/test_shapes.py +120 -0
  229. termaid-0.1.1/tests/test_snapshots.py +94 -0
  230. termaid-0.1.1/tests/test_state_diagram.py +301 -0
  231. termaid-0.1.1/tests/test_themes.py +119 -0
  232. termaid-0.1.1/tests/test_warnings.py +120 -0
  233. termaid-0.1.1/uv.lock +209 -0
@@ -0,0 +1,29 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.11", "3.12", "3.13"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Install uv
20
+ uses: astral-sh/setup-uv@v4
21
+
22
+ - name: Set up Python ${{ matrix.python-version }}
23
+ run: uv python install ${{ matrix.python-version }}
24
+
25
+ - name: Install dependencies
26
+ run: uv sync --all-extras
27
+
28
+ - name: Run tests
29
+ run: uv run pytest tests/ -q
@@ -0,0 +1,22 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ permissions:
11
+ id-token: write
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+
15
+ - name: Install uv
16
+ uses: astral-sh/setup-uv@v4
17
+
18
+ - name: Build
19
+ run: uv build
20
+
21
+ - name: Publish to PyPI
22
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,10 @@
1
+ .DS_Store
2
+ __pycache__/
3
+ *.pyc
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .venv/
8
+ .pytest_cache/
9
+ # Scratch diagram files in root
10
+ /*.mmd
@@ -0,0 +1,34 @@
1
+ # Changelog
2
+
3
+ ## 0.1.1 (2026-03-04)
4
+
5
+ - Rename package from `termmaid` to `termaid`
6
+
7
+ ## 0.1.0 (2026-03-04)
8
+
9
+ Initial release.
10
+
11
+ ### Features
12
+
13
+ - **7 diagram types:** flowcharts, sequence, class, ER, state, block, and git graphs
14
+ - **Flowcharts** (`graph`/`flowchart`) with all 5 directions (`LR`, `RL`, `TD`/`TB`, `BT`)
15
+ - **Sequence diagrams** with participants, actors, solid/dashed messages
16
+ - **Class diagrams** with attributes, methods, visibility, and 6 relationship types
17
+ - **ER diagrams** with cardinality, attributes, keys, and relationship labels
18
+ - **State diagrams** (`stateDiagram-v2`) with transitions, composite states, stereotypes
19
+ - **Block diagrams** (`block-beta`) with column layout and spanning
20
+ - **Git graphs** (`gitGraph`) with branches, merges, cherry-picks, tags, and 3 orientations
21
+ - 14 flowchart node shapes: rectangle, rounded, stadium, subroutine, diamond, hexagon, circle, double circle, asymmetric, cylinder, parallelogram, parallelogram alt, trapezoid, trapezoid alt
22
+ - 3 edge styles: solid, dotted, thick
23
+ - Bidirectional edges (`<-->`, `<-.->`, `<==>`)
24
+ - Edge labels (`-->|label|`)
25
+ - Subgraphs with nesting and cross-boundary edges
26
+ - `classDef`, `style`, and `linkStyle` directives
27
+ - `@{shape}` node syntax
28
+ - Link length control (`--->`, `---->`)
29
+ - Markdown labels (`**bold**`, `*italic*`)
30
+ - ASCII mode (`--ascii`) for terminals without Unicode support
31
+ - Colored output via Rich (`--color`) with 6 built-in themes
32
+ - Textual widget for TUI applications
33
+ - CLI tool with stdin/file input
34
+ - Pure Python, zero runtime dependencies
@@ -0,0 +1,73 @@
1
+ # Contributing to termaid
2
+
3
+ ## Development setup
4
+
5
+ ```bash
6
+ git clone https://github.com/fasouto/termaid.git
7
+ cd termaid
8
+ uv sync --all-extras
9
+ ```
10
+
11
+ ## Running tests
12
+
13
+ ```bash
14
+ uv run pytest tests/ -q
15
+ ```
16
+
17
+ To update snapshot tests after changing rendering output:
18
+
19
+ ```bash
20
+ uv run pytest tests/ --update-snapshots
21
+ ```
22
+
23
+ ## Project structure
24
+
25
+ ```
26
+ src/termaid/
27
+ __init__.py # Public API: render(), render_rich(), parse()
28
+ cli.py # CLI entry point (argparse)
29
+ graph/ # Graph data model (Node, Edge, Subgraph, NodeShape)
30
+ model/ # Diagram-specific models (sequence, class, ER, block, gitgraph)
31
+ parser/ # Mermaid syntax parsers (one per diagram type)
32
+ layout/ # Grid-based layout computation (flowcharts)
33
+ routing/ # A* edge routing (flowcharts)
34
+ renderer/ # Canvas rendering, shapes, charsets, themes
35
+ output/ # Output formats (text, rich, textual widget)
36
+ tests/
37
+ fixtures/flowcharts/ # .mmd input fixtures + expected .txt outputs
38
+ ```
39
+
40
+ ### Architecture
41
+
42
+ There are two rendering paths:
43
+
44
+ **Path A — Flowcharts and state diagrams** use the shared `Graph` model with the grid layout engine and A* edge routing (`layout/` + `routing/` + `renderer/draw.py`).
45
+
46
+ **Path B — All other diagram types** (sequence, class, ER, block, git graph) have their own model (`model/`), parser (`parser/`), and renderer (`renderer/`) that draw directly onto a `Canvas`.
47
+
48
+ ### Diagram dispatch
49
+
50
+ Both `render()` and `render_rich()` auto-detect the diagram type from the source text prefix (e.g. `sequenceDiagram`, `classDiagram`, `gitGraph`) and dispatch to the appropriate parser + renderer.
51
+
52
+ ## Adding a new diagram type
53
+
54
+ 1. Create the model in `src/termaid/model/yourdiagram.py` (dataclasses)
55
+ 2. Create the parser in `src/termaid/parser/yourdiagram.py`
56
+ 3. Create the renderer in `src/termaid/renderer/yourdiagram.py` (returns a `Canvas`)
57
+ 4. Add dispatch in `src/termaid/__init__.py` (both `render()` and `render_rich()`)
58
+ 5. Add tests
59
+
60
+ ## Adding a new node shape
61
+
62
+ 1. Add the shape to `NodeShape` enum in `src/termaid/graph/shapes.py`
63
+ 2. Add parser detection in `src/termaid/parser/flowchart.py` (`_parse_node`)
64
+ 3. Add renderer in `src/termaid/renderer/shapes/__init__.py`
65
+ 4. Register in `SHAPE_RENDERERS` dict
66
+ 5. Add tests in `tests/test_shapes.py`
67
+
68
+ ## Adding a test fixture
69
+
70
+ 1. Create `tests/fixtures/flowcharts/my_test.mmd`
71
+ 2. Run `uv run pytest tests/test_renderer.py -q` — it auto-generates the expected output
72
+ 3. Review the generated `.txt` file in `tests/fixtures/expected/`
73
+ 4. Run again to confirm it passes
termaid-0.1.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fabio Souto
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
termaid-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,416 @@
1
+ Metadata-Version: 2.4
2
+ Name: termaid
3
+ Version: 0.1.1
4
+ Summary: Render Mermaid diagram syntax as beautiful Unicode art in the terminal
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ Keywords: ascii,diagram,flowchart,mermaid,terminal,unicode
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Topic :: Text Processing :: General
16
+ Classifier: Topic :: Utilities
17
+ Requires-Python: >=3.11
18
+ Provides-Extra: dev
19
+ Requires-Dist: pytest-snapshot; extra == 'dev'
20
+ Requires-Dist: pytest>=7.0; extra == 'dev'
21
+ Provides-Extra: rich
22
+ Requires-Dist: rich>=13.0; extra == 'rich'
23
+ Provides-Extra: textual
24
+ Requires-Dist: textual>=0.40; extra == 'textual'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # termaid
28
+
29
+ Terminal-native Mermaid rendering for Python.
30
+
31
+ <p align="center">
32
+ <img src="demo/termaid-demo.gif" alt="termaid demo" width="800">
33
+ </p>
34
+
35
+ Render [Mermaid](https://mermaid.js.org/) diagrams as Unicode art directly in your terminal. Pure Python, zero dependencies.
36
+
37
+ ## Features
38
+
39
+ - **7 diagram types:** flowcharts, sequence, class, ER, state, block, and git graphs
40
+ - **Zero dependencies:** pure Python, nothing to install beyond the package itself
41
+ - **Rich and Textual integration:** colored output and TUI widgets with optional extras
42
+ - **6 color themes:** default, terra, neon, mono, amber, phosphor
43
+ - **ASCII fallback:** works on any terminal, even the most basic ones
44
+ - **Pipe-friendly CLI:** `cat diagram.mmd | termaid` just works
45
+
46
+ ## Why?
47
+
48
+ Mermaid is great for documentation, but rendering it usually means spinning up a browser or calling an external service. termaid lets you render diagrams over SSH, in CI logs, inside TUI apps, or anywhere you have a Python environment. It was built because the existing tools in this space, like [mermaid-ascii](https://github.com/AlexanderGrooff/mermaid-ascii) (Go) and [beautiful-mermaid](https://github.com/lukilabs/beautiful-mermaid) (TypeScript), don't offer a native Python library you can import and call directly.
49
+
50
+ ## Install
51
+
52
+ ```bash
53
+ pip install termaid
54
+ ```
55
+
56
+ ## Quick start
57
+
58
+ ### CLI
59
+
60
+ ```bash
61
+ termaid diagram.mmd
62
+ echo "graph LR; A-->B-->C" | termaid
63
+ termaid diagram.mmd --theme neon
64
+ termaid diagram.mmd --ascii
65
+ ```
66
+
67
+ ### Python
68
+
69
+ ```python
70
+ from termaid import render
71
+
72
+ print(render("graph LR\n A --> B --> C"))
73
+ ```
74
+
75
+ ```python
76
+ # Colored output (requires: pip install termaid[rich])
77
+ from termaid import render_rich
78
+ from rich import print as rprint
79
+
80
+ rprint(render_rich("graph LR\n A --> B", theme="terra"))
81
+ ```
82
+
83
+ ```python
84
+ # Textual TUI widget (requires: pip install termaid[textual])
85
+ from termaid import MermaidWidget
86
+
87
+ widget = MermaidWidget("graph LR\n A --> B")
88
+ ```
89
+
90
+ ## Supported diagram types
91
+
92
+ ### Flowcharts
93
+
94
+ All directions supported: `LR`, `RL`, `TD`/`TB`, `BT`.
95
+
96
+ ```mermaid
97
+ graph TD
98
+ A[Start] --> B{Is valid?}
99
+ B -->|Yes| C(Process)
100
+ C --> D([Done])
101
+ B -->|No| E[Error]
102
+ ```
103
+
104
+ ```
105
+ ┌─────────────┐
106
+ │ │
107
+ │ Start │
108
+ │ │
109
+ └──────┬──────┘
110
+ │
111
+ │
112
+ ▼
113
+ ┌──────◇──────┐
114
+ │ │
115
+ │ Is valid? │
116
+ │ │
117
+ └──────◇──────┘
118
+ │
119
+ │
120
+ ╰──────────────────╮
121
+ Yes│ │No
122
+ ▼ ▼
123
+ ╭─────────────╮ ┌─────────────┐
124
+ │ │ │ │
125
+ │ Process │ │ Error │
126
+ │ │ │ │
127
+ ╰──────┬──────╯ └─────────────┘
128
+ │
129
+ │
130
+ ▼
131
+ ╭─────────────╮
132
+ ( )
133
+ ( Done )
134
+ ( )
135
+ ╰─────────────╯
136
+ ```
137
+
138
+ **Node shapes:** rectangle `[text]`, rounded `(text)`, diamond `{text}`, stadium `([text])`, subroutine `[[text]]`, circle `((text))`, double circle `(((text)))`, hexagon `{{text}}`, cylinder `[(text)]`, asymmetric `>text]`, parallelogram `[/text/]`, trapezoid `[/text\]`, and `@{shape}` syntax
139
+
140
+ **Edge styles:** solid `-->`, dotted `-.->`, thick `==>`, bidirectional `<-->`, circle endpoint `--o`, cross endpoint `--x`, labeled `-->|text|`, variable length `--->`, `---->`
141
+
142
+ **Styling:** `classDef`, `style`, `linkStyle` directives, `:::className` suffix
143
+
144
+ **Subgraphs:** nesting, cross-boundary edges, per-subgraph `direction` override
145
+
146
+ **Other:** `%%` comments, `;` line separators, Markdown labels `` "`**bold** *italic*`" ``, `&` operator (`A & B --> C`)
147
+
148
+ ### Sequence diagrams
149
+
150
+ ```mermaid
151
+ sequenceDiagram
152
+ Alice->>Bob: Hello Bob
153
+ Bob-->>Alice: Hi Alice
154
+ Alice->>Bob: How are you?
155
+ Bob-->>Alice: Great!
156
+ ```
157
+
158
+ ```
159
+ ┌──────────┐ ┌──────────┐
160
+ │ Alice │ │ Bob │
161
+ └──────────┘ └──────────┘
162
+ ┆ Hello Bob ┆
163
+ ──────────────────►
164
+ ┆ Hi Alice ┆
165
+ ◄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
166
+ ┆ How are you? ┆
167
+ ──────────────────►
168
+ ┆ Great! ┆
169
+ ◄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
170
+ ┆ ┆
171
+ ```
172
+
173
+ **Message types:** solid arrow `->>`, dashed arrow `-->>`, solid line `->`, dashed line `-->`
174
+
175
+ **Participants:** `participant`, `actor`, aliases
176
+
177
+ ### Class diagrams
178
+
179
+ ```mermaid
180
+ classDiagram
181
+ class Animal {
182
+ +String name
183
+ +int age
184
+ +makeSound()
185
+ }
186
+ class Dog {
187
+ +String breed
188
+ +fetch()
189
+ }
190
+ Animal <|-- Dog
191
+ ```
192
+
193
+ ```
194
+ ┌──────────────┐
195
+ │ Animal │
196
+ ├──────────────┤
197
+ │ +String name │
198
+ │ +int age │
199
+ ├──────────────┤
200
+ │ +makeSound() │
201
+ └──────────────┘
202
+ △
203
+ │
204
+ │
205
+ │
206
+ ┌───────────────┐
207
+ │ Dog │
208
+ ├───────────────┤
209
+ │ +String breed │
210
+ ├───────────────┤
211
+ │ +fetch() │
212
+ └───────────────┘
213
+ ```
214
+
215
+ **Relationships:** inheritance `<|--`, composition `*--`, aggregation `o--`, association `--`, dependency `..>`, realization `..|>`
216
+
217
+ **Members:** attributes and methods with visibility (`+` public, `-` private, `#` protected, `~` package)
218
+
219
+ ### ER diagrams
220
+
221
+ ```mermaid
222
+ erDiagram
223
+ CUSTOMER ||--o{ ORDER : places
224
+ ORDER ||--|{ LINE-ITEM : contains
225
+ ```
226
+
227
+ ```
228
+ ┌──────────────┐
229
+ │ CUSTOMER │
230
+ └──────────────┘
231
+ │1
232
+ │ places
233
+ │
234
+ │0..*
235
+ ┌──────────────┐
236
+ │ ORDER │
237
+ └──────────────┘
238
+ │1
239
+ │ contains
240
+ │
241
+ │1..*
242
+ ┌──────────────┐
243
+ │ LINE-ITEM │
244
+ └──────────────┘
245
+ ```
246
+
247
+ **Cardinality:** `||` (exactly one), `o|` (zero or one), `}|` (one or more), `o{` (zero or more)
248
+
249
+ **Line styles:** solid `--`, dashed `..`
250
+
251
+ **Attributes:** type, name, keys (`PK`, `FK`, `UK`), comments
252
+
253
+ ### State diagrams
254
+
255
+ ```mermaid
256
+ stateDiagram-v2
257
+ [*] --> Idle
258
+ Idle --> Processing : start
259
+ Processing --> Done : complete
260
+ Done --> [*]
261
+ ```
262
+
263
+ ```
264
+ ╭───────◯──────╮
265
+ │ │
266
+ │ ● │
267
+ │ │
268
+ ╰───────◯──────╯
269
+ │
270
+ │
271
+ ▼
272
+ ╭──────────────╮
273
+ │ │
274
+ │ Idle │
275
+ │ │
276
+ ╰───────┬──────╯
277
+ │
278
+ start│
279
+ ▼
280
+ ╭──────────────╮
281
+ │ │
282
+ │ Processing │
283
+ │ │
284
+ ╰───────┬──────╯
285
+ │
286
+ complete│
287
+ ▼
288
+ ╭──────────────╮
289
+ │ │
290
+ │ Done │
291
+ │ │
292
+ ╰───────┬──────╯
293
+ │
294
+ │
295
+ ▼
296
+ ╭───────◯──────╮
297
+ │ │
298
+ │ ◉ │
299
+ │ │
300
+ ╰───────◯──────╯
301
+ ```
302
+
303
+ **Features:** `[*]` start/end states, transition labels, `state "name" as alias`, composite states (`state Parent { }`), stereotypes (`<<choice>>`, `<<fork>>`, `<<join>>`)
304
+
305
+ ### Block diagrams
306
+
307
+ ```mermaid
308
+ block-beta
309
+ columns 3
310
+ A["Frontend"] B["API"] C["Database"]
311
+ ```
312
+
313
+ ```
314
+ ┌──────────┐ ┌──────────┐ ┌──────────┐
315
+ │ │ │ │ │ │
316
+ │ Frontend │ │ API │ │ Database │
317
+ │ │ │ │ │ │
318
+ └──────────┘ └──────────┘ └──────────┘
319
+ ```
320
+
321
+ **Features:** `columns N`, column spanning (`blockname:N`), links between blocks, nested blocks
322
+
323
+ ### Git graphs
324
+
325
+ ```mermaid
326
+ gitGraph
327
+ commit id: "init"
328
+ commit id: "feat"
329
+ branch develop
330
+ commit id: "dev-1"
331
+ commit id: "dev-2"
332
+ checkout main
333
+ commit id: "fix"
334
+ merge develop id: "merge"
335
+ ```
336
+
337
+ ```
338
+ main ───●─────●──────┼──────────────●──────●─
339
+ init feat │ fix merge
340
+ │ │
341
+ develop ●───────●─────────────┼
342
+ dev-1 dev-2
343
+ ```
344
+
345
+ **Directions:** `LR` (default), `TB`, `BT`
346
+
347
+ **Commands:** `commit` (with `id:`, `type:`, `tag:`), `branch` (with `order:`), `checkout`/`switch`, `merge`, `cherry-pick`
348
+
349
+ **Commit types:** `NORMAL` (●), `REVERSE` (✖), `HIGHLIGHT` (■)
350
+
351
+ **Config:** `%%{init: {"gitGraph": {"mainBranchName": "master"}}}%%`
352
+
353
+ ## CLI options
354
+
355
+ | Flag | Description |
356
+ |------|-------------|
357
+ | `--ascii` | ASCII-only output (no Unicode box-drawing) |
358
+ | `--theme NAME` | Color theme: `default`, `terra`, `neon`, `mono`, `amber`, `phosphor` (requires `pip install termaid[rich]`) |
359
+ | `--padding-x N` | Horizontal padding inside boxes (default: 4) |
360
+ | `--padding-y N` | Vertical padding inside boxes (default: 2) |
361
+ | `--sharp-edges` | Sharp corners on edge turns instead of rounded |
362
+
363
+ ## Python API
364
+
365
+ ### `render(source, ...) -> str`
366
+
367
+ Render a Mermaid diagram as a plain text string. Auto-detects diagram type.
368
+
369
+ ### `render_rich(source, ..., theme="default") -> rich.text.Text`
370
+
371
+ Render as a [Rich](https://rich.readthedocs.io/) `Text` object with colors. Requires `pip install termaid[rich]`.
372
+
373
+ ### `MermaidWidget`
374
+
375
+ A [Textual](https://textual.textualize.io/) widget with a reactive `source` attribute. Requires `pip install termaid[textual]`. Updates live when you change the `source` property.
376
+
377
+ ```python
378
+ from termaid import MermaidWidget
379
+
380
+ class MyApp(App):
381
+ def compose(self):
382
+ yield MermaidWidget("graph LR\n A --> B")
383
+ ```
384
+
385
+ ## Themes
386
+
387
+ Six built-in themes for `--theme` / `render_rich()`:
388
+
389
+ | Theme | Colors | Description |
390
+ |-------|--------|-------------|
391
+ | `default` | ![#00FFFF](https://placehold.co/12x12/00FFFF/00FFFF.png) ![#FFFF00](https://placehold.co/12x12/FFFF00/FFFF00.png) ![#FFFFFF](https://placehold.co/12x12/FFFFFF/FFFFFF.png) | Cyan nodes, yellow arrows, white labels |
392
+ | `terra` | ![#D4845A](https://placehold.co/12x12/D4845A/D4845A.png) ![#E8A87C](https://placehold.co/12x12/E8A87C/E8A87C.png) ![#F5E6D3](https://placehold.co/12x12/F5E6D3/F5E6D3.png) | Warm earth tones (browns, oranges) |
393
+ | `neon` | ![#FF00FF](https://placehold.co/12x12/FF00FF/FF00FF.png) ![#00FF00](https://placehold.co/12x12/00FF00/00FF00.png) ![#00FFFF](https://placehold.co/12x12/00FFFF/00FFFF.png) | Magenta nodes, green arrows, cyan edges |
394
+ | `mono` | ![#FFFFFF](https://placehold.co/12x12/FFFFFF/FFFFFF.png) ![#AAAAAA](https://placehold.co/12x12/AAAAAA/AAAAAA.png) ![#666666](https://placehold.co/12x12/666666/666666.png) | White/gray monochrome |
395
+ | `amber` | ![#FFB000](https://placehold.co/12x12/FFB000/FFB000.png) ![#FFD080](https://placehold.co/12x12/FFD080/FFD080.png) ![#FFD580](https://placehold.co/12x12/FFD580/FFD580.png) | Amber/gold CRT-style |
396
+ | `phosphor` | ![#33FF33](https://placehold.co/12x12/33FF33/33FF33.png) ![#66FF66](https://placehold.co/12x12/66FF66/66FF66.png) ![#AAFFAA](https://placehold.co/12x12/AAFFAA/AAFFAA.png) | Green phosphor terminal-style |
397
+
398
+ ## Optional extras
399
+
400
+ ```bash
401
+ pip install termaid[rich] # Colored terminal output
402
+ pip install termaid[textual] # Textual TUI widget
403
+ ```
404
+
405
+ ## Limitations
406
+
407
+ - **Layout engine is approximate.** Node positioning uses a grid-based barycenter heuristic. Graphs with many cross-layer edges may still produce crossings.
408
+ - **Manhattan-only edge routing.** Edges use A* pathfinding on a grid. Very dense graphs may have overlapping edges.
409
+
410
+ ## Acknowledgements
411
+
412
+ Inspired by [mermaid-ascii](https://github.com/AlexanderGrooff/mermaid-ascii) by Alexander Grooff and [beautiful-mermaid](https://github.com/lukilabs/beautiful-mermaid) by Lukilabs.
413
+
414
+ ## License
415
+
416
+ MIT