ASCII Art:使用純文本流程圖
我們使用純文本寫代碼,有了Markdown又可以使用純文本寫文檔,那么對于更直觀的信息表達方式——圖片,能不能使用純文本描述呢?
另外,你是否見到過這樣的注釋:
沒錯,這種逼格極高的ASCII圖片注釋方式就是我們要討論的話題。
使用純ASCII文本表達圖像的方式有什么好處呢?大致有下面幾點:
- 裝B;沒啥好解釋的。
- 可以在代碼注釋里面用圖像充分表達信息;沒圖say個jb?一圖勝千言。迄今為止好像沒有什么IDE可以支持直接在代碼編輯里面放圖片的,在另外一些純文本的場合也是如此。比如RFC的文檔都是txt,里面很多圖都是純ASCII表達。
- 你以為僅僅是一個純文本圖片這么簡單?它可以轉換為普通的諸如png格式的真正的圖片,還支持SVG矢量圖!
好了,也許有人說markdown的一些拓展格式不也是支持流程圖的嗎?它使用的 flowchart.js 確實可以很好滴完成一些漂亮的流程圖,還有 plantuml 和圖片DSL語言 dot 及它的軟件包 graphviz 等;沒錯,它們可以使用純文本表達圖像,但它們不是真正的圖像;無法嵌入文本代碼中,只有在經過渲染之后才能直觀地看到圖。
又有人說,我知道 asciiflow 這個網站,可以繪制這種流程圖,完美解決我的需求。但是,你在手動繪制的時候,是不是要考慮圖像的各種細節?大小,放置位置,對齊方式?我們關注的應該是圖像本身,而不是如何繪制這個圖。markdown為什么這么易用?就是因為我們不用關心文檔的格式,不用考慮什么字體,幾級標題等等繁瑣的格式,可以專注于創作本身。
姑且你已經認同了這種使用ASCII表達圖像方式的優點,但是…這種圖難道要使用手一個個字符地敲出來嗎??如果真的這么做,簡直不要太麻煩!光在前面添加一個空格,后面的所有行都需要改;我們需要一個自動化工具。
Graph::Easy
Graph::Easy就是今天要介紹的主角;它是 perl 的一個軟件包,可以使用 perl 代碼直接描述圖像;當然,我們肯定不會為了畫個圖專門去學習 perl ;
這個軟件包的強大之處在于: 它定義了一套非常簡單易用的專門用來描述圖像的DSL(領域專用語言),我們可以像寫代碼一樣表達我們需要描述的圖像(放心,這個語法非常簡單);不用關心圖像里面如何布局;這種語言經過處理可以得到ASCII圖像,直接放在代碼注釋中;如果需要還可以轉換成png或者矢量圖等格式。
先舉個簡單的例子,感受一下:
[ Bonn ] --> [ Koblenz ] --> [ Frankfurt ] --> [ Dresden ] [ Koblenz ] --> [ Trier ] { origin: Koblenz; offset: 2, 2; } --> [ Frankfurt ]
這種DSL經過渲染之后得到的ASCII圖是這樣的:
+------+ +---------+ +-----------+ +---------+ | Bonn | --> | Koblenz | ----------------> | Frankfurt | --> | Dresden | +------+ +---------+ +-----------+ +---------+ | ^ | | | | | +-------+ | +-----------> | Trier | ------+ +-------+
安裝
- 首先需要安裝 graphviz 軟件包,可以在 graphviz官網 下載;mac用戶可以 brew install graphviz ;其他linux發行版參考 官網 。
- 安裝 perl ;mac和linux用戶可以略過;一般系統自帶,沒有的話和windows一起去 perl官網 查詢如何安裝; 據說windows下有傻瓜包 activeperl ;請自行搜索。
- 安裝 cpan ; 這個是 perl 的軟件包管理,類似 npm , pip , apt-get ; mac下直接在命令行輸入 cpan 命令,一路next即可。其他系統參考 cpan官網
- 安裝 Graph::Easy ;這一步就很容易了;在命令行輸入 cpan 進入cpan shell;然后輸入 install Graph::Easy 即可。
使用
使用分為兩步
- 使用Graph::Easy DSL的語法描述圖像,存為文本文件,比如 simple.txt
- 使用 graph-easy 命令處理這個文件: graph-easy simple.txt
最簡單的使用方式就是這樣;當然, Graph::Easy 不僅僅支持自己的DSL語法,它還支持諸如 dot 這種較為通用的圖像描述語言;可以直接讀取 dot 格式的輸入,產生其他的諸如 ascii,png,svg格式的圖像。
語法
注釋
注釋用 # 表達;注意 # 之后,一定需要加空格;由于歷史原因;Graph::Easy的顏色也使用了 # ,不加空格會解析失敗。
############################################################## # 合法的注釋 ############################################################## #有問題的注釋 node { label: \#5; } # 注意轉義! edge { color: #aabbcc; } # 可以使用顏色值
空格
空格通常沒有什么影響,多個空字符會合并成一個,換行的空字符會忽略;下面的表述是等價的。
[A]->[B][C]->[D]
[ A ] -> [ B ] [ C ] -> [ D ]
節點(Node)
用中括號括起來的就是節點,我們簡單可以理解為一些形狀;比如流程圖里面的矩形,圓等;
[ Single node ] [ Node A ] --> [ Node B ]
可以用逗號分割多個節點:
[ A ], [ B ], [ C ] --> [ D ]
上面的代碼圖像如下:
+---+ +---+ +---+ | A | --> | D | <-- | C | +---+ +---+ +---+ ^ | | +---+ | B | +---+
邊(Edges)
將節點連接起來的就是邊;Graph::Easy 的DSL支持這幾種風格的邊:
-> 實線 => 雙實線 .> 點線 ~> 波浪線 - > 虛線 .-> 點虛線 ..-> dot-dot-dash = > double-dash
可以給邊加標簽,如下:
[ client ] - request -> [ server ] ``` 結果如下: ```asciidoc +--------+ request +--------+ | client | ---------> | server | +--------+ +--------+
屬性(Attributes)
可以給節點和邊添加屬性;比如標簽,方向等;使用大括號 {} 表示,里面的內容類似css, attribute: value 。
[ "Monitor Size" ] --> { label: 21"; } [ Big ] { label: "Huge"; }
上面的DSL輸入如下:
+----------------+ 21" +------+ | "Monitor Size" | -----> | Huge | +----------------+ +------+
Graph::Easy提供了非常多的屬性; 另外, Graph::Easy 的 文檔 非常詳細,建議通讀一遍;了解其中的原理和細節,對于繪圖和布局有巨大幫助。有時間的話我就翻譯一下。
實例
語法是不是非常簡單?有了這些知識,我們就可以建立自己的流程圖了;Have a try!來個MVP模式的示意圖試試~
- 新建文件, vi mvp.txt ; 輸入以下代碼:
[ View ] {rows:3} - Parse calls to -> [ Presenter ] {flow: south; rows: 3} - Manipulates -> [ Model ] [ Presenter ] - Updates -> [ View ]
- 保存然后退出;命令行執行 graph-easy mvp.txt , 輸入效果如下:
+------+ Parse calls to +--------------+ | | ----------------> | | | View | | Presenter | | | Updates | | | | <---------------- | | +------+ +--------------+ | | Manipulates v +--------------+ | Model | +--------------+
兩行代碼就搞定了!自動對齊,調整位置,箭頭,標簽等等;我們完全不用管具體圖形應該如何繪制,注意力集中在描述圖像本身;還在等什么!趕緊試一試吧!!
原文: http://weishu.me/2016/01/03/use-pure-ascii-present-graph/
來自: http://tianweishu.com/2016/01/03/use-pure-ascii-present-graph/