From: Nicolas Goaziou <n.goaziou@gmail.com>
To: Bastien <bzg@gnu.org>
Cc: Leonard Randall <leonard.a.randall@gmail.com>,
emacs-orgmode <emacs-orgmode@gnu.org>
Subject: Re: Moving footnotes
Date: Sat, 31 May 2014 11:30:41 +0200 [thread overview]
Message-ID: <87fvjqthvi.fsf@gmail.com> (raw)
In-Reply-To: <87ppiv8jdv.fsf@bzg.ath.cx> (Bastien's message of "Fri, 30 May 2014 15:51:24 +0200")
Bastien <bzg@gnu.org> writes:
> Nicolas Goaziou <n.goaziou@gmail.com> 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
next prev parent reply other threads:[~2014-05-31 9:30 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-21 12:23 Moving footnotes Leonard Randall
2014-05-21 16:39 ` Nicolas Goaziou
2014-05-30 12:57 ` Bastien
2014-05-30 13:35 ` Nicolas Goaziou
2014-05-30 13:51 ` Bastien
2014-05-31 9:30 ` Nicolas Goaziou [this message]
2014-05-31 11:09 ` Bastien
2014-06-01 6:48 ` Nicolas Goaziou
2014-06-01 8:49 ` Bastien
2014-06-02 12:10 ` Leonard Avery Randall
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=87fvjqthvi.fsf@gmail.com \
--to=n.goaziou@gmail.com \
--cc=bzg@gnu.org \
--cc=emacs-orgmode@gnu.org \
--cc=leonard.a.randall@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).