| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 | ;;; ob-processing.el --- Babel functions for processing -*- lexical-binding: t; -*-;; Copyright (C) 2015-2018 Free Software Foundation, Inc.;; Author: Jarmo Hurri (adapted from ob-asymptote.el written by Eric Schulte);; Keywords: literate programming, reproducible research;; Homepage: https://orgmode.org;; This file is part of GNU Emacs.;; GNU Emacs is free software: you can redistribute it and/or modify;; it under the terms of the GNU General Public License as published by;; the Free Software Foundation, either version 3 of the License, or;; (at your option) any later version.;; GNU Emacs is distributed in the hope that it will be useful,;; but WITHOUT ANY WARRANTY; without even the implied warranty of;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the;; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.;;; Commentary:;; Babel support for evaluating processing source code.;;;; This differs from most standard languages in that;;;; 1) there is no such thing as a "session" in processing;;;; 2) results can only be exported as html; in this case, the;;    processing code is embedded via a file into a javascript block;;    using the processing.js module; the script then draws the;;    resulting output when the web page is viewed in a browser; note;;    that the user is responsible for making sure that processing.js;;    is available on the website;;;; 3) it is possible to interactively view the sketch of the;;    Processing code block via Processing 2.0 Emacs mode, using;;    `org-babel-processing-view-sketch'.  You can bind this command;;    to, e.g., C-c C-v C-k with;;;;      (define-key org-babel-map (kbd "C-k") 'org-babel-processing-view-sketch);;; Requirements:;; - processing2-emacs mode :: https://github.com/ptrv/processing2-emacs;; - Processing.js module :: http://processingjs.org/;;; Code:(require 'ob)(require 'sha1)(declare-function processing-sketch-run "ext:processing-mode" ())(defvar org-babel-temporary-directory)(defvar org-babel-tangle-lang-exts)(add-to-list 'org-babel-tangle-lang-exts '("processing" . "pde"));; Default header tags depend on whether exporting html or not; if not;; exporting html, then no results are produced; otherwise results are;; HTML.(defvar org-babel-default-header-args:processing  '((:results . "html") (:exports . "results"))  "Default arguments when evaluating a Processing source block.")(defvar org-babel-processing-processing-js-filename "processing.js"  "Filename of the processing.js file.")(defun org-babel-processing-view-sketch ()  "Show the sketch of the Processing block under point in an external viewer."  (interactive)  (require 'processing-mode)  (let ((info (org-babel-get-src-block-info)))    (if (string= (nth 0 info) "processing")	(let* ((body (nth 1 info))	       (params (org-babel-process-params (nth 2 info)))	       (sketch-code		(org-babel-expand-body:generic		 body		 params		 (org-babel-variable-assignments:processing params))))	  ;; Note: sketch filename can not contain a hyphen, since it	  ;; has to be a valid java class name; for this reason	  ;; make-temp-file is repeated until no hyphen is in the	  ;; name; also sketch dir name must be the same as the	  ;; basename of the sketch file.	  (let* ((temporary-file-directory org-babel-temporary-directory)		 (sketch-dir		  (let (sketch-dir-candidate)		    (while			(progn			  (setq sketch-dir-candidate				(make-temp-file "processing" t))			  (when (string-match-p				 "-"				 (file-name-nondirectory sketch-dir-candidate))			    (delete-directory sketch-dir-candidate)			    t)))		    sketch-dir-candidate))		 (sketch-filename		  (concat sketch-dir			  "/"			  (file-name-nondirectory sketch-dir)			  ".pde")))	    (with-temp-file sketch-filename (insert sketch-code))	    (find-file sketch-filename)	    (processing-sketch-run)	    (kill-buffer)))      (message "Not inside a Processing source block."))))(defun org-babel-execute:processing (body params)  "Execute a block of Processing code.This function is called by `org-babel-execute-src-block'."  (let ((sketch-code	 (org-babel-expand-body:generic	  body	  params	  (org-babel-variable-assignments:processing params))))    ;; Results are HTML.    (let ((sketch-canvas-id (concat "ob-" (sha1 sketch-code))))      (concat "<script src=\""	      org-babel-processing-processing-js-filename	      "\"></script>\n <script type=\"text/processing\""	      " data-processing-target=\""	      sketch-canvas-id	      "\">\n"	      sketch-code	      "\n</script> <canvas id=\""	      sketch-canvas-id	      "\"></canvas>"))))(defun org-babel-prep-session:processing (_session _params)  "Return an error if the :session header argument is set.Processing does not support sessions"  (error "Processing does not support sessions"))(defun org-babel-variable-assignments:processing (params)  "Return list of processing statements assigning the block's variables."  (mapcar #'org-babel-processing-var-to-processing	  (org-babel--get-vars params)))(defun org-babel-processing-var-to-processing (pair)  "Convert an elisp value into a Processing variable.The elisp value PAIR is converted into Processing code specifyinga variable of the same value."  (let ((var (car pair))        (val (let ((v (cdr pair)))	       (if (symbolp v) (symbol-name v) v))))    (cond     ((integerp val)      (format "int %S=%S;" var val))     ((floatp val)      (format "float %S=%S;" var val))     ((stringp val)      (format "String %S=\"%s\";" var val))     ((and (listp val) (not (listp (car val))))      (let* ((type (org-babel-processing-define-type val))	     (fmt (if (eq 'String type) "\"%s\"" "%s"))	     (vect (mapconcat (lambda (e) (format fmt e)) val ", ")))	(format "%s[] %S={%s};" type var vect)))     ((listp val)      (let* ((type (org-babel-processing-define-type val))	     (fmt (if (eq 'String type) "\"%s\"" "%s"))             (array (mapconcat (lambda (row)				 (concat "{"					 (mapconcat (lambda (e) (format fmt e))						    row ", ")					 "}"))			       val ",")))        (format "%S[][] %S={%s};" type var array))))))(defun org-babel-processing-define-type (data)  "Determine type of DATA.DATA is a list.  Return type as a symbol.The type is `String' if any element in DATA is a string.Otherwise, it is either `float', if some elements are floats, or`int'."  (letrec ((type 'int)	   (find-type	    (lambda (row)	      (dolist (e row type)		(cond ((listp e) (setq type (funcall find-type e)))		      ((stringp e) (throw 'exit 'String))		      ((floatp e) (setq type 'float)))))))    (catch 'exit (funcall find-type data))))(provide 'ob-processing);;; ob-processing.el ends here
 |