Nicolas,
More patches (as you can see). Now ox.el, ob-core.el, and ob-exp.el are
patched.
A few examples of how they render various src_<lang>[headers]{code} setups
are also attached.
Discussion inline below.
On Thu, 13 Nov 2014, Nicolas Goaziou wrote:
Hello,
"Charles C. Berry" <ccbe...@ucsd.edu> writes:
I like the flexibility that macros would allow.
I like it too. Macros are much better than export snippets for the task.
I don't think the usual #+MACRO works here, as the definition would be
found in `org-macro-templates' by the first call and existing stuff
would be expanded instead of being left for babel to remove it. But
setting it up as a document keyword should work, right?
Don't know if there are other gotchas.
Maybe a limited collection of formats could be set up to support basic
markup options and the macro could choose amongst them with a second
arg set by a babel header arg.
I think {{{results()}}} should remain a dumb wrapper itself and not try
to do some formatting (i.e., a simple, hard-coded macro). Formatting
should be on the side of Babel and, possibly, its arguments. Let's not
duplicate features.
Point taken.
Also, the user can customize org-babel-inline-result-wrap to always get
verbatim or otherwise wrap the contents of the macro.
I am not quite sure how to marry this to header args. Maybe the :wrap
header arg should be hijacked for inline src blocks to specify a macro
for the results.
Macro can be the default output. If you don't want a macro, use raw
header. IOW, there is no need for a specific header arg.
I mean, does anyone actually use stuff like src_R[:wrap latex]{1+2}?
The current result cannot be parsed as an export block, AFAICS.
It could evaluate to @@latex:3@@. Parsing can also be solved if
necessary.
`:wrap latex' results in @@latex: ... @@.
`:results latex' results in
: @@LaTeX:
: <results>@@
which is a bit unsightly, but can be parsed and removed.
I have not touched
- :RESULTS drawers
- lists
- tables
---
I appreciate your coaching/feedback.
Aaron Ecay's suggestion to use a macro was a good one. Thanks Aron.
Best,
Chuck
From b369b0a1e69fd2b91c8f4eb7d824dcd18232917b Mon Sep 17 00:00:00 2001
From: chasberry <ccbe...@ucsd.edu>
Date: Thu, 13 Nov 2014 20:45:01 -0800
Subject: [PATCH 1/3] lisp/ob-core.el: Replace inline `results' macro call or
export-snippet
* lisp/ob-core.el (org-babel-inline-result-wrap): Default is
"{{{results(%s)}}}".
* lisp/ob-core.el (org-babel-insert-result): Delete any `results'
macro or export-snippet immediately following inline src block;
insert current value in 'results' macro or export snippet if :wrap
header argument is given. Escape commas in the result with
backslashes if the macro form is used.
* lisp/ob-core.el (org-babel-delete-babel-snippet): Add function to
delete "{{{results(.*)}}}" macro calls or "@@backend:.*@@" provided
they follow inline src blocks. Adding extra spaces between an
export snippet and its inline src block will protect it from
removal.
---
lisp/ob-core.el | 49 +++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 41 insertions(+), 8 deletions(-)
diff --git a/lisp/ob-core.el b/lisp/ob-core.el
index 6c38677..227c8f0 100644
--- a/lisp/ob-core.el
+++ b/lisp/ob-core.el
@@ -156,7 +156,7 @@ See also `org-babel-noweb-wrap-start'."
:group 'org-babel
:type 'string)
-(defcustom org-babel-inline-result-wrap "=%s="
+(defcustom org-babel-inline-result-wrap "{{{results(%s)}}}"
"Format string used to wrap inline results.
This string must include a \"%s\" which will be replaced by the results."
:group 'org-babel
@@ -2136,8 +2136,9 @@ code ---- the results are extracted in the syntax of the
source
(goto-char (match-end 0))
(insert (if (listp result) "\n" " "))
(point))))
- (existing-result (unless inlinep
- (org-babel-where-is-src-block-result
+ (existing-result (if inlinep
+ (org-babel-delete-babel-snippet)
+ (org-babel-where-is-src-block-result
t info hash indent)))
(results-switches
(cdr (assoc :results_switches (nth 2 info))))
@@ -2216,6 +2217,12 @@ code ---- the results are extracted in the syntax of the
source
((member "file" result-params)
(when inlinep (goto-char inlinep))
(insert result))
+ ;; escape commas, e.g. {{{results(a\,b)}}}
+ ((and inlinep
+ (equal '("replace") result-params)
+ (not (assoc :wrap (nth 2 info))))
+ (goto-char beg)
+ (insert (replace-regexp-in-string "," "\\," result nil t)))
(t (goto-char beg) (insert result)))
(when (funcall proper-list-p result) (goto-char
(org-table-end)))
(setq end (point-marker))
@@ -2223,12 +2230,18 @@ code ---- the results are extracted in the syntax of
the source
(cond
((assoc :wrap (nth 2 info))
(let ((name (or (cdr (assoc :wrap (nth 2 info))) "RESULTS")))
- (funcall wrap (concat "#+BEGIN_" name)
- (concat "#+END_" (car (org-split-string name))))))
+ (if inlinep
+ (funcall wrap (concat "@@" name ":") "@@" nil t)
+ (funcall wrap (concat "#+BEGIN_" name)
+ (concat "#+END_" (car (org-split-string
name)))))))
((member "html" result-params)
- (funcall wrap "#+BEGIN_HTML" "#+END_HTML"))
- ((member "latex" result-params)
- (funcall wrap "#+BEGIN_LaTeX" "#+END_LaTeX"))
+ (if inlinep
+ (funcall wrap "@@HTML:" "@@")
+ (funcall wrap "#+BEGIN_HTML" "#+END_HTML")))
+ ((member "latex" result-params)
+ (if inlinep
+ (funcall wrap "@@LaTeX:" "@@")
+ (funcall wrap "#+BEGIN_LaTeX" "#+END_LaTeX")))
((member "org" result-params)
(goto-char beg) (if (org-at-table-p) (org-cycle))
(if inlinep
@@ -2279,6 +2292,26 @@ code ---- the results are extracted in the syntax of the
source
(if keep-keyword (1+ (match-end 0)) (1- (match-beginning 0)))
(progn (forward-line 1) (org-babel-result-end))))))))
+(defun org-babel-delete-babel-snippet (&optional info)
+ "When point is in an inline src block, delete an export-snippet
+or `results' macro call just after it. To protect export snippets
+from removal, add extra spaces between the src block and the
+snippet."
+ (let ((location (org-babel-where-is-src-block-result nil info)))
+ (when location
+ (save-excursion
+ (goto-char location)
+ (cond
+ ((looking-at "\\([ ]\\{1,2\\}\\)\\(@\\)")
+ (goto-char (match-end 1))
+ (let ((export-snippet (org-element-export-snippet-parser)))
+ (if export-snippet
+ (let ((start (org-element-property :begin export-snippet))
+ (end (org-element-property :end export-snippet)))
+ (delete-region start end)))))
+ ((looking-at "\\([[:space:]]*\\)\\({{{results(.*?)}}}\\)")
+ (delete-region (match-end 1) (match-end 2))))))))
+
(defun org-babel-remove-result-one-or-many (x)
"Remove the result of the current source block.
If called with a prefix argument, remove all result blocks
--
1.9.3 (Apple Git-50)
From c69e49f551d4dbef0753512ac7dd89115478244b Mon Sep 17 00:00:00 2001
From: chasberry <ccbe...@ucsd.edu>
Date: Thu, 13 Nov 2014 20:49:57 -0800
Subject: [PATCH 2/3] lisp/ob-exp.el: Enable removable inline src results
* lisp/ob-exp.el (org-babel-exp-do-export): After inline src block clean
`@@<backend>:<result>@@' or `{{{results(<result>}}}'.
---
lisp/ob-exp.el | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lisp/ob-exp.el b/lisp/ob-exp.el
index edb889c..83359e5 100644
--- a/lisp/ob-exp.el
+++ b/lisp/ob-exp.el
@@ -315,7 +315,9 @@ The function respects the value of the :exports header
argument."
(let ((silently (lambda () (let ((session (cdr (assoc :session (nth 2
info)))))
(when (not (and session (equal "none" session)))
(org-babel-exp-results info type 'silent)))))
- (clean (lambda () (unless (eq type 'inline) (org-babel-remove-result
info)))))
+ (clean (lambda () (if (eq type 'inline)
+ (org-babel-delete-babel-snippet info)
+ (org-babel-remove-result info)))))
(case (intern (or (cdr (assoc :exports (nth 2 info))) "code"))
('none (funcall silently) (funcall clean) "")
('code (funcall silently) (funcall clean) (org-babel-exp-code info type))
--
1.9.3 (Apple Git-50)
From d510c83e5eb027ca2e8678b5557ac3af870a588b Mon Sep 17 00:00:00 2001
From: chasberry <ccbe...@ucsd.edu>
Date: Thu, 13 Nov 2014 20:55:36 -0800
Subject: [PATCH 3/3] lisp/ox.el: Enable removable inline src results
* lisp/ox.el: (org-export-as): Treat `results' as an `identity' macro
with one argument after Babel executes.
---
lisp/ox.el | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lisp/ox.el b/lisp/ox.el
index d04e97a..fd7c67a 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -2885,7 +2885,8 @@ Return code as a string."
;; EMAIL is not a parsed keyword: store it as-is.
(cons "email" (or (plist-get info :email) ""))
(cons "title"
- (org-element-interpret-data (plist-get info :title))))
+ (org-element-interpret-data (plist-get info :title)))
+ (cons "results" "$1"))
'finalize)
;; Parse buffer.
(setq tree (org-element-parse-buffer nil visible-only))
--
1.9.3 (Apple Git-50)
Executing these commands:
src_emacs-lisp[:wrap latex]{"Aa,b"} @@latex: wrap @@
src_emacs-lisp[:results raw]{"a,b"} @@latex: raw @@
src_emacs-lisp{"A,B,C"} @@latex: macro @@
src_emacs-lisp[:results latex]{"a,b"} @@latex: :results latex @@
src_emacs-lisp[:wrap latex]{"a,b"} @@latex: KEEP ME!!! @@
src_emacs-lisp{"a,b"} {{{results(DEELETE ME)}}}
Gives this output:
src_emacs-lisp[:wrap latex]{"Aa,b"} @@latex:Aa,b@@
src_emacs-lisp[:results raw]{"a,b"} a,b
src_emacs-lisp{"A,B,C"} {{{results(A\,B\,C)}}}
src_emacs-lisp[:results latex]{"a,b"} @@LaTeX:
a,b@@
src_emacs-lisp[:wrap latex]{"a,b"} @@latex:a,b@@ @@latex: KEEP ME!!! @@
src_emacs-lisp{"a,b"} {{{results(a\,b)}}}