-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathob-pic.el
116 lines (110 loc) · 4.41 KB
/
ob-pic.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
;;; ob-pic.el --- Org babel functions for pic language -*- lexical-binding: t;
;;
;; Copyright (C) 2024 Daniel E. Doherty
;;
;; Author: Daniel E. Doherty <[email protected]>
;; Keywords: org, babel, pic, tools
;; Homepage: https://github.com/ob-pic
;; SPDX-License-Identifier: MIT
;; Created: 2024-12-07
;; Package-Requires: ((emacs "24.1"))
;; Package-Version: 1.0.0
;;
;;; Commentary:
;;
;; Org-Babel support for evaluating pic source code.
;;
;; This package allows a source block to use the =pic= language designator on a
;; source block:
;;
;; #+header: :file output.png
;; #+begin_src pic
;; down;
;; box "Emacs"; arrow;box "OrgMode"; arrow
;; box "begin_src" "pic"; arrow; box "ob-pic"; arrow;
;; box "pic2plot"; arrow; box "output.png"
;; #+end_src
;;
;; This produces a PNG file containing the generated diagram in output.png in
;; the current directory.
;;
;; For further usage information on this package, see https://github.com/ddoherty03/ob-pic
;;
;; For information on pic see https://pikchr.org/home/uv/pic.pdf and
;; on gpic at https://pikchr.org/home/uv/gpic.pdf
;;
;; The program actually used to generate the output is pic2plot, which is part
;; of the GNU plotutils collection of programs. Thus, you must have it
;; installed on your system in order for this to work.
;;
;; On ubuntu, you can install with `apt install plotutils`; on arch linux, do
;; something like `pacman -Sy plotutils`.
;;
;; This means that pic differs from most standard org-babel languages in that
;;
;; 1) there is no such thing as a "session" in pic
;;
;; 2) we are generally only going to return results of type "file"
;;
;; 3) we are adding the "file" and "cmdline" header arguments
;;
;; 4) there are no variables (at least for now)
;;
;; 5) one of the command line arguments is "-T <type>" where <type> is one of
;; "X", "png", "pnm", "gif", "svg", "ai", "ps", "cgm", "fig", "pcl",
;; "hpgl", "regis", "tek", and "meta". By default, this implementation
;; assumes an output type of "png". If you use "X", it will pop up an X
;; window with the graph displayed.
;;
;;; Code:
(require 'ob)
(require 'ob-eval)
(defvar org-babel-default-header-args:pic
'((:results . "file link") (:exports . "results"))
"Default arguments for evaluating a pic source block.")
(defun org-babel-execute:pic (body params)
"Execute a block of pic code from BODY with PARAMS from org-babel.
This function is called by `org-babel-execute-src-block'."
(let* ((user-cmdline (or (cdr (assq :cmdline params)) ""))
;; Match "-T" followed by one or more spaces and then "X"
(is-x-output (string-match-p "-T[[:space:]]+X" user-cmdline))
(outfile (if is-x-output
nil
(or (cdr (assq :file params))
(error "You must specify a :file header argument for non-X output types"))))
;; Resolve outfile path relative to default-directory
(outfile (expand-file-name outfile default-directory))
;; Ensure -T png is included in the cmdline unless overridden
(cmdline (if (string-match-p "-T" user-cmdline)
user-cmdline
(concat "-T png " user-cmdline)))
(infile (org-babel-temp-file "pic-"))
(cmd (if is-x-output
;; Append 'read' to keep the process open
(format "pic2plot %s %s; read"
cmdline
(shell-quote-argument infile))
(format "pic2plot %s %s > %s"
cmdline
(shell-quote-argument infile)
(shell-quote-argument outfile)))))
;; Write the body with .PS/.PE tags to the input file
(with-temp-file infile
(insert (format ".PS\n%s\n.PE\n" body)))
(message "Input file: %s" infile)
(message "Output file: %s" outfile)
(message "Running command: %s" cmd)
;; Execute the command
(if is-x-output
;; Non-blocking execution for X output
(start-process-shell-command "pic2plot" nil cmd)
;; Blocking execution for file-based outputs
(org-babel-eval cmd ""))
;; Return nil if the output is handled as a side effect
nil))
(defun org-babel-prep-session:pic (_session _params)
"Return an error because pic does not support sessions."
(error "Language 'pic' does not support sessions"))
(add-to-list 'org-babel-tangle-lang-exts '("pic" . "pic"))
(provide 'ob-pic)
;;; ob-pic.el ends here