termaid 0.1.2__tar.gz → 0.2.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 (244) hide show
  1. {termaid-0.1.2 → termaid-0.2.0}/CHANGELOG.md +8 -1
  2. {termaid-0.1.2 → termaid-0.2.0}/PKG-INFO +58 -7
  3. {termaid-0.1.2 → termaid-0.2.0}/README.md +54 -5
  4. {termaid-0.1.2 → termaid-0.2.0}/demo/demo.tape +24 -0
  5. termaid-0.2.0/demo/erdiagram.mmd +19 -0
  6. termaid-0.2.0/demo/termaid-demo.gif +0 -0
  7. {termaid-0.1.2 → termaid-0.2.0}/pyproject.toml +3 -2
  8. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/__init__.py +28 -0
  9. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/cli.py +1 -1
  10. termaid-0.2.0/src/termaid/model/piechart.py +18 -0
  11. termaid-0.2.0/src/termaid/model/treemap.py +28 -0
  12. termaid-0.2.0/src/termaid/parser/piechart.py +63 -0
  13. termaid-0.2.0/src/termaid/parser/treemap.py +67 -0
  14. termaid-0.2.0/src/termaid/renderer/piechart.py +83 -0
  15. termaid-0.2.0/src/termaid/renderer/treemap.py +244 -0
  16. {termaid-0.1.2 → termaid-0.2.0}/tests/test_blockdiagram.py +1 -0
  17. termaid-0.2.0/tests/test_corner_cases.py +656 -0
  18. {termaid-0.1.2 → termaid-0.2.0}/tests/test_edge_styles.py +1 -1
  19. {termaid-0.1.2 → termaid-0.2.0}/tests/test_erdiagram.py +2 -2
  20. {termaid-0.1.2 → termaid-0.2.0}/tests/test_gitgraph.py +2 -0
  21. {termaid-0.1.2 → termaid-0.2.0}/tests/test_integration.py +23 -29
  22. termaid-0.2.0/tests/test_piechart.py +252 -0
  23. {termaid-0.1.2 → termaid-0.2.0}/tests/test_renderer.py +0 -34
  24. {termaid-0.1.2 → termaid-0.2.0}/tests/test_sequence.py +8 -4
  25. {termaid-0.1.2 → termaid-0.2.0}/tests/test_shapes.py +8 -4
  26. {termaid-0.1.2 → termaid-0.2.0}/tests/test_themes.py +2 -1
  27. termaid-0.2.0/tests/test_treemap.py +240 -0
  28. {termaid-0.1.2 → termaid-0.2.0}/tests/test_warnings.py +5 -3
  29. {termaid-0.1.2 → termaid-0.2.0}/uv.lock +1 -1
  30. termaid-0.1.2/demo/termaid-demo.gif +0 -0
  31. termaid-0.1.2/tests/test_parser.py +0 -332
  32. {termaid-0.1.2 → termaid-0.2.0}/.github/workflows/ci.yml +0 -0
  33. {termaid-0.1.2 → termaid-0.2.0}/.github/workflows/publish.yml +0 -0
  34. {termaid-0.1.2 → termaid-0.2.0}/.gitignore +0 -0
  35. {termaid-0.1.2 → termaid-0.2.0}/CONTRIBUTING.md +0 -0
  36. {termaid-0.1.2 → termaid-0.2.0}/LICENSE +0 -0
  37. {termaid-0.1.2 → termaid-0.2.0}/demo/flowchart.mmd +0 -0
  38. {termaid-0.1.2 → termaid-0.2.0}/demo/gitgraph.mmd +0 -0
  39. {termaid-0.1.2 → termaid-0.2.0}/demo/sequence.mmd +0 -0
  40. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/__main__.py +0 -0
  41. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/graph/__init__.py +0 -0
  42. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/graph/model.py +0 -0
  43. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/graph/shapes.py +0 -0
  44. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/layout/__init__.py +0 -0
  45. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/layout/grid.py +0 -0
  46. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/model/__init__.py +0 -0
  47. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/model/blockdiagram.py +0 -0
  48. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/model/classdiagram.py +0 -0
  49. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/model/erdiagram.py +0 -0
  50. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/model/gitgraph.py +0 -0
  51. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/model/sequence.py +0 -0
  52. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/output/__init__.py +0 -0
  53. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/output/rich.py +0 -0
  54. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/output/text.py +0 -0
  55. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/output/widget.py +0 -0
  56. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/parser/__init__.py +0 -0
  57. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/parser/blockdiagram.py +0 -0
  58. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/parser/classdiagram.py +0 -0
  59. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/parser/erdiagram.py +0 -0
  60. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/parser/flowchart.py +0 -0
  61. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/parser/gitgraph.py +0 -0
  62. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/parser/sequence.py +0 -0
  63. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/parser/statediagram.py +0 -0
  64. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/parser/tokens.py +0 -0
  65. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/py.typed +0 -0
  66. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/renderer/__init__.py +0 -0
  67. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/renderer/blockdiagram.py +0 -0
  68. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/renderer/canvas.py +0 -0
  69. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/renderer/charset.py +0 -0
  70. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/renderer/classdiagram.py +0 -0
  71. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/renderer/draw.py +0 -0
  72. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/renderer/erdiagram.py +0 -0
  73. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/renderer/gitgraph.py +0 -0
  74. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/renderer/sequence.py +0 -0
  75. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/renderer/shapes/__init__.py +0 -0
  76. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/renderer/themes.py +0 -0
  77. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/routing/__init__.py +0 -0
  78. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/routing/pathfinder.py +0 -0
  79. {termaid-0.1.2 → termaid-0.2.0}/src/termaid/routing/router.py +0 -0
  80. {termaid-0.1.2 → termaid-0.2.0}/tests/__init__.py +0 -0
  81. {termaid-0.1.2 → termaid-0.2.0}/tests/conftest.py +0 -0
  82. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/blockdiagram/basic.mmd +0 -0
  83. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/blockdiagram/col_span.mmd +0 -0
  84. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/blockdiagram/grid.mmd +0 -0
  85. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/blockdiagram/links.mmd +0 -0
  86. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/classdiagram/annotation.mmd +0 -0
  87. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/classdiagram/basic.mmd +0 -0
  88. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/classdiagram/inheritance.mmd +0 -0
  89. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/classdiagram/relationships.mmd +0 -0
  90. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/erdiagram/attributes.mmd +0 -0
  91. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/erdiagram/basic.mmd +0 -0
  92. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/erdiagram/dashed.mmd +0 -0
  93. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/erdiagram/multiple_entities.mmd +0 -0
  94. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/all_shapes.txt +0 -0
  95. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/ampersand_both.txt +0 -0
  96. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/backlink_complex.txt +0 -0
  97. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/bidir_dotted.txt +0 -0
  98. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/bidir_labeled.txt +0 -0
  99. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/bidir_td.txt +0 -0
  100. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/bidir_thick.txt +0 -0
  101. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/bidirectional.txt +0 -0
  102. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/blockdiagram/basic.txt +0 -0
  103. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/blockdiagram/col_span.txt +0 -0
  104. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/blockdiagram/grid.txt +0 -0
  105. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/blockdiagram/links.txt +0 -0
  106. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/branching.txt +0 -0
  107. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/chain.txt +0 -0
  108. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/classdiagram/annotation.txt +0 -0
  109. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/classdiagram/basic.txt +0 -0
  110. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/classdiagram/inheritance.txt +0 -0
  111. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/classdiagram/relationships.txt +0 -0
  112. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/comments.txt +0 -0
  113. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/cycle.txt +0 -0
  114. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/diamond.txt +0 -0
  115. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/dotted_arrow.txt +0 -0
  116. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/duplicate_labels.txt +0 -0
  117. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/empty_graph.txt +0 -0
  118. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/erdiagram/attributes.txt +0 -0
  119. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/erdiagram/basic.txt +0 -0
  120. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/erdiagram/dashed.txt +0 -0
  121. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/erdiagram/multiple_entities.txt +0 -0
  122. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/fan_in.txt +0 -0
  123. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/fan_out.txt +0 -0
  124. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/flowchart_keyword.txt +0 -0
  125. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/gitgraph/cherry_pick.txt +0 -0
  126. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/gitgraph/feature_branch.txt +0 -0
  127. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/gitgraph/linear.txt +0 -0
  128. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/gitgraph/tags.txt +0 -0
  129. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/gitgraph/tb_direction.txt +0 -0
  130. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/graph_bt.txt +0 -0
  131. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/graph_rl.txt +0 -0
  132. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/labeled_edges.txt +0 -0
  133. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/large_graph.txt +0 -0
  134. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/long_labels.txt +0 -0
  135. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/mermaid_comprehensive.txt +0 -0
  136. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/mixed_arrow_styles.txt +0 -0
  137. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/multiple_links.txt +0 -0
  138. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/no_arrow_dotted.txt +0 -0
  139. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/no_arrow_solid.txt +0 -0
  140. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/no_arrow_thick.txt +0 -0
  141. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/node_with_label.txt +0 -0
  142. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/parallelogram.txt +0 -0
  143. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/self_ref_with_edge.txt +0 -0
  144. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/self_reference.txt +0 -0
  145. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/semicolons.txt +0 -0
  146. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/sequence/arrows.txt +0 -0
  147. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/sequence/autonumber.txt +0 -0
  148. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/sequence/basic.txt +0 -0
  149. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/sequence/multiline_notes.txt +0 -0
  150. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/sequence/nested_blocks.txt +0 -0
  151. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/sequence/notes.txt +0 -0
  152. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/sequence/participant_kinds.txt +0 -0
  153. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/sequence/self_message.txt +0 -0
  154. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/simple_lr.txt +0 -0
  155. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/simple_tb.txt +0 -0
  156. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/simple_td.txt +0 -0
  157. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/single_node.txt +0 -0
  158. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/statediagram/basic.txt +0 -0
  159. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/statediagram/choice.txt +0 -0
  160. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/statediagram/composite.txt +0 -0
  161. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/statediagram/start_end.txt +0 -0
  162. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/subgraph_basic.txt +0 -0
  163. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/subgraph_nested.txt +0 -0
  164. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/subgraph_three_levels.txt +0 -0
  165. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/subgraph_two_separate.txt +0 -0
  166. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/subgraph_with_labels.txt +0 -0
  167. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/thick_arrow.txt +0 -0
  168. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/three_nodes_inline.txt +0 -0
  169. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/trapezoid.txt +0 -0
  170. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/two_roots.txt +0 -0
  171. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/expected/unicode_labels.txt +0 -0
  172. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/all_shapes.mmd +0 -0
  173. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/ampersand_both.mmd +0 -0
  174. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/backlink_complex.mmd +0 -0
  175. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/bidir_dotted.mmd +0 -0
  176. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/bidir_labeled.mmd +0 -0
  177. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/bidir_td.mmd +0 -0
  178. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/bidir_thick.mmd +0 -0
  179. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/bidirectional.mmd +0 -0
  180. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/branching.mmd +0 -0
  181. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/chain.mmd +0 -0
  182. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/comments.mmd +0 -0
  183. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/cycle.mmd +0 -0
  184. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/diamond.mmd +0 -0
  185. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/dotted_arrow.mmd +0 -0
  186. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/duplicate_labels.mmd +0 -0
  187. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/empty_graph.mmd +0 -0
  188. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/fan_in.mmd +0 -0
  189. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/fan_out.mmd +0 -0
  190. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/flowchart_keyword.mmd +0 -0
  191. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/graph_bt.mmd +0 -0
  192. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/graph_rl.mmd +0 -0
  193. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/labeled_edges.mmd +0 -0
  194. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/large_graph.mmd +0 -0
  195. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/long_labels.mmd +0 -0
  196. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/mermaid_comprehensive.mmd +0 -0
  197. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/mixed_arrow_styles.mmd +0 -0
  198. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/multiple_links.mmd +0 -0
  199. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/no_arrow_dotted.mmd +0 -0
  200. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/no_arrow_solid.mmd +0 -0
  201. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/no_arrow_thick.mmd +0 -0
  202. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/node_with_label.mmd +0 -0
  203. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/parallelogram.mmd +0 -0
  204. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/self_ref_with_edge.mmd +0 -0
  205. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/self_reference.mmd +0 -0
  206. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/semicolons.mmd +0 -0
  207. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/simple_lr.mmd +0 -0
  208. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/simple_tb.mmd +0 -0
  209. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/simple_td.mmd +0 -0
  210. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/single_node.mmd +0 -0
  211. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/subgraph_basic.mmd +0 -0
  212. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/subgraph_nested.mmd +0 -0
  213. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/subgraph_three_levels.mmd +0 -0
  214. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/subgraph_two_separate.mmd +0 -0
  215. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/subgraph_with_labels.mmd +0 -0
  216. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/thick_arrow.mmd +0 -0
  217. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/three_nodes_inline.mmd +0 -0
  218. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/trapezoid.mmd +0 -0
  219. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/two_roots.mmd +0 -0
  220. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/flowcharts/unicode_labels.mmd +0 -0
  221. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/gitgraph/cherry_pick.mmd +0 -0
  222. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/gitgraph/feature_branch.mmd +0 -0
  223. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/gitgraph/linear.mmd +0 -0
  224. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/gitgraph/tags.mmd +0 -0
  225. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/gitgraph/tb_direction.mmd +0 -0
  226. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/sequence/arrows.mmd +0 -0
  227. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/sequence/autonumber.mmd +0 -0
  228. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/sequence/basic.mmd +0 -0
  229. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/sequence/multiline_notes.mmd +0 -0
  230. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/sequence/nested_blocks.mmd +0 -0
  231. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/sequence/notes.mmd +0 -0
  232. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/sequence/participant_kinds.mmd +0 -0
  233. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/sequence/self_message.mmd +0 -0
  234. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/statediagram/basic.mmd +0 -0
  235. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/statediagram/choice.mmd +0 -0
  236. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/statediagram/composite.mmd +0 -0
  237. {termaid-0.1.2 → termaid-0.2.0}/tests/fixtures/statediagram/start_end.mmd +0 -0
  238. {termaid-0.1.2 → termaid-0.2.0}/tests/test_classdiagram.py +0 -0
  239. {termaid-0.1.2 → termaid-0.2.0}/tests/test_cli.py +0 -0
  240. {termaid-0.1.2 → termaid-0.2.0}/tests/test_layout.py +0 -0
  241. {termaid-0.1.2 → termaid-0.2.0}/tests/test_parser_comprehensive.py +0 -0
  242. {termaid-0.1.2 → termaid-0.2.0}/tests/test_routing.py +0 -0
  243. {termaid-0.1.2 → termaid-0.2.0}/tests/test_snapshots.py +0 -0
  244. {termaid-0.1.2 → termaid-0.2.0}/tests/test_state_diagram.py +0 -0
