ob-spice.el 7.3 KB

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