I have a list of items.
* Heading 1
1. Item
2. Item
* Heading 2
1. Item
2. Item
3. Item
Is there an easy way to make the numbers run across the headings like this?
* Heading 1
1. Item
2. Item
* Heading 2
3. Item
4. Item
5. Item
It is possible to define the item number of any entry of a numbered list.
For setting the item number to 3 one inserts [@3]
between the item number and the item text.
If you apply that syntax in your example you get:
* Heading 1
1. Item
2. Item
* Heading 2
3. [@3] Item
4. Item
5. Item
Note that a similar question had been asked and answered on stackoverflow before.
The following Elisp code implements automatic item number continuation.
Two numbers are given as cons
in the new option org-list-continuation-marker
.
The number in the car
is the begin of the automatic number continuation range and the number in the cdr
is a zero offset in this range.
Numbers given in the [@...]
tag that are larger than the first entry of org-list-continuation-marker
continue the numbering of the last list.
The first item number of the continued list is that one of the last item of the last numbered list before plus the offset that results from [@...]
entry minus the zero offset.
(defcustom org-list-continuation-marker '(900 . 1000)
"Continue last list if the bullet counter is larger than
the car of this option.
In that case the next index is calculated as:
last index - counter + (cdr org-list-continuation-marker)."
:type '(cons integer integer)
:group 'org)
(defun my-org-list-last-bullet-counter (indent &optional point)
"Get last bullet counter before POINT."
(save-excursion
(when point
(goto-char point))
(let (found current)
(while (and (setq found (org-list-search-backward "^[[:space:]]\\([0-9]+\\)\\." nil t))
(< indent (setq current (current-indentation)))))
(when found
(if (eq indent current)
(string-to-number (match-string 1))
0)
))))
(defun my-org-list-struct-continue (struct &optional full-update)
"Continue last enumeration.
Use this function as filter-return advice
of `org-list-struct' with STRUCT.
Fully update item number list if FULL-UPDATE is non-nil."
(when (consp struct)
(let ((counter (nth 3 (car struct)))
last-counter)
(when (stringp counter)
(setq counter (string-to-number counter))
(when (>= counter (car org-list-continuation-marker))
(setq last-counter (or (save-excursion
(goto-char (caar struct))
(my-org-list-last-bullet-counter (current-indentation)))
0))
(setq last-counter (+ last-counter counter (- (cdr org-list-continuation-marker))))
(setf (nth 3 (car struct)) (number-to-string last-counter))
;; Adjusting the item numbers in advance is necessary in `org-list-struct-apply-struct'.
(when full-update
(dolist (item struct)
(setf (nth 2 item) (replace-regexp-in-string "[0-9]+" (number-to-string last-counter) (nth 2 item)))
(cl-incf last-counter)))
))))
struct)
(defvar org-export-current-backend) ;; from ox.el
(defun my-ox-list-struct-continue-full (struct)
"Export the same as `my-org-list-struct-continue' but with FULL-UPDATE."
(if (bound-and-true-p org-export-current-backend)
(my-org-list-struct-continue struct t)
struct))
;; `org-list-struct-apply-struct' is used for correcting item numbers in `org-ctrl-c-ctrl-c'.
(defun my-org-list-struct-apply-struct (args)
"Continue last enumeration.
Use this function as filter-args advice for `org-list-struct-apply-struct'.
This function transforms argument list ARGS for `org-list-struct-apply-struct'."
(cons (my-org-list-struct-continue (car args) t) (cdr args)))
(defun my-org-element-item-parser (fun _ struct &optional raw-secondary-p)
"Automatically continue list item number in STRUCT."
(let* ((info (funcall fun _ struct raw-secondary-p))
(counter (org-element-property :counter info)))
(when (and
(bound-and-true-p org-export-current-backend)
(numberp counter)
(>= counter (car org-list-continuation-marker)))
;; We have done all the work in `my-ox-list-struct-continue-full'
(let ((tag (nth 2 (car struct))))
(when (string-match "[0-9]+" tag)
(org-element-put-property info :counter (string-to-number (match-string 0 tag))))
))
info))
(advice-add 'org-list-struct :filter-return #'my-org-list-struct-continue)
(advice-add 'org-element--list-struct :filter-return #'my-ox-list-struct-continue-full)
(advice-add 'org-element-item-parser :around #'my-org-element-item-parser)
(advice-add 'org-list-struct-apply-struct :filter-args #'my-org-list-struct-apply-struct)
We can apply the automatical continuation to your example in the following way with the standard settings for org-list-continuation-marker
.
* Heading 1
1. Item
2. Item
* Heading 2
3. [@1001] Item
4. Item
5. Item
The following things are currently not automatic:
The following things are working:
One could create a feature request for continued enumerated lists via org-submit-bug-report
.
In that case I would propose to add the syntax [@+1]
instead of [@1001]
, and [@-1]
instead of [@999]
, for a continued item numbering.
With this syntax one could even intentionally leave one item number out by [@+2]
in the middle of a numbered list. (That may make sense as placeholder.)
Heading 2
a heading or a paragraph? That makes a big difference. There is no leading star beforeHeading 2
.