#diagram #graph #layout #ascii-art #input-file #cli

app mono-diagram

一种跨平台工具,可以从特定语法生成纯文本图

2 个不稳定版本

0.2.0 2024 年 5 月 8 日
0.1.0 2024 年 5 月 1 日

#299 in 解析实现

MIT 许可证

100KB
2K SLoC

███╗   ███╗ ██████╗ ███╗   ██╗ ██████╗       ██████╗ ██╗ █████╗  ██████╗ ██████╗  █████╗ ███╗   ███╗
████╗ ████║██╔═══██╗████╗  ██║██╔═══██╗      ██╔══██╗██║██╔══██╗██╔════╝ ██╔══██╗██╔══██╗████╗ ████║
██╔████╔██║██║   ██║██╔██╗ ██║██║   ██║█████╗██║  ██║██║███████║██║  ███╗██████╔╝███████║██╔████╔██║
██║╚██╔╝██║██║   ██║██║╚██╗██║██║   ██║╚════╝██║  ██║██║██╔══██║██║   ██║██╔══██╗██╔══██║██║╚██╔╝██║
██║ ╚═╝ ██║╚██████╔╝██║ ╚████║╚██████╔╝      ██████╔╝██║██║  ██║╚██████╔╝██║  ██║██║  ██║██║ ╚═╝ ██║
╚═╝     ╚═╝ ╚═════╝ ╚═╝  ╚═══╝ ╚═════╝       ╚═════╝ ╚═╝╚═╝  ╚═╝ ╚═════╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝     ╚═╝
                                                                                    


单图

crates.io License

一种跨平台命令行工具,可以从特定语法生成纯文本图。纯文本图的优点是它可以适应任何地方。

用法

定义图表

单图的基本思想是在文件中定义图表,并将其传递给程序以生成平面图。一个文件可以包含多个图表。每个图表必须以标签开头,例如 [table] 以告诉程序图表的类型。

二叉树

标签:[binary_tree]

输入文件

[binary_tree] {style: ascii}  // Specify diagram category
a->b,c          // Node 'a' has left child 'b' and right child 'c'
b->d,f          // Node name is just like variables
f->fa,fb
c->k,m
k->e,           // Node 'k' only has one left child
m->,x

a:2             // Assign values to node
b:0.42
c:9.5
f:-3
k:abc
m:2             // Different nodes can have same value
d:001
fa:451
fb:8.9
x:1.2

花括号中的键值对为图表提供属性,如果不指定,每个属性都有一个默认值。我们将 style 设置为 ascii,但您也可以将其设置为 unicode 以更改图表的外观。

输出图表(ascii)

            ___2___
        ___/       \___
     0.42             9.5
    _/   \_         _/   \_
  001     -3      abc      2
          / \     /         \
        451 8.9  e          1.2

输出图表(unicode)

               2
       ┌───────┴───────┐
     0.42             9.5
   ┌───┴───┐       ┌───┴───┐
  001     -3      abc      2
         ┌─┴─┐   ┌─┘       └─┐
        451 8.9  e          1.2

仅当节点值非常简单时才使用 binary_tree,因为二叉树的最后一行的节点只能容纳最多 3 个字符。对于具有复杂值的节点,请使用 dag

有向无环图 (DAG)

标签:[dag]

输入文件

[dag]
a->b    // <NODE-NAME>-><NODE-NAME> represents an edge in the graph
a->c    // The graph cannot have cycles
b->d
c->f
c->g
a->f
d->da
d->db
g->gg
a->gg


a:Home Page     // Assign values
b:Main Section 1
c:Main Section 2
d:Subsection 1
f:Subsection 2
g:Subsection 3
da:Sub-sub
db:Sub-sub
gg:#page#

输出图表(dag 只有 unicode 版本)

 ┌───────────────────────────────────────────────────┐
 │ Home Page                                         │
 └┬─────────────────┬──┬────────────────────────────┬┘
 ┌V───────────────┐ │ ┌V───────────────┐            │
 │ Main Section 1 │ │ │ Main Section 2 │            │
 └┬───────────────┘ │ └┬────────────┬──┘            │
 ┌V─────────────┐ ┌─V──V─────────┐ ┌V─────────────┐ │
 │ Subsection 1 │ │ Subsection 2 │ │ Subsection 3 │ │
 └┬───────────┬─┘ └──────────────┘ └┬─────────────┘ │
 ┌V────────┐ ┌V────────┐ ┌──────────V───────────────V┐
 │ Sub-sub │ │ Sub-sub │ │ #page#                    │
 └─────────┘ └─────────┘ └───────────────────────────┘

注意:此 dag 图不稳定,这意味着您可能每次都会得到不同外观的图表

表格

标签:[table]

输入文件

[table]     // Each column is seperated by '|' and each row is seperated by newline
Base Class Member|Public Inheritance|Protected Inheritance|Private Inheritance
Public|Public|Protected|Private
Protected|Protected|Protected|Private
Private|Hidden|Hidden|Hidden

输出图表(ascii)

+-------------------+--------------------+-----------------------+---------------------+
| Base Class Member | Public Inheritance | Protected Inheritance | Private Inheritance |
+-------------------+--------------------+-----------------------+---------------------+
| Public            | Public             | Protected             | Private             |
+-------------------+--------------------+-----------------------+---------------------+
| Protected         | Protected          | Protected             | Private             |
+-------------------+--------------------+-----------------------+---------------------+
| Private           | Hidden             | Hidden                | Hidden              |
+-------------------+--------------------+-----------------------+---------------------+

