ob-plantuml.el (6456B)
1 ;;; ob-plantuml.el --- Babel Functions for Plantuml -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2010-2024 Free Software Foundation, Inc. 4 5 ;; Author: Zhang Weize 6 ;; Keywords: literate programming, reproducible research 7 ;; URL: https://orgmode.org 8 9 ;; This file is part of GNU Emacs. 10 11 ;; GNU Emacs is free software: you can redistribute it and/or modify 12 ;; it under the terms of the GNU General Public License as published by 13 ;; the Free Software Foundation, either version 3 of the License, or 14 ;; (at your option) any later version. 15 16 ;; GNU Emacs is distributed in the hope that it will be useful, 17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 ;; GNU General Public License for more details. 20 21 ;; You should have received a copy of the GNU General Public License 22 ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. 23 24 ;;; Commentary: 25 26 ;; Org-Babel support for evaluating plantuml script. 27 ;; 28 ;; Inspired by Ian Yang's org-export-blocks-format-plantuml 29 ;; https://www.emacswiki.org/emacs/org-export-blocks-format-plantuml.el 30 31 ;;; Requirements: 32 33 ;; plantuml | https://plantuml.com/ 34 ;; plantuml.jar | `org-plantuml-jar-path' should point to the jar file (when exec mode is `jar') 35 36 ;;; Code: 37 38 (require 'org-macs) 39 (org-assert-version) 40 41 (require 'ob) 42 43 (defvar org-babel-default-header-args:plantuml 44 '((:results . "file") (:exports . "results")) 45 "Default arguments for evaluating a plantuml source block.") 46 47 (defcustom org-plantuml-jar-path "" 48 "Path to the plantuml.jar file." 49 :group 'org-babel 50 :version "24.1" 51 :type 'string) 52 53 (defcustom org-plantuml-exec-mode 'jar 54 "Method to use for PlantUML diagram generation. 55 `jar' means to use java together with the JAR. 56 The JAR can be configured via `org-plantuml-jar-path'. 57 58 `plantuml' means to use the PlantUML executable. 59 The executable can be configured via `org-plantuml-executable-path'. 60 You can also configure extra arguments via `org-plantuml-args'." 61 :group 'org-babel 62 :package-version '(Org . "9.4") 63 :type 'symbol 64 :options '(jar plantuml)) 65 66 (defcustom org-plantuml-executable-path "plantuml" 67 "File name of the PlantUML executable." 68 :group 'org-babel 69 :package-version '(Org . "9.4") 70 :type 'string) 71 72 (defcustom org-plantuml-args (list "-headless") 73 "The arguments passed to plantuml when executing PlantUML." 74 :group 'org-babel 75 :package-version '(Org . "9.4") 76 :type '(repeat string)) 77 78 (defcustom org-babel-plantuml-svg-text-to-path nil 79 "When non-nil, export text in SVG images to paths using Inkscape." 80 :group 'org-babel 81 :package-version '(Org . "9.5") 82 :type 'boolean) 83 84 (defun org-babel-variable-assignments:plantuml (params) 85 "Return a list of PlantUML statements assigning the block's variables. 86 PARAMS is a property list of source block parameters, which may 87 contain multiple entries for the key `:var'. `:var' entries in PARAMS 88 are expected to be scalar variables." 89 (mapcar 90 (lambda (pair) 91 (format "!define %s %s" 92 (car pair) 93 (replace-regexp-in-string "\"" "" (cdr pair)))) 94 (org-babel--get-vars params))) 95 96 (defun org-babel-plantuml-make-body (body params) 97 "Return PlantUML input string. 98 99 BODY is the content of the source block and PARAMS is a property list 100 of source block parameters. This function relies on the 101 `org-babel-expand-body:generic' function to extract `:var' entries 102 from PARAMS and on the `org-babel-variable-assignments:plantuml' 103 function to convert variables to PlantUML assignments. 104 105 If BODY does not contain @startXXX ... @endXXX clauses, @startuml 106 ... @enduml will be added." 107 (let ((full-body 108 (org-babel-expand-body:generic 109 body params (org-babel-variable-assignments:plantuml params)))) 110 (if (string-prefix-p "@start" body t) full-body 111 (format "@startuml\n%s\n@enduml" full-body)))) 112 113 (defun org-babel-execute:plantuml (body params) 114 "Execute a block of plantuml code with org-babel. 115 This function is called by `org-babel-execute-src-block'." 116 (let* ((do-export (member "file" (cdr (assq :result-params params)))) 117 (out-file (if do-export 118 (or (cdr (assq :file params)) 119 (error "No :file provided but :results set to file. For plain text output, set :results to verbatim")) 120 (org-babel-temp-file "plantuml-" ".txt"))) 121 (cmdline (cdr (assq :cmdline params))) 122 (in-file (org-babel-temp-file "plantuml-")) 123 (java (or (cdr (assq :java params)) "")) 124 (executable (cond ((eq org-plantuml-exec-mode 'plantuml) org-plantuml-executable-path) 125 (t "java"))) 126 (executable-args (cond ((eq org-plantuml-exec-mode 'plantuml) org-plantuml-args) 127 ((string= "" org-plantuml-jar-path) 128 (error "`org-plantuml-jar-path' is not set")) 129 ((not (file-exists-p org-plantuml-jar-path)) 130 (error "Could not find plantuml.jar at %s" org-plantuml-jar-path)) 131 (t `(,java 132 "-jar" 133 ,(shell-quote-argument (expand-file-name org-plantuml-jar-path)) 134 ,@org-plantuml-args)))) 135 (full-body (org-babel-plantuml-make-body body params)) 136 (cmd (mapconcat #'identity 137 (append 138 (list executable) 139 executable-args 140 (pcase (file-name-extension out-file) 141 ("png" '("-tpng")) 142 ("svg" '("-tsvg")) 143 ("eps" '("-teps")) 144 ("pdf" '("-tpdf")) 145 ("tex" '("-tlatex")) 146 ("tikz" '("-tlatex:nopreamble")) 147 ("vdx" '("-tvdx")) 148 ("xmi" '("-txmi")) 149 ("scxml" '("-tscxml")) 150 ("html" '("-thtml")) 151 ("txt" '("-ttxt")) 152 ("utxt" '("-utxt"))) 153 (list 154 "-p" 155 cmdline 156 "<" 157 (org-babel-process-file-name in-file) 158 ">" 159 (org-babel-process-file-name out-file))) 160 " "))) 161 (with-temp-file in-file (insert full-body)) 162 (message "%s" cmd) (org-babel-eval cmd "") 163 (if (and (string= (file-name-extension out-file) "svg") 164 org-babel-plantuml-svg-text-to-path) 165 (org-babel-eval (format "inkscape %s -T -l %s" out-file out-file) "")) 166 (unless do-export (with-temp-buffer 167 (insert-file-contents out-file) 168 (buffer-substring-no-properties 169 (point-min) (point-max)))))) 170 171 (defun org-babel-prep-session:plantuml (_session _params) 172 "Return an error because plantuml does not support sessions." 173 (error "Plantuml does not support sessions")) 174 175 (provide 'ob-plantuml) 176 177 ;;; ob-plantuml.el ends here