emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* ob-lua.el
@ 2014-05-06 22:34 dieter
  2014-05-06 22:46 ` ob-lua.el Bastien
  2014-05-06 23:25 ` ob-lua.el John Busch
  0 siblings, 2 replies; 14+ messages in thread
From: dieter @ 2014-05-06 22:34 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 517 bytes --]

hi all,
for a project I need to tangle lua files (including parameters and tables),
and there seems to be no ob-lua.el (yet).
so I shamelessly copied ob-python.el and adapted it to my needs.
right now it can tangle lua, also with simple or table parameters.
if anybody is interested, I can upload it.
before that, it should maybe be completed, and also pass some generic
tangle test, I think.
I have shortly looked at testing/examples/ob-shell-test.org. Is a test like
this suitable?
kind regards,
dieter

[-- Attachment #2: Type: text/html, Size: 754 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: ob-lua.el
  2014-05-06 22:34 ob-lua.el dieter
@ 2014-05-06 22:46 ` Bastien
  2014-05-09 20:23   ` ob-lua.el Dieter Schoen
  2014-05-06 23:25 ` ob-lua.el John Busch
  1 sibling, 1 reply; 14+ messages in thread
From: Bastien @ 2014-05-06 22:46 UTC (permalink / raw)
  To: dieter; +Cc: emacs-orgmode

Hi Dieter,

dieter@schoen.or.at writes:

> for a project I need to tangle lua files (including parameters and
> tables),
> and there seems to be no ob-lua.el (yet).
>
> so I shamelessly copied ob-python.el and adapted it to my needs.
> right now it can tangle lua, also with simple or table parameters.
>
> if anybody is interested, I can upload it.

Yes, please do!

> before that, it should maybe be completed, and also pass some generic
> tangle test, I think.
> I have shortly looked at testing/examples/ob-shell-test.org. Is a
> test like this suitable?

I suggest to look at testing/lisp/test-ob-shell.el.

HTH,

-- 
 Bastien

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: ob-lua.el
  2014-05-06 22:34 ob-lua.el dieter
  2014-05-06 22:46 ` ob-lua.el Bastien
@ 2014-05-06 23:25 ` John Busch
  1 sibling, 0 replies; 14+ messages in thread
From: John Busch @ 2014-05-06 23:25 UTC (permalink / raw)
  To: emacs-orgmode@gnu.org

I'm VERY interested!

Regards,
John V. Busch
________________________________________
From: emacs-orgmode-bounces+jbusch=dataverve.com@gnu.org [emacs-orgmode-bounces+jbusch=dataverve.com@gnu.org] on behalf of dieter@schoen.or.at [dieter@schoen.or.at]
Sent: Tuesday, May 6, 2014 6:34 PM
To: emacs-orgmode@gnu.org
Subject: [O] ob-lua.el

hi all,

for a project I need to tangle lua files (including parameters and tables),
and there seems to be no ob-lua.el (yet).

so I shamelessly copied ob-python.el and adapted it to my needs.
right now it can tangle lua, also with simple or table parameters.

if anybody is interested, I can upload it.
before that, it should maybe be completed, and also pass some generic tangle test, I think.
I have shortly looked at testing/examples/ob-shell-test.org. Is a test like this suitable?

kind regards,
dieter

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: ob-lua.el
  2014-05-06 22:46 ` ob-lua.el Bastien
@ 2014-05-09 20:23   ` Dieter Schoen
  0 siblings, 0 replies; 14+ messages in thread
From: Dieter Schoen @ 2014-05-09 20:23 UTC (permalink / raw)
  To: emacs-orgmode


At Wed, 07 May 2014 00:46:03 +0200,
Bastien wrote:
> 
> Hi Dieter,
> 
> dieter@schoen.or.at writes:
> 
> > for a project I need to tangle lua files (including parameters and
> > tables),
> > and there seems to be no ob-lua.el (yet).
> >
> > so I shamelessly copied ob-python.el and adapted it to my needs.
> > right now it can tangle lua, also with simple or table parameters.
> >
> > if anybody is interested, I can upload it.
> 
> Yes, please do!
> 
> > before that, it should maybe be completed, and also pass some generic
> > tangle test, I think.
> > I have shortly looked at testing/examples/ob-shell-test.org. Is a
> > test like this suitable?
> 
> I suggest to look at testing/lisp/test-ob-shell.el.
> 

sorry for the delay, I had to fix some quoting..

here is what i have already. it is not yet ERT tested, only manually.
ob-lua.el is capable to tangle code  which uses tables with one, two or many
columns.
i have not yet done any code executing tests.

first, here is my test harness:

#+NAME: simple-table
| simple one |
| two        |
| three      |

is converted into

  sim={{"simple one"}, {"two"}, {"three"}}


#+NAME: assoc-table
| name    | value |
|---------+-------|
| colour  | blue  |
| weather | fine  |

this is converted into

    mapv={{"colour", "blue"}, {"weather", "fine"}}

i copied this behaviour (an associative map) from ob-shell.el
    
#+NAME: big-table
| name        | value  | remark |
|-------------+--------+--------|
| tool        | emacs  | cool   |
| environment | debian | fair   |

and finally,

    big={{"tool", "emacs", "cool"}, {"environment", "debian", "fair"}}


<#part type="text/x-org" filename="/home/dieter/git/org/code-exporter.org" disposition=attachment>
<#/part>

and ob-lua.el

<#part type="application/emacs-lisp" filename="/home/dieter/.emacs.d/elpa/org-20140505/ob-lua.el" disposition=attachment>
<#/part>

as i am quite new to emacs/org, i will be thankful for any feedback.

kind regards,
dieter

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: ob-lua.el
@ 2014-05-09 20:26 dieter
  2014-05-12 15:26 ` ob-lua.el Eric Schulte
  0 siblings, 1 reply; 14+ messages in thread
From: dieter @ 2014-05-09 20:26 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 2319 bytes --]

now with attachments, i hope....



>---- Original Message ----
>From: Dieter Schoen <dieter@schoen.or.at>
>To: emacs-orgmode@gnu.org
>Sent: Fri, May 9, 2014, 10:23 PM
>Subject: Re: [O] ob-lua.el
>
>At Wed, 07 May 2014 00:46:03 +0200,
>Bastien wrote:
>>
>> Hi Dieter,
>>
>> dieter@schoen.or.at writes:
>>
>> > for a project I need to tangle lua files (including parameters and
>> > tables),
>> > and there seems to be no ob-lua.el (yet).
>> >
>> > so I shamelessly copied ob-python.el and adapted it to my needs.
>> > right now it can tangle lua, also with simple or table parameters.
>> >
>> > if anybody is interested, I can upload it.
>>
>> Yes, please do!
>>
>> > before that, it should maybe be completed, and also pass some generic
>> > tangle test, I think.
>> > I have shortly looked at testing/examples/ob-shell-test.org. Is a
>> > test like this suitable?
>>
>> I suggest to look at testing/lisp/test-ob-shell.el.
>>
>
>sorry for the delay, I had to fix some quoting..
>
>here is what i have already. it is not yet ERT tested, only manually.
>ob-lua.el is capable to tangle code  which uses tables with one, two or many
>columns.
>i have not yet done any code executing tests.
>
>first, here is my test harness:
>
>#+NAME: simple-table
>| simple one |
>| two        |
>| three      |
>
>is converted into
>
>  sim={{"simple one"}, {"two"}, {"three"}}
>
>
>#+NAME: assoc-table
>| name    | value |
>|---------+-------|
>| colour  | blue  |
>| weather | fine  |
>
>this is converted into
>
>    mapv={{"colour", "blue"}, {"weather", "fine"}}
>
>i copied this behaviour (an associative map) from ob-shell.el
>
>#+NAME: big-table
>| name        | value  | remark |
>|-------------+--------+--------|
>| tool        | emacs  | cool   |
>| environment | debian | fair   |
>
>and finally,
>
>    big={{"tool", "emacs", "cool"}, {"environment", "debian", "fair"}}
>
>
><#part type="text/x-org" filename="/home/dieter/git/org/code-exporter.org" disposition=attachment>
><#/part>
>
>and ob-lua.el
>
><#part type="application/emacs-lisp" filename="/home/dieter/.emacs.d/elpa/org-20140505/ob-lua.el" disposition=attachment>
><#/part>
>
>as i am quite new to emacs/org, i will be thankful for any feedback.
>
>kind regards,
>dieter

