From mboxrd@z Thu Jan 1 00:00:00 1970 From: Nicolas Goaziou Subject: Re: Moving footnotes Date: Sat, 31 May 2014 11:30:41 +0200 Message-ID: <87fvjqthvi.fsf@gmail.com> References: <87a99zmnkp.fsf@bzg.ath.cx> <87k393tmn6.fsf@gmail.com> <87ppiv8jdv.fsf@bzg.ath.cx> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:57043) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WqfcA-0005f8-C1 for emacs-orgmode@gnu.org; Sat, 31 May 2014 05:30:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Wqfc4-0004kz-US for emacs-orgmode@gnu.org; Sat, 31 May 2014 05:30:10 -0400 In-Reply-To: <87ppiv8jdv.fsf@bzg.ath.cx> (Bastien's message of "Fri, 30 May 2014 15:51:24 +0200") List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Bastien Cc: Leonard Randall , emacs-orgmode Bastien writes: > Nicolas Goaziou writes: >> All in all, I'm not convinced this should be a function provided in Org. > > Okay. Still, it's useful to have it *somewhere*. If you have a > moment, could you revert the commit Done. > rewrite the function with the suggested enhancements Here it is. It could be prettier but I think it should get the job done. (defun org-footnote-inline-footnotes () "Convert external footnotes into inline ones." (interactive) (org-with-wide-buffer (let ((random-labels (make-hash-table :test #'equal)) failed seen) (goto-char (point-min)) (while (re-search-forward org-footnote-re nil t) (let ((context (save-excursion (backward-char) (org-element-context)))) ;; Ignore false positives. (when (eq (org-element-type context) 'footnote-reference) (let ((label (org-element-property :label context))) ;; Ignore anonymous footnotes. (when label (if (member label seen) (let ((normalized-label (gethash label random-labels))) (when normalized-label (search-backward "[" nil t) (forward-char) (insert normalized-label) (delete-region (point) (progn (skip-chars-forward "0-9") (point))))) (push label seen) (when (eq (org-element-property :type context) 'standard) (let ((beg (copy-marker (org-element-property :begin context))) (end (copy-marker (save-excursion (goto-char (org-element-property :end context)) (skip-chars-backward " \t") (point)))) (definition (save-excursion (goto-char (point-min)) (catch 'exit (while (re-search-forward (format "^\\[%s\\]" (regexp-quote label)) nil t) (let ((def (save-excursion (backward-char) (org-element-at-point)))) (when (eq (org-element-type def) 'footnote-definition) (let ((cbeg (org-element-property :contents-begin def)) (cend (org-element-property :contents-end def))) ;; Ensure definition can be inline, ;; i.e., contains a single ;; paragraph. Return nil if it ;; cannot. (if (not cbeg) (throw 'exit "") (goto-char cbeg) (let ((contents (org-element-at-point))) (if (or (not (eq (org-element-type contents) 'paragraph)) (< (org-element-property :end contents) cend)) (throw 'exit nil) (throw 'exit (prog1 (org-trim (buffer-substring cbeg cend)) (delete-region (org-element-property :begin def) (org-element-property :end def))))))))))))))) (if (not definition) (push label failed) (delete-region beg end) (goto-char beg) ;; Convert [1] to [fn:random-id] to avoid ;; confusion between [1] and [fn:1]. (let ((normalized-label (if (not (org-string-match-p "\\`[0-9]+\\'" label)) label (require 'org-id) (puthash label (concat "fn:" (substring (org-id-uuid) 0 8)) random-labels)))) (insert "[" normalized-label ":" definition "]"))) (set-marker beg nil) (set-marker end nil))))))))) (cond (failed (user-error "Some footnotes could not be converted : %s" (mapconcat #'identity failed ", "))) ;; If process completed without failure, there is no regular ;; footnote definition left, so we remove footnote sections, ;; if any. (org-footnote-section (goto-char (point-min)) (let ((section-re (concat "^\\*+ " org-footnote-section "[ \t]*$"))) (while (re-search-forward section-re nil t) (delete-region (match-beginning 0) (org-end-of-subtree t t)))))) (message "Footnotes successfully inlined.")))) > and add it to worg/org-hacks.org? I suggest to test it first. > PS: I think it's useful to trigger the org-footnote-action menu > when org-footnote-new cannot do anything useful. Sure, I will add it back later today, unless you're faster than me. Regards, -- Nicolas Goaziou