165 lines
5.3 KiB
EmacsLisp
165 lines
5.3 KiB
EmacsLisp
;;; ob-mermaid.el --- org-babel functions for mermaid evaluation
|
|
|
|
;; Copyright (C) 2009-2012 Free Software Foundation, Inc.
|
|
|
|
;; Author: Rongsong Shen
|
|
;; Keywords: literate programming, mermaid
|
|
;; Homepage: http://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 <http://www.gnu.org/licenses/>.
|
|
|
|
;;; Commentary:
|
|
|
|
;; Org-Babel support for evaluating mermaid source code.
|
|
;;
|
|
;; This differs from most standard languages in that
|
|
;;
|
|
;; 1) there is no such thing as a "session" in mermaid
|
|
;;
|
|
;; 2) we are generally only going to return results of type "file"
|
|
;;
|
|
;; 3) we are adding the "file" and "cmdline" header arguments, if file
|
|
;; is omitted then the -V option is passed to the mermaid command for
|
|
;; interactive viewing
|
|
|
|
;;; Requirements:
|
|
|
|
;;
|
|
;; - mermaid-mode :: Major mode for editing mermaid files
|
|
|
|
;;; Code:
|
|
(require 'ob)
|
|
(eval-when-compile (require 'cl))
|
|
|
|
(defvar org-babel-default-header-args:mermaid
|
|
'((:results . "file") (:exports . "results"))
|
|
"Default arguments when evaluating an Mermaid source block.")
|
|
|
|
(defcustom org-mermaid-program "mmdc"
|
|
"Command of mermaid. The command should use command line `mmc sourcefile'"
|
|
:group 'org-babel
|
|
:version "24.1"
|
|
:type 'string)
|
|
|
|
(defcustom org-mermaid-convert "convert"
|
|
"Command for convert picture format. The command should use format `convert source destintion'"
|
|
:group 'org-babel
|
|
:version "24.1"
|
|
:type 'string)
|
|
|
|
(defun mermaid-shell-command (dir cmd)
|
|
(shell-command (concat "/bin/sh -c \" cd "
|
|
dir ";"
|
|
cmd "\"")))
|
|
|
|
(defun org-babel-expand-body:mermaid (body params &optional var-lines)
|
|
body)
|
|
|
|
(defun mermaid-script (body)
|
|
body)
|
|
|
|
(defun mermaid-run (fmt in-file out-file)
|
|
(cond ((string= fmt "svg")
|
|
(copy-file (concat (file-name-nondirectory in-file) ".svg")
|
|
out-file))
|
|
(t (mermaid-shell-command org-babel-temporary-directory
|
|
(concat org-mermaid-convert " "
|
|
(file-name-nondirectory in-file)
|
|
".svg" " "
|
|
out-file)))))
|
|
|
|
;;;###autoload
|
|
(defun org-babel-execute:mermaid (body params)
|
|
"Execute a block of Mermaid code.
|
|
This function is called by `org-babel-execute-src-block'."
|
|
(let* ((result-params (split-string (or (cdr (assoc :results params)) "")))
|
|
(out-file (expand-file-name (cdr (assoc :file params))))
|
|
(format (or (and out-file
|
|
(string-match ".+\\.\\(.+\\)" out-file)
|
|
(match-string 1 out-file))
|
|
"pdf"))
|
|
(cmdline (cdr (assoc :cmdline params)))
|
|
(in-file (org-babel-temp-file "mermaid-"))
|
|
(cmd (concat org-mermaid-program " -i "
|
|
(file-name-nondirectory
|
|
(org-babel-process-file-name in-file)))))
|
|
(with-temp-file in-file
|
|
(insert (mermaid-script
|
|
(org-babel-expand-body:mermaid
|
|
body params))))
|
|
(mermaid-shell-command org-babel-temporary-directory
|
|
cmd)
|
|
(mermaid-run format in-file out-file)
|
|
nil)) ;; signal that output has already been written to file
|
|
|
|
;;;###autoload
|
|
(defun org-babel-prep-session:mermaid (session params)
|
|
"Return an error if the :session header argument is set.
|
|
Mermaid does not support sessions"
|
|
(error "Mermaid does not support sessions"))
|
|
|
|
;;;###autoload
|
|
(defun org-babel-variable-assignments:mermaid (params)
|
|
"Return list of mermaid statements assigning the block's variables"
|
|
t)
|
|
|
|
(defconst mermaid-type-prefix "^[^:]*:")
|
|
|
|
|
|
(defun org-babel-mermaid-var-value (val)
|
|
(setq mmd-m-end 0)
|
|
(setq mmd-m-start (string-match mermaid-type-prefix val))
|
|
(if mmd-m-start
|
|
(setq mmd-m-end (match-end 0)))
|
|
(setq mmd-var-type "")
|
|
(setq mmd-var-value val)
|
|
(if (> mmd-m-end 0)
|
|
(progn (setq mmd-var-type
|
|
(substring val mmd-m-start (- mmd-m-end 1)))
|
|
(setq mmd-var-value
|
|
(substring val mmd-m-end (length val)))))
|
|
(cons mmd-var-type (cons mmd-var-value nil)))
|
|
|
|
(defun org-babel-mermaid-var-to-mermaid (pair)
|
|
"Convert an elisp value into an Mermaid variable.
|
|
The elisp value PAIR is converted into Mermaid code specifying
|
|
a variable of the same value."
|
|
)
|
|
|
|
(defun org-babel-mermaid-define-type (data)
|
|
"Determine type of DATA.
|
|
|
|
DATA is a list. Return type as a symbol.
|
|
|
|
The type is `string' if any element in DATA is
|
|
a string. Otherwise, it is either `numeric', if some elements are
|
|
floats, or `numeric'."
|
|
(let* ((type 'numeric)
|
|
find-type ; for byte-compiler
|
|
(find-type
|
|
(function
|
|
(lambda (row)
|
|
(catch 'exit
|
|
(mapc (lambda (el)
|
|
(cond ((listp el) (funcall find-type el))
|
|
((stringp el) (throw 'exit (setq type 'string)))
|
|
((floatp el) (setq type 'numeric))))
|
|
row))))))
|
|
(funcall find-type data) type))
|
|
|
|
(provide 'ob-mermaid)
|
|
;;; ob-mermaid.el ends here
|