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
| | ;;; ob-svgbob.el --- Babel Functions for SVGBob -*- lexical-binding: t; -*-
;; Copyright (C) 2021 Free Software Foundation, Inc.
;; Author: Steven vanZyl <rushsteve1@rushsteve1.us>
;; TEC <tec@tecosaur.com>
;; Maintainer: Timothy <tec@tecosaur.com>
;; Keywords: literate programming, reproducible research
;; Homepage: https://orgmode.org
;; This file is part of GNU Emacs.
;; GNU Emacs 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.
;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; Org-Babel support for evaluating and SVGBob diagrams.
;; https://github.com/ivanceras/svgbob
;; This is very similar to ob-dot.el with a similar list of caveats:
;; * There are no sessions
;; * We are generally only going to return results of type "file graphics"
;; * The "file" header argument is required
;; * SVGBob has no definite syntax
;; This file also includes some additional utility functions and a simple
;; derived major-mode for SVGBob
;;; Code:
(require 'ob)
(defcustom svgbob-executable "svgbob"
"The path to the SVGBob binary.
This can be installed from source using `cargo install svgbob_cli'"
:group 'svgbob
:type 'file)
(defcustom svgbob-buffer-name "*svgbob-output*"
"The name of the buffer that SVGBob will output to"
:group 'svgbob
:type 'string)
(defcustom org-babel-svgbob-options
'((background . "transparent"))
"Options passed to the SVGBob executable"
:group 'svgbob
:type '(alist :value-type (symbol string)))
;; So `org-edit-special' works.
;; Since SVGBob is based on simple ASCII diagrams without a definite, this mode
;; is derived from `artist-mode'.
(unless (fboundp 'svgbob-mode)
(define-derived-mode svgbob-mode artist-mode "svgbob"))
(defun ob-svgbob-string-to-svg (str)
"Converts a string to SVG text and returns a string of that"
(org-babel-eval
(concat svgbob-executable " "
(mapconcat (lambda (opt) (format "--%s %s " (symbol-name (car opt)) (cdr opt)))
org-babel-svgbob-options
" "))
str))
(defun ob-svgbob-region-to-svg (start end)
"Converts a region to SVG text in a new buffer"
(interactive "r")
(let ((str (ob-svgbob-string-to-svg (buffer-substring-no-properties start end))))
(with-current-buffer (get-buffer-create svgbob-buffer-name)
(read-only-mode 0) ; Disable read-only
(fundamental-mode) ; Required to erase the buffer
(erase-buffer)
(insert str)
(image-mode)
(read-only-mode)
(display-buffer-in-side-window (current-buffer) '((side . right))))))
(defun ob-svgbob-buffer-to-svg ()
"Converts a buffer to SVG text in a new buffer.
See `svgbob-region-to-svg' for more"
(interactive)
(ob-svgbob-region-to-svg (point-min) (point-max)))
(defvar org-babel-default-header-args:svgbob
'((:results . "file graphics") (:exports . "results"))
"Default arguments to use when evaluating a dot source block.")
(defun org-babel-execute:svgbob (body params)
(if (alist-get :file params)
(ob-svgbob-string-to-svg body)
(user-error "You need to specify a :file parameter")))
(defun org-babel-prep-session:svgbob (_session _params)
"Return an error because SVGBob does not support sessions."
(user-error "SVGBob does not support sessions"))
(provide 'ob-svgbob)
;;; ob-svgbob.el ends here
|