-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpel-graphviz-dot.el
121 lines (110 loc) · 5.36 KB
/
pel-graphviz-dot.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
;;; pel-graphviz-dot.el --- Graphviz Dot utilities. -*-lexical-binding: t-*-
;; Copyright (C) 2020, 2021 Pierre Rouleau
;; Author: Pierre Rouleau <[email protected]>
;; This file is part of the PEL package
;; This file is not part of GNU Emacs.
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;; -----------------------------------------------------------------------------
;;; Commentary:
;;
;; This file contains code that extends support for Graphviz Dot
;;
;; The functions are:
;;
;; * pel-render-commented-graphviz-dot
;; - pel--graphviz-dot-region
;; -----------------------------------------------------------------------------
;;; Code:
(require 'pel--base) ; use: pel-region-for
(require 'pel-ccp) ; use: pel-delete-whole-line
(defun pel--graphviz-dot-region (&optional pos)
"Return the position of the beginning & end of graphviz dot code block.
Search at POS if specified, otherwise search around point.
Include whole lines.
Return a (start . end) cons cell if found, otherwise return nil."
(pel-region-for "@start-gdot" "@end-gdot" pos))
;;-pel-autoload
(defun pel-render-commented-graphviz-dot (&optional pos)
"Render the Graphviz-Dot markup embedded in current mode comment.
Search at POS if specified, otherwise search around point.
Use region if identified otherwise use Graphviz-Dot block.
NOTE: creates an image file in a temporary directory."
(interactive)
(if (and (require 'graphviz-dot-mode nil :noerror)
(fboundp 'graphviz-dot-mode)
(fboundp 'graphviz-dot-preview))
(let ((beg nil)
(end nil)
(text nil)
(f-comment-start comment-start)
(f-comment-end comment-end)
(f-comment-continue comment-continue))
(if (use-region-p)
(progn
(setq beg (region-beginning))
(setq end (region-end)))
(let ((beg.end (pel--graphviz-dot-region pos)))
(setq beg (car beg.end))
(setq end (cdr beg.end))))
(if (and beg end)
;; Creates a temporary file, open that file, write the text
;; in it, then remove comments, remove markers are surrounding
;; empty lines. Then use graphviz-dot-preview to render the DOT
;; code inside a new buffer and clean up.
;; Unfortunately the buffer for the temp file is visible during the
;; operation. I could not get this to work by using a temp buffer;
;; it had to be a file otherwise graphviz-dot-preview would prompt
;; for a file name.
(progn
(setq text (buffer-substring-no-properties beg end))
(let ((temp-fname (make-temp-file
(format "pel-gdot-%s-"
(file-name-nondirectory
(file-name-sans-extension
(buffer-file-name))))
nil ".dot")))
(find-file temp-fname)
(insert text)
(unwind-protect
(progn
;; Remove comments : TODO: won't work for comments like C
;; if the beginning and end of the comment is not in buffer.
(setq comment-start f-comment-start)
(setq comment-end f-comment-end)
(setq comment-continue f-comment-continue)
(uncomment-region (point-min) (point-max))
;; Remove the marker lines and blank lines around the
;; graph definition
(goto-char (point-min))
(pel-delete-whole-line)
(delete-blank-lines)
(goto-char (point-max))
(pel-delete-whole-line)
(delete-blank-lines)
;; activate Graphviz-Dot mode and render the diagram in
;; other window
(graphviz-dot-mode)
(goto-char (point-min))
(forward-line 2)
(graphviz-dot-preview))
;; cleanup - remove buffer and temp file.
;; But does NOT remove the generated PNG file.
(and (file-exists-p temp-fname)
(kill-buffer (get-file-buffer temp-fname))
(delete-file temp-fname)))))
(user-error "Missing `@start-gdot' & `@end-gdot' markers!")))
(user-error "Requires missing graphviz-dot-mode!")))
;; -----------------------------------------------------------------------------
(provide 'pel-graphviz-dot)
;;; pel-graphviz-dot.el ends here