@@ -1,8 +1,15 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.2 (2026-03-04)
3
+ ## 0.2.0 (2026-03-20)
4
+
5
+ - Add pie chart support (`pie` syntax, rendered as horizontal bar charts)
6
+ - Add treemap support (`treemap-beta` syntax with nested sections and proportional sizing)
7
+ - 9 diagram types now supported
8
+
9
+ ## 0.1.3 (2026-03-04)
4
10
 
5
11
  - Add `--tui` flag to CLI for interactive TUI viewer
12
+ - Update demo GIF with pipe and TUI examples
6
13
 
7
14
  ## 0.1.1 (2026-03-04)
8
15
 
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: termaid
3
- Version: 0.1.2
4
- Summary: Render Mermaid diagram syntax as beautiful Unicode art in the terminal
3
+ Version: 0.2.0
4
+ Summary: Render Mermaid diagrams in your terminal or Python app
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
7
7
  Keywords: ascii,diagram,flowchart,mermaid,terminal,unicode
@@ -22,21 +22,21 @@ Provides-Extra: rich
22
22
  Requires-Dist: rich>=13.0; extra == 'rich'
23
23
  Provides-Extra: textual
24
24
  Requires-Dist: textual>=0.40; extra == 'textual'
25
+ Provides-Extra: tui
26
+ Requires-Dist: textual>=0.40; extra == 'tui'
25
27
  Description-Content-Type: text/markdown
