[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/org f83e45526b: org-toggle-item: Move footnote-definiti
From: |
ELPA Syncer |
Subject: |
[elpa] externals/org f83e45526b: org-toggle-item: Move footnote-definitions out of the lists |
Date: |
Fri, 11 Nov 2022 00:57:55 -0500 (EST) |
branch: externals/org
commit f83e45526b5ec4627d601673be3680e2dece1b33
Author: Ihor Radchenko <yantar92@posteo.net>
Commit: Ihor Radchenko <yantar92@posteo.net>
org-toggle-item: Move footnote-definitions out of the lists
* lisp/org-list.el (org-toggle-item): When headings contain
footnote-definitions, move them out of the list. Footnote-definitions
must not be indented and hence cannot belong to the list. Ensure that
definitions do not slurp the following element after the list.
Consider when the list created by `org-toggle-item' is continued by an
existing list.
* testing/lisp/test-org-list.el (test-org-list/toggle-item): Add
tests.
Reported-by: Ypo <ypuntot@gmail.com>
Link: https://orgmode.org/list/877d3k70lu.fsf@localhost
---
lisp/org-list.el | 73 ++++++++++++++++++++++++++++++++++++++-----
testing/lisp/test-org-list.el | 63 +++++++++++++++++++++++++++++++++++++
2 files changed, 128 insertions(+), 8 deletions(-)
diff --git a/lisp/org-list.el b/lisp/org-list.el
index dbd64599e0..7da2187cb1 100644
--- a/lisp/org-list.el
+++ b/lisp/org-list.el
@@ -3021,7 +3021,38 @@ If it is an item, convert all items to normal lines.
If it is normal text, change region into a list of items.
With a prefix argument ARG, change the region in a single item."
(interactive "P")
- (let ((shift-text
+ (let ((extract-footnote-definitions
+ (lambda (end)
+ ;; Remove footnote definitions from point to END.
+ ;; Return the list of the extracted definitions.
+ (let (definitions element)
+ (save-excursion
+ (while (re-search-forward org-footnote-definition-re end t)
+ (setq element (org-element-at-point))
+ (when (eq 'footnote-definition
+ (org-element-type element))
+ (push (buffer-substring-no-properties
+ (org-element-property :begin element)
+ (org-element-property :end element))
+ definitions)
+ ;; Ensure at least 2 blank lines after the last
+ ;; footnote definition, thus not slurping the
+ ;; following element.
+ (unless (<= 2 (org-element-property
+ :post-blank
+ (org-element-at-point)))
+ (setf (car definitions)
+ (concat (car definitions)
+ (make-string
+ (- 2 (org-element-property
+ :post-blank
+ (org-element-at-point)))
+ ?\n))))
+ (delete-region
+ (org-element-property :begin element)
+ (org-element-property :end element))))
+ definitions))))
+ (shift-text
(lambda (ind end)
;; Shift text in current section to IND, from point to END.
;; The function leaves point to END line.
@@ -3079,7 +3110,7 @@ With a prefix argument ARG, change the region in a single
item."
(skip-chars-forward " \t")
(delete-region (point) (match-end 0)))
(forward-line)))
- ;; Case 2. Start at an heading: convert to items.
+ ;; Case 2. Start at a heading: convert to items.
((org-at-heading-p)
;; Remove metadata
(let (org-loop-over-headlines-in-active-region)
@@ -3095,7 +3126,9 @@ With a prefix argument ARG, change the region in a single
item."
(t (length (match-string 0))))))
;; Level of first heading. Further headings will be
;; compared to it to determine hierarchy in the list.
- (ref-level (org-reduced-level (org-outline-level))))
+ (ref-level (org-reduced-level (org-outline-level)))
+ (footnote-definitions
+ (funcall extract-footnote-definitions end)))
(while (< (point) end)
(let* ((level (org-reduced-level (org-outline-level)))
(delta (max 0 (- level ref-level)))
@@ -3124,8 +3157,8 @@ With a prefix argument ARG, change the region in a single
item."
"[X]"
"[ ]"))
(org-list-write-struct struct
- (org-list-parents-alist struct)
- old)))
+ (org-list-parents-alist struct)
+ old)))
;; Ensure all text down to END (or SECTION-END) belongs
;; to the newly created item.
(let ((section-end (save-excursion
@@ -3133,13 +3166,23 @@ With a prefix argument ARG, change the region in a
single item."
(forward-line)
(funcall shift-text
(+ start-ind (* (1+ delta) bul-len))
- (min end section-end)))))))
+ (min end section-end)))))
+ (when footnote-definitions
+ (goto-char end)
+ ;; Insert footnote definitions after the list.
+ (unless (bolp) (beginning-of-line 2))
+ ;; At (point-max).
+ (unless (bolp) (insert "\n"))
+ (dolist (def footnote-definitions)
+ (insert def)))))
;; Case 3. Normal line with ARG: make the first line of region
;; an item, and shift indentation of others lines to
;; set them as item's body.
(arg (let* ((bul (org-list-bullet-string "-"))
(bul-len (length bul))
- (ref-ind (org-current-text-indentation)))
+ (ref-ind (org-current-text-indentation))
+ (footnote-definitions
+ (funcall extract-footnote-definitions end)))
(skip-chars-forward " \t")
(insert bul)
(forward-line)
@@ -3150,7 +3193,21 @@ With a prefix argument ARG, change the region in a
single item."
(+ ref-ind bul-len)
(min end (save-excursion (or (outline-next-heading)
(point)))))
- (forward-line))))
+ (forward-line))
+ (when footnote-definitions
+ ;; If the new list is followed by same-level items,
+ ;; move past them as well.
+ (goto-char (org-element-property
+ :end
+ (org-element-lineage
+ (org-element-at-point (1- end))
+ '(plain-list) t)))
+ ;; Insert footnote definitions after the list.
+ (unless (bolp) (beginning-of-line 2))
+ ;; At (point-max).
+ (unless (bolp) (insert "\n"))
+ (dolist (def footnote-definitions)
+ (insert def)))))
;; Case 4. Normal line without ARG: turn each non-item line
;; into an item.
(t
diff --git a/testing/lisp/test-org-list.el b/testing/lisp/test-org-list.el
index 1c13c5d970..0ee3a14c27 100644
--- a/testing/lisp/test-org-list.el
+++ b/testing/lisp/test-org-list.el
@@ -1356,6 +1356,69 @@ b. Item 2<point>"
(goto-char (point-max))
(org-toggle-item nil)
(buffer-string))))
+ ;; When headings contain footnote definitions, move the definition
+ ;; out of the list. Footnote definitions cannot be indented.
+ (should
+ (equal "- Main headline
+ - Headline 1
+ bbbbbbbb [fn:1]
+
+- Headline 2
+[fn:1] cccccccccccccccc
+
+
+"
+ (org-test-with-temp-text "* Main headline
+** Headline 1
+bbbbbbbb [fn:1]
+
+[fn:1] cccccccccccccccc
+* Headline 2"
+ (transient-mark-mode 1)
+ (push-mark (point) t t)
+ (goto-char (point-max))
+ (org-toggle-item t)
+ (buffer-string))))
+ ;; Footnote definitions that did not have trailing double blank line
+ ;; must not slurp the following element.
+ (should
+ (equal "- Head 1
+- Head 2
+[fn:1] cccccccccccccccc
+
+
+Paragraph outside footnote definitions."
+ (org-test-with-temp-text "* Head 1
+[fn:1] cccccccccccccccc
+* Head 2
+
+
+Paragraph outside footnote definitions."
+ (transient-mark-mode 1)
+ (push-mark (point) t t)
+ (search-forward "Head 2")
+ (org-toggle-item t)
+ (buffer-string))))
+ ;; Move footnote definitions past pre-existing items after.
+ (should
+ (equal "- Line 1
+ Line 2
+- next item
+[fn:1] definition
+
+
+"
+ (org-test-with-temp-text "Line 1
+Line 2
+[fn:1] definition
+
+
+- next item"
+ (transient-mark-mode 1)
+ (push-mark (point) t t)
+ (search-forward "definition")
+ (org-toggle-item t)
+ (buffer-string))))
;; When argument ARG is non-nil, change the whole region into
;; a single item.
(should
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] externals/org f83e45526b: org-toggle-item: Move footnote-definitions out of the lists,
ELPA Syncer <=