输出图表(unicode)

┌───────────────────┬────────────────────┬───────────────────────┬─────────────────────┐
│ Base Class Member │ Public Inheritance │ Protected Inheritance │ Private Inheritance │
├───────────────────┼────────────────────┼───────────────────────┼─────────────────────┤
│ Public            │ Public             │ Protected             │ Private             │
├───────────────────┼────────────────────┼───────────────────────┼─────────────────────┤
│ Protected         │ Protected          │ Protected             │ Private             │
├───────────────────┼────────────────────┼───────────────────────┼─────────────────────┤
│ Private           │ Hidden             │ Hidden                │ Hidden              │
└───────────────────┴────────────────────┴───────────────────────┴─────────────────────┘
网格

标签: [grid]

输入文件

[grid]

width: 10       // The grid has 10 colums
height: 7       // And 7 rows

1,1:a 
6,2:l           // The cell at column 6, row 2 has content 'l'
3,3:j
10,5:m
2,7:k

输出图(ascii)

+---+---+---+---+---+---+---+---+---+---+
| a |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   | l |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
|   |   | j |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   | m |
+---+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+
|   | k |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+---+

输出图(unicode)

┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ a │   │   │   │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │ l │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │ j │   │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │   │   │ m │
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │   │   │   │
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
│   │ k │   │   │   │   │   │   │   │   │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
甘特图

标签: [gantt]

输入文件

[gantt] {style: unicode}

timeline: Week 1|Week 2|Week 3|Week 4|Week 5    // Specify the time line

task 1|   0 ~ 0.6      // Specify the time period of each task
task 2| 0.9 ~ 2.3      // This means task 2 starts at Week 0.9 and ends at Week 2.3 (you know what I mean)
task 3| 2.0 ~ 2.8
task 4| 2.8 ~ 3.5
task 5| 3.5 ~ 5.0

输出图(ascii)

        |  Week 1  |  Week 2  |  Week 3  |  Week 4  |  Week 5
--------+----------+----------+----------+----------+-----------
 task 1 |<=====>   .          .          .          .
 task 2 |         <===============>      .          .
 task 3 |          .          .<=======> .          .
 task 4 |          .          .        <=======>    .
 task 5 |          .          .          .     <================>
        |

输出图(unicode)

           Week 1     Week 2     Week 3     Week 4     Week 5
────────────────────────────────────────────────────────────────
 task 1[━━━━━]   ·          ·          ·          ·
 task 2[━━━━━━━━━━━━━━━]      ·          ·
 task 3 │          ·          ·[━━━━━━━] ·          ·
 task 4 │          ·          ·        [━━━━━━━]    ·
 task 5 │          ·          ·          ·     [━━━━━━━━━━━━━━━━]
时间线

标签: [timeline]

输入文件

[timeline] {style: unicode}

2022.06|Some things happened in 2022        // The format is <TIME>|<EVENT>
2023|                                       // Time can have no event
2024.11|Some things that is happening now
2030.01|Some things that will happen in the future

输出图(ascii)

    |
    |
    |
----v----
 2022.06  >--- Some things happened in 2022
----v----
    |
 ---v---
   2023
 ---v---
    |
----v----
 2024.11  >--- Some things that is happening now
----v----
    |
----v----
 2030.01  >--- Some things that will happen in the future
----v----
    |
    |
    |
    V

输出图(unicode)

    ║
    ║
    ║
    ╨
 2022.06  ┄┄┄┄ Some things happened in 2022
    ╥
    ║
    ╨
   2023
    ╥
    ║
    ╨
 2024.11  ┄┄┄┄ Some things that is happening now
    ╥
    ║
    ╨
 2030.01  ┄┄┄┄ Some things that will happen in the future
    ╥
    ║
    ║
    ║
    ▼

属性

属性用于赋予图表样式外观。格式为

[<DIAGRAM TAG>] {<KEY1: VALUE1>, <KEY2: VALUE2>, ...}
...

所有属性

  • styleascii / unicode

目前,Attrib 只包含 style,但未来还将增加更多。

命令行参数

Usage: mono-diagram [OPTIONS] <FILE_PATH>

Arguments:
  <FILE_PATH>
          The path to the input file

Options:
  -p, --prefix <PREFIX>
          Add a prefix to each line in the output

          This is useful when you want to paste the diagram to code comments

  -c, --copy
          Copy the output to your computer clipboard

  -h, --help
          Print help (see a summary with '-h')

  -V, --version
          Print version

示例命令

解析文件 examples/test,并输出带有前缀 '# ',然后复制到剪贴板

mono-diagram examples/test -c -p "# " 

示例

你可以在项目目录 examples/ 中找到一些示例输入文件。

安装

请首先安装 rust

然后,只需运行以下命令

cargo install mono-diagram

待办事项

  1. dag 中的节点可以是表格。这使你能够绘制类图
  2. 改进 dag 中的边绘制
  3. 添加纯文本 Venn 图
  4. 添加纯文本序列图
  5. 制作具有跨多行和多列单元格的更灵活的表格

贡献和帮助

任何贡献都受欢迎,即使只是想法。

如果你发现任何错误,请随时提出问题或联系我。

依赖项

~6.5MB
~113K SLoC