dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

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