ob-spice.el (7487B)
1 ;;; ob-spice.el --- org-babel functions for spice evaluation 2 ;;; -*- coding: utf-8 -*- 3 4 ;; Author: Tiago Oliveira Weber 5 ;; Maintainer: stardiviner <numbchild@gmail.com> 6 ;; Homepage: https://git.sr.ht/~bzg/org-contrib 7 ;; Version: 0.4 8 ;; Package-Requires: ((spice-mode "0.0.1") (org "8")) 9 10 ;; License: GPL v3, or any later version 11 ;; 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. 16 ;; 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. 21 ;; 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/>. 24 25 ;;; Commentary: 26 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) 29 30 ;;; Requirements: 31 ;; 32 ;; - ngspice 33 34 ;;; Code: 35 (require 'ob) 36 37 (add-to-list 'org-babel-tangle-lang-exts '("spice" . "cir")) 38 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)))) 47 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)))) 51 (setq newbody ""); 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 " ")) 56 (setq firstword 1) 57 (dolist (word wordlist) 58 (progn ;loop through the words 59 (if (string-match "\\$\\(.*\\)\\[\\(.*\\)\\]" word) 60 (progn 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 65 (setq newword 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)) 73 (setq word newword))) 74 ) 75 ) ; end of (if (string-match "\\$\\(.*\\)\\[\\(.*\\)\\]" word)) 76 (if (string-match "\\$\\(.*\\)\\." word) ; if variable has a dot in the end 77 (progn 78 ;; if matches a non-vector variable format 79 (setq varname (match-string 1 word)) 80 (setq newword 81 (assoc-default varname vars 82 (lambda (key candidate) 83 (string= key candidate)))) 84 (if (not (eq newword nil)) 85 (progn 86 (if (not (stringp newword)) 87 (setq newword (number-to-string newword))) 88 (setq word (replace-match (concat newword ".") nil nil word)) 89 ;(setq word word) 90 ) 91 )) 92 );; end of (if (string-match "\\$\\(.*\\)\\." word) 93 (if (string-match "\\$\\(.*\\)" word) 94 (progn 95 ;; if matches a non-vector variable format 96 (setq varname (match-string 1 word)) 97 (setq newword 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)) 104 (setq word newword) 105 )) 106 ) 107 ) ; end of (if (string-match "\\$\\(.*\\)" word) 108 109 110 (setq newbody (concat newbody 111 (if (not (eq firstword 1)) " ") 112 word)) 113 (setq firstword 0) 114 ) ; end of (progn 115 ) ; end of (dolist (word wordlist)) 116 117 (setq newbody (concat newbody "\n")) 118 ) ; end of (progn ;; loop through list of lines ... ) 119 ) ; end of (dolist (line bodylinelist) ...function ...) 120 )) 121 122 ;;;###autoload 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)))) 127 128 ;;****************************** 129 ;; clean temporary files 130 (mapc (lambda (pair) 131 (when (string= (car pair) "file") 132 (setq textfile (concat (cdr pair) ".txt")) 133 (setq imagefile (concat (cdr pair) ".png")) 134 ) 135 ) 136 vars) 137 ;; (if (file-readable-p textfile) (delete-file textfile)) 138 ;; (if (file-readable-p imagefile) (delete-file imagefile)) 139 ;;******************************* 140 141 (org-babel-eval "ngspice -b " body) 142 143 ;; loop through all pairs (elements) of the list vars and set text and image file if finds "file" var 144 (mapc (lambda (pair) 145 (when (string= (car pair) "file") 146 (setq textfile (concat (cdr pair) ".txt")) 147 (setq imagefile (concat (cdr pair) ".png")))) 148 vars) 149 ;; produce results 150 ;; THE FOLLOWING WAS COMMENTED TEMPORARILY 151 ;; (concat 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 "]]") 156 ;; ) 157 ;; ) 158 159 ;; ;; Get measurement values from text-file by splitting comma separated values 160 (if (file-readable-p textfile) 161 (progn 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) 167 (progn 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 "]]") 172 ;;) 173 )) 174 result 175 ;; Produce output like '(test test2) 176 ;;'(test test2) 177 178 ) 179 ) 180 181 (provide 'ob-spice) 182 ;;; ob-spice.el ends here