26
28
 
27
- # termaid
29
+ <h1 align="center">termaid</h1>
28
30
 
29
- Terminal-native Mermaid rendering for Python.
31
+ <p align="center">Render Mermaid diagrams in your terminal or Python app.</p>
30
32
 
31
33
  <p align="center">
32
34
  <img src="demo/termaid-demo.gif" alt="termaid demo" width="800">
33
35
  </p>
34
36
 
35
- Render [Mermaid](https://mermaid.js.org/) diagrams as Unicode art directly in your terminal. Pure Python, zero dependencies.
36
-
37
37
  ## Features
38
38
 
39
- - **7 diagram types:** flowcharts, sequence, class, ER, state, block, and git graphs
39
+ - **9 diagram types:** flowcharts, sequence, class, ER, state, block, git graphs, pie charts, and treemaps
40
40
  - **Zero dependencies:** pure Python, nothing to install beyond the package itself
41
41
  - **Rich and Textual integration:** colored output and TUI widgets with optional extras
42
42
  - **6 color themes:** default, terra, neon, mono, amber, phosphor
@@ -53,6 +53,12 @@ Mermaid is great for documentation, but rendering it usually means spinning up a
53
53
  pip install termaid
54
54
  ```
55
55
 
56
+ Or try it without installing:
57
+
58
+ ```bash
59
+ uvx termaid diagram.mmd
60
+ ```
61
+
56
62
  ## Quick start
57
63
 
58
64
  ### CLI
@@ -350,10 +356,55 @@ gitGraph
350
356
 
351
357
  **Config:** `%%{init: {"gitGraph": {"mainBranchName": "master"}}}%%`
352
358
 
359
+ ### Pie charts
360
+
361
+ Yes, the syntax says `pie`. No, we don't draw a circle. I know. Have you ever tried to read a pie chart made of `█` and `▓`? Exactly. We render them as horizontal bar charts instead.
362
+
363
+ ```mermaid
364
+ pie title Pets adopted by volunteers
365
+ "Dogs" : 386
366
+ "Cats" : 85
367
+ "Rats" : 15
368
+ ```
369
+
370
+ ```
371
+ Dogs┃████████████████████████████████ 79.4%
372
+ Cats┃▓▓▓▓▓▓▓ 17.5%
373
+ Rats┃░ 3.1%
374
+ ```
375
+
376
+ **Features:** `title`, `showData` (display raw values), `%%` comments
377
+
378
+ ### Treemaps
379
+
380
+ ```mermaid
381
+ treemap-beta
382
+ "Frontend"
383
+ "React": 40
384
+ "CSS": 15
385
+ "Backend"
386
+ "API": 35
387
+ "Auth": 10
388
+ ```
389
+
390
+ ```
391
+ ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐ ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐
392
+ ┆ Frontend ┆ ┆ Backend ┆
393
+ ┆┌───────────────────────┐ ┌───────┐┆ ┆┌───────────────────┐ ┌────┐┆
394
+ ┆│ React │ │ CSS │┆ ┆│ API │ │Auth│┆
395
+ ┆│ 40 │ │ 15 │┆ ┆│ 35 │ │ 10 │┆
396
+ ┆│ │ │ │┆ ┆│ │ │ │┆
397
+ ┆└───────────────────────┘ └───────┘┆ ┆└───────────────────┘ └────┘┆
398
+ └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘ └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘
399
+ ```
400
+
401
+ **Features:** nested sections via indentation, `"label": value` syntax, proportional sizing, `%%` comments
402
+
353
403
  ## CLI options
354
404
 
355
405
  | Flag | Description |
356
406
  |------|-------------|
407
+ | `--tui` | Interactive TUI viewer (requires `pip install termaid[tui]`) |
357
408
  | `--ascii` | ASCII-only output (no Unicode box-drawing) |
358
409
  | `--theme NAME` | Color theme: `default`, `terra`, `neon`, `mono`, `amber`, `phosphor` (requires `pip install termaid[rich]`) |
359
410
  | `--padding-x N` | Horizontal padding inside boxes (default: 4) |
@@ -1,16 +1,14 @@
1
- # termaid
1
+ <h1 align="center">termaid</h1>
2
2
 
3
- Terminal-native Mermaid rendering for Python.
3
+ <p align="center">Render Mermaid diagrams in your terminal or Python app.</p>
4
4
 
5
5
  <p align="center">
6
6
  <img src="demo/termaid-demo.gif" alt="termaid demo" width="800">
7
7
  </p>
8
8
 
9
- Render [Mermaid](https://mermaid.js.org/) diagrams as Unicode art directly in your terminal. Pure Python, zero dependencies.
10
-
11
9
  ## Features
12
10
 
13
- - **7 diagram types:** flowcharts, sequence, class, ER, state, block, and git graphs
11
+ - **9 diagram types:** flowcharts, sequence, class, ER, state, block, git graphs, pie charts, and treemaps
14
12
  - **Zero dependencies:** pure Python, nothing to install beyond the package itself
15
13
  - **Rich and Textual integration:** colored output and TUI widgets with optional extras
16
14
  - **6 color themes:** default, terra, neon, mono, amber, phosphor
@@ -27,6 +25,12 @@ Mermaid is great for documentation, but rendering it usually means spinning up a
27
25
  pip install termaid
28
26
  ```
29
27
 
28
+ Or try it without installing:
29
+
30
+ ```bash
31
+ uvx termaid diagram.mmd
32
+ ```
33
+
30
34
  ## Quick start
31
35
 
32
36
  ### CLI
@@ -324,10 +328,55 @@ gitGraph
324
328
 
325
329
  **Config:** `%%{init: {"gitGraph": {"mainBranchName": "master"}}}%%`
326
330
 
331
+ ### Pie charts
332
+
333
+ Yes, the syntax says `pie`. No, we don't draw a circle. I know. Have you ever tried to read a pie chart made of `█` and `▓`? Exactly. We render them as horizontal bar charts instead.
334
+
335
+ ```mermaid
336
+ pie title Pets adopted by volunteers
337
+ "Dogs" : 386
338
+ "Cats" : 85
339
+ "Rats" : 15
340
+ ```
341
+
342
+ ```
343
+ Dogs┃████████████████████████████████ 79.4%
344
+ Cats┃▓▓▓▓▓▓▓ 17.5%
345
+ Rats┃░ 3.1%
346
+ ```
347
+
348
+ **Features:** `title`, `showData` (display raw values), `%%` comments
349
+
350
+ ### Treemaps
351
+
352
+ ```mermaid
353
+ treemap-beta
354
+ "Frontend"
355
+ "React": 40
356
+ "CSS": 15
357
+ "Backend"
358
+ "API": 35
359
+ "Auth": 10
360
+ ```
361
+
362
+ ```
363
+ ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐ ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐
364
+ ┆ Frontend ┆ ┆ Backend ┆
365
+ ┆┌───────────────────────┐ ┌───────┐┆ ┆┌───────────────────┐ ┌────┐┆
366
+ ┆│ React │ │ CSS │┆ ┆│ API │ │Auth│┆
367
+ ┆│ 40 │ │ 15 │┆ ┆│ 35 │ │ 10 │┆
368
+ ┆│ │ │ │┆ ┆│ │ │ │┆
369
+ ┆└───────────────────────┘ └───────┘┆ ┆└───────────────────┘ └────┘┆
370
+ └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘ └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘
371
+ ```
372
+
373
+ **Features:** nested sections via indentation, `"label": value` syntax, proportional sizing, `%%` comments
374
+
327
375
  ## CLI options
328
376
 
329
377
  | Flag | Description |
330
378
  |------|-------------|
379
+ | `--tui` | Interactive TUI viewer (requires `pip install termaid[tui]`) |
331
380
  | `--ascii` | ASCII-only output (no Unicode box-drawing) |
332
381
  | `--theme NAME` | Color theme: `default`, `terra`, `neon`, `mono`, `amber`, `phosphor` (requires `pip install termaid[rich]`) |
333
382
  | `--padding-x N` | Horizontal padding inside boxes (default: 4) |
@@ -16,9 +16,15 @@ Env "PS1" "$ "
16
16
  Env "VIRTUAL_ENV" ""
17
17
 
18
18
  Hide
19
+ Type "source .venv/bin/activate"
20
+ Enter
21
+ Sleep 500ms
19
22
  Type "cd demo"
20
23
  Enter
21
24
  Sleep 500ms
25
+ Type "export PS1='$ '"
26
+ Enter
27
+ Sleep 500ms
22
28
  Ctrl+L
23
29
  Show
24
30
 
@@ -39,6 +45,24 @@ Sleep 4s
39
45
 
40
46
  # 4. One-liner hook — pipe-friendly with branching
41
47
  Ctrl+L
48
+ Set TypingSpeed 0
49
+ Type "# Pipe-friendly: works with echo, cat, curl..."
50
+ Enter
51
+ Set TypingSpeed 32ms
52
+ Sleep 1s
42
53
  Type "echo 'graph LR; A[Request] --> B{Valid?}; B -->|Yes| C[Process]; B -->|No| D[Error]' | termaid --theme default"
43
54
  Enter
55
+ Sleep 3s
56
+
57
+ # 5. TUI mode — interactive viewer
58
+ Ctrl+L
59
+ Set TypingSpeed 0
60
+ Type "# Interactive TUI mode"
61
+ Enter
62
+ Set TypingSpeed 32ms
63
+ Sleep 1s
64
+ Type "termaid erdiagram.mmd --tui"
65
+ Enter
44
66
  Sleep 4s
67
+ Type "q"
68
+ Sleep 1s
@@ -0,0 +1,19 @@
1
+ erDiagram
2
+ USER ||--o{ ORDER : places
3
+ USER {
4
+ int id PK
5
+ string name
6
+ string email
7
+ }
8
+ ORDER ||--|{ LINE_ITEM : contains
9
+ ORDER {
10
+ int id PK
11
+ date created
12
+ string status
13
+ }
14
+ PRODUCT ||--o{ LINE_ITEM : "ordered in"
15
+ PRODUCT {
16
+ int id PK
17
+ string name
18
+ float price
19
+ }
Binary file
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "termaid"
7
- version = "0.1.2"
8
- description = "Render Mermaid diagram syntax as beautiful Unicode art in the terminal"
7
+ version = "0.2.0"
8
+ description = "Render Mermaid diagrams in your terminal or Python app"
9
9
  readme = "README.md"
10
10
  license = "MIT"
11
11
  requires-python = ">=3.11"
@@ -25,6 +25,7 @@ classifiers = [
25
25
  [project.optional-dependencies]
26
26
  rich = ["rich>=13.0"]
27
27
  textual = ["textual>=0.40"]
28
+ tui = ["textual>=0.40"]
28
29
  dev = [
29
30
  "pytest>=7.0",
30
31
  "pytest-snapshot",
@@ -90,6 +90,18 @@ def render(
90
90
  diagram = parse_git_graph(text)
91
91
  return render_git_graph(diagram, use_ascii=use_ascii).to_string()
92
92
 
93
+ if text.startswith("pie"):
94
+ from .parser.piechart import parse_pie_chart
95
+ from .renderer.piechart import render_pie_chart
96
+ diagram = parse_pie_chart(text)
97
+ return render_pie_chart(diagram, use_ascii=use_ascii).to_string()
98
+
99
+ if text.startswith("treemap"):
100
+ from .parser.treemap import parse_treemap
101
+ from .renderer.treemap import render_treemap
102
+ diagram = parse_treemap(text)
103
+ return render_treemap(diagram, use_ascii=use_ascii).to_string()
104
+
93
105
  graph = parse(text)
94
106
  from .output.text import render_text
95
107
  return render_text(graph, use_ascii=use_ascii, padding_x=padding_x, padding_y=padding_y, rounded_edges=rounded_edges)
@@ -162,6 +174,22 @@ def render_rich(
162
174
  canvas = render_git_graph(diagram, use_ascii=use_ascii)
163
175
  return render_sequence_rich(canvas, theme=theme)
164
176
 
177
+ if text.startswith("pie"):
178
+ from .parser.piechart import parse_pie_chart
179
+ from .renderer.piechart import render_pie_chart
180
+ from .output.rich import render_sequence_rich
181
+ diagram = parse_pie_chart(text)
182
+ canvas = render_pie_chart(diagram, use_ascii=use_ascii)
183
+ return render_sequence_rich(canvas, theme=theme)
184
+
185
+ if text.startswith("treemap"):
186
+ from .parser.treemap import parse_treemap
187
+ from .renderer.treemap import render_treemap
188
+ from .output.rich import render_sequence_rich
189
+ diagram = parse_treemap(text)
190
+ canvas = render_treemap(diagram, use_ascii=use_ascii)
191
+ return render_sequence_rich(canvas, theme=theme)
192
+
165
193
  graph = parse(text)
166
194
  from .output.rich import render_rich as _render_rich
167
195
  return _render_rich(graph, use_ascii=use_ascii, padding_x=padding_x, padding_y=padding_y, rounded_edges=rounded_edges, theme=theme)
@@ -53,7 +53,7 @@ def main(argv: list[str] | None = None) -> int:
53
53
  parser.add_argument(
54
54
  "--version",
55
55
  action="version",
56
- version="%(prog)s 0.1.2",
56
+ version="%(prog)s 0.1.3",
57
57
  )
58
58
 
59
59
  args = parser.parse_args(argv)
@@ -0,0 +1,18 @@
1
+ """Data model for pie chart diagrams (rendered as bar charts)."""
2
+ from __future__ import annotations
3
+
4
+ from dataclasses import dataclass, field
5
+
6
+
7
+ @dataclass
8
+ class PieSlice:
9
+ label: str
10
+ value: float
11
+
12
+
13
+ @dataclass
14
+ class PieChart:
15
+ title: str = ""
16
+ show_data: bool = False
17
+ slices: list[PieSlice] = field(default_factory=list)
18
+ warnings: list[str] = field(default_factory=list)
@@ -0,0 +1,28 @@
1
+ """Data model for treemap diagrams."""
2
+ from __future__ import annotations
3
+
4
+ from dataclasses import dataclass, field
5
+
6
+
7
+ @dataclass
8
+ class TreemapNode:
9
+ label: str
10
+ value: float = 0
11
+ children: list[TreemapNode] = field(default_factory=list)
12
+
13
+ @property
14
+ def total_value(self) -> float:
15
+ """Total value: own value for leaves, sum of children for sections."""
16
+ if self.children:
17
+ return sum(c.total_value for c in self.children)
18
+ return self.value
19
+
20
+
21
+ @dataclass
22
+ class Treemap:
23
+ roots: list[TreemapNode] = field(default_factory=list)
24
+ warnings: list[str] = field(default_factory=list)
25
+
26
+ @property
27
+ def total_value(self) -> float:
28
+ return sum(r.total_value for r in self.roots)
@@ -0,0 +1,63 @@
1
+ """Parser for Mermaid pie chart diagrams.
2
+
3
+ Syntax:
4
+ pie [showData]
5
+ [title <text>]
6
+ "<label>" : <value>
7
+ ...
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import re
12
+
13
+ from ..model.piechart import PieChart, PieSlice
14
+
15
+ _SLICE_RE = re.compile(r'^\s*"([^"]+)"\s*:\s*([0-9]+(?:\.[0-9]*)?)$')
16
+
17
+
18
+ def parse_pie_chart(text: str) -> PieChart:
19
+ """Parse a mermaid pie chart definition."""
20
+ lines = text.strip().splitlines()
21
+ chart = PieChart()
22
+
23
+ if not lines:
24
+ return chart
25
+
26
+ # Parse header line: pie [showData]
27
+ header = lines[0].strip()
28
+ if "showData" in header:
29
+ chart.show_data = True
30
+
31
+ for line in lines[1:]:
32
+ stripped = line.strip()
33
+ if not stripped:
34
+ continue
35
+
36
+ # Strip comments
37
+ comment_idx = stripped.find("%%")
38
+ if comment_idx >= 0:
39
+ stripped = stripped[:comment_idx].strip()
40
+ if not stripped:
41
+ continue
42
+
43
+ # Title
44
+ if stripped.lower().startswith("title "):
45
+ chart.title = stripped[6:].strip()
46
+ continue
47
+
48
+ # Slice: "Label" : value
49
+ m = _SLICE_RE.match(stripped)
50
+ if m:
51
+ label = m.group(1)
52
+ value = float(m.group(2))
53
+ if value <= 0:
54
+ chart.warnings.append(f"Pie slice value must be positive: {label} = {value}")
55
+ continue
56
+ chart.slices.append(PieSlice(label=label, value=value))
57
+ continue
58
+
59
+ # Unrecognized line
60
+ if stripped:
61
+ chart.warnings.append(f"Unrecognized line: {stripped}")
62
+
63
+ return chart
@@ -0,0 +1,67 @@
1
+ """Parser for Mermaid treemap diagrams.
2
+
3
+ Syntax:
4
+ treemap-beta
5
+ "Section 1"
6
+ "Leaf 1.1": 12
7
+ "Section 1.2"
8
+ "Leaf 1.2.1": 12
9
+ "Section 2"
10
+ "Leaf 2.1": 20
11
+ """
12
+ from __future__ import annotations
13
+
14
+ import re
15
+
16
+ from ..model.treemap import Treemap, TreemapNode
17
+
18
+ _NODE_RE = re.compile(r'^(\s*)"([^"]+)"(?:\s*:\s*([0-9]+(?:\.[0-9]*)?))?')
19
+
20
+
21
+ def parse_treemap(text: str) -> Treemap:
22
+ """Parse a mermaid treemap definition."""
23
+ lines = text.strip().splitlines()
24
+ treemap = Treemap()
25
+
26
+ if not lines:
27
+ return treemap
28
+
29
+ # Skip header line (treemap-beta)
30
+ body_lines: list[tuple[int, str, float]] = []
31
+ for line in lines[1:]:
32
+ # Strip comments
33
+ comment_idx = line.find("%%")
34
+ if comment_idx >= 0:
35
+ line = line[:comment_idx]
36
+
37
+ m = _NODE_RE.match(line)
38
+ if not m:
39
+ continue
40
+
41
+ indent = len(m.group(1))
42
+ label = m.group(2)
43
+ value = float(m.group(3)) if m.group(3) else 0
44
+ body_lines.append((indent, label, value))
45
+
46
+ if not body_lines:
47
+ return treemap
48
+
49
+ # Build tree from indentation
50
+ # Stack: (indent_level, node)
51
+ stack: list[tuple[int, TreemapNode]] = []
52
+
53
+ for indent, label, value in body_lines:
54
+ node = TreemapNode(label=label, value=value)
55
+
56
+ # Pop stack until we find a parent with less indentation
57
+ while stack and stack[-1][0] >= indent:
58
+ stack.pop()
59
+
60
+ if stack:
61
+ stack[-1][1].children.append(node)
62
+ else:
63
+ treemap.roots.append(node)
64
+
65
+ stack.append((indent, node))
66
+
67
+ return treemap
@@ -0,0 +1,83 @@
1
+ """Renderer for pie chart diagrams as horizontal bar charts.
2
+
3
+ Draws per-slice horizontal bars with right-aligned labels,
4
+ percentages, and optional raw values.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from ..model.piechart import PieChart
9
+ from .canvas import Canvas
10
+ from .charset import ASCII, UNICODE, CharSet
11
+
12
+ _FILL_CHARS = ["█", "▓", "░", "▒", "▞", "▚", "▖", "▗"]
13
+ _FILL_CHARS_ASCII = ["#", "*", "+", "~", ":", ".", "o", "="]
14
+
15
+ _BAR_WIDTH = 40
16
+ _MARGIN = 2
17
+
18
+
19
+ def render_pie_chart(
20
+ diagram: PieChart,
21
+ *,
22
+ use_ascii: bool = False,
23
+ ) -> Canvas:
24
+ """Render a PieChart as a horizontal bar chart on a Canvas."""
25
+
26
+ if not diagram.slices:
27
+ canvas = Canvas(1, 1)
28
+ return canvas
29
+
30
+ total = sum(s.value for s in diagram.slices)
31
+ fills = _FILL_CHARS_ASCII if use_ascii else _FILL_CHARS
32
+
33
+ # Compute label column width
34
+ max_label_len = max(len(s.label) for s in diagram.slices)
35
+ label_col_w = max_label_len + _MARGIN
36
+
37
+ # Compute suffix (percentage + optional value)
38
+ suffixes: list[str] = []
39
+ for s in diagram.slices:
40
+ pct = s.value / total * 100
41
+ if diagram.show_data:
42
+ suffixes.append(f" {pct:5.1f}% [{s.value:g}]")
43
+ else:
44
+ suffixes.append(f" {pct:5.1f}%")
45
+ max_suffix_len = max(len(sf) for sf in suffixes)
46
+
47
+ bar_left = label_col_w
48
+ canvas_w = bar_left + _BAR_WIDTH + max_suffix_len + _MARGIN
49
+ title_rows = 2 if diagram.title else 0
50
+
51
+ bars_top = _MARGIN + title_rows
52
+ canvas_h = bars_top + len(diagram.slices) + _MARGIN
53
+
54
+ canvas = Canvas(canvas_w, canvas_h)
55
+
56
+ # Title
57
+ if diagram.title:
58
+ title_col = max(0, (canvas_w - len(diagram.title)) // 2)
59
+ canvas.put_text(_MARGIN, title_col, diagram.title, style="label")
60
+
61
+ # ── Per-slice bars ────────────────────────────────────────────────────
62
+ for i, s in enumerate(diagram.slices):
63
+ row = bars_top + i
64
+ pct = s.value / total * 100
65
+ fill = fills[i % len(fills)]
66
+ bar_len = max(1, round(s.value / total * _BAR_WIDTH))
67
+
68
+ # Label (right-aligned)
69
+ label_text = s.label.rjust(max_label_len)
70
+ canvas.put_text(row, _MARGIN, label_text, style="label")
71
+
72
+ # Bar
73
+ if use_ascii:
74
+ canvas.put(row, bar_left, "|", merge=False, style="edge")
75
+ else:
76
+ canvas.put(row, bar_left, "┃", merge=False, style="edge")
77
+ for c in range(bar_len):
78
+ canvas.put(row, bar_left + 1 + c, fill, merge=False, style="node")
79
+
80
+ # Suffix
81
+ canvas.put_text(row, bar_left + 1 + bar_len, suffixes[i], style="label")
82
+
83
+ return canvas