emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Nicolas Girard <girard.nicolas@gmail.com>
To: Nicolas Goaziou <n.goaziou@gmail.com>
Cc: emacs-orgmode <emacs-orgmode@gnu.org>
Subject: Re: [Babel] org-babel-execute-buffer gives different results than org-babel-exp-non-block-elements
Date: Fri, 23 Aug 2013 01:20:09 +0200	[thread overview]
Message-ID: <CANMKmecqCo9SeCrET1-ecv8E5=pk0Rw=M-nWMZViCy437d94Jw@mail.gmail.com> (raw)
In-Reply-To: <87siy1jpff.fsf@gmail.com>

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

2013/8/23 Nicolas Goaziou <n.goaziou@gmail.com>:
> Nicolas Girard <girard.nicolas@gmail.com> writes:
>
> I see.
>
> There is an important difference between evaluating a buffer and
> evaluating a buffer during export. In the latter, Babel has to deal with
> replacement values, i.e., code block is replaced by its results. See the
> difference between `org-export-execute-babel-code' and
> `org-babel-execute-buffer' in a buffer containing only
>
>   src_emacs-lisp[:results raw]{(+ 1 2)}
>
> In this case, your code removes the code (and much more) as
> a side-effect. This confuses `org-babel-exp-non-block-elements', which
> also tries to remove it. As this fails, it removes a random part of the
> buffer instead (probably as a mean revenge).
>

Thanks very much for your insight ! I came to the same conclusions and
found a temporary solution, namely using the value (bufferp
org-current-export-file) to check wether the code is called by the
exporter or just Babel. Attached is a modified version of my code that
behaves differently depending of the value of (bufferp
org-current-export-file).

Do you think it could be robust enough ?

> `org-babel-exp-non-block-elements' and `org-babel-exp-process-buffer'
> could probably check if code still exists before trying to remove (and
> replace) it.
>

Yeah, I don't know how much work it would represent but it seems much
more appropriate that my hack-ish solution.

---
Nicolas

