emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Nicolas Goaziou <n.goaziou@gmail.com>
To: Xavier Garrido <xavier.garrido@gmail.com>
Cc: James Harkins <jamshark70@gmail.com>, emacs-orgmode@gnu.org
Subject: Re: Bad footnotes when including org files
Date: Wed, 26 Mar 2014 15:41:51 +0100	[thread overview]
Message-ID: <874n2luimo.fsf@gmail.com> (raw)
In-Reply-To: <5325DF5C.9040606@gmail.com> (Xavier Garrido's message of "Sun, 16 Mar 2014 18:29:00 +0100")

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

Hello,

Xavier Garrido <xavier.garrido@gmail.com> writes:

> Thanks for your answer. Maybe I will try your solution. Otherwise
> I will run a "before-parse-hook" to change fn:XX to something unique
> (by adding buffer name for example.

We could do it by default.

One problem is that INCLUDE keyword is a very simple feature. For
example, if you include two files in a row and the first one ends with
a footnote section, the other one will be included in that section and,
therefore, not exported. So if we start to make it smart, we could be
tempted to add too many other checks.

Anyway, here's a patch for that.

WDYT?


Regards,

-- 
Nicolas Goaziou

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-Make-footnotes-file-specific-when-including-Org-f.patch --]
[-- Type: text/x-diff, Size: 3411 bytes --]

From 2a22d4dc3beb300094c9ee28158f227dbf467cda Mon Sep 17 00:00:00 2001
From: Nicolas Goaziou <n.goaziou@gmail.com>
Date: Wed, 26 Mar 2014 15:34:59 +0100
Subject: [PATCH] ox: Make footnotes file specific when including Org files

* lisp/ox.el (org-export-expand-include-keyword,
  org-export--prepare-file-contents): Make footnotes file specific
  when including Org files.

http://permalink.gmane.org/gmane.emacs.orgmode/83606
---
 lisp/ox.el | 32 ++++++++++++++++++++++++++++----
 1 file changed, 28 insertions(+), 4 deletions(-)

diff --git a/lisp/ox.el b/lisp/ox.el
index 9f77af4..cf70643 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -3279,7 +3279,9 @@ with their line restriction, when appropriate.  It is used to
 avoid infinite recursion.  Optional argument DIR is the current
 working directory.  It is used to properly resolve relative
 paths."
-  (let ((case-fold-search t))
+  (let ((case-fold-search t)
+	(file-prefix (make-hash-table :test #'equal))
+	(current-prefix 0))
     (goto-char (point-min))
     (while (re-search-forward "^[ \t]*#\\+INCLUDE:" nil t)
       (let ((element (save-match-data (org-element-at-point))))
@@ -3349,13 +3351,16 @@ paths."
 		 (with-temp-buffer
 		   (let ((org-inhibit-startup t)) (org-mode))
 		   (insert
-		    (org-export--prepare-file-contents file lines ind minlevel))
+		    (org-export--prepare-file-contents
+		     file lines ind minlevel
+		     (or (gethash file file-prefix)
+			 (puthash file (incf current-prefix) file-prefix))))
 		   (org-export-expand-include-keyword
 		    (cons (list file lines) included)
 		    (file-name-directory file))
 		   (buffer-string)))))))))))))
 
-(defun org-export--prepare-file-contents (file &optional lines ind minlevel)
+(defun org-export--prepare-file-contents (file &optional lines ind minlevel id)
   "Prepare the contents of FILE for inclusion and return them as a string.
 
 When optional argument LINES is a string specifying a range of
@@ -3369,7 +3374,12 @@ headline encountered.
 
 Optional argument MINLEVEL, when non-nil, is an integer
 specifying the level that any top-level headline in the included
-file should have."
+file should have.
+
+Optional argument ID is an integer that will be inserted before
+each footnote definition and reference if FILE is an Org file.
+This is useful to avoid clashes when more than one Org file with
+footnotes is included in a document."
   (with-temp-buffer
     (insert-file-contents file)
     (when lines
@@ -3428,6 +3438,20 @@ file should have."
 	       (org-map-entries
 		(lambda () (if (< offset 0) (delete-char (abs offset))
 			(insert (make-string offset ?*)))))))))))
+    ;; Append ID to all footnote references and definitions, so they
+    ;; are file specific and cannot collide with other included files.
+    (goto-char (point-min))
+    (while (re-search-forward org-footnote-re nil t)
+      (let ((reference (org-element-context)))
+	(when (memq (org-element-type reference)
+		    '(footnote-reference footnote-definition))
+	  (goto-char (org-element-property :begin reference))
+	  (forward-char)
+	  (let ((label (org-element-property :label reference)))
+	    (cond ((not label))
+		  ((org-string-match-p "\\`[0-9]+\\'" label)
+		   (insert (format "fn:%d-" id)))
+		  (t (forward-char 3) (insert (format "%d-" id))))))))
     (org-element-normalize-string (buffer-string))))
 
 (defun org-export-execute-babel-code ()
-- 
1.9.1


  reply	other threads:[~2014-03-26 14:41 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-15 23:44 Bad footnotes when including org files Xavier Garrido
2014-03-16  1:32 ` James Harkins
2014-03-16 17:29   ` Xavier Garrido
2014-03-26 14:41     ` Nicolas Goaziou [this message]
2014-03-26 20:34       ` Xavier Garrido
2014-04-12 13:10         ` 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=874n2luimo.fsf@gmail.com \
    --to=n.goaziou@gmail.com \
    --cc=emacs-orgmode@gnu.org \
    --cc=jamshark70@gmail.com \
    --cc=xavier.garrido@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).