Skip to main content

__debug's Home Keep it simple, stupid

在 Emacs 里用 Graphviz 画图

前几周一天晚上由于调图论题画图画烦了, 于是写了这么一个函数

(defun oi-draw-graph (beg end region)
  "Draw a graph through graphviz
Directed graph is default;
To draw undirected graph, add C-u prefix"
  (interactive (list (mark) (point)
		     (prefix-numeric-value current-prefix-arg)))
  (let ((edge-expr (if current-prefix-arg " --" " ->"))
	(graph-type (if current-prefix-arg "graph" "digraph")))
    (copy-region-as-kill beg end region)
    (with-temp-file "~/temp_graph.dot"
      (yank)
      (flush-lines "^[[:space:]]*$" (point-min) (point-max) t)
      (replace-regexp "[ \t]+$" "" nil (point-min) (point-max))
      (replace-regexp "^[ \t]+" "" nil (point-min) (point-max))
      (goto-char (point-min))
      (while (< (point) (point-max))
	(move-beginning-of-line 1)
	(insert "\"")
	(forward-word)
	(insert "\"")
	(insert edge-expr)
	(forward-word)
	(backward-word)
	(insert "\"")
	(forward-word)
	(insert "\" [label=\"")
	(move-end-of-line 1)
	(insert "\"];")
	(forward-line))
      (goto-char (point-min))
      (open-line 2)
      (insert (concat graph-type " tmp {"))
      (goto-char (point-max))
      (newline)
      (insert "}")))
  (shell-command "dot ~/temp_graph.dot -T png -o ~/temp_graph.png")
  (find-file "~/temp_graph.png"))

写的丑的可以, 并且 Emacs 里 replace-regexp 函数的文档里都说了 "This function is usually the wrong thing to use in a Lisp program", 233.

用着还可以, 就这样吧.

用法很简单. 先装一下 graphviz. 用的时候选中一个 region, 然后 M-x oi-draw-graph 就是画有向图, C-u M-x oi-draw-graph 就是画无向图. 可以自己绑个键. (比如说, (global-set-key (kbd "C-c C-d") 'oi-draw-graph))

大概就是这样:

Comments

Comments powered by Disqus