[-- Attachment #2: transclusion.org --]
[-- Type: application/octet-stream, Size: 4528 bytes --]

#+AUTHOR: Nicolas Girard <girard.nicolas@gmail.com>

* Instructions
:PROPERTIES:
:VISIBILITY: all
:END:

1. Evaluate the elisp code contained in the section "Code to evaluate", either by executing =(org-babel-load-file buffer-file-name)=, or by evaluating manually each function using =C-x C-e=
2. Run the small tests contained in the section "Transclusion tests" using =(org-babel-execute-buffer)=. This will behave as expected
=(org-babel-exp-process-buffer)=
3. Restore the buffer to its original contents using =C-_=
4. Now, run =(progn (require 'ox) (org-export-execute-babel-code))= and compare with the behaviour in step (2.)

   Ultimately this boils down to
   #+BEGIN_SRC emacs-lisp :tangle no
     (let ((reference (org-export-copy-buffer)))
         (unwind-protect (let ((org-current-export-file reference))
                           ; beginning of (org-babel-exp-process-buffer)
                           (org-babel-exp-non-block-elements (point-min) (point-max))
                           ; end of (org-babel-exp-process-buffer)
                           )
           (kill-buffer reference)))
   #+END_SRC

* Code to evaluate
Evaluate with: (org-babel-load-file buffer-file-name)
** required
#+BEGIN_SRC emacs-lisp 
(eval-when-compile
    (require 'cl)
    (require 'org-id))
#+END_SRC
** ng/decode-link
#+BEGIN_SRC emacs-lisp 
(defun ng/decode-link (s)
  "[[x][y]] -> (x . y)"
  (let (desc link)
    (when
	(string-match org-bracket-link-regexp s)
      (setq desc (if (match-end 3) (org-match-string-no-properties 3 s)))
      (setq link (org-link-unescape
		  (org-match-string-no-properties 1 s)))
      (cons link desc))))
#+END_SRC
** ng/get-symlink-id
#+BEGIN_SRC emacs-lisp 
(defun ng/get-symlink-id (s)
  "[[id:888-77][ffff]] -> 888-77"
  (when 
    (and (string-match org-bracket-link-regexp s)
	 (setq s (match-string 1 s))
	 (string-match "^id\\:\\([^][]+\\)" s))
    (match-string 1 s)
    ))
#+END_SRC
** ng/delete-current-line
#+BEGIN_SRC emacs-lisp 
(defun ng/delete-current-line ()
  (let ((b (point-at-bol))
	(e (+ 1 (point-at-eol))))
    (delete-region b e)))
#+END_SRC
** ng/org-get-entry-title
#+BEGIN_SRC emacs-lisp 
(defun ng/org-get-entry-title (&optional pom)
  " * WORK aa :b: ---> aa"
  (org-with-point-at pom
    (org-no-properties (org-get-heading 'notags 'notodo))))
#+END_SRC
** ng/org-tc
#+BEGIN_SRC emacs-lisp 
  (defun ng/org-tc (s)
    (let* ((at-heading-p (org-at-heading-p))
           ; are we called by the exporter, or just Babel ?
           (exporting-p (bufferp org-current-export-file))
           (dec (ng/decode-link s))
           (link (first dec))
           (new-title (rest dec))
           (id (or (ng/get-symlink-id s) link))
           (curr-lv (or (org-current-level) 0)))
      (unless id
        (error (format "No id found: %s" s)))
      ;(ng/delete-current-line)
      (save-excursion
        (save-window-excursion
          (org-id-open id)
          (org-copy-subtree)))
      (with-temp-buffer
        (org-mode)
        (org-paste-subtree curr-lv nil nil)
        (org-delete-property "ID") ; prevents ID duplication if an entry gets pasted several times
        (org-back-to-heading)
        (if at-heading-p
          (progn
            ; Rename the heading
            (replace-string (ng/org-get-entry-title) new-title nil (point) (point-at-eol))
            (when exporting-p
              (org-back-to-heading)
              (save-excursion (replace-regexp "\\*+ " "" nil (point) (point-at-eol)))))
          ; body only
          (progn
            (ng/delete-current-line)))
        (buffer-string))))
#+END_SRC
* Source blocks
** Source bloc 1
:PROPERTIES:
:ID:       7002ef55-6d58-465c-ad89-b9394bf6f089
:DUMMY_PROP: dummy_value
:END:
Contents of source bloc 1
** Source bloc 2
:PROPERTIES:
:ID:       ad6acd70-b97e-4479-8388-7a5473bcb3bc
:END:
| A | B |
|---+---|
| 1 | 2 |
* Transclusion tests
:PROPERTIES:
:VISIBILITY: all
:END:

Works as expected using =(org-babel-execute-buffer)=.

Doesn't work when exporting the buffer via =C-c C-e t U=.

Apparently, the exporter calls =org-export-execute-babel-code=, which eventually triggers
  =(org-babel-exp-non-block-elements (point-min) (point-max))=.

** src_emacs-lisp[:results raw]{(ng/org-tc "[[id:7002ef55-6d58-465c-ad89-b9394bf6f089][New title 1]]")}
Aa
*** src_emacs-lisp[:results raw]{(ng/org-tc "[[id:ad6acd70-b97e-4479-8388-7a5473bcb3bc][New title 2]]")}

** Body only
src_emacs-lisp[:results raw]{(ng/org-tc "[[id:7002ef55-6d58-465c-ad89-b9394bf6f089][Source bloc 1]]")}
B

  reply	other threads:[~2013-08-22 23:20 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-22 18:23 [Babel] org-babel-execute-buffer gives different results than org-babel-exp-non-block-elements Nicolas Girard
2013-08-22 18:41 ` Nicolas Goaziou
2013-08-22 19:28   ` Nicolas Girard
2013-08-22 20:28     ` Nicolas Girard
2013-08-22 20:33       ` Nicolas Goaziou
2013-08-22 21:01         ` Nicolas Girard
2013-08-22 23:06           ` Nicolas Goaziou
2013-08-22 23:20             ` Nicolas Girard [this message]
2013-08-23  8:11               ` Nicolas Goaziou
2013-08-23 14:55                 ` Eric Schulte
2013-08-26 10:33                   ` Nicolas Goaziou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CANMKmecqCo9SeCrET1-ecv8E5=pk0Rw=M-nWMZViCy437d94Jw@mail.gmail.com' \
    --to=girard.nicolas@gmail.com \
    --cc=emacs-orgmode@gnu.org \
    --cc=n.goaziou@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).