diff --git a/modules/lang/plantuml/autoload.el b/modules/lang/plantuml/autoload.el index 5ae3d4c6e..c42902891 100644 --- a/modules/lang/plantuml/autoload.el +++ b/modules/lang/plantuml/autoload.el @@ -1,10 +1,49 @@ ;;; lang/plantuml/autoload.el -*- lexical-binding: t; -*- ;;;###autoload -(defun +plantuml/install () - "Install plantuml.jar." - (interactive) - (if (file-exists-p plantuml-jar-path) - (user-error "plantuml.jar already installed") - (url-copy-file "https://downloads.sourceforge.net/project/plantuml/plantuml.jar" - plantuml-jar-path))) +(defun +plantuml-org-babel-execute:plantuml-a (body params) + "Execute a block of plantuml code with org-babel. +This function is called by `org-babel-execute-src-block'." + (require 'plantuml-mode) + (let* ((body (replace-regexp-in-string + "^[[:blank:]\n]*\\(@start\\)" + "\\\\\\1" + body)) + (out-file (or (cdr (assoc :file params)) + (concat doom-cache-dir + "ob-plantuml/" + (md5 str nil nil nil t) + ".png"))) + (in-file (org-babel-temp-file "plantuml-"))) + (if (eq plantuml-default-exec-mode 'server) + (let* ((url-request-location )) + (with-current-buffer + (url-retrieve-synchronously (plantuml-server-encode-url body)) + (goto-char (point-min)) + ;; skip the HTTP headers + (while (not (looking-at "\n")) (forward-line)) + (kill-region (point-min) (+ 1 (point))) + (write-file (org-babel-process-file-name out-file)))) + (let* ((cmd (concat (cond ((eq plantuml-default-exec-mode 'executable) + (unless (executable-find plantuml-executable-path) + (error "Could not find plantuml at %s" + (executable-find plantuml-executable-path))) + (concat (shell-quote-argument (executable-find plantuml-executable-path)) + " --headless ")) + ((not (file-exists-p org-plantuml-jar-path)) + (error "Could not find plantuml.jar at %s" org-plantuml-jar-path)) + ((concat "java " (or (cdr (assoc :java params)) "") " -jar " + (shell-quote-argument (expand-file-name plantuml-executable-path))))) + (concat (if (string= (file-name-extension out-file) "svg") + " -tsvg" "") + (if (string= (file-name-extension out-file) "eps") + " -teps" "") + " -p " (cdr (assoc :cmdline params)) " < " + (org-babel-process-file-name in-file) + " > " + (org-babel-process-file-name out-file))))) + (with-temp-file in-file + (insert (concat "@startuml\n" body "\n@enduml"))) + (message "%s" cmd) + (org-babel-eval cmd "") + nil)))) ;; signal that output has already been written to file diff --git a/modules/lang/plantuml/config.el b/modules/lang/plantuml/config.el index 1daf6eba3..4c7d1e749 100644 --- a/modules/lang/plantuml/config.el +++ b/modules/lang/plantuml/config.el @@ -1,12 +1,17 @@ ;;; lang/plantuml/config.el -*- lexical-binding: t; -*- (use-package! plantuml-mode - :defer t + :commands plantuml-download-jar :init (setq plantuml-jar-path (concat doom-etc-dir "plantuml.jar") org-plantuml-jar-path plantuml-jar-path) :config - (set-popup-rule! "^\\*PLANTUML" :size 0.4 :select nil :ttl 0)) + (set-popup-rule! "^\\*PLANTUML" :size 0.4 :select nil :ttl 0) + + (setq plantuml-default-exec-mode + (cond ((executable-find "plantuml") 'executable) + ((file-exists-p plantuml-jar-path) 'jar) + (plantuml-default-exec-mode)))) (use-package! flycheck-plantuml @@ -16,19 +21,9 @@ (after! ob-plantuml - (defadvice! +plantuml--fix-atstart-in-org-src-blocks-a (args) - "Fix error when executing plantuml src blocks in org-mode for code that -begins with '@'. This character needs to be escaped with a backslash or comma -for the block to execute correctly, so we do it automatically." - :filter-args #'org-babel-execute:plantuml - (cl-destructuring-bind (body params) args - (let* ((origin-body body) - (fix-body - (replace-regexp-in-string - "^[[:blank:]\n]*\\(@start\\)" - "\\\\\\1" - origin-body))) - (list fix-body params)))) - + ;; HACK We force ob-plantuml to use `plantuml-mode''s building mechanism, + ;; which is more sophisticated. + (advice-add #'org-babel-execute:plantuml + :override #'+plantuml-org-babel-execute:plantuml-a) (add-to-list 'org-babel-default-header-args:plantuml '(:cmdline . "-charset utf-8")))