| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 | ;;; ob-picolisp.el --- org-babel functions for picolisp evaluation;; Copyright (C) 2010-2016 Free Software Foundation, Inc.;; Authors: Thorsten Jolitz;;	 Eric Schulte;; Keywords: literate programming, reproducible research;; Homepage: http://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 <http://www.gnu.org/licenses/>.;;; Commentary:;; This library enables the use of PicoLisp in the multi-language;; programming framework Org-Babel.  PicoLisp is a minimal yet;; fascinating lisp dialect and a highly productive application;; framework for web-based client-server applications on top of;; object-oriented databases.  A good way to learn PicoLisp is to first;; read Paul Grahams essay "The hundred year language";; (http://www.paulgraham.com/hundred.html) and then study the various;; documents and essays published in the PicoLisp wiki;; (http://picolisp.com/5000/-2.html). PicoLisp is included in some;; GNU/Linux Distributions, and can be downloaded here:;; http://software-lab.de/down.html.  It ships with a picolisp-mode and;; a inferior-picolisp-mode for Emacs (to be found in the /lib/el/;; directory).;; Although it might seem more natural to use Emacs Lisp for most;; Lisp-based programming tasks inside Org-Mode, an Emacs library;; written in Emacs Lisp, PicoLisp has at least two outstanding;; features that make it a valuable addition to Org-Babel:;; PicoLisp _is_ an object-oriented database with a Prolog-based query;; language implemented in PicoLisp (Pilog). Database objects are;; first-class members of the language.;; PicoLisp is an extremely productive framework for the development;; of interactive web-applications (on top of a database).;;; Requirements:;;; Code:(require 'ob)(require 'comint)(eval-when-compile (require 'cl))(declare-function run-picolisp "ext:inferior-picolisp" (cmd))(defvar org-babel-tangle-lang-exts) ;; Autoloaded;; optionally define a file extension for this language(add-to-list 'org-babel-tangle-lang-exts '("picolisp" . "l"));;; interferes with settings in org-babel buffer?;; optionally declare default header arguments for this language;; (defvar org-babel-default-header-args:picolisp;;   '((:colnames . "no"));;   "Default arguments for evaluating a picolisp source block.")(defvar org-babel-picolisp-eoe "org-babel-picolisp-eoe"  "String to indicate that evaluation has completed.")(defcustom org-babel-picolisp-cmd "pil"  "Name of command used to evaluate picolisp blocks."  :group 'org-babel  :version "24.1"  :type 'string)(defun org-babel-expand-body:picolisp (body params)  "Expand BODY according to PARAMS, return the expanded body."  (let ((vars (mapcar #'cdr (org-babel-get-header params :var)))        (result-params (cdr (assoc :result-params params)))        (print-level nil) (print-length nil))    (if (> (length vars) 0)        (concat "(prog (let ("                (mapconcat                 (lambda (var)                   (format "%S '%S)"                           (print (car var))                           (print (cdr var))))                 vars "\n      ")                " \n" body ") )")      body)))(defun org-babel-execute:picolisp (body params)  "Execute a block of Picolisp code with org-babel.  This function is called by `org-babel-execute-src-block'"  (message "executing Picolisp source code block")  (let* (	 ;; Name of the session or "none".	 (session-name (cdr (assoc :session params)))	 ;; Set the session if the session variable is non-nil.	 (session (org-babel-picolisp-initiate-session session-name))	 ;; Either OUTPUT or VALUE which should behave as described above.	 (result-type (cdr (assoc :result-type params)))	 (result-params (cdr (assoc :result-params params)))	 ;; Expand the body with `org-babel-expand-body:picolisp'.	 (full-body (org-babel-expand-body:picolisp body params))         ;; Wrap body appropriately for the type of evaluation and results.         (wrapped-body          (cond           ((or (member "code" result-params)                (member "pp" result-params))            (format "(pretty (out \"/dev/null\" %s))" full-body))           ((and (member "value" result-params) (not session))            (format "(print (out \"/dev/null\" %s))" full-body))           ((member "value" result-params)            (format "(out \"/dev/null\" %s)" full-body))           (t full-body)))         (result          (if (not (string= session-name "none"))              ;; Session based evaluation.              (mapconcat ;; <- joins the list back into a single string               #'identity               (butlast ;; <- remove the org-babel-picolisp-eoe line                (delq nil                      (mapcar                       (lambda (line)                         (org-babel-chomp      ;; Remove trailing newlines.                          (when (> (length line) 0) ;; Remove empty lines.                            (cond                             ;; Remove leading "-> " from return values.                             ((and (>= (length line) 3)                                   (string= "-> " (substring line 0 3)))                              (substring line 3))                             ;; Remove trailing "-> <<return-value>>" on the                             ;; last line of output.                             ((and (member "output" result-params)                                   (string-match-p "->" line))                              (substring line 0 (string-match "->" line)))                             (t line)                             )                            ;;(if (and (>= (length line) 3);Remove leading "<-"                            ;;         (string= "-> " (substring line 0 3)))                            ;;    (substring line 3)                            ;;  line)                            )))                       ;; Returns a list of the output of each evaluated exp.                       (org-babel-comint-with-output                           (session org-babel-picolisp-eoe)                         (insert wrapped-body) (comint-send-input)                         (insert "'" org-babel-picolisp-eoe)                         (comint-send-input)))))               "\n")            ;; external evaluation            (let ((script-file (org-babel-temp-file "picolisp-script-")))              (with-temp-file script-file                (insert (concat wrapped-body "(bye)")))              (org-babel-eval               (format "%s %s"                       org-babel-picolisp-cmd                       (org-babel-process-file-name script-file))               "")))))    (org-babel-result-cond result-params      result      (read result))))(defun org-babel-picolisp-initiate-session (&optional session-name)  "If there is not a current inferior-process-buffer in SESSIONthen create.  Return the initialized session."  (unless (string= session-name "none")    (require 'inferior-picolisp)    ;; provide a reasonable default session name    (let ((session (or session-name "*inferior-picolisp*")))      ;; check if we already have a live session by this name      (if (org-babel-comint-buffer-livep session)          (get-buffer session)        (save-window-excursion          (run-picolisp org-babel-picolisp-cmd)          (rename-buffer session-name)          (current-buffer))))))(provide 'ob-picolisp);;; ob-picolisp.el ends here
 |