1 ;;; ob-spice.el --- org-babel functions for spice evaluation
2 ;;; -*- coding: utf-8 -*-
4 ;; Author: Tiago Oliveira Weber
5 ;; Maintainer: stardiviner (numbchild@gmail.com)
7 ;; Package-Requires: ((spice-mode "0.0.1") (org "8"))
8 ;; Homepage: https://tiagoweber.github.io
10 ;; License: GPL v3, or any later version
12 ;; This file is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 3, or (at your option)
17 ;; This file is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
27 ;; Org-Babel support for evaluating spice script.
28 ;; Inspired by Ian Yang's org-export-blocks-format-plantuml (https://www.emacswiki.org/emacs/org-export-blocks-format-plantuml.el)
37 (add-to-list 'org-babel-tangle-lang-exts
'("spice" .
"cir"))
39 (defun ob-spice-concat (wordlist)
40 "Concatenate elements of a `WORDLIST' into a string separated by spaces."
42 ;; (ob-spice-concat '("This" "is" "a" "long" "journey"))
43 (setq newtext
(car wordlist
)) ; first word is without space before
44 (setq wordlist
(rest wordlist
)) ; exclude the first word from the list
45 (dolist (word wordlist newtext
) ; loop through the list and concatenate the values
46 (setq newtext
(concat newtext
" " word
))))
48 (defun org-babel-expand-body:spice
(body params
)
49 "Expand BODY according to PARAMS, return the expanded body."
50 (let* ((vars (mapcar #'cdr
(org-babel-get-header params
:var
))))
52 (setq bodylinelist
(split-string body
"\n"))
53 (dolist (line bodylinelist newbody
)
54 (progn ;loop through list of lines
55 (setq wordlist
(split-string line
" "))
57 (dolist (word wordlist
)
58 (progn ;loop through the words
59 (if (string-match "\\$\\(.*\\)\\[\\(.*\\)\\]" word
)
61 ;; if matches a vector variable format
62 (setq varname
(match-string 1 word
))
63 (setq varindex
(match-string 2 word
))
64 ;; search varname in vars and use the value of varindex to word
66 (nth (string-to-number varindex
)
67 (car (assoc-default varname vars
68 (lambda (key candidate
)
69 (string= key candidate
))))))
70 (if (not (eq newword nil
))
71 (if (not (stringp newword
))
72 (setq word
(number-to-string newword
))
75 ) ; end of (if (string-match "\\$\\(.*\\)\\[\\(.*\\)\\]" word))
76 (if (string-match "\\$\\(.*\\)\\." word
) ; if variable has a dot in the end
78 ;; if matches a non-vector variable format
79 (setq varname
(match-string 1 word
))
81 (assoc-default varname vars
82 (lambda (key candidate
)
83 (string= key candidate
))))
84 (if (not (eq newword nil
))
86 (if (not (stringp newword
))
87 (setq newword
(number-to-string newword
)))
88 (setq word
(replace-match (concat newword
".") nil nil word
))
92 );; end of (if (string-match "\\$\\(.*\\)\\." word)
93 (if (string-match "\\$\\(.*\\)" word
)
95 ;; if matches a non-vector variable format
96 (setq varname
(match-string 1 word
))
98 (assoc-default varname vars
99 (lambda (key candidate
)
100 (string= key candidate
))))
101 (if (not (eq newword nil
))
102 (if (not (stringp newword
))
103 (setq word
(number-to-string newword
))
107 ) ; end of (if (string-match "\\$\\(.*\\)" word)
110 (setq newbody
(concat newbody
111 (if (not (eq firstword
1)) " ")
115 ) ; end of (dolist (word wordlist))
117 (setq newbody
(concat newbody
"\n"))
118 ) ; end of (progn ;; loop through list of lines ... )
119 ) ; end of (dolist (line bodylinelist) ...function ...)
123 (defun org-babel-execute:spice
(body params
)
124 "Execute a block of Spice code `BODY' with org-babel and `PARAMS'."
125 (let ((body (org-babel-expand-body:spice body params
))
126 (vars (mapcar #'cdr
(org-babel-get-header params
:var
))))
128 ;;******************************
129 ;; clean temporary files
131 (when (string= (car pair
) "file")
132 (setq textfile
(concat (cdr pair
) ".txt"))
133 (setq imagefile
(concat (cdr pair
) ".png"))
137 ;; (if (file-readable-p textfile) (delete-file textfile))
138 ;; (if (file-readable-p imagefile) (delete-file imagefile))
139 ;;*******************************
141 (org-babel-eval "ngspice -b " body
)
143 ;; loop through all pairs (elements) of the list vars and set text and image file if finds "file" var
145 (when (string= (car pair
) "file")
146 (setq textfile
(concat (cdr pair
) ".txt"))
147 (setq imagefile
(concat (cdr pair
) ".png"))))
150 ;; THE FOLLOWING WAS COMMENTED TEMPORARILY
152 ;; (if (file-readable-p textfile)
153 ;; (get-string-from-file textfile))
154 ;; (if (file-readable-p imagefile)
155 ;; (concat '"#+ATTR_HTML: :width 600px \n [[file:./" imagefile "]]")
159 ;; ;; Get measurement values from text-file by splitting comma separated values
160 (if (file-readable-p textfile
)
162 (setq rawtext
(get-string-from-file textfile
))
163 ;;(setq rawtext (replace-regexp-in-string "\n" "" rawtext))
164 (setq rawtext
(replace-regexp-in-string "\n" "" rawtext
))
165 (setq result
(split-string rawtext
","))))
166 (if (file-readable-p imagefile
)
168 ;; test if result exist already
169 ;;(if (boundp 'result)
170 (add-to-list 'result
(concat '"[[file:./" imagefile
"]]") t
) ;; add imagefile to last entry
171 ;;(concat '"[[file:./" imagefile "]]")
175 ;; Produce output like '(test test2)
182 ;;; ob-spice.el ends here