diff --git a/lisp/langs/org-babel-gnuplot.el b/lisp/langs/org-babel-gnuplot.el index 34a4f4ebd..6281a9079 100644 --- a/lisp/langs/org-babel-gnuplot.el +++ b/lisp/langs/org-babel-gnuplot.el @@ -41,12 +41,68 @@ (add-to-list 'org-babel-tangle-langs '("gnuplot" "gnuplot")) +(defvar org-babel-default-header-args:gnuplot '((:results . "file")) + "Default arguments to use when evaluating a gnuplot source block.") + +(defvar org-babel-gnuplot-timestamp-fmt nil) + (defun org-babel-execute:gnuplot (body params) "Execute a block of Gnuplot code with org-babel. This function is called by `org-babel-execute-src-block'." - (message "executing Gnuplot source code block")) + (message "executing Gnuplot source code block") + (let* ((vars (org-babel-ref-variables params)) + (result-params (split-string (or (cdr (assoc :results params)) ""))) + (out-file (cdr (assoc :file params))) + (cmdline (cdr (assoc :cmdline params))) + (in-file (make-temp-file "org-babel-ditaa"))) + ;; insert variables into code body + (mapc + (lambda (pair) + (message "resolving %S" pair) ;; debugging + (setq body + (replace-regexp-in-string + (regexp-quote (format "%s" (car pair))) + (if (listp (cdr pair)) + (org-babel-gnuplot-table-to-data + (cdr pair) (make-temp-file "org-babel-gnuplot") params) + (cdr pair)) body))) + vars) + (with-temp-buffer ;; evaluate the code body with gnuplot + (insert (concat body "\n")) + (gnuplot-mode) + (gnuplot-send-buffer-to-gnuplot)) + out-file)) (defun org-babel-prep-session:gnuplot (session params)) +(defun org-babel-gnuplot-quote-timestamp-field (s) + "Convert field S from timestamp to Unix time and export to gnuplot." + (format-time-string org-babel-gnuplot-timestamp-fmt (org-time-string-to-time s))) + +(defun org-babel-gnuplot-quote-tsv-field (s) + "Quote field S for export to gnuplot." + (unless (stringp s) + (setq s (format "%s" s))) + (if (string-match org-table-number-regexp s) s + (if (string-match org-ts-regexp3 s) + (org-babel-gnuplot-quote-timestamp-field s) + (concat "\"" (mapconcat 'identity (split-string s "\"") "\"\"") "\"")))) + +(defun org-babel-gnuplot-table-to-data (table data-file params) + "Export TABLE to DATA-FILE in a format readable by gnuplot. +Pass PARAMS through to `orgtbl-to-generic' when exporting TABLE." + (with-temp-file data-file + (message "table = %S" table) + (make-local-variable 'org-babel-gnuplot-timestamp-fmt) + (setq org-babel-gnuplot-timestamp-fmt (or + (plist-get params :timefmt) + "%Y-%m-%d-%H:%M:%S")) + (insert (orgtbl-to-generic + table + (org-combine-plists + '(:sep "\t" :fmt org-babel-gnuplot-quote-tsv-field) + params)))) + data-file) + (provide 'org-babel-gnuplot) ;;; org-babel-gnuplot.el ends here diff --git a/lisp/org-babel.el b/lisp/org-babel.el index 60c60b376..5cf876939 100644 --- a/lisp/org-babel.el +++ b/lisp/org-babel.el @@ -160,8 +160,8 @@ the header arguments specified at the source code block." (result-params (third processed-params)) (result-type (fourth processed-params)) (cmd (intern (concat "org-babel-execute:" lang))) - result) - ;; (message (format "params=%S" params)) ;; debugging + result) + ;; (message "params=%S" params) ;; debugging statement (unless (member lang org-babel-interpreters) (error "Language is not in `org-babel-interpreters': %s" lang)) (when arg (setq result-params (cons "silent" result-params))) @@ -414,8 +414,8 @@ line. If no result exists for this block then create a (let* ((on-lob-line (progn (beginning-of-line 1) (looking-at org-babel-lob-one-liner-regexp))) (name (if on-lob-line (org-babel-lob-get-info) (org-babel-get-src-block-name))) - end head) - (unless on-lob-line (goto-char (org-babel-where-is-src-block-head))) + (head (unless on-lob-line (org-babel-where-is-src-block-head))) end) + (when head (goto-char head)) (or (and name (message name) (org-babel-find-named-result name)) (and (or on-lob-line (re-search-forward "#\\+end_src" nil t)) (progn (move-end-of-line 1) @@ -460,7 +460,8 @@ silent -- no results are inserted" (string-equal (substring result -1) "\r")))) (setq result (concat result "\n"))) (save-excursion - (goto-char (org-babel-where-is-src-block-result)) (forward-line 1) + (let ((existing-result (org-babel-where-is-src-block-result))) + (when existing-result (goto-char existing-result) (forward-line 1))) (if (stringp result) ;; assume the result is a table if it's not a string (if (member "file" insert) (insert result) diff --git a/org-babel.org b/org-babel.org index c059273f1..b848cc12c 100644 --- a/org-babel.org +++ b/org-babel.org @@ -1985,13 +1985,37 @@ This could probably be added to [[file:lisp/org-babel-script.el][org-babel-scrip *** STARTED gnuplot (see [[* file result types][file result types]]) -- a required =file= header argument +- a =file= header argument - a =cmdline= header argument - to add variables - scalar variables should be replaced in the body of the gnuplot code - vector variables should be exported to tab-separated files, and the variable names should be replaced with the path to the files +#+PLOT: title:"Citas" ind:1 deps:(3) type:2d with:histograms set:"yrange [0:]" +#+TBLNAME: gnuplot-data +| independent var | first dependent var | second dependent var | +|-----------------+---------------------+----------------------| +| 0.1 | 0.425 | 0.375 | +| 0.2 | 0.3125 | 0.3375 | +| 0.3 | 0.24999993 | 0.28333338 | +| 0.4 | 0.275 | 0.28125 | +| 0.5 | 0.26 | 0.27 | +| 0.6 | 0.25833338 | 0.24999993 | +| 0.7 | 0.24642845 | 0.23928553 | +| 0.8 | 0.23125 | 0.2375 | +| 0.9 | 0.23333323 | 0.2333332 | +| 1 | 0.2225 | 0.22 | +| 1.1 | 0.20909075 | 0.22272708 | +| 1.2 | 0.19999998 | 0.21458333 | +| 1.3 | 0.19615368 | 0.21730748 | + +#+srcname: implementing-gnuplot +#+begin_src gnuplot :var data=gnuplot-data +set title "Implementing Gnuplot" +plot "data" using 1:2 with lines +#+end_src + *** TODO dot (see [[* file result types][file result types]])