emacs/layers.personal/orgtools/local/ob-mermaid/ob-mermaid.el
2018-04-07 10:54:04 +08:00

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