[-- Attachment #2: code-exporter.org --]
[-- Type: application/octet-stream, Size: 1216 bytes --]

* shell script

#+NAME: simple-table
| simple one |
| two        |
| three      |



#+NAME: assoc-table
| name    | value |
|---------+-------|
| colour  | blue  |
| weather | fine  |

#+NAME: big-table
| name        | value  | remark |
|-------------+--------+--------|
| tool        | emacs  | cool   |
| environment | debian | fair   |

* the code blocks
** lua
#+HEADER: :var WHAT=simple-table[1,0] VAL=simple-table[2,0]
#+HEADER: :var  sim=simple-table
#+HEADER: :var  mapv=assoc-table
#+HEADER: :var  big=big-table
#+BEGIN_SRC lua :exports code :tangle yes
  -- this just contains the function table_print
  -- copied from http://lua-users.org/wiki/TableSerialization
  --
  dofile "test-lua-lib.lua"

  print("WHAT=",WHAT)
  print("VAL=",VAL)

  print("sim table")
  table_print(sim)
  print("mapv table")
  table_print(mapv)
  print("big table")
  table_print(big)
#+END_SRC

** for comparison, python
#+HEADER: :var WHAT=simple-table[1,0] VAL=simple-table[2,0]
#+HEADER: :var  sim=simple-table
#+HEADER: :var  mapv=assoc-table
#+HEADER: :var  big=big-table
#+BEGIN_SRC python :exports code :tangle yes
  print WHAT, "=", VAL

  print "simple", sim
  print "mapv  ", mapv
  print "big   ", big

#+END_SRC



[-- Attachment #3: ob-lua.el --]
[-- Type: application/octet-stream, Size: 13238 bytes --]

;;; ob-lua.el --- org-babel functions for lua evaluation

;; Copyright (C) 2009-2014 Free Software Foundation, Inc.

;; Authors: Eric Schulte
;;	 Dan Davison
;; 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:

;; Org-Babel support for evaluating lua source code.

;;; Code:
(require 'ob)
(eval-when-compile (require 'cl))

(declare-function org-remove-indentation "org" )
(declare-function lua-shell "ext:lua-mode" (&optional argprompt))
(declare-function lua-toggle-shells "ext:lua-mode" (arg))
(declare-function run-lua "ext:lua" (cmd &optional dedicated show))

(defvar org-babel-tangle-lang-exts)
(add-to-list 'org-babel-tangle-lang-exts '("lua" . "lua"))

(defvar org-babel-default-header-args:lua '())

(defcustom org-babel-lua-command "lua"
  "Name of the command for executing Lua code."
  :version "24.4"
  :package-version '(Org . "8.0")
  :group 'org-babel
  :type 'string)

(defcustom org-babel-lua-mode
  (if (or (featurep 'xemacs) (featurep 'lua-mode)) 'lua-mode 'lua)
  "Preferred lua mode for use in running lua interactively.
This will typically be either 'lua or 'lua-mode."
  :group 'org-babel
  :version "24.4"
  :package-version '(Org . "8.0")
  :type 'symbol)

(defvar org-src-preserve-indentation)

(defcustom org-babel-lua-hline-to "None"
  "Replace hlines in incoming tables with this when translating to lua."
  :group 'org-babel
  :version "24.4"
  :package-version '(Org . "8.0")
  :type 'string)

(defcustom org-babel-lua-None-to 'hline
  "Replace 'None' in lua tables with this before returning."
  :group 'org-babel
  :version "24.4"
  :package-version '(Org . "8.0")
  :type 'symbol)

(defun org-babel-execute:lua (body params)
  "Execute a block of Lua code with Babel.
This function is called by `org-babel-execute-src-block'."
  (let* ((session (org-babel-lua-initiate-session
		   (cdr (assoc :session params))))
         (result-params (cdr (assoc :result-params params)))
         (result-type (cdr (assoc :result-type params)))
	 (return-val (when (and (eq result-type 'value) (not session))
		       (cdr (assoc :return params))))
	 (preamble (cdr (assoc :preamble params)))
         (full-body
	  (org-babel-expand-body:generic
	   (concat body (if return-val (format "\nreturn %s" return-val) ""))
	   params (org-babel-variable-assignments:lua params)))
         (result (org-babel-lua-evaluate
		  session full-body result-type result-params preamble)))
    (org-babel-reassemble-table
     result
     (org-babel-pick-name (cdr (assoc :colname-names params))
			  (cdr (assoc :colnames params)))
     (org-babel-pick-name (cdr (assoc :rowname-names params))
			  (cdr (assoc :rownames params))))))

(defun org-babel-prep-session:lua (session params)
  "Prepare SESSION according to the header arguments in PARAMS.
VARS contains resolved variable references"
  (let* ((session (org-babel-lua-initiate-session session))
	 (var-lines
	  (org-babel-variable-assignments:lua params)))
    (org-babel-comint-in-buffer session
      (mapc (lambda (var)
              (end-of-line 1) (insert var) (comint-send-input)
              (org-babel-comint-wait-for-output session)) var-lines))
    session))

(defun org-babel-load-session:lua (session body params)
  "Load BODY into SESSION."
  (save-window-excursion
    (let ((buffer (org-babel-prep-session:lua session params)))
      (with-current-buffer buffer
        (goto-char (process-mark (get-buffer-process (current-buffer))))
        (insert (org-babel-chomp body)))
      buffer)))

;; helper functions

(defun org-babel-variable-assignments:lua (params)
  "Return a list of Lua statements assigning the block's variables."
  (mapcar
   (lambda (pair)
     (format "%s=%s"
	     (car pair)
	     (org-babel-lua-var-to-lua (cdr pair))))
   (mapcar #'cdr (org-babel-get-header params :var))))

(defun org-babel-lua-var-to-lua (var)
  "Convert an elisp value to a lua variable.
Convert an elisp value, VAR, into a string of lua source code
specifying a variable of the same value."
  (if (listp var)
      (if (and (= 1 (length var)) (not (listp (car var))))
          (org-babel-lua-var-to-lua (car var))
        (if (and
             (= 2 (length var))
             (not (listp (car var))))
            (concat
             (substring-no-properties (car var))
             "="
             (org-babel-lua-var-to-lua (cdr var)))
          (concat "{" (mapconcat #'org-babel-lua-var-to-lua var ", ") "}")))
    (if (equal var 'hline)
        org-babel-lua-hline-to
      (format
       (if (and (stringp var) (string-match "[\n\r]" var)) "\"\"%S\"\"" "%S")
       (if (stringp var) (substring-no-properties var) var)))))

(defun org-babel-lua-table-or-string (results)
  "Convert RESULTS into an appropriate elisp value.
If the results look like a list or tuple, then convert them into an
Emacs-lisp table, otherwise return the results as a string."
  (let ((res (org-babel-script-escape results)))
    (if (listp res)
        (mapcar (lambda (el) (if (equal el 'None)
                            org-babel-lua-None-to el))
                res)
      res)))

(defvar org-babel-lua-buffers '((:default . "*Lua*")))

(defun org-babel-lua-session-buffer (session)
  "Return the buffer associated with SESSION."
  (cdr (assoc session org-babel-lua-buffers)))

(defun org-babel-lua-with-earmuffs (session)
  (let ((name (if (stringp session) session (format "%s" session))))
    (if (and (string= "*" (substring name 0 1))
	     (string= "*" (substring name (- (length name) 1))))
	name
      (format "*%s*" name))))

(defun org-babel-lua-without-earmuffs (session)
  (let ((name (if (stringp session) session (format "%s" session))))
    (if (and (string= "*" (substring name 0 1))
	     (string= "*" (substring name (- (length name) 1))))
	(substring name 1 (- (length name) 1))
      name)))

(defvar lua-default-interpreter)
(defvar lua-which-bufname)
(defvar lua-shell-buffer-name)
(defun org-babel-lua-initiate-session-by-key (&optional session)
  "Initiate a lua session.
If there is not a current inferior-process-buffer in SESSION
then create.  Return the initialized session."
  (require org-babel-lua-mode)
  (save-window-excursion
    (let* ((session (if session (intern session) :default))
           (lua-buffer (org-babel-lua-session-buffer session))
	   (cmd (if (member system-type '(cygwin windows-nt ms-dos))
		    (concat org-babel-lua-command " -i")
		  org-babel-lua-command)))
      (cond
       ((and (eq 'lua org-babel-lua-mode)
	     (fboundp 'run-lua)) ; lua.el
	(if (not (version< "24.1" emacs-version))
	    (run-lua cmd)
	  (unless lua-buffer
	    (setq lua-buffer (org-babel-lua-with-earmuffs session)))
	  (let ((lua-shell-buffer-name
		 (org-babel-lua-without-earmuffs lua-buffer)))
	    (run-lua cmd))))
       ((and (eq 'lua-mode org-babel-lua-mode)
	     (fboundp 'lua-shell)) ; lua-mode.el
	;; Make sure that lua-which-bufname is initialized, as otherwise
	;; it will be overwritten the first time a Lua buffer is
	;; created.
	(lua-toggle-shells lua-default-interpreter)
	;; `lua-shell' creates a buffer whose name is the value of
	;; `lua-which-bufname' with '*'s at the beginning and end
	(let* ((bufname (if (and lua-buffer (buffer-live-p lua-buffer))
			    (replace-regexp-in-string ;; zap surrounding *
			     "^\\*\\([^*]+\\)\\*$" "\\1" lua-buffer)
			  (concat "Lua-" (symbol-name session))))
	       (lua-which-bufname bufname))
	  (lua-shell)
	  (setq lua-buffer (org-babel-lua-with-earmuffs bufname))))
       (t
	(error "No function available for running an inferior Lua")))
      (setq org-babel-lua-buffers
	    (cons (cons session lua-buffer)
		  (assq-delete-all session org-babel-lua-buffers)))
      session)))

(defun org-babel-lua-initiate-session (&optional session params)
  "Create a session named SESSION according to PARAMS."
  (unless (string= session "none")
    (org-babel-lua-session-buffer
     (org-babel-lua-initiate-session-by-key session))))

(defvar org-babel-lua-eoe-indicator "'org_babel_lua_eoe'"
  "A string to indicate that evaluation has completed.")
(defvar org-babel-lua-wrapper-method
  "
def main():
%s

open('%s', 'w').write( str(main()) )")
(defvar org-babel-lua-pp-wrapper-method
  "
import pprint
def main():
%s

open('%s', 'w').write( pprint.pformat(main()) )")

(defun org-babel-lua-evaluate
  (session body &optional result-type result-params preamble)
  "Evaluate BODY as Lua code."
  (if session
      (org-babel-lua-evaluate-session
       session body result-type result-params)
    (org-babel-lua-evaluate-external-process
     body result-type result-params preamble)))

(defun org-babel-lua-evaluate-external-process
  (body &optional result-type result-params preamble)
  "Evaluate BODY in external lua process.
If RESULT-TYPE equals 'output then return standard output as a
string.  If RESULT-TYPE equals 'value then return the value of the
last statement in BODY, as elisp."
  (let ((raw
         (case result-type
           (output (org-babel-eval org-babel-lua-command
                                   (concat (if preamble (concat preamble "\n"))
                                           body)))
           (value (let ((tmp-file (org-babel-temp-file "lua-")))
                    (org-babel-eval
                     org-babel-lua-command
                     (concat
                      (if preamble (concat preamble "\n") "")
                      (format
                       (if (member "pp" result-params)
                           org-babel-lua-pp-wrapper-method
                         org-babel-lua-wrapper-method)
                       (mapconcat
                        (lambda (line) (format "\t%s" line))
                        (split-string
                         (org-remove-indentation
                          (org-babel-trim body))
                         "[\r\n]") "\n")
                       (org-babel-process-file-name tmp-file 'noquote))))
                    (org-babel-eval-read-file tmp-file))))))
    (org-babel-result-cond result-params
      raw
      (org-babel-lua-table-or-string (org-babel-trim raw)))))

(defun org-babel-lua-evaluate-session
    (session body &optional result-type result-params)
  "Pass BODY to the Lua process in SESSION.
If RESULT-TYPE equals 'output then return standard output as a
string.  If RESULT-TYPE equals 'value then return the value of the
last statement in BODY, as elisp."
  (let* ((send-wait (lambda () (comint-send-input nil t) (sleep-for 0 5)))
	 (dump-last-value
	  (lambda
	    (tmp-file pp)
	    (mapc
	     (lambda (statement) (insert statement) (funcall send-wait))
	     (if pp
		 (list
		  "import pprint"
		  (format "open('%s', 'w').write(pprint.pformat(_))"
			  (org-babel-process-file-name tmp-file 'noquote)))
	       (list (format "open('%s', 'w').write(str(_))"
			     (org-babel-process-file-name tmp-file
                                                          'noquote)))))))
	 (input-body (lambda (body)
		       (mapc (lambda (line) (insert line) (funcall send-wait))
			     (split-string body "[\r\n]"))
		       (funcall send-wait)))
         (results
          (case result-type
            (output
             (mapconcat
              #'org-babel-trim
              (butlast
               (org-babel-comint-with-output
                   (session org-babel-lua-eoe-indicator t body)
                 (funcall input-body body)
                 (funcall send-wait) (funcall send-wait)
                 (insert org-babel-lua-eoe-indicator)
                 (funcall send-wait))
               2) "\n"))
            (value
             (let ((tmp-file (org-babel-temp-file "lua-")))
               (org-babel-comint-with-output
                   (session org-babel-lua-eoe-indicator nil body)
                 (let ((comint-process-echoes nil))
                   (funcall input-body body)
                   (funcall dump-last-value tmp-file
                            (member "pp" result-params))
                   (funcall send-wait) (funcall send-wait)
                   (insert org-babel-lua-eoe-indicator)
                   (funcall send-wait)))
               (org-babel-eval-read-file tmp-file))))))
    (unless (string= (substring org-babel-lua-eoe-indicator 1 -1) results)
      (org-babel-result-cond result-params
	results
        (org-babel-lua-table-or-string results)))))

(defun org-babel-lua-read-string (string)
  "Strip 's from around Lua string."
  (if (string-match "^'\\([^\000]+\\)'$" string)
      (match-string 1 string)
    string))

(provide 'ob-lua)



;;; ob-lua.el ends here

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: ob-lua.el
  2014-05-09 20:26 ob-lua.el dieter
@ 2014-05-12 15:26 ` Eric Schulte
  2014-05-13 10:57   ` ob-lua.el Dieter Schoen
  0 siblings, 1 reply; 14+ messages in thread
From: Eric Schulte @ 2014-05-12 15:26 UTC (permalink / raw)
  To: dieter; +Cc: emacs-orgmode

This looks good so far.

Does code execution work but it is untested, or has it not been
implemented?  Would you suggest adding this now or waiting for code
execution?  I don't see you listed on the contributors page, would you
be willing to do FSF copyright assignment?

http://orgmode.org/worg/org-contribute.html

Thanks!
Eric

dieter@schoen.or.at writes:

> now with attachments, i hope....
>
>
>
>>---- Original Message ----
>>From: Dieter Schoen <dieter@schoen.or.at>
>>To: emacs-orgmode@gnu.org
>>Sent: Fri, May 9, 2014, 10:23 PM
>>Subject: Re: [O] ob-lua.el
>>
>>At Wed, 07 May 2014 00:46:03 +0200,
>>Bastien wrote:
>>> 
>>> Hi Dieter,
>>> 
>>> dieter@schoen.or.at writes:
>>> 
>>> > for a project I need to tangle lua files (including parameters and
>>> > tables),
>>> > and there seems to be no ob-lua.el (yet).
>>> >
>>> > so I shamelessly copied ob-python.el and adapted it to my needs.
>>> > right now it can tangle lua, also with simple or table parameters.
>>> >
>>> > if anybody is interested, I can upload it.
>>> 
>>> Yes, please do!
>>> 
>>> > before that, it should maybe be completed, and also pass some generic
>>> > tangle test, I think.
>>> > I have shortly looked at testing/examples/ob-shell-test.org. Is a
>>> > test like this suitable?
>>> 
>>> I suggest to look at testing/lisp/test-ob-shell.el.
>>> 
>>
>>sorry for the delay, I had to fix some quoting..
>>
>>here is what i have already. it is not yet ERT tested, only manually.
>>ob-lua.el is capable to tangle code  which uses tables with one, two or many
>>columns.
>>i have not yet done any code executing tests.
>>
>>first, here is my test harness:
>>
>>#+NAME: simple-table
>>| simple one |
>>| two        |
>>| three      |
>>
>>is converted into
>>
>>  sim={{"simple one"}, {"two"}, {"three"}}
>>
>>
>>#+NAME: assoc-table
>>| name    | value |
>>|---------+-------|
>>| colour  | blue  |
>>| weather | fine  |
>>
>>this is converted into
>>
>>    mapv={{"colour", "blue"}, {"weather", "fine"}}
>>
>>i copied this behaviour (an associative map) from ob-shell.el
>>    
>>#+NAME: big-table
>>| name        | value  | remark |
>>|-------------+--------+--------|
>>| tool        | emacs  | cool   |
>>| environment | debian | fair   |
>>
>>and finally,
>>
>>    big={{"tool", "emacs", "cool"}, {"environment", "debian", "fair"}}
>>
>>
>><#part type="text/x-org" filename="/home/dieter/git/org/code-exporter.org" disposition=attachment>
>><#/part>
>>
>>and ob-lua.el
>>
>><#part type="application/emacs-lisp" filename="/home/dieter/.emacs.d/elpa/org-20140505/ob-lua.el" disposition=attachment>
>><#/part>
>>
>>as i am quite new to emacs/org, i will be thankful for any feedback.
>>
>>kind regards,
>>dieter
>
>
> ;;; ob-lua.el --- org-babel functions for lua evaluation
>
> ;; Copyright (C) 2009-2014 Free Software Foundation, Inc.
>
> ;; Authors: Eric Schulte
> ;;	 Dan Davison
> ;; 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:
>
> ;; Org-Babel support for evaluating lua source code.
>
> ;;; Code:
> (require 'ob)
> (eval-when-compile (require 'cl))
>
> (declare-function org-remove-indentation "org" )
> (declare-function lua-shell "ext:lua-mode" (&optional argprompt))
> (declare-function lua-toggle-shells "ext:lua-mode" (arg))
> (declare-function run-lua "ext:lua" (cmd &optional dedicated show))
>
> (defvar org-babel-tangle-lang-exts)
> (add-to-list 'org-babel-tangle-lang-exts '("lua" . "lua"))
>
> (defvar org-babel-default-header-args:lua '())
>
> (defcustom org-babel-lua-command "lua"
>   "Name of the command for executing Lua code."
>   :version "24.4"
>   :package-version '(Org . "8.0")
>   :group 'org-babel
>   :type 'string)
>
> (defcustom org-babel-lua-mode
>   (if (or (featurep 'xemacs) (featurep 'lua-mode)) 'lua-mode 'lua)
>   "Preferred lua mode for use in running lua interactively.
> This will typically be either 'lua or 'lua-mode."
>   :group 'org-babel
>   :version "24.4"
>   :package-version '(Org . "8.0")
>   :type 'symbol)
>
> (defvar org-src-preserve-indentation)
>
> (defcustom org-babel-lua-hline-to "None"
>   "Replace hlines in incoming tables with this when translating to lua."
>   :group 'org-babel
>   :version "24.4"
>   :package-version '(Org . "8.0")
>   :type 'string)
>
> (defcustom org-babel-lua-None-to 'hline
>   "Replace 'None' in lua tables with this before returning."
>   :group 'org-babel
>   :version "24.4"
>   :package-version '(Org . "8.0")
>   :type 'symbol)
>
> (defun org-babel-execute:lua (body params)
>   "Execute a block of Lua code with Babel.
> This function is called by `org-babel-execute-src-block'."
>   (let* ((session (org-babel-lua-initiate-session
> 		   (cdr (assoc :session params))))
>          (result-params (cdr (assoc :result-params params)))
>          (result-type (cdr (assoc :result-type params)))
> 	 (return-val (when (and (eq result-type 'value) (not session))
> 		       (cdr (assoc :return params))))
> 	 (preamble (cdr (assoc :preamble params)))
>          (full-body
> 	  (org-babel-expand-body:generic
> 	   (concat body (if return-val (format "\nreturn %s" return-val) ""))
> 	   params (org-babel-variable-assignments:lua params)))
>          (result (org-babel-lua-evaluate
> 		  session full-body result-type result-params preamble)))
>     (org-babel-reassemble-table
>      result
>      (org-babel-pick-name (cdr (assoc :colname-names params))
> 			  (cdr (assoc :colnames params)))
>      (org-babel-pick-name (cdr (assoc :rowname-names params))
> 			  (cdr (assoc :rownames params))))))
>
> (defun org-babel-prep-session:lua (session params)
>   "Prepare SESSION according to the header arguments in PARAMS.
> VARS contains resolved variable references"
>   (let* ((session (org-babel-lua-initiate-session session))
> 	 (var-lines
> 	  (org-babel-variable-assignments:lua params)))
>     (org-babel-comint-in-buffer session
>       (mapc (lambda (var)
>               (end-of-line 1) (insert var) (comint-send-input)
>               (org-babel-comint-wait-for-output session)) var-lines))
>     session))
>
> (defun org-babel-load-session:lua (session body params)
>   "Load BODY into SESSION."
>   (save-window-excursion
>     (let ((buffer (org-babel-prep-session:lua session params)))
>       (with-current-buffer buffer
>         (goto-char (process-mark (get-buffer-process (current-buffer))))
>         (insert (org-babel-chomp body)))
>       buffer)))
>
> ;; helper functions
>
> (defun org-babel-variable-assignments:lua (params)
>   "Return a list of Lua statements assigning the block's variables."
>   (mapcar
>    (lambda (pair)
>      (format "%s=%s"
> 	     (car pair)
> 	     (org-babel-lua-var-to-lua (cdr pair))))
>    (mapcar #'cdr (org-babel-get-header params :var))))
>
> (defun org-babel-lua-var-to-lua (var)
>   "Convert an elisp value to a lua variable.
> Convert an elisp value, VAR, into a string of lua source code
> specifying a variable of the same value."
>   (if (listp var)
>       (if (and (= 1 (length var)) (not (listp (car var))))
>           (org-babel-lua-var-to-lua (car var))
>         (if (and
>              (= 2 (length var))
>              (not (listp (car var))))
>             (concat
>              (substring-no-properties (car var))
>              "="
>              (org-babel-lua-var-to-lua (cdr var)))
>           (concat "{" (mapconcat #'org-babel-lua-var-to-lua var ", ") "}")))
>     (if (equal var 'hline)
>         org-babel-lua-hline-to
>       (format
>        (if (and (stringp var) (string-match "[\n\r]" var)) "\"\"%S\"\"" "%S")
>        (if (stringp var) (substring-no-properties var) var)))))
>
> (defun org-babel-lua-table-or-string (results)
>   "Convert RESULTS into an appropriate elisp value.
> If the results look like a list or tuple, then convert them into an
> Emacs-lisp table, otherwise return the results as a string."
>   (let ((res (org-babel-script-escape results)))
>     (if (listp res)
>         (mapcar (lambda (el) (if (equal el 'None)
>                             org-babel-lua-None-to el))
>                 res)
>       res)))
>
> (defvar org-babel-lua-buffers '((:default . "*Lua*")))
>
> (defun org-babel-lua-session-buffer (session)
>   "Return the buffer associated with SESSION."
>   (cdr (assoc session org-babel-lua-buffers)))
>
> (defun org-babel-lua-with-earmuffs (session)
>   (let ((name (if (stringp session) session (format "%s" session))))
>     (if (and (string= "*" (substring name 0 1))
> 	     (string= "*" (substring name (- (length name) 1))))
> 	name
>       (format "*%s*" name))))
>
> (defun org-babel-lua-without-earmuffs (session)
>   (let ((name (if (stringp session) session (format "%s" session))))
>     (if (and (string= "*" (substring name 0 1))
> 	     (string= "*" (substring name (- (length name) 1))))
> 	(substring name 1 (- (length name) 1))
>       name)))
>
> (defvar lua-default-interpreter)
> (defvar lua-which-bufname)
> (defvar lua-shell-buffer-name)
> (defun org-babel-lua-initiate-session-by-key (&optional session)
>   "Initiate a lua session.
> If there is not a current inferior-process-buffer in SESSION
> then create.  Return the initialized session."
>   (require org-babel-lua-mode)
>   (save-window-excursion
>     (let* ((session (if session (intern session) :default))
>            (lua-buffer (org-babel-lua-session-buffer session))
> 	   (cmd (if (member system-type '(cygwin windows-nt ms-dos))
> 		    (concat org-babel-lua-command " -i")
> 		  org-babel-lua-command)))
>       (cond
>        ((and (eq 'lua org-babel-lua-mode)
> 	     (fboundp 'run-lua)) ; lua.el
> 	(if (not (version< "24.1" emacs-version))
> 	    (run-lua cmd)
> 	  (unless lua-buffer
> 	    (setq lua-buffer (org-babel-lua-with-earmuffs session)))
> 	  (let ((lua-shell-buffer-name
> 		 (org-babel-lua-without-earmuffs lua-buffer)))
> 	    (run-lua cmd))))
>        ((and (eq 'lua-mode org-babel-lua-mode)
> 	     (fboundp 'lua-shell)) ; lua-mode.el
> 	;; Make sure that lua-which-bufname is initialized, as otherwise
> 	;; it will be overwritten the first time a Lua buffer is
> 	;; created.
> 	(lua-toggle-shells lua-default-interpreter)
> 	;; `lua-shell' creates a buffer whose name is the value of
> 	;; `lua-which-bufname' with '*'s at the beginning and end
> 	(let* ((bufname (if (and lua-buffer (buffer-live-p lua-buffer))
> 			    (replace-regexp-in-string ;; zap surrounding *
> 			     "^\\*\\([^*]+\\)\\*$" "\\1" lua-buffer)
> 			  (concat "Lua-" (symbol-name session))))
> 	       (lua-which-bufname bufname))
> 	  (lua-shell)
> 	  (setq lua-buffer (org-babel-lua-with-earmuffs bufname))))
>        (t
> 	(error "No function available for running an inferior Lua")))
>       (setq org-babel-lua-buffers
> 	    (cons (cons session lua-buffer)
> 		  (assq-delete-all session org-babel-lua-buffers)))
>       session)))
>
> (defun org-babel-lua-initiate-session (&optional session params)
>   "Create a session named SESSION according to PARAMS."
>   (unless (string= session "none")
>     (org-babel-lua-session-buffer
>      (org-babel-lua-initiate-session-by-key session))))
>
> (defvar org-babel-lua-eoe-indicator "'org_babel_lua_eoe'"
>   "A string to indicate that evaluation has completed.")
> (defvar org-babel-lua-wrapper-method
>   "
> def main():
> %s
>
> open('%s', 'w').write( str(main()) )")
> (defvar org-babel-lua-pp-wrapper-method
>   "
> import pprint
> def main():
> %s
>
> open('%s', 'w').write( pprint.pformat(main()) )")
>
> (defun org-babel-lua-evaluate
>   (session body &optional result-type result-params preamble)
>   "Evaluate BODY as Lua code."
>   (if session
>       (org-babel-lua-evaluate-session
>        session body result-type result-params)
>     (org-babel-lua-evaluate-external-process
>      body result-type result-params preamble)))
>
> (defun org-babel-lua-evaluate-external-process
>   (body &optional result-type result-params preamble)
>   "Evaluate BODY in external lua process.
> If RESULT-TYPE equals 'output then return standard output as a
> string.  If RESULT-TYPE equals 'value then return the value of the
> last statement in BODY, as elisp."
>   (let ((raw
>          (case result-type
>            (output (org-babel-eval org-babel-lua-command
>                                    (concat (if preamble (concat preamble "\n"))
>                                            body)))
>            (value (let ((tmp-file (org-babel-temp-file "lua-")))
>                     (org-babel-eval
>                      org-babel-lua-command
>                      (concat
>                       (if preamble (concat preamble "\n") "")
>                       (format
>                        (if (member "pp" result-params)
>                            org-babel-lua-pp-wrapper-method
>                          org-babel-lua-wrapper-method)
>                        (mapconcat
>                         (lambda (line) (format "\t%s" line))
>                         (split-string
>                          (org-remove-indentation
>                           (org-babel-trim body))
>                          "[\r\n]") "\n")
>                        (org-babel-process-file-name tmp-file 'noquote))))
>                     (org-babel-eval-read-file tmp-file))))))
>     (org-babel-result-cond result-params
>       raw
>       (org-babel-lua-table-or-string (org-babel-trim raw)))))
>
> (defun org-babel-lua-evaluate-session
>     (session body &optional result-type result-params)
>   "Pass BODY to the Lua process in SESSION.
> If RESULT-TYPE equals 'output then return standard output as a
> string.  If RESULT-TYPE equals 'value then return the value of the
> last statement in BODY, as elisp."
>   (let* ((send-wait (lambda () (comint-send-input nil t) (sleep-for 0 5)))
> 	 (dump-last-value
> 	  (lambda
> 	    (tmp-file pp)
> 	    (mapc
> 	     (lambda (statement) (insert statement) (funcall send-wait))
> 	     (if pp
> 		 (list
> 		  "import pprint"
> 		  (format "open('%s', 'w').write(pprint.pformat(_))"
> 			  (org-babel-process-file-name tmp-file 'noquote)))
> 	       (list (format "open('%s', 'w').write(str(_))"
> 			     (org-babel-process-file-name tmp-file
>                                                           'noquote)))))))
> 	 (input-body (lambda (body)
> 		       (mapc (lambda (line) (insert line) (funcall send-wait))
> 			     (split-string body "[\r\n]"))
> 		       (funcall send-wait)))
>          (results
>           (case result-type
>             (output
>              (mapconcat
>               #'org-babel-trim
>               (butlast
>                (org-babel-comint-with-output
>                    (session org-babel-lua-eoe-indicator t body)
>                  (funcall input-body body)
>                  (funcall send-wait) (funcall send-wait)
>                  (insert org-babel-lua-eoe-indicator)
>                  (funcall send-wait))
>                2) "\n"))
>             (value
>              (let ((tmp-file (org-babel-temp-file "lua-")))
>                (org-babel-comint-with-output
>                    (session org-babel-lua-eoe-indicator nil body)
>                  (let ((comint-process-echoes nil))
>                    (funcall input-body body)
>                    (funcall dump-last-value tmp-file
>                             (member "pp" result-params))
>                    (funcall send-wait) (funcall send-wait)
>                    (insert org-babel-lua-eoe-indicator)
>                    (funcall send-wait)))
>                (org-babel-eval-read-file tmp-file))))))
>     (unless (string= (substring org-babel-lua-eoe-indicator 1 -1) results)
>       (org-babel-result-cond result-params
> 	results
>         (org-babel-lua-table-or-string results)))))
>
> (defun org-babel-lua-read-string (string)
>   "Strip 's from around Lua string."
>   (if (string-match "^'\\([^\000]+\\)'$" string)
>       (match-string 1 string)
>     string))
>
> (provide 'ob-lua)
>
>
>
> ;;; ob-lua.el ends here

-- 
Eric Schulte
https://cs.unm.edu/~eschulte
PGP: 0x614CA05D

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: ob-lua.el
  2014-05-12 15:26 ` ob-lua.el Eric Schulte
@ 2014-05-13 10:57   ` Dieter Schoen
  2014-05-21  7:30     ` ob-lua.el Bastien
  0 siblings, 1 reply; 14+ messages in thread
From: Dieter Schoen @ 2014-05-13 10:57 UTC (permalink / raw)
  To: Eric Schulte; +Cc: emacs-orgmode

At Mon, 12 May 2014 09:26:21 -0600,
Eric Schulte wrote:
> 
> This looks good so far.

thank you. it's my first published lisp code (although big parts are stolen..)

> Does code execution work but it is untested, or has it not been
> implemented?  Would you suggest adding this now or waiting for code
> execution?

i have added a "results: output" and as such perform a limited test now,
and that worked fine.
so i would say that it's fit for basic usage.
in parallel i will continue to learn ERT (emacs regression testing) and write
formal tests.

> I don't see you listed on the contributors page, would you
> be willing to do FSF copyright assignment?
> 
> http://orgmode.org/worg/org-contribute.html

i thought that it's not a copyright is not a question since i posted the code
here. ;)
but formally: yes, i'd like to do a FSF copyright assignment.
i have just sent the email to assign@gnu.org to start the process.

kind regards,
dieter

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: ob-lua.el
  2014-05-13 10:57   ` ob-lua.el Dieter Schoen
@ 2014-05-21  7:30     ` Bastien
  2014-05-24 10:55       ` ob-lua.el Dieter Schoen
  0 siblings, 1 reply; 14+ messages in thread
From: Bastien @ 2014-05-21  7:30 UTC (permalink / raw)
  To: Dieter Schoen; +Cc: emacs-orgmode, Eric Schulte

Hi Dieter,

Dieter Schoen <dieter@schoen.or.at> writes:

> i have just sent the email to assign@gnu.org to start the process.

Great -- let us know how it goes (can take one month.)

In the meantime, you can fix small things like the authors of the
package, the owner of the copyright and such.

Thanks for this contribution!

-- 
 Bastien

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: ob-lua.el
  2014-05-21  7:30     ` ob-lua.el Bastien
@ 2014-05-24 10:55       ` Dieter Schoen
  2014-05-24 12:25         ` ob-lua.el Bastien
  0 siblings, 1 reply; 14+ messages in thread
From: Dieter Schoen @ 2014-05-24 10:55 UTC (permalink / raw)
  To: Bastien; +Cc: emacs-orgmode, Eric Schulte

[-- Attachment #1: Type: text/plain, Size: 885 bytes --]

At Wed, 21 May 2014 09:30:44 +0200,
Bastien wrote:
> 
> Hi Dieter,
> 
> Dieter Schoen <dieter@schoen.or.at> writes:
> 
> > i have just sent the email to assign@gnu.org to start the process.
> 
> Great -- let us know how it goes (can take one month.)

As I wrote off-list, I received the signed pdf yesterday.

> In the meantime, you can fix small things like the authors of the
> package, the owner of the copyright and such.

I have my name to the copyright, but left in the name of the authors
of ob-python.el, as I used that as a template.
Is that ok?

Another change to the first version is that it's now also possible
to do :results value and :results value pp.
(The first version still had python wrapper code in there.)

The Lua pretty-printer function is a home-brew, as Lua does not provide
much in that direction out of the box, at least to my knowledge.

So here it comes:


[-- Attachment #2: ob-lua.el --]
[-- Type: text/plain, Size: 13813 bytes --]

;;; ob-lua.el --- org-babel functions for lua evaluation

;; Copyright (C) 2009-2014 Free Software Foundation, Inc.

;; Authors: Eric Schulte
;;	 Dan Davison
;; 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:

;; Org-Babel support for evaluating lua source code.

;;; Code:
(require 'ob)
(eval-when-compile (require 'cl))

(declare-function org-remove-indentation "org" )
(declare-function lua-shell "ext:lua-mode" (&optional argprompt))
(declare-function lua-toggle-shells "ext:lua-mode" (arg))
(declare-function run-lua "ext:lua" (cmd &optional dedicated show))

(defvar org-babel-tangle-lang-exts)
(add-to-list 'org-babel-tangle-lang-exts '("lua" . "lua"))

(defvar org-babel-default-header-args:lua '())

(defcustom org-babel-lua-command "lua"
  "Name of the command for executing Lua code."
  :version "24.4"
  :package-version '(Org . "8.0")
  :group 'org-babel
  :type 'string)

(defcustom org-babel-lua-mode
  (if (or (featurep 'xemacs) (featurep 'lua-mode)) 'lua-mode 'lua)
  "Preferred lua mode for use in running lua interactively.
This will typically be either 'lua or 'lua-mode."
  :group 'org-babel
  :version "24.4"
  :package-version '(Org . "8.0")
  :type 'symbol)

(defvar org-src-preserve-indentation)

(defcustom org-babel-lua-hline-to "None"
  "Replace hlines in incoming tables with this when translating to lua."
  :group 'org-babel
  :version "24.4"
  :package-version '(Org . "8.0")
  :type 'string)

(defcustom org-babel-lua-None-to 'hline
  "Replace 'None' in lua tables with this before returning."
  :group 'org-babel
  :version "24.4"
  :package-version '(Org . "8.0")
  :type 'symbol)

(defun org-babel-execute:lua (body params)
  "Execute a block of Lua code with Babel.
This function is called by `org-babel-execute-src-block'."
  (let* ((session (org-babel-lua-initiate-session
		   (cdr (assoc :session params))))
         (result-params (cdr (assoc :result-params params)))
         (result-type (cdr (assoc :result-type params)))
	 (return-val (when (and (eq result-type 'value) (not session))
		       (cdr (assoc :return params))))
	 (preamble (cdr (assoc :preamble params)))
         (full-body
	  (org-babel-expand-body:generic
	   (concat body (if return-val (format "\nreturn %s" return-val) ""))
	   params (org-babel-variable-assignments:lua params)))
         (result (org-babel-lua-evaluate
		  session full-body result-type result-params preamble)))
    (org-babel-reassemble-table
     result
     (org-babel-pick-name (cdr (assoc :colname-names params))
			  (cdr (assoc :colnames params)))
     (org-babel-pick-name (cdr (assoc :rowname-names params))
			  (cdr (assoc :rownames params))))))

(defun org-babel-prep-session:lua (session params)
  "Prepare SESSION according to the header arguments in PARAMS.
VARS contains resolved variable references"
  (let* ((session (org-babel-lua-initiate-session session))
	 (var-lines
	  (org-babel-variable-assignments:lua params)))
    (org-babel-comint-in-buffer session
      (mapc (lambda (var)
              (end-of-line 1) (insert var) (comint-send-input)
              (org-babel-comint-wait-for-output session)) var-lines))
    session))

(defun org-babel-load-session:lua (session body params)
  "Load BODY into SESSION."
  (save-window-excursion
    (let ((buffer (org-babel-prep-session:lua session params)))
      (with-current-buffer buffer
        (goto-char (process-mark (get-buffer-process (current-buffer))))
        (insert (org-babel-chomp body)))
      buffer)))

;; helper functions

(defun org-babel-variable-assignments:lua (params)
  "Return a list of Lua statements assigning the block's variables."
  (mapcar
   (lambda (pair)
     (format "%s=%s"
	     (car pair)
	     (org-babel-lua-var-to-lua (cdr pair))))
   (mapcar #'cdr (org-babel-get-header params :var))))

(defun org-babel-lua-var-to-lua (var)
  "Convert an elisp value to a lua variable.
Convert an elisp value, VAR, into a string of lua source code
specifying a variable of the same value."
  (if (listp var)
      (if (and (= 1 (length var)) (not (listp (car var))))
          (org-babel-lua-var-to-lua (car var))
        (if (and
             (= 2 (length var))
             (not (listp (car var))))
            (concat
             (substring-no-properties (car var))
             "="
             (org-babel-lua-var-to-lua (cdr var)))
          (concat "{" (mapconcat #'org-babel-lua-var-to-lua var ", ") "}")))
    (if (equal var 'hline)
        org-babel-lua-hline-to
      (format
       (if (and (stringp var) (string-match "[\n\r]" var)) "\"\"%S\"\"" "%S")
       (if (stringp var) (substring-no-properties var) var)))))

(defun org-babel-lua-table-or-string (results)
  "Convert RESULTS into an appropriate elisp value.
If the results look like a list or tuple, then convert them into an
Emacs-lisp table, otherwise return the results as a string."
  (let ((res (org-babel-script-escape results)))
    (if (listp res)
        (mapcar (lambda (el) (if (equal el 'None)
                            org-babel-lua-None-to el))
                res)
      res)))

(defvar org-babel-lua-buffers '((:default . "*Lua*")))

(defun org-babel-lua-session-buffer (session)
  "Return the buffer associated with SESSION."
  (cdr (assoc session org-babel-lua-buffers)))

(defun org-babel-lua-with-earmuffs (session)
  (let ((name (if (stringp session) session (format "%s" session))))
    (if (and (string= "*" (substring name 0 1))
	     (string= "*" (substring name (- (length name) 1))))
	name
      (format "*%s*" name))))

(defun org-babel-lua-without-earmuffs (session)
  (let ((name (if (stringp session) session (format "%s" session))))
    (if (and (string= "*" (substring name 0 1))
	     (string= "*" (substring name (- (length name) 1))))
	(substring name 1 (- (length name) 1))
      name)))

(defvar lua-default-interpreter)
(defvar lua-which-bufname)
(defvar lua-shell-buffer-name)
(defun org-babel-lua-initiate-session-by-key (&optional session)
  "Initiate a lua session.
If there is not a current inferior-process-buffer in SESSION
then create.  Return the initialized session."
  (require org-babel-lua-mode)
  (save-window-excursion
    (let* ((session (if session (intern session) :default))
           (lua-buffer (org-babel-lua-session-buffer session))
	   (cmd (if (member system-type '(cygwin windows-nt ms-dos))
		    (concat org-babel-lua-command " -i")
		  org-babel-lua-command)))
      (cond
       ((and (eq 'lua org-babel-lua-mode)
	     (fboundp 'run-lua)) ; lua.el
	(if (not (version< "24.1" emacs-version))
	    (run-lua cmd)
	  (unless lua-buffer
	    (setq lua-buffer (org-babel-lua-with-earmuffs session)))
	  (let ((lua-shell-buffer-name
		 (org-babel-lua-without-earmuffs lua-buffer)))
	    (run-lua cmd))))
       ((and (eq 'lua-mode org-babel-lua-mode)
	     (fboundp 'lua-shell)) ; lua-mode.el
	;; Make sure that lua-which-bufname is initialized, as otherwise
	;; it will be overwritten the first time a Lua buffer is
	;; created.
	(lua-toggle-shells lua-default-interpreter)
	;; `lua-shell' creates a buffer whose name is the value of
	;; `lua-which-bufname' with '*'s at the beginning and end
	(let* ((bufname (if (and lua-buffer (buffer-live-p lua-buffer))
			    (replace-regexp-in-string ;; zap surrounding *
			     "^\\*\\([^*]+\\)\\*$" "\\1" lua-buffer)
			  (concat "Lua-" (symbol-name session))))
	       (lua-which-bufname bufname))
	  (lua-shell)
	  (setq lua-buffer (org-babel-lua-with-earmuffs bufname))))
       (t
	(error "No function available for running an inferior Lua")))
      (setq org-babel-lua-buffers
	    (cons (cons session lua-buffer)
		  (assq-delete-all session org-babel-lua-buffers)))
      session)))

(defun org-babel-lua-initiate-session (&optional session params)
  "Create a session named SESSION according to PARAMS."
  (unless (string= session "none")
    (org-babel-lua-session-buffer
     (org-babel-lua-initiate-session-by-key session))))

(defvar org-babel-lua-eoe-indicator "'org_babel_lua_eoe'"
  "A string to indicate that evaluation has completed.")
(defvar org-babel-lua-wrapper-method
  "
function main()
%s
end

fd=io.open(\"%s\", \"w\")
fd:write( main() )
fd:close()")
(defvar org-babel-lua-pp-wrapper-method
  "
-- table to string
function t2s(t, indent)
   if indent == nil then
      indent = \"\"
   end
   if type(t) == \"table\" then
      ts = \"\"
      for k,v in pairs(t) do
         if type(v) == \"table\" then
            ts = ts .. indent .. t2s(k,indent .. \"  \") .. \" = \\n\" ..
               t2s(v, indent .. \"  \")
         else
            ts = ts .. indent .. t2s(k,indent .. \"  \") .. \" = \" ..
               t2s(v, indent .. \"  \") .. \"\\n\"
         end
      end
      return ts
   else
      return tostring(t)
   end
end


function main()
%s
end

fd=io.open(\"%s\", \"w\")
fd:write(t2s(main()))
fd:close()")

(defun org-babel-lua-evaluate
  (session body &optional result-type result-params preamble)
  "Evaluate BODY as Lua code."
  (if session
      (org-babel-lua-evaluate-session
       session body result-type result-params)
    (org-babel-lua-evaluate-external-process
     body result-type result-params preamble)))

(defun org-babel-lua-evaluate-external-process
  (body &optional result-type result-params preamble)
  "Evaluate BODY in external lua process.
If RESULT-TYPE equals 'output then return standard output as a
string.  If RESULT-TYPE equals 'value then return the value of the
last statement in BODY, as elisp."
  (let ((raw
         (case result-type
           (output (org-babel-eval org-babel-lua-command
                                   (concat (if preamble (concat preamble "\n"))
                                           body)))
           (value (let ((tmp-file (org-babel-temp-file "lua-")))
                    (org-babel-eval
                     org-babel-lua-command
                     (concat
                      (if preamble (concat preamble "\n") "")
                      (format
                       (if (member "pp" result-params)
                           org-babel-lua-pp-wrapper-method
                         org-babel-lua-wrapper-method)
                       (mapconcat
                        (lambda (line) (format "\t%s" line))
                        (split-string
                         (org-remove-indentation
                          (org-babel-trim body))
                         "[\r\n]") "\n")
                       (org-babel-process-file-name tmp-file 'noquote))))
                    (org-babel-eval-read-file tmp-file))))))
    (org-babel-result-cond result-params
      raw
      (org-babel-lua-table-or-string (org-babel-trim raw)))))

(defun org-babel-lua-evaluate-session
    (session body &optional result-type result-params)
  "Pass BODY to the Lua process in SESSION.
If RESULT-TYPE equals 'output then return standard output as a
string.  If RESULT-TYPE equals 'value then return the value of the
last statement in BODY, as elisp."
  (let* ((send-wait (lambda () (comint-send-input nil t) (sleep-for 0 5)))
	 (dump-last-value
	  (lambda
	    (tmp-file pp)
	    (mapc
	     (lambda (statement) (insert statement) (funcall send-wait))
	     (if pp
		 (list
		  "import pprint"
		  (format "open('%s', 'w').write(pprint.pformat(_))"
			  (org-babel-process-file-name tmp-file 'noquote)))
	       (list (format "open('%s', 'w').write(str(_))"
			     (org-babel-process-file-name tmp-file
                                                          'noquote)))))))
	 (input-body (lambda (body)
		       (mapc (lambda (line) (insert line) (funcall send-wait))
			     (split-string body "[\r\n]"))
		       (funcall send-wait)))
         (results
          (case result-type
            (output
             (mapconcat
              #'org-babel-trim
              (butlast
               (org-babel-comint-with-output
                   (session org-babel-lua-eoe-indicator t body)
                 (funcall input-body body)
                 (funcall send-wait) (funcall send-wait)
                 (insert org-babel-lua-eoe-indicator)
                 (funcall send-wait))
               2) "\n"))
            (value
             (let ((tmp-file (org-babel-temp-file "lua-")))
               (org-babel-comint-with-output
                   (session org-babel-lua-eoe-indicator nil body)
                 (let ((comint-process-echoes nil))
                   (funcall input-body body)
                   (funcall dump-last-value tmp-file
                            (member "pp" result-params))
                   (funcall send-wait) (funcall send-wait)
                   (insert org-babel-lua-eoe-indicator)
                   (funcall send-wait)))
               (org-babel-eval-read-file tmp-file))))))
    (unless (string= (substring org-babel-lua-eoe-indicator 1 -1) results)
      (org-babel-result-cond result-params
	results
        (org-babel-lua-table-or-string results)))))

(defun org-babel-lua-read-string (string)
  "Strip 's from around Lua string."
  (if (string-match "^'\\([^\000]+\\)'$" string)
      (match-string 1 string)
    string))

(provide 'ob-lua)

;;; ob-lua.el ends here

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: ob-lua.el
  2014-05-24 10:55       ` ob-lua.el Dieter Schoen
@ 2014-05-24 12:25         ` Bastien
  2014-05-24 21:17           ` ob-lua.el Dieter Schoen
  0 siblings, 1 reply; 14+ messages in thread
From: Bastien @ 2014-05-24 12:25 UTC (permalink / raw)
  To: Dieter Schoen; +Cc: emacs-orgmode, Eric Schulte

Hi Dieter,

Dieter Schoen <dieter@schoen.or.at> writes:

> I have my name to the copyright, but left in the name of the authors
> of ob-python.el, as I used that as a template.
> Is that ok?

Yes -- but I don't see your name anywhere in the file.

> Another change to the first version is that it's now also possible
> to do :results value and :results value pp.
> (The first version still had python wrapper code in there.)

Great!

> The Lua pretty-printer function is a home-brew, as Lua does not provide
> much in that direction out of the box, at least to my knowledge.

What ob-lua.el depends on?

You declare functions that suggests there is both lua-mode.el and
lua.el* -- I think this is a leftover from ob-pyhton.el.  Can you
double-check this?  Also, there should be a note explaining how to
install lua-mode.el, since it is not part of Emacs.

* See (defcustom org-babel-lua-mode ...

Also, there is (defvar org-src-preserve-indentation) which is not
used.

Let's do some more cleaning and then apply this to master.

Thanks!

-- 
 Bastien

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: ob-lua.el
  2014-05-24 12:25         ` ob-lua.el Bastien
@ 2014-05-24 21:17           ` Dieter Schoen
  2014-05-25  5:24             ` ob-lua.el Bastien
  0 siblings, 1 reply; 14+ messages in thread
From: Dieter Schoen @ 2014-05-24 21:17 UTC (permalink / raw)
  To: Bastien; +Cc: emacs-orgmode, Eric Schulte

[-- Attachment #1: Type: text/plain, Size: 1279 bytes --]

At Sat, 24 May 2014 14:25:05 +0200,
Bastien wrote:
> 
> Hi Dieter,
> 
> Dieter Schoen <dieter@schoen.or.at> writes:
> 
> > I have my name to the copyright, but left in the name of the authors
> > of ob-python.el, as I used that as a template.
> > Is that ok?
> 
> Yes -- but I don't see your name anywhere in the file.

madre-de-dios. i should not try to work when my boys are around.

> What ob-lua.el depends on?
> 
> You declare functions that suggests there is both lua-mode.el and
> lua.el* -- I think this is a leftover from ob-pyhton.el.  Can you
> double-check this?  Also, there should be a note explaining how to
> install lua-mode.el, since it is not part of Emacs.

Yes, that was a copy/paste relict from ob-python, I removed the latter
mode reference.

> * See (defcustom org-babel-lua-mode ...

As far as I understand the code, lua-mode would only be used for the session
support, to have an inferior process as receiver for code blocks.
I could not yet get the session support to work, there is a bit more work
involved than simple s/py/lua/.
I'll continue to work in that area.
 
> Also, there is (defvar org-src-preserve-indentation) which is not
> used.

removed.

> Let's do some more cleaning and then apply this to master.



regards,
dieter



------------

[-- Attachment #2: ob-lua.el --]
[-- Type: text/plain, Size: 14463 bytes --]

;;; ob-lua.el --- org-babel functions for lua evaluation

;; Copyright (C) 2009-2014 Free Software Foundation, Inc.

;; Authors: Dieter Schoen
;;	 Eric Schulte, Dan Davison
;; 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/>.

;; Requirements:
;; for session support, lua-mode is needed.
;; lua-mode is not part of GNU Emacs/orgmode, but can be obtained
;; from marmalade or melpa.

;; However, sessions are not yet working.

;; Org-Babel support for evaluating lua source code.

;;; Code:
(require 'ob)
(eval-when-compile (require 'cl))

(declare-function org-remove-indentation "org" )
(declare-function lua-shell "ext:lua-mode" (&optional argprompt))
(declare-function lua-toggle-shells "ext:lua-mode" (arg))
(declare-function run-lua "ext:lua" (cmd &optional dedicated show))

(defvar org-babel-tangle-lang-exts)
(add-to-list 'org-babel-tangle-lang-exts '("lua" . "lua"))

(defvar org-babel-default-header-args:lua '())

(defcustom org-babel-lua-command "lua"
  "Name of the command for executing Lua code."
  :version "24.4"
  :package-version '(Org . "8.0")
  :group 'org-babel
  :type 'string)

(defcustom org-babel-lua-mode
  (if (or (featurep 'xemacs) (featurep 'lua-mode)) 'lua-mode)
  "Preferred lua mode for use in running lua interactively.
This will typically be 'lua-mode."
  :group 'org-babel
  :version "24.4"
  :package-version '(Org . "8.0")
  :type 'symbol)

(defcustom org-babel-lua-hline-to "None"
  "Replace hlines in incoming tables with this when translating to lua."
  :group 'org-babel
  :version "24.4"
  :package-version '(Org . "8.0")
  :type 'string)

(defcustom org-babel-lua-None-to 'hline
  "Replace 'None' in lua tables with this before returning."
  :group 'org-babel
  :version "24.4"
  :package-version '(Org . "8.0")
  :type 'symbol)

(defun org-babel-execute:lua (body params)
  "Execute a block of Lua code with Babel.
This function is called by `org-babel-execute-src-block'."
  (let* ((session (org-babel-lua-initiate-session
		   (cdr (assoc :session params))))
         (result-params (cdr (assoc :result-params params)))
         (result-type (cdr (assoc :result-type params)))
	 (return-val (when (and (eq result-type 'value) (not session))
		       (cdr (assoc :return params))))
	 (preamble (cdr (assoc :preamble params)))
         (full-body
	  (org-babel-expand-body:generic
	   (concat body (if return-val (format "\nreturn %s" return-val) ""))
	   params (org-babel-variable-assignments:lua params)))
         (result (org-babel-lua-evaluate
		  session full-body result-type result-params preamble)))
    (org-babel-reassemble-table
     result
     (org-babel-pick-name (cdr (assoc :colname-names params))
			  (cdr (assoc :colnames params)))
     (org-babel-pick-name (cdr (assoc :rowname-names params))
			  (cdr (assoc :rownames params))))))

(defun org-babel-prep-session:lua (session params)
  "Prepare SESSION according to the header arguments in PARAMS.
VARS contains resolved variable references"
  (let* ((session (org-babel-lua-initiate-session session))
	 (var-lines
	  (org-babel-variable-assignments:lua params)))
    (org-babel-comint-in-buffer session
      (mapc (lambda (var)
              (end-of-line 1) (insert var) (comint-send-input)
              (org-babel-comint-wait-for-output session)) var-lines))
    session))

(defun org-babel-load-session:lua (session body params)
  "Load BODY into SESSION."
  (save-window-excursion
    (let ((buffer (org-babel-prep-session:lua session params)))
      (with-current-buffer buffer
        (goto-char (process-mark (get-buffer-process (current-buffer))))
        (insert (org-babel-chomp body)))
      buffer)))

;; helper functions

(defun org-babel-variable-assignments:lua (params)
  "Return a list of Lua statements assigning the block's variables."
  (mapcar
   (lambda (pair)
     (format "%s=%s"
	     (car pair)
	     (org-babel-lua-var-to-lua (cdr pair))))
   (mapcar #'cdr (org-babel-get-header params :var))))

(defun org-babel-lua-var-to-lua (var)
  "Convert an elisp value to a lua variable.
Convert an elisp value, VAR, into a string of lua source code
specifying a variable of the same value."
  (if (listp var)
      (if (and (= 1 (length var)) (not (listp (car var))))
          (org-babel-lua-var-to-lua (car var))
        (if (and
             (= 2 (length var))
             (not (listp (car var))))
            (concat
             (substring-no-properties (car var))
             "="
             (org-babel-lua-var-to-lua (cdr var)))
          (concat "{" (mapconcat #'org-babel-lua-var-to-lua var ", ") "}")))
    (if (equal var 'hline)
        org-babel-lua-hline-to
      (format
       (if (and (stringp var) (string-match "[\n\r]" var)) "\"\"%S\"\"" "%S")
       (if (stringp var) (substring-no-properties var) var)))))

(defun org-babel-lua-table-or-string (results)
  "Convert RESULTS into an appropriate elisp value.
If the results look like a list or tuple, then convert them into an
Emacs-lisp table, otherwise return the results as a string."
  (let ((res (org-babel-script-escape results)))
    (if (listp res)
        (mapcar (lambda (el) (if (equal el 'None)
                            org-babel-lua-None-to el))
                res)
      res)))

(defvar org-babel-lua-buffers '((:default . "*Lua*")))

(defun org-babel-lua-session-buffer (session)
  "Return the buffer associated with SESSION."
  (cdr (assoc session org-babel-lua-buffers)))

(defun org-babel-lua-with-earmuffs (session)
  (let ((name (if (stringp session) session (format "%s" session))))
    (if (and (string= "*" (substring name 0 1))
	     (string= "*" (substring name (- (length name) 1))))
	name
      (format "*%s*" name))))

(defun org-babel-lua-without-earmuffs (session)
  (let ((name (if (stringp session) session (format "%s" session))))
    (if (and (string= "*" (substring name 0 1))
	     (string= "*" (substring name (- (length name) 1))))
	(substring name 1 (- (length name) 1))
      name)))

(defvar lua-default-interpreter)
(defvar lua-which-bufname)
(defvar lua-shell-buffer-name)
(defun org-babel-lua-initiate-session-by-key (&optional session)
  "Initiate a lua session.
If there is not a current inferior-process-buffer in SESSION
then create.  Return the initialized session."
  (require org-babel-lua-mode)
  (save-window-excursion
    (let* ((session (if session (intern session) :default))
           (lua-buffer (org-babel-lua-session-buffer session))
           (cmd (if (member system-type '(cygwin windows-nt ms-dos))
                    (concat org-babel-lua-command " -i")
                  org-babel-lua-command)))
      (cond
       ((and (eq 'lua-mode org-babel-lua-mode)
             (fboundp 'lua-start-process)) ; lua-mode.el
        ;; Make sure that lua-which-bufname is initialized, as otherwise
        ;; it will be overwritten the first time a Lua buffer is
        ;; created.
        ;;(lua-toggle-shells lua-default-interpreter)
        ;; `lua-shell' creates a buffer whose name is the value of
        ;; `lua-which-bufname' with '*'s at the beginning and end
        (let* ((bufname (if (and lua-process-buffer
                                 (buffer-live-p lua-process-buffer))
                            (replace-regexp-in-string ;; zap surrounding *
                             "^\\*\\([^*]+\\)\\*$" "\\1" (buffer-name lua-process-buffer))
                          (concat "Lua-" (symbol-name session))))
               (lua-which-bufname bufname))
          (lua-start-process)
          (setq lua-buffer (org-babel-lua-with-earmuffs bufname))))
       (t
        (error "No function available for running an inferior Lua")))
      (setq org-babel-lua-buffers
            (cons (cons session lua-process-buffer)
                  (assq-delete-all session org-babel-lua-buffers)))
      session)))

(defun org-babel-lua-initiate-session (&optional session params)
  "Create a session named SESSION according to PARAMS."
  (unless (string= session "none")
    (org-babel-lua-session-buffer
     (org-babel-lua-initiate-session-by-key session))))

(defvar org-babel-lua-eoe-indicator "\"org_babel_lua_eoe\""
  "A string to indicate that evaluation has completed.")
(defvar org-babel-lua-wrapper-method
  "
function main()
%s
end

fd=io.open(\"%s\", \"w\")
fd:write( main() )
fd:close()")
(defvar org-babel-lua-pp-wrapper-method
  "
-- table to string
function t2s(t, indent)
   if indent == nil then
      indent = \"\"
   end
   if type(t) == \"table\" then
      ts = \"\"
      for k,v in pairs(t) do
         if type(v) == \"table\" then
            ts = ts .. indent .. t2s(k,indent .. \"  \") .. \" = \\n\" ..
               t2s(v, indent .. \"  \")
         else
            ts = ts .. indent .. t2s(k,indent .. \"  \") .. \" = \" ..
               t2s(v, indent .. \"  \") .. \"\\n\"
         end
      end
      return ts
   else
      return tostring(t)
   end
end


function main()
%s
end

fd=io.open(\"%s\", \"w\")
fd:write(t2s(main()))
fd:close()")

(defun org-babel-lua-evaluate
  (session body &optional result-type result-params preamble)
  "Evaluate BODY as Lua code."
  (if session
      (org-babel-lua-evaluate-session
       session body result-type result-params)
    (org-babel-lua-evaluate-external-process
     body result-type result-params preamble)))

(defun org-babel-lua-evaluate-external-process
  (body &optional result-type result-params preamble)
  "Evaluate BODY in external lua process.
If RESULT-TYPE equals 'output then return standard output as a
string.  If RESULT-TYPE equals 'value then return the value of the
last statement in BODY, as elisp."
  (let ((raw
         (case result-type
           (output (org-babel-eval org-babel-lua-command
                                   (concat (if preamble (concat preamble "\n"))
                                           body)))
           (value (let ((tmp-file (org-babel-temp-file "lua-")))
                    (org-babel-eval
                     org-babel-lua-command
                     (concat
                      (if preamble (concat preamble "\n") "")
                      (format
                       (if (member "pp" result-params)
                           org-babel-lua-pp-wrapper-method
                         org-babel-lua-wrapper-method)
                       (mapconcat
                        (lambda (line) (format "\t%s" line))
                        (split-string
                         (org-remove-indentation
                          (org-babel-trim body))
                         "[\r\n]") "\n")
                       (org-babel-process-file-name tmp-file 'noquote))))
                    (org-babel-eval-read-file tmp-file))))))
    (org-babel-result-cond result-params
      raw
      (org-babel-lua-table-or-string (org-babel-trim raw)))))

(defun org-babel-lua-evaluate-session
    (session body &optional result-type result-params)
  "Pass BODY to the Lua process in SESSION.
If RESULT-TYPE equals 'output then return standard output as a
string.  If RESULT-TYPE equals 'value then return the value of the
last statement in BODY, as elisp."
  (let* ((send-wait (lambda () (comint-send-input nil t) (sleep-for 0 5)))
	 (dump-last-value
	  (lambda
	    (tmp-file pp)
	    (mapc
	     (lambda (statement) (insert statement) (funcall send-wait))
	     (if pp
		 (list
		  "-- table to string
function t2s(t, indent)
   if indent == nil then
      indent = \"\"
   end
   if type(t) == \"table\" then
      ts = \"\"
      for k,v in pairs(t) do
         if type(v) == \"table\" then
            ts = ts .. indent .. t2s(k,indent .. \"  \") .. \" = \\n\" ..
               t2s(v, indent .. \"  \")
         else
            ts = ts .. indent .. t2s(k,indent .. \"  \") .. \" = \" ..
               t2s(v, indent .. \"  \") .. \"\\n\"
         end
      end
      return ts
   else
      return tostring(t)
   end
end
"
		  (format "fd:write(_))
fd:close()"
			  (org-babel-process-file-name tmp-file 'noquote)))
	       (list (format "fd=io.open(\"%s\", \"w\")
fd:write( _ )
fd:close()"
			     (org-babel-process-file-name tmp-file
                                                          'noquote)))))))
	 (input-body (lambda (body)
		       (mapc (lambda (line) (insert line) (funcall send-wait))
			     (split-string body "[\r\n]"))
		       (funcall send-wait)))
         (results
          (case result-type
            (output
             (mapconcat
              #'org-babel-trim
              (butlast
               (org-babel-comint-with-output
                   (session org-babel-lua-eoe-indicator t body)
                 (funcall input-body body)
                 (funcall send-wait) (funcall send-wait)
                 (insert org-babel-lua-eoe-indicator)
                 (funcall send-wait))
               2) "\n"))
            (value
             (let ((tmp-file (org-babel-temp-file "lua-")))
               (org-babel-comint-with-output
                   (session org-babel-lua-eoe-indicator nil body)
                 (let ((comint-process-echoes nil))
                   (funcall input-body body)
                   (funcall dump-last-value tmp-file
                            (member "pp" result-params))
                   (funcall send-wait) (funcall send-wait)
                   (insert org-babel-lua-eoe-indicator)
                   (funcall send-wait)))
               (org-babel-eval-read-file tmp-file))))))
    (unless (string= (substring org-babel-lua-eoe-indicator 1 -1) results)
      (org-babel-result-cond result-params
	results
        (org-babel-lua-table-or-string results)))))

(defun org-babel-lua-read-string (string)
  "Strip 's from around Lua string."
  (if (string-match "^'\\([^\000]+\\)'$" string)
      (match-string 1 string)
    string))

(provide 'ob-lua)



;;; ob-lua.el ends here

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: ob-lua.el
  2014-05-24 21:17           ` ob-lua.el Dieter Schoen
@ 2014-05-25  5:24             ` Bastien
  2014-05-26 20:57               ` ob-lua.el Dieter Schoen
  0 siblings, 1 reply; 14+ messages in thread
From: Bastien @ 2014-05-25  5:24 UTC (permalink / raw)
  To: Dieter Schoen; +Cc: emacs-orgmode, Eric Schulte

Hi Dieter,

Dieter Schoen <dieter@schoen.or.at> writes:

> Yes, that was a copy/paste relict from ob-python, I removed the latter
> mode reference.

OK -- I see there are still references to both lua-mode.el and lua.el
(which does not exist) and you need to add a link to the lua-mode.el
github repository.

>> * See (defcustom org-babel-lua-mode ...
>
> As far as I understand the code, lua-mode would only be used for the session
> support, to have an inferior process as receiver for code blocks.
> I could not yet get the session support to work, there is a bit more work
> involved than simple s/py/lua/.
> I'll continue to work in that area.

Okay.  Another thing:

  :version "24.4"
  :package-version '(Org . "8.0")

needs to be

  :version "24.5"
  :package-version '(Org . "8.3")

to be accurate.

Thanks for the ongoing work, keep us posted and we can put this in
master when you get the confirmation from the FSF for the copyright
assignment.

Thanks!

-- 
 Bastien

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: ob-lua.el
  2014-05-25  5:24             ` ob-lua.el Bastien
@ 2014-05-26 20:57               ` Dieter Schoen
  2014-05-29 17:57                 ` ob-lua.el Bastien
  0 siblings, 1 reply; 14+ messages in thread
From: Dieter Schoen @ 2014-05-26 20:57 UTC (permalink / raw)
  To: Bastien; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 936 bytes --]

At Sun, 25 May 2014 07:24:07 +0200,
Bastien wrote:
> 
> OK -- I see there are still references to both lua-mode.el and lua.el
> (which does not exist) and you need to add a link to the lua-mode.el
> github repository.

The reference to lua.el should be gone now.
Link added.

> Okay.  Another thing:
> 
>   :version "24.4"
>   :package-version '(Org . "8.0")
> 
> needs to be
> 
>   :version "24.5"
>   :package-version '(Org . "8.3")
> 
> to be accurate.

Fixed.

One problem which I am currently working on is session mode.
This is not yet working.
Therefore I have put an (error "..") in org-babel-lua-initiate-session.

> Thanks for the ongoing work, keep us posted and we can put this in
> master when you get the confirmation from the FSF for the copyright
> assignment.

I already received the confirmation from FSF (the signed PDF), and I have seen
that I have been added to the contributors of org-mode.

Kind regards,
Dieter


[-- Attachment #2: ob-lua.el --]
[-- Type: text/plain, Size: 14493 bytes --]

;;; ob-lua.el --- org-babel functions for lua evaluation

;; Copyright (C) 2009-2014 Free Software Foundation, Inc.

;; Authors: Dieter Schoen
;;	 Eric Schulte, Dan Davison
;; 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/>.

;; Requirements:
;; for session support, lua-mode is needed.
;; lua-mode is not part of GNU Emacs/orgmode, but can be obtained
;; from marmalade or melpa.
;; The source respository is here:
;; https://github.com/immerrr/lua-mode

;; However, sessions are not yet working.

;; Org-Babel support for evaluating lua source code.

;;; Code:
(require 'ob)
(eval-when-compile (require 'cl))

(declare-function org-remove-indentation "org" )
(declare-function lua-shell "ext:lua-mode" (&optional argprompt))
(declare-function lua-toggle-shells "ext:lua-mode" (arg))
(declare-function run-lua "ext:lua" (cmd &optional dedicated show))

(defvar org-babel-tangle-lang-exts)
(add-to-list 'org-babel-tangle-lang-exts '("lua" . "lua"))

(defvar org-babel-default-header-args:lua '())

(defcustom org-babel-lua-command "lua"
  "Name of the command for executing Lua code."
  :version "24.5"
  :package-version '(Org . "8.3")
  :group 'org-babel
  :type 'string)

(defcustom org-babel-lua-mode 'lua-mode
  "Preferred lua mode for use in running lua interactively.
This will typically be 'lua-mode."
  :group 'org-babel
  :version "24.5"
  :package-version '(Org . "8.3")
  :type 'symbol)

(defcustom org-babel-lua-hline-to "None"
  "Replace hlines in incoming tables with this when translating to lua."
  :group 'org-babel
  :version "24.5"
  :package-version '(Org . "8.3")
  :type 'string)

(defcustom org-babel-lua-None-to 'hline
  "Replace 'None' in lua tables with this before returning."
  :group 'org-babel
  :version "24.5"
  :package-version '(Org . "8.3")
  :type 'symbol)

(defun org-babel-execute:lua (body params)
  "Execute a block of Lua code with Babel.
This function is called by `org-babel-execute-src-block'."
  (let* ((session (org-babel-lua-initiate-session
		   (cdr (assoc :session params))))
         (result-params (cdr (assoc :result-params params)))
         (result-type (cdr (assoc :result-type params)))
	 (return-val (when (and (eq result-type 'value) (not session))
		       (cdr (assoc :return params))))
	 (preamble (cdr (assoc :preamble params)))
         (full-body
	  (org-babel-expand-body:generic
	   (concat body (if return-val (format "\nreturn %s" return-val) ""))
	   params (org-babel-variable-assignments:lua params)))
         (result (org-babel-lua-evaluate
		  session full-body result-type result-params preamble)))
    (org-babel-reassemble-table
     result
     (org-babel-pick-name (cdr (assoc :colname-names params))
			  (cdr (assoc :colnames params)))
     (org-babel-pick-name (cdr (assoc :rowname-names params))
			  (cdr (assoc :rownames params))))))

(defun org-babel-prep-session:lua (session params)
  "Prepare SESSION according to the header arguments in PARAMS.
VARS contains resolved variable references"
  (let* ((session (org-babel-lua-initiate-session session))
	 (var-lines
	  (org-babel-variable-assignments:lua params)))
    (org-babel-comint-in-buffer session
      (mapc (lambda (var)
              (end-of-line 1) (insert var) (comint-send-input)
              (org-babel-comint-wait-for-output session)) var-lines))
    session))

(defun org-babel-load-session:lua (session body params)
  "Load BODY into SESSION."
  (save-window-excursion
    (let ((buffer (org-babel-prep-session:lua session params)))
      (with-current-buffer buffer
        (goto-char (process-mark (get-buffer-process (current-buffer))))
        (insert (org-babel-chomp body)))
      buffer)))

;; helper functions

(defun org-babel-variable-assignments:lua (params)
  "Return a list of Lua statements assigning the block's variables."
  (mapcar
   (lambda (pair)
     (format "%s=%s"
	     (car pair)
	     (org-babel-lua-var-to-lua (cdr pair))))
   (mapcar #'cdr (org-babel-get-header params :var))))

(defun org-babel-lua-var-to-lua (var)
  "Convert an elisp value to a lua variable.
Convert an elisp value, VAR, into a string of lua source code
specifying a variable of the same value."
  (if (listp var)
      (if (and (= 1 (length var)) (not (listp (car var))))
          (org-babel-lua-var-to-lua (car var))
        (if (and
             (= 2 (length var))
             (not (listp (car var))))
            (concat
             (substring-no-properties (car var))
             "="
             (org-babel-lua-var-to-lua (cdr var)))
          (concat "{" (mapconcat #'org-babel-lua-var-to-lua var ", ") "}")))
    (if (equal var 'hline)
        org-babel-lua-hline-to
      (format
       (if (and (stringp var) (string-match "[\n\r]" var)) "\"\"%S\"\"" "%S")
       (if (stringp var) (substring-no-properties var) var)))))

(defun org-babel-lua-table-or-string (results)
  "Convert RESULTS into an appropriate elisp value.
If the results look like a list or tuple, then convert them into an
Emacs-lisp table, otherwise return the results as a string."
  (let ((res (org-babel-script-escape results)))
    (if (listp res)
        (mapcar (lambda (el) (if (equal el 'None)
                            org-babel-lua-None-to el))
                res)
      res)))

(defvar org-babel-lua-buffers '((:default . "*Lua*")))

(defun org-babel-lua-session-buffer (session)
  "Return the buffer associated with SESSION."
  (cdr (assoc session org-babel-lua-buffers)))

(defun org-babel-lua-with-earmuffs (session)
  (let ((name (if (stringp session) session (format "%s" session))))
    (if (and (string= "*" (substring name 0 1))
	     (string= "*" (substring name (- (length name) 1))))
	name
      (format "*%s*" name))))

(defun org-babel-lua-without-earmuffs (session)
  (let ((name (if (stringp session) session (format "%s" session))))
    (if (and (string= "*" (substring name 0 1))
	     (string= "*" (substring name (- (length name) 1))))
	(substring name 1 (- (length name) 1))
      name)))

(defvar lua-default-interpreter)
(defvar lua-which-bufname)
(defvar lua-shell-buffer-name)
(defun org-babel-lua-initiate-session-by-key (&optional session)
  "Initiate a lua session.
If there is not a current inferior-process-buffer in SESSION
then create.  Return the initialized session."
  (require org-babel-lua-mode)
  (save-window-excursion
    (let* ((session (if session (intern session) :default))
           (lua-buffer (org-babel-lua-session-buffer session))
	   (cmd (if (member system-type '(cygwin windows-nt ms-dos))
		    (concat org-babel-lua-command " -i")
		  org-babel-lua-command)))
      (cond
       ((and (eq 'lua-mode org-babel-lua-mode)
             (fboundp 'lua-start-process)) ; lua-mode.el
        ;; Make sure that lua-which-bufname is initialized, as otherwise
        ;; it will be overwritten the first time a Lua buffer is
        ;; created.
        ;;(lua-toggle-shells lua-default-interpreter)
        ;; `lua-shell' creates a buffer whose name is the value of
        ;; `lua-which-bufname' with '*'s at the beginning and end
        (let* ((bufname (if (and lua-process-buffer
                                 (buffer-live-p lua-process-buffer))
                            (replace-regexp-in-string ;; zap surrounding *
                             "^\\*\\([^*]+\\)\\*$" "\\1" (buffer-name lua-process-buffer))
                          (concat "Lua-" (symbol-name session))))
               (lua-which-bufname bufname))
          (lua-start-process)
          (setq lua-buffer (org-babel-lua-with-earmuffs bufname))))
       (t
	(error "No function available for running an inferior Lua")))
      (setq org-babel-lua-buffers
            (cons (cons session lua-process-buffer)
                  (assq-delete-all session org-babel-lua-buffers)))
      session)))

(defun org-babel-lua-initiate-session (&optional session params)
  "Create a session named SESSION according to PARAMS."
  (unless (string= session "none")
    (error "Sessions currently not supported, work in progress")
    (org-babel-lua-session-buffer
     (org-babel-lua-initiate-session-by-key session))))

(defvar org-babel-lua-eoe-indicator "--eoe"
  "A string to indicate that evaluation has completed.")

(defvar org-babel-lua-wrapper-method
  "
function main()
%s
end

fd=io.open(\"%s\", \"w\")
fd:write( main() )
fd:close()")
(defvar org-babel-lua-pp-wrapper-method
  "
-- table to string
function t2s(t, indent)
   if indent == nil then
      indent = \"\"
   end
   if type(t) == \"table\" then
      ts = \"\"
      for k,v in pairs(t) do
         if type(v) == \"table\" then
            ts = ts .. indent .. t2s(k,indent .. \"  \") .. \" = \\n\" ..
               t2s(v, indent .. \"  \")
         else
            ts = ts .. indent .. t2s(k,indent .. \"  \") .. \" = \" ..
               t2s(v, indent .. \"  \") .. \"\\n\"
         end
      end
      return ts
   else
      return tostring(t)
   end
end


function main()
%s
end

fd=io.open(\"%s\", \"w\")
fd:write(t2s(main()))
fd:close()")

(defun org-babel-lua-evaluate
  (session body &optional result-type result-params preamble)
  "Evaluate BODY as Lua code."
  (if session
      (org-babel-lua-evaluate-session
       session body result-type result-params)
    (org-babel-lua-evaluate-external-process
     body result-type result-params preamble)))

(defun org-babel-lua-evaluate-external-process
  (body &optional result-type result-params preamble)
  "Evaluate BODY in external lua process.
If RESULT-TYPE equals 'output then return standard output as a
string.  If RESULT-TYPE equals 'value then return the value of the
last statement in BODY, as elisp."
  (let ((raw
         (case result-type
           (output (org-babel-eval org-babel-lua-command
                                   (concat (if preamble (concat preamble "\n"))
                                           body)))
           (value (let ((tmp-file (org-babel-temp-file "lua-")))
                    (org-babel-eval
                     org-babel-lua-command
                     (concat
                      (if preamble (concat preamble "\n") "")
                      (format
                       (if (member "pp" result-params)
                           org-babel-lua-pp-wrapper-method
                         org-babel-lua-wrapper-method)
                       (mapconcat
                        (lambda (line) (format "\t%s" line))
                        (split-string
                         (org-remove-indentation
                          (org-babel-trim body))
                         "[\r\n]") "\n")
                       (org-babel-process-file-name tmp-file 'noquote))))
                    (org-babel-eval-read-file tmp-file))))))
    (org-babel-result-cond result-params
      raw
      (org-babel-lua-table-or-string (org-babel-trim raw)))))

(defun org-babel-lua-evaluate-session
    (session body &optional result-type result-params)
  "Pass BODY to the Lua process in SESSION.
If RESULT-TYPE equals 'output then return standard output as a
string.  If RESULT-TYPE equals 'value then return the value of the
last statement in BODY, as elisp."
  (let* ((send-wait (lambda () (comint-send-input nil t) (sleep-for 0 5)))
	 (dump-last-value
	  (lambda
	    (tmp-file pp)
	    (mapc
	     (lambda (statement) (insert statement) (funcall send-wait))
	     (if pp
		 (list
		  "-- table to string
function t2s(t, indent)
   if indent == nil then
      indent = \"\"
   end
   if type(t) == \"table\" then
      ts = \"\"
      for k,v in pairs(t) do
         if type(v) == \"table\" then
            ts = ts .. indent .. t2s(k,indent .. \"  \") .. \" = \\n\" ..
               t2s(v, indent .. \"  \")
         else
            ts = ts .. indent .. t2s(k,indent .. \"  \") .. \" = \" ..
               t2s(v, indent .. \"  \") .. \"\\n\"
         end
      end
      return ts
   else
      return tostring(t)
   end
end
"
		  (format "fd:write(_))
fd:close()"
			  (org-babel-process-file-name tmp-file 'noquote)))
	       (list (format "fd=io.open(\"%s\", \"w\")
fd:write( _ )
fd:close()"
			     (org-babel-process-file-name tmp-file
                                                          'noquote)))))))
	 (input-body (lambda (body)
		       (mapc (lambda (line) (insert line) (funcall send-wait))
			     (split-string body "[\r\n]"))
		       (funcall send-wait)))
         (results
          (case result-type
            (output
             (mapconcat
              #'org-babel-trim
              (butlast
               (org-babel-comint-with-output
                   (session org-babel-lua-eoe-indicator t body)
                 (funcall input-body body)
                 (funcall send-wait) (funcall send-wait)
                 (insert org-babel-lua-eoe-indicator)
                 (funcall send-wait))
               2) "\n"))
            (value
             (let ((tmp-file (org-babel-temp-file "lua-")))
               (org-babel-comint-with-output
                   (session org-babel-lua-eoe-indicator nil body)
                 (let ((comint-process-echoes nil))
                   (funcall input-body body)
                   (funcall dump-last-value tmp-file
                            (member "pp" result-params))
                   (funcall send-wait) (funcall send-wait)
                   (insert org-babel-lua-eoe-indicator)
                   (funcall send-wait)))
               (org-babel-eval-read-file tmp-file))))))
    (unless (string= (substring org-babel-lua-eoe-indicator 1 -1) results)
      (org-babel-result-cond result-params
	results
        (org-babel-lua-table-or-string results)))))

(defun org-babel-lua-read-string (string)
  "Strip 's from around Lua string."
  (if (string-match "^'\\([^\000]+\\)'$" string)
      (match-string 1 string)
    string))

(provide 'ob-lua)



;;; ob-lua.el ends here

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: ob-lua.el
  2014-05-26 20:57               ` ob-lua.el Dieter Schoen
@ 2014-05-29 17:57                 ` Bastien
  0 siblings, 0 replies; 14+ messages in thread
From: Bastien @ 2014-05-29 17:57 UTC (permalink / raw)
  To: Dieter Schoen; +Cc: emacs-orgmode

Hi Dieter,

Dieter Schoen <dieter@schoen.or.at> writes:

> I already received the confirmation from FSF (the signed PDF), and I have seen
> that I have been added to the contributors of org-mode.

Please send me your public key and I'll give you access to the
repository.  When you're done fixing `org-babel-lua-initiate-session'
and other stuff, please commit ob-lua.el to the lisp/ directory.

If you are unsure about the commit message, please post the patch to
the list first and we'll see.

Thanks!

-- 
 Bastien

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2014-05-29 17:57 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-09 20:26 ob-lua.el dieter
2014-05-12 15:26 ` ob-lua.el Eric Schulte
2014-05-13 10:57   ` ob-lua.el Dieter Schoen
2014-05-21  7:30     ` ob-lua.el Bastien
2014-05-24 10:55       ` ob-lua.el Dieter Schoen
2014-05-24 12:25         ` ob-lua.el Bastien
2014-05-24 21:17           ` ob-lua.el Dieter Schoen
2014-05-25  5:24             ` ob-lua.el Bastien
2014-05-26 20:57               ` ob-lua.el Dieter Schoen
2014-05-29 17:57                 ` ob-lua.el Bastien
  -- strict thread matches above, loose matches on Subject: below --
2014-05-06 22:34 ob-lua.el dieter
2014-05-06 22:46 ` ob-lua.el Bastien
2014-05-09 20:23   ` ob-lua.el Dieter Schoen
2014-05-06 23:25 ` ob-lua.el John Busch

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).