Fix README History declaration
[ob-spice.git] / ob-spice.el
blobc4b21d31f6b69bc075d86e33e0deed4ea9817fe0
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)
6 ;; Version: 0.4
7 ;; Package-Requires: ((spice-mode "0.0.1") (org "8"))
8 ;; Homepage: https://repo.or.cz/ob-spice.git
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)
15 ;; any later version.
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/>.
25 ;;; Commentary:
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)
30 ;;; Requirements:
32 ;; - ngspice
34 ;;; Code:
35 (require 'ob)
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."
41 ;; example of usage
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 (if (fboundp 'org-babel--get-vars)
51 (org-babel--get-vars params)
52 (mapcar #'cdr (org-babel-get-header params :var)))))
53 (setq newbody "");
54 (setq bodylinelist (split-string body "\n"))
55 (dolist (line bodylinelist newbody)
56 (progn ;loop through list of lines
57 (setq wordlist (split-string line " "))
58 (setq firstword 1)
59 (dolist (word wordlist)
60 (progn ;loop through the words
61 (if (string-match "\\$\\(.*\\)\\[\\(.*\\)\\]" word)
62 (progn
63 ;; if matches a vector variable format
64 (setq varname (match-string 1 word))
65 (setq varindex (match-string 2 word))
66 ;; search varname in vars and use the value of varindex to word
67 (setq newword
68 (nth (string-to-number varindex)
69 (car (assoc-default varname vars
70 (lambda (key candidate)
71 (string= key candidate))))))
72 (if (not (eq newword nil))
73 (if (not (stringp newword))
74 (setq word (number-to-string newword))
75 (setq word newword)))
77 ) ; end of (if (string-match "\\$\\(.*\\)\\[\\(.*\\)\\]" word))
78 (if (string-match "\\$\\(.*\\)\\." word) ; if variable has a dot in the end
79 (progn
80 ;; if matches a non-vector variable format
81 (setq varname (match-string 1 word))
82 (setq newword
83 (assoc-default varname vars
84 (lambda (key candidate)
85 (string= key candidate))))
86 (if (not (eq newword nil))
87 (progn
88 (if (not (stringp newword))
89 (setq newword (number-to-string newword)))
90 (setq word (replace-match (concat newword ".") nil nil word))
91 ;(setq word word)
94 );; end of (if (string-match "\\$\\(.*\\)\\." word)
95 (if (string-match "\\$\\(.*\\)" word)
96 (progn
97 ;; if matches a non-vector variable format
98 (setq varname (match-string 1 word))
99 (setq newword
100 (assoc-default varname vars
101 (lambda (key candidate)
102 (string= key candidate))))
103 (if (not (eq newword nil))
104 (if (not (stringp newword))
105 (setq word (number-to-string newword))
106 (setq word newword)
109 ) ; end of (if (string-match "\\$\\(.*\\)" word)
112 (setq newbody (concat newbody
113 (if (not (eq firstword 1)) " ")
114 word))
115 (setq firstword 0)
116 ) ; end of (progn
117 ) ; end of (dolist (word wordlist))
119 (setq newbody (concat newbody "\n"))
120 ) ; end of (progn ;; loop through list of lines ... )
121 ) ; end of (dolist (line bodylinelist) ...function ...)
124 ;;;###autoload
125 (defun org-babel-execute:spice (body params)
126 "Execute a block of Spice code `BODY' with org-babel and `PARAMS'."
127 (let ((body (org-babel-expand-body:spice body params))
128 (vars (if (fboundp 'org-babel--get-vars)
129 (org-babel--get-vars params)
130 (mapcar #'cdr (org-babel-get-header params :var)))))
132 ;;******************************
133 ;; clean temporary files
134 (mapc (lambda (pair)
135 (when (string= (car pair) "file")
136 (setq textfile (concat (cdr pair) ".txt"))
137 (setq imagefile (concat (cdr pair) ".png"))
140 vars)
141 ;; (if (file-readable-p textfile) (delete-file textfile))
142 ;; (if (file-readable-p imagefile) (delete-file imagefile))
143 ;;*******************************
145 (org-babel-eval "ngspice -b " body)
147 ;; loop through all pairs (elements) of the list vars and set text and image file if finds "file" var
148 (mapc (lambda (pair)
149 (when (string= (car pair) "file")
150 (setq textfile (concat (cdr pair) ".txt"))
151 (setq imagefile (concat (cdr pair) ".png"))))
152 vars)
153 ;; produce results
154 ;; THE FOLLOWING WAS COMMENTED TEMPORARILY
155 ;; (concat
156 ;; (if (file-readable-p textfile)
157 ;; (get-string-from-file textfile))
158 ;; (if (file-readable-p imagefile)
159 ;; (concat '"#+ATTR_HTML: :width 600px \n [[file:./" imagefile "]]")
160 ;; )
161 ;; )
163 ;; ;; Get measurement values from text-file by splitting comma separated values
164 (if (file-readable-p textfile)
165 (progn
166 (setq rawtext (get-string-from-file textfile))
167 ;;(setq rawtext (replace-regexp-in-string "\n" "" rawtext))
168 (setq rawtext (replace-regexp-in-string "\n" "" rawtext))
169 (setq result (split-string rawtext ","))))
170 (if (file-readable-p imagefile)
171 (progn
172 ;; test if result exist already
173 ;;(if (boundp 'result)
174 (add-to-list 'result (concat '"[[file:./" imagefile "]]") t) ;; add imagefile to last entry
175 ;;(concat '"[[file:./" imagefile "]]")
176 ;;)
178 result
179 ;; Produce output like '(test test2)
180 ;;'(test test2)
185 (provide 'ob-spice)
186 ;;; ob-spice.el ends here