From: Nathaniel Flath <flat0103@gmail.com>
To: Nicolas Goaziou <n.goaziou@gmail.com>
Cc: Bernt Hansen <bernt@norang.ca>,
Jacob Mitchell <jacob.d.mitchell@gmail.com>,
org-mode List <emacs-orgmode@gnu.org>,
Carsten Dominik <carsten.dominik@gmail.com>
Subject: Re: Re: [PATCH] Alphabetical ordered lists
Date: Wed, 12 Jan 2011 12:05:19 -0800 [thread overview]
Message-ID: <AANLkTim9ATWcEUAgi+tTTEcj1S5PzNc9NqZ0j1uX8VG4@mail.gmail.com> (raw)
In-Reply-To: <87pqswti6w.wl%n.goaziou@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2075 bytes --]
Updated patch attached.
Thanks,
Nathaniel Flath
On Mon, Dec 20, 2010 at 10:25 AM, Nicolas Goaziou <n.goaziou@gmail.com> wrote:
> Hello,
>
>>>>>> Nathaniel Flath writes:
>
>> Sory for the long delay - I got caught up in other work. A
>> patchaddressing the sisues brought up is attached.
>
> I've had a look at your patch.
>
> I think the modifications to HTML and DocBook exporters are nice. It
> could be possible to do the same thing in LaTeX, but it would require
> yet another package (enumitem) by default. Anyway, here are the code
> comments :
>
> - in your patch, you should try to list modifications to the
> functions, and which functions were created. For example :
>
> * org-list.el (org-alphabetical-lists): new variable
> (org-cycle-list-bullet): added "A)" "a)" "A." and "a." to the list
> of bullets in cycle. None of them is allowed in a description list.
>
> - The "yes" at the beginning of org-docbook.el should be removed
>
> - I advise against using (org-next-item) programmatically. It means
> you compute the structure associated to the list for each item in
> the list. I left a note about this circa line 847 in org-list.el
>
> - There's a bug with the following situation :
>
> A) test
> B) tersi
> C) teirsu
> D) tersiu
> E) tesiu
> F) teisru
> G) etisu
> - sub-item 1
> - sub-item 2
> - sub-item 3
> - sub-item 4
> H) tesinu
> I) tesinru
> J) etnrsiu
> K) tesriun
> L) etnsiu
> M) estinu
> N) etsniu
> O) etsinu
> P) tesnu
> Q) etsinu
> R) etsiun
> S) etsnriu
> T) etsnriu
> U) etsinu
> V) etsiu
> W) etinrsu
> X) last item
>
> If you outdent sub-items 2 to 4 at the same time (with a region),
> bullet of the last item will become "AA)" and will not be recognized
> as a list item anymore.
>
> - There's also a bug with counters:
>
> * [0/0] Counter
>
> A. [X] first box
> B. [X] second box
>
> These boxes are not counted when bullets are literals (try C-c #).
>
>
> HTH,
>
> Regards,
>
> -- Nicolas
>
[-- Attachment #2: 0001-Added-support-for-alphabetical-patches-to-org-list.patch --]
[-- Type: application/octet-stream, Size: 33155 bytes --]
From 11a5b944d6475f150333502a15ede70ce71807af Mon Sep 17 00:00:00 2001
From: Nathaniel Flath <flat0103@gmail.com>
Date: Wed, 12 Jan 2011 11:52:32 -0800
Subject: [PATCH] Added support for alphabetical patches to org-list.
Support can be enabled with the 'org-alphabetical-lists' variable, and
the numeration goes from 'a' to 'z'. The latex, html, and docbook exporters
have been updated to use these.
* org-capture.el: (org-capture-place-item): changed use of variable org-item-beginning-re to be a function call.
* org-docbook.el: (org-export-as-docbook): changed to export alphabetical lists
* org-exp.el: (org-export-mark-list-ending): changed variable use of org-item-beginning-re to be function call.
* org-html.el: (org-export-as-html): changed to export alphabetical lists
* org-latex.el: (org-export-latex-lists): changed variable use of org-item-beginning-re to be a function call.
* org-list.el:
org-alphabetical-lists: new variable to control whether to use alphabetical lists(defaults nil)
(org-item-re): converted to use correct regex for alphabetical lists if enabled
(org-item-beginning-re): converted from a variable to a function
(org-list-in-item-p-with-indent), (org-toggle-checkbox),(org-list-in-item-p-with-regexp), (org-list-top-point-with-regexp), (org-list-struct), (org-list-get-item-same-level), (org-get-item-beginning), (org-end-of-item-or-at-child), (org-list-first-item-p), (org-list-indent-item-generic): converted use of org-item-beginning-re to a function
(org-list-at-regexp-after-bullet-p), (org-update-checkbox-count), (org-list-parse-list), (org-list-insert-item-generic), org-list-struct-assoc-at-point), (org-list-struct-fix-bul): corrected regexp to allow for alphabetical lists
(org-increment-string), (org--convert-alpha-str-to-num), (org-convert-num-toalpha-str): new functions used to increment a bullet in an alphabetical list
(org-list-can-be-alphabetical): new function that returns 't' if a list can be alphabetical( <27 items)
(org-list-bullet-inc-maybe): modified to support alphabetical bullets as well as numeric ones
(org-cycle-list-bullet): modified to also cycle into both capital and lowercas alphabetical bullets, if possible
---
lisp/org-capture.el | 4 +-
lisp/org-docbook.el | 21 +++-
lisp/org-exp.el | 2 +-
lisp/org-html.el | 24 ++++--
lisp/org-latex.el | 2 +-
lisp/org-list.el | 262 +++++++++++++++++++++++++++++++++------------------
6 files changed, 208 insertions(+), 107 deletions(-)
diff --git a/lisp/org-capture.el b/lisp/org-capture.el
index a28c3b8..462f3c9 100644
--- a/lisp/org-capture.el
+++ b/lisp/org-capture.el
@@ -815,14 +815,14 @@ already gone. Any prefix argument will be passed to the refile comand."
(if (org-capture-get :prepend)
(progn
(goto-char beg)
- (if (org-search-forward-unenclosed org-item-beginning-re end t)
+ (if (org-search-forward-unenclosed (org-item-beginning-re) end t)
(progn
(goto-char (match-beginning 0))
(setq ind (org-get-indentation)))
(goto-char end)
(setq ind 0)))
(goto-char end)
- (if (org-search-backward-unenclosed org-item-beginning-re beg t)
+ (if (org-search-backward-unenclosed (org-item-beginning-re) beg t)
(progn
(setq ind (org-get-indentation))
(org-end-of-item))
diff --git a/lisp/org-docbook.el b/lisp/org-docbook.el
index ed835b0..a636dba 100644
--- a/lisp/org-docbook.el
+++ b/lisp/org-docbook.el
@@ -1012,14 +1012,15 @@ publishing directory."
;; Normal lines
(when (string-match
(cond
- ((eq llt t) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+[.)]\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
- ((= llt ?.) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+\\.\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
- ((= llt ?\)) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+)\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
+ ((eq llt t) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\(\\(?:[0-9]+\\|[a-zA-Z]\\)[.)]\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
+ ((= llt ?.) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\(\\(?:[0-9]+\\|[a-zA-Z]\\)\\.\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
+ ((= llt ?\)) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\(\\(?:[0-9]+\\|[a-zA-Z]\\))\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
(t (error "Invalid value of `org-plain-list-ordered-item-terminator'")))
line)
(setq ind (or (get-text-property 0 'original-indentation line)
(org-get-string-indentation line))
item-type (if (match-beginning 4) "o" "u")
+ ordered-type (match-string 2 line)
starter (if (match-beginning 2)
(substring (match-string 2 line) 0 -1))
line (substring line (match-beginning 5))
@@ -1040,7 +1041,7 @@ publishing directory."
(org-export-docbook-close-para-maybe)
(insert (cond
((equal item-type "u") "<itemizedlist>\n<listitem>\n")
- ((and (equal item-type "o") item-number)
+ ((equal item-type "o")
;; Check for a specific start number. If it
;; is specified, we use the ``override''
;; attribute of element <listitem> to pass the
@@ -1048,8 +1049,16 @@ publishing directory."
;; ``startingnumber'' attribute of element
;; <orderedlist>, but the former works on both
;; DocBook 5.0 and prior versions.
- (format "<orderedlist>\n<listitem override=\"%s\">\n" item-number))
- ((equal item-type "o") "<orderedlist>\n<listitem>\n")
+ (progn
+ (concat "<orderedlist numeration=\""
+ (cond
+ ((not starter) "arabic")
+ ((string-match "[0-9]+[.)]" ordered-type) "arabic")
+ ((string-match "[A-Z][.)]" ordered-type) "upperalpha")
+ ((string-match "[a-z][.)]" ordered-type) "loweralpha"))
+ "\">\n<listitem"
+ (if item-number (concat " override=\"" item-number "\">\n")
+ ">\n"))))
((equal item-type "d")
(format "<variablelist>\n<varlistentry><term>%s</term><listitem>\n" item-tag))))
;; For DocBook, we need to open a para right after tag
diff --git a/lisp/org-exp.el b/lisp/org-exp.el
index 3d466fa..680587b 100644
--- a/lisp/org-exp.el
+++ b/lisp/org-exp.el
@@ -1664,7 +1664,7 @@ These special cookies will later be interpreted by the backend.
(let ((process-buffer
(lambda (end-list-marker)
(goto-char (point-min))
- (while (org-search-forward-unenclosed org-item-beginning-re nil t)
+ (while (org-search-forward-unenclosed (org-item-beginning-re) nil t)
(goto-char (org-list-bottom-point))
(when (and (not (eq org-list-ending-method 'indent))
(looking-at (org-list-end-re)))
diff --git a/lisp/org-html.el b/lisp/org-html.el
index 312e716..be1d760 100644
--- a/lisp/org-html.el
+++ b/lisp/org-html.el
@@ -1553,20 +1553,21 @@ lang=\"%s\" xml:lang=\"%s\">
;; Normal lines
(when (string-match
(cond
- ((eq llt t) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+[.)]\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
- ((= llt ?.) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+\\.\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
- ((= llt ?\)) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+)\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
+ ((eq llt t) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\(\\(?:[0-9]+\\|[a-zA-Z]\\)[.)]\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
+ ((= llt ?.) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\(\\(?:[0-9]+\\|[a-zA-Z]\\)\\.\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
+ ((= llt ?\)) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\(\\(?:[0-9]+\\|[a-zA-Z]\\))\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
(t (error "Invalid value of `org-plain-list-ordered-item-terminator'")))
line)
(setq ind (or (get-text-property 0 'original-indentation line)
(org-get-string-indentation line))
item-type (if (match-beginning 4) "o" "u")
+ ordered-type (match-string 2 line)
starter (if (match-beginning 2)
(substring (match-string 2 line) 0 -1))
line (substring line (match-beginning 5))
item-number nil
item-tag nil)
- (if (string-match "\\[@\\(?:start:\\)?\\([0-9]+\\)\\][ \t]?" line)
+ (if (string-match "\\[@\\(?:start:\\)?\\([0-9]+\\|[a-zA-Z]\\)\\][ \t]?" line)
(setq item-number (match-string 1 line)
line (replace-match "" t t line)))
(if (and starter (string-match "\\(.*?\\) ::[ \t]*" line))
@@ -1581,9 +1582,18 @@ lang=\"%s\" xml:lang=\"%s\">
(org-close-par-maybe)
(insert (cond
((equal item-type "u") "<ul>\n<li>\n")
- ((and (equal item-type "o") item-number)
- (format "<ol>\n<li value=\"%s\">\n" item-number))
- ((equal item-type "o") "<ol>\n<li>\n")
+ ((equal item-type "o")
+ (progn
+ (message ordered-type)
+ (concat "<ol type=\""
+ (cond
+ ((not starter) "1")
+ ((string-match "[0-9]+[.)]" ordered-type) "1")
+ ((string-match "[A-Z][.)]" ordered-type) "A")
+ ((string-match "[a-z][.)]" ordered-type) "a"))
+ "\"><li"
+ (if item-number (concat" value=\"" item-number "\">\n")
+ ">\n"))))
((equal item-type "d")
(format "<dl>\n<dt>%s</dt><dd>\n" item-tag))))
(push item-type local-list-type)
diff --git a/lisp/org-latex.el b/lisp/org-latex.el
index 4085d6e..58feede 100644
--- a/lisp/org-latex.el
+++ b/lisp/org-latex.el
@@ -2385,7 +2385,7 @@ The conversion is made depending of STRING-BEFORE and STRING-AFTER."
"Convert plain text lists in current buffer into LaTeX lists."
(let (res)
(goto-char (point-min))
- (while (org-search-forward-unenclosed org-item-beginning-re nil t)
+ (while (org-search-forward-unenclosed (org-item-beginning-re) nil t)
(beginning-of-line)
(setq res (org-list-to-latex (org-list-parse-list t)
org-export-latex-list-parameters))
diff --git a/lisp/org-list.el b/lisp/org-list.el
index bc8e7bd..b4eb60d 100644
--- a/lisp/org-list.el
+++ b/lisp/org-list.el
@@ -221,16 +221,16 @@ indent when non-nil, indenting or outdenting list top-item
insert when non-nil, trying to insert an item inside a block
will insert it right before the block instead of
throwing an error."
- :group 'org-plain-lists
- :type '(alist :tag "Sets of rules"
- :key-type
- (choice
- (const :tag "Bullet" bullet)
- (const :tag "Checkbox" checkbox)
- (const :tag "Indent" indent)
- (const :tag "Insert" insert))
- :value-type
- (boolean :tag "Activate" :value t)))
+ :group 'org-plain-lists
+ :type '(alist :tag "Sets of rules"
+ :key-type
+ (choice
+ (const :tag "Bullet" bullet)
+ (const :tag "Checkbox" checkbox)
+ (const :tag "Indent" indent)
+ (const :tag "Insert" insert))
+ :value-type
+ (boolean :tag "Activate" :value t)))
(defcustom org-hierarchical-checkbox-statistics t
"Non-nil means checkbox statistics counts only the state of direct children.
@@ -240,6 +240,11 @@ with the word \"recursive\" in the value."
:group 'org-plain-lists
:type 'boolean)
+(defcustom org-alphabetical-lists nil
+ "Non-nil means alphabetical lists are activated."
+ :group 'org-plain-lists
+ :type 'boolean)
+
(defcustom org-description-max-indent 20
"Maximum indentation for the second line of a description list.
When the indentation would be larger than this, it will become
@@ -288,16 +293,23 @@ It depends on `org-empty-line-terminates-plain-lists'."
If GENERAL is non-nil, return the general regexp independent of the value
of `org-plain-list-ordered-item-terminator'."
(cond
+ ((and org-alphabetical-lists (or general (eq org-plain-list-ordered-item-terminator t)))
+ "\\([ \t]*\\([-+]\\|\\(\\([0-9]+\\|[A-Za-z]\\)[.)]\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
+ ((and org-alphabetical-lists (= org-plain-list-ordered-item-terminator ?.))
+ "\\([ \t]*\\([-+]\\|\\(\\([0-9]+\\|[A-Za-z]\\)\\.\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
+ ((and org-alphabetical-lists (= org-plain-list-ordered-item-terminator ?\)))
+ "\\([ \t]*\\([-+]\\|\\(\\([0-9]+\\|[A-Za-z]\\))\\)\\)\\|[ \t]+\\*\\)\\([ \t]+\\|$\\)")
((or general (eq org-plain-list-ordered-item-terminator t))
- "\\([ \t]*\\([-+]\\|\\([0-9]+[.)]\\)\\)\\|[ \t]+\\*\\)\\([ \t]+\\|$\\)")
+ "\\([ \t]*\\([-+]\\|\\(\\([0-9]+\\)[.)]\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
((= org-plain-list-ordered-item-terminator ?.)
- "\\([ \t]*\\([-+]\\|\\([0-9]+\\.\\)\\)\\|[ \t]+\\*\\)\\([ \t]+\\|$\\)")
+ "\\([ \t]*\\([-+]\\|\\(\\([0-9]+)\\.\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
((= org-plain-list-ordered-item-terminator ?\))
- "\\([ \t]*\\([-+]\\|\\([0-9]+)\\)\\)\\|[ \t]+\\*\\)\\([ \t]+\\|$\\)")
+ "\\([ \t]*\\([-+]\\|\\(\\([0-9]+\\))\\)\\)\\|[ \t]+\\*\\)\\([ \t]+\\|$\\)")
(t (error "Invalid value of `org-plain-list-ordered-item-terminator'"))))
-(defconst org-item-beginning-re (concat "^" (org-item-re))
- "Regexp matching the beginning of a plain list item.")
+(defun org-item-beginning-re ()
+ "Regexp matching the beginning of a plain list item."
+ (concat "^" (org-item-re)))
(defun org-list-ending-between (min max &optional firstp)
"Find the position of a list ending between MIN and MAX, or nil.
@@ -327,11 +339,11 @@ stopping at LIMIT."
(save-match-data
(let ((case-fold-search t)
(boundary (if (eq search 're-search-forward) 3 5)))
- (when (save-excursion
- (and (funcall search "^[ \t]*#\\+\\(begin\\|end\\)_" limit t)
- (= (length (match-string 1)) boundary)))
- ;; We're in a block: get out of it
- (goto-char (match-beginning 0))))))
+ (when (save-excursion
+ (and (funcall search "^[ \t]*#\\+\\(begin\\|end\\)_" limit t)
+ (= (length (match-string 1)) boundary)))
+ ;; We're in a block: get out of it
+ (goto-char (match-beginning 0))))))
(defun org-list-search-unenclosed-generic (search re bound noerr)
"Search a string outside blocks and protected places.
@@ -385,7 +397,7 @@ indented than the previous item within LIMIT."
;; Ensure there is at least an item above
(up-item-p (save-excursion
(org-search-backward-unenclosed
- org-item-beginning-re limit t))))
+ (org-item-beginning-re) limit t))))
(and up-item-p
(catch 'exit
(while t
@@ -413,7 +425,7 @@ Argument LIMIT specifies the upper-bound of the search."
;; `org-item-re'.
(last-item-start (save-excursion
(org-search-backward-unenclosed
- org-item-beginning-re limit t)))
+ (org-item-beginning-re) limit t)))
(list-ender (org-list-ending-between
last-item-start actual-pos)))
;; We are in a list when we are on an item line or when we can
@@ -433,7 +445,7 @@ List ending is determined by regexp. See
;; Otherwise, go back to the heading above or bob.
(goto-char (or (org-list-ending-between limit pos) limit))
;; From there, search down our list.
- (org-search-forward-unenclosed org-item-beginning-re pos t)
+ (org-search-forward-unenclosed (org-item-beginning-re) pos t)
(point-at-bol))))
(defun org-list-bottom-point-with-regexp (limit)
@@ -536,8 +548,8 @@ List ending is determined by the indentation of text. See
(save-excursion
(goto-char (match-end 0))
;; Ignore counter if any
- (when (looking-at "\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?")
- (goto-char (match-end 0)))
+ (when (looking-at "\\(?:\\[@\\(?:start:\\)?\\(?:[0-9]+\\|[A-Za-z]\\)\\][ \t]*\\)?")
+ (goto-char (match-end 0)))
(looking-at regexp))))
(defun org-list-get-item-same-level (search-fun pos limit pre-move)
@@ -551,7 +563,7 @@ uses PRE-MOVE before search. Return nil if no item was found."
;; We don't want to match the current line.
(funcall pre-move)
;; Skip any sublist on the way
- (while (and (funcall search-fun org-item-beginning-re limit t)
+ (while (and (funcall search-fun (org-item-beginning-re) limit t)
(> (org-get-indentation) ind)))
(when (and (/= (point-at-bol) start) ; Have we moved ?
(= (org-get-indentation) ind))
@@ -612,7 +624,7 @@ function ends."
(goto-char pos)
;; Is point in a special block?
(when (org-in-regexps-block-p
- "^[ \t]*#\\+\\(begin\\|BEGIN\\)_\\([a-zA-Z0-9_]+\\)"
+ "^[ \t]*#\\+\\(begin\\|BEGIN\\)_\\(\\(?:[a-zA-Z]\\|[0-9_]+\\)\\)"
'(concat "^[ \t]*#\\+\\(end\\|END\\)_" (match-string 2)))
(if (not (cdr (assq 'insert org-list-automatic-rules)))
;; Rule in `org-list-automatic-rules' forbids insertion.
@@ -655,9 +667,9 @@ function ends."
(org-list-exchange-items
(org-get-item-beginning) (org-get-next-item (point) bottom)
bottom)
- ;; recompute next-item: last sexp modified list
- (goto-char (org-get-next-item (point) bottom))
- (org-move-to-column col)))
+ ;; recompute next-item: last sexp modified list
+ (goto-char (org-get-next-item (point) bottom))
+ (org-move-to-column col)))
;; checkbox update might modify bottom point, so use a
;; marker here
(setq bottom (copy-marker bottom))
@@ -710,7 +722,7 @@ Return t if successful."
(cond
((and regionp
(goto-char rbeg)
- (not (org-search-forward-unenclosed org-item-beginning-re rend t)))
+ (not (org-search-forward-unenclosed (org-item-beginning-re) rend t)))
(error "No item in region"))
((not (org-at-item-p))
(error "Not on an item"))
@@ -808,13 +820,13 @@ TOP is the position of list's top-item."
(save-excursion
(beginning-of-line)
(let ((ind (org-get-indentation)))
- (or (not (org-search-backward-unenclosed org-item-beginning-re top t))
+ (or (not (org-search-backward-unenclosed (org-item-beginning-re) top t))
(< (org-get-indentation) ind)))))
(defun org-at-item-p ()
"Is point in a line starting a hand-formatted item?"
(save-excursion
- (beginning-of-line) (looking-at org-item-beginning-re)))
+ (beginning-of-line) (looking-at (org-item-beginning-re))))
(defun org-at-item-bullet-p ()
"Is point at the bullet of a plain list item?"
@@ -913,7 +925,7 @@ Assume point is in a list."
(save-excursion
;; possibly match current line
(end-of-line)
- (org-search-backward-unenclosed org-item-beginning-re nil t)
+ (org-search-backward-unenclosed (org-item-beginning-re) nil t)
(point-at-bol)))
(defun org-beginning-of-item ()
@@ -949,7 +961,7 @@ BOTTOM is the position at list ending."
(let ((ind (org-get-indentation)))
(while (and (/= (point) bottom)
(>= (org-get-indentation) ind))
- (org-search-forward-unenclosed org-item-beginning-re bottom 'move))
+ (org-search-forward-unenclosed (org-item-beginning-re) bottom 'move))
(if (= (point) bottom) bottom (point-at-bol)))))
(defun org-end-of-item-list ()
@@ -979,7 +991,7 @@ If the cursor is not in an item, throw an error."
BOTTOM is the position at list ending."
(end-of-line)
(goto-char
- (if (org-search-forward-unenclosed org-item-beginning-re bottom t)
+ (if (org-search-forward-unenclosed (org-item-beginning-re) bottom t)
(point-at-bol)
(org-get-end-of-item bottom))))
@@ -1141,11 +1153,11 @@ bullet string and bullet counter, if any."
(list (point-at-bol)
(org-get-indentation)
(progn
- (looking-at "^[ \t]*\\([-+*0-9.)]+[ \t]+\\)")
+ (looking-at "^[ \t]*\\([-+*0-9A-Za-z.)]+[ \t]+\\)")
(match-string 1))
(progn
(goto-char (match-end 0))
- (and (looking-at "\\[@\\(?:start:\\)?\\([0-9]+\\)\\]")
+ (and (looking-at "\\[@\\(?:start:\\)?\\(\\(?:[0-9]+\\|[A-Za-z]\\)\\)\\]")
(match-string 1))))))
(defun org-list-struct (begin end top bottom &optional outdent)
@@ -1174,7 +1186,7 @@ change is an outdent."
(goto-char begin)
;; Find beginning of most outdented list (min list)
(while (and (org-search-backward-unenclosed
- org-item-beginning-re top t)
+ (org-item-beginning-re) top t)
(>= (org-get-indentation) ind-min))
(setq pre-list (cons (org-list-struct-assoc-at-point)
pre-list)))
@@ -1188,7 +1200,7 @@ change is an outdent."
(goto-char end)
(end-of-line)
(while (and (org-search-forward-unenclosed
- org-item-beginning-re bottom 'move)
+ (org-item-beginning-re) bottom 'move)
(>= (org-get-indentation) ind-min))
(setq post-list (cons (org-list-struct-assoc-at-point)
post-list)))
@@ -1197,13 +1209,13 @@ change is an outdent."
(when (and (= (caar pre-list) 0) (< (point) bottom))
(beginning-of-line)
(while (org-search-forward-unenclosed
- org-item-beginning-re bottom t)
+ (org-item-beginning-re) bottom t)
(setq post-list (cons (org-list-struct-assoc-at-point)
post-list))))
(append pre-list struct (reverse post-list))))))
;; Here we start: first get the core zone...
(goto-char end)
- (while (org-search-backward-unenclosed org-item-beginning-re begin t)
+ (while (org-search-backward-unenclosed (org-item-beginning-re) begin t)
(setq struct (cons (org-list-struct-assoc-at-point) struct)))
;; ... then, extend it to make it a structure...
(let ((extended (funcall extend struct)))
@@ -1247,7 +1259,7 @@ STRUCT is the list's structure looked up."
"Return parent association of ITEM in STRUCT or nil.
ORIGINS is the alist of parents. See `org-list-struct-origins'."
(let* ((parent-pos (cdr (assq (car item) origins))))
- (when (> parent-pos 0) (assq parent-pos struct))))
+ (when (and parent-pos (> parent-pos 0)) (assq parent-pos struct))))
(defun org-list-struct-get-child (item struct)
"Return child association of ITEM in STRUCT or nil."
@@ -1260,21 +1272,27 @@ ORIGINS is the alist of parents. See `org-list-struct-origins'."
ORIGINS is the alist of parents. See `org-list-struct-origins'.
This function modifies STRUCT."
+
(let* (acc
(init-bul (lambda (item)
(let ((counter (nth 3 item))
(bullet (org-list-bullet-string (nth 2 item))))
(cond
- ((and (string-match "[0-9]+" bullet) counter)
+ ((and (string-match "[0-9]+\\|[A-Za-z]" bullet) counter)
(replace-match counter nil nil bullet))
((string-match "[0-9]+" bullet)
(replace-match "1" nil nil bullet))
+ ((and (org-list-can-be-alphabetical origins)
+ (string-match "[A-Za-z]" bullet))
+ (replace-match "a" nil nil bullet))
+ ((string-match "[A-Za-z]" bullet)
+ (replace-match "1" nil nil bullet))
(t bullet)))))
(set-bul (lambda (item bullet)
(setcdr item (list (nth 1 item) bullet (nth 3 item)))))
(get-bul (lambda (item bullet)
(let* ((counter (nth 3 item)))
- (if (and counter (string-match "[0-9]+" bullet))
+ (if (and counter (string-match "[0-9]+\\|[A-Za-z]" bullet))
(replace-match counter nil nil bullet)
bullet))))
(fix-bul
@@ -1588,13 +1606,60 @@ It determines the number of whitespaces to append by looking at
" ")))
nil nil bullet 1)))
+(defun org-increment-string (str cap)
+ "Increments str (a->a, b->b, z->aa, aa->ab etc). If cap is non-nil, then
+ the letters are capitalized."
+ (let ((res (org-convert-num-to-alpha-str
+ (1+ (org-convert-alpha-str-to-num str 1 (length str) cap)) cap))
+ (z (if cap ?Z ?z))
+ (b (if cap ?B ?b))
+ (a (if cap ?A ?a)))
+ (if (and(= (string-to-char str) z)
+ (= (string-to-char res) b))
+ (concat (if cap "A" "a") (substring res 1))
+ (concat (make-string (- (length str) (length res)) a) res))))
+
+(defun org-convert-alpha-str-to-num (str n pos cap)
+ "Converts the substring consisting of locations pos to pos-n to a
+ numeric representation."
+ (let ((a (if cap ?A ?a)))
+ (if (= pos 1) (* (- (string-to-char str) a) n)
+ (+ (* (- (nth (1- pos) (string-to-list str)) a) n)
+ (org-convert-alpha-str-to-num str (* 26 n) (1- pos) cap)))))
+
+(defun org-convert-num-to-alpha-str (n cap)
+ "Converts the number n to a alphabetical, base-26 representation."
+ (if (= n 0) ""
+ (concat (org-convert-num-to-alpha-str (/ n 26) cap)
+ (string (+ (if cap ?A ?a) (% n 26))))))
+
+(defun org-list-can-be-alphabetical (origins)
+ "Returns t if the list has only 26 elements."
+ (let ((retn 1)
+ (tmp origins))
+ (while (and (cdr tmp) (< retn 28))
+ (when (= 0 (cdr (car tmp)))
+ (setq retn (1+ retn)))
+ (setq tmp (cdr tmp)))
+ (< retn 28)))
+
(defun org-list-inc-bullet-maybe (bullet)
"Increment BULLET if applicable."
- (if (string-match "[0-9]+" bullet)
+ (let ((case-fold-search nil))
+ (cond
+ ((string-match "[0-9]+" bullet)
(replace-match
(number-to-string (1+ (string-to-number (match-string 0 bullet))))
- nil nil bullet)
- bullet))
+ nil nil bullet))
+ ((string-match "[a-z]" bullet)
+ (replace-match
+ (org-increment-string (match-string 0 bullet) nil)
+ nil nil bullet))
+ ((string-match "[A-Z]" bullet)
+ (replace-match
+ (org-increment-string (match-string 0 bullet) t)
+ nil nil bullet))
+ (t bullet))))
(defun org-list-repair (&optional force-bullet top bottom)
"Make sure all items are correctly indented, with the right bullet.
@@ -1635,36 +1700,52 @@ If WHICH is a valid string, use that as the new bullet. If WHICH
is an integer, 0 means `-', 1 means `+' etc. If WHICH is
'previous, cycle backwards."
(interactive "P")
- (save-excursion
- (let* ((top (org-list-top-point))
- (bullet (progn
- (goto-char (org-get-beginning-of-list top))
- (org-get-bullet)))
- (current (cond
- ((string-match "\\." bullet) "1.")
- ((string-match ")" bullet) "1)")
- (t bullet)))
- (bullet-rule-p (cdr (assq 'bullet org-list-automatic-rules)))
- (bullet-list (append '("-" "+" )
- ;; *-bullets are not allowed at column 0
- (unless (and bullet-rule-p
- (looking-at "\\S-")) '("*"))
- ;; Description items cannot be numbered
- (unless (and bullet-rule-p
- (or (eq org-plain-list-ordered-item-terminator ?\))
- (org-at-item-description-p))) '("1."))
- (unless (and bullet-rule-p
- (or (eq org-plain-list-ordered-item-terminator ?.)
- (org-at-item-description-p))) '("1)"))))
- (len (length bullet-list))
- (item-index (- len (length (member current bullet-list))))
- (get-value (lambda (index) (nth (mod index len) bullet-list)))
- (new (cond
- ((member which bullet-list) which)
- ((numberp which) (funcall get-value which))
- ((eq 'previous which) (funcall get-value (1- item-index)))
- (t (funcall get-value (1+ item-index))))))
- (org-list-repair new top))))
+ (let* ((top (org-list-top-point))
+ (list (progn (save-excursion (goto-char top) (org-list-parse-list))))
+ (alpha-possible (org-list-can-be-alphabetical (org-list-struct-origins list)))
+ (bullet (save-excursion
+ (goto-char (org-get-beginning-of-list top))
+ (org-get-bullet)))
+ (current (let ((case-fold-search nil))
+ (cond
+ ((string-match "[0-9]+\\." bullet) "1.")
+ ((string-match "[0-9]+)" bullet) "1)")
+ ((string-match "[a-z]\\." bullet) "a.")
+ ((string-match "[a-z])" bullet) "a)")
+ ((string-match "[A-Z]\\." bullet) "A.")
+ ((string-match "[A-Z])" bullet) "A)")
+ (t bullet))))
+ (bullet-rule-p (cdr (assq 'bullet org-list-automatic-rules)))
+ (bullet-list (append '("-" "+" )
+ ;; *-bullets are not allowed at column 0
+ (unless (and bullet-rule-p
+ (looking-at "\\S-")) '("*"))
+ ;; Description items cannot be numbered
+ (unless (and bullet-rule-p
+ (or (eq org-plain-list-ordered-item-terminator ?.)
+ (org-at-item-description-p))) '("1)"))
+ (unless (and bullet-rule-p
+ (or (eq org-plain-list-ordered-item-terminator ?\))
+ (org-at-item-description-p))) '("1."))
+ (when (and org-alphabetical-lists alpha-possible)
+ (append
+ (unless (and bullet-rule-p
+ (or (eq org-plain-list-ordered-item-terminator ?.)
+ (org-at-item-description-p)))
+ '("A)" "a)"))
+ (unless (and bullet-rule-p
+ (or (eq org-plain-list-ordered-item-terminator ?\))
+ (org-at-item-description-p)))
+ '("A." "a."))))))
+ (len (length bullet-list))
+ (item-index (- len (length (member current bullet-list))))
+ (get-value (lambda (index) (nth (mod index len) bullet-list)))
+ (new (cond
+ ((member which bullet-list) which)
+ ((numberp which) (funcall get-value which))
+ ((eq 'previous which) (funcall get-value (1- item-index)))
+ (t (funcall get-value (1+ item-index))))))
+ (org-list-repair new top)))
;;; Checkboxes
@@ -1691,7 +1772,7 @@ in subtree, ignoring drawers."
(rend (region-end)))
(save-excursion
(goto-char rbeg)
- (if (org-search-forward-unenclosed org-item-beginning-re rend 'move)
+ (if (org-search-forward-unenclosed (org-item-beginning-re) rend 'move)
(list (point-at-bol) rend nil)
(error "No item in region")))))
((org-on-heading-p)
@@ -1703,7 +1784,7 @@ in subtree, ignoring drawers."
(goto-char limit)
(org-search-backward-unenclosed ":END:" pos 'move)
(org-search-forward-unenclosed
- org-item-beginning-re limit 'move)
+ (org-item-beginning-re) limit 'move)
(list (point) limit nil))))
((org-at-item-p)
(list (point-at-bol) (1+ (point-at-eol)) t))
@@ -1751,7 +1832,7 @@ in subtree, ignoring drawers."
(goto-char beg)
(while (< (point) end)
(funcall act-on-item ref-presence ref-status)
- (org-search-forward-unenclosed org-item-beginning-re end 'move)))
+ (org-search-forward-unenclosed (org-item-beginning-re) end 'move)))
(org-update-checkbox-count-maybe)))
(defun org-reset-checkbox-state-subtree ()
@@ -1782,6 +1863,7 @@ information.")
(org-update-checkbox-count))
(run-hooks 'org-checkbox-statistics-hook))
+
(defun org-update-checkbox-count (&optional all)
"Update the checkbox statistics in the current section.
This will find all statistic cookies like [57%] and [6/12] and update them
@@ -1798,8 +1880,8 @@ the whole buffer."
(error (point-min))))
(end (copy-marker (save-excursion
(outline-next-heading) (point))))
- (re-cookie "\\(\\(\\[[0-9]*%\\]\\)\\|\\(\\[[0-9]*/[0-9]*\\]\\)\\)")
- (re-box "^[ \t]*\\([-+*]\\|[0-9]+[.)]\\)[ \t]+\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\(\\[[- X]\\]\\)")
+ (re-cookie "\\(\\(\\[0-9]*%\\]\\)\\|\\(\\[[0-9]*/[0-9]*\\]\\)\\)")
+ (re-box "^[ \t]*\\([-+*]\\|\\(?:[0-9]+\\|[A-Za-z]\\)[.)]\\)[ \t]+\\(?:\\[@\\(?:start:\\)?\\(?:[0-9]+\\|[A-Za-z]\\)\\][ \t]*\\)?\\(\\[[- X]\\]\\)")
beg-cookie end-cookie is-percent c-on c-off lim new
curr-ind next-ind continue-from startsearch list-beg list-end
(recursive
@@ -1860,7 +1942,7 @@ the whole buffer."
(goto-char (or (org-get-next-item (point) lim) lim))
(end-of-line)
(when (org-search-forward-unenclosed
- org-item-beginning-re lim t)
+ (org-item-beginning-re) lim t)
(beginning-of-line)))
(setq next-ind (org-get-indentation)))))
(goto-char continue-from)
@@ -1886,8 +1968,8 @@ the whole buffer."
(goto-char continue-from)))
(unless (and all (outline-next-heading)) (throw 'exit nil))))
(when (interactive-p)
- (message "Checkbox statistics updated %s (%d places)"
- (if all "in entire file" "in current outline entry") cstat)))))
+ (message "Checkbox statistics updated %s (%d places)"
+ (if all "in entire file" "in current outline entry") cstat)))))
(defun org-get-checkbox-statistics-face ()
"Select the face for checkbox statistics.
@@ -2033,10 +2115,10 @@ sublevels as a list of strings."
(let* ((start (goto-char (org-list-top-point)))
(end (org-list-bottom-point))
output itemsep ltype)
- (while (org-search-forward-unenclosed org-item-beginning-re end t)
+ (while (org-search-forward-unenclosed (org-item-beginning-re) end t)
(save-excursion
(beginning-of-line)
- (setq ltype (cond ((org-looking-at-p "^[ \t]*[0-9]") 'ordered)
+ (setq ltype (cond ((org-looking-at-p "^[ \t]*\\([0-9]+\\|[A-Za-z]\\)") 'ordered)
((org-at-item-description-p) 'descriptive)
(t 'unordered))))
(let* ((indent1 (org-get-indentation))
@@ -2045,7 +2127,7 @@ sublevels as a list of strings."
(org-end-of-item-or-at-child end))))
(nextindent (if (= (point) end) 0 (org-get-indentation)))
(item (if (string-match
- "^\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\([xX ]\\)\\]"
+ "^\\(?:\\[@\\(?:start:\\)?\\(?:[0-9]+\\|[A-Za-z]\\)\\][ \t]*\\)?\\[\\([xX ]\\)\\]"
item)
(replace-match (if (equal (match-string 1 item) " ")
"CBOFF"
@@ -2130,7 +2212,7 @@ this list."
(top-point
(progn
(re-search-backward "#\\+ORGLST" nil t)
- (re-search-forward org-item-beginning-re bottom-point t)
+ (re-search-forward (org-item-beginning-re) bottom-point t)
(match-beginning 0)))
(list (save-restriction
(narrow-to-region top-point bottom-point)
--
1.7.2.3.msysgit.0
[-- Attachment #3: Type: text/plain, Size: 201 bytes --]
_______________________________________________
Emacs-orgmode mailing list
Please use `Reply All' to send replies to the list.
Emacs-orgmode@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-orgmode
prev parent reply other threads:[~2011-01-12 20:05 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-29 20:27 [PATCH] Alphabetical ordered lists Nathaniel Flath
2010-07-29 21:07 ` Nick Dokos
2010-08-01 18:33 ` David Maus
2010-08-02 9:31 ` Nicolas Goaziou
2010-08-27 8:11 ` Carsten Dominik
2010-08-27 10:53 ` Bernt Hansen
2010-08-27 12:44 ` Jacob Mitchell
2010-08-27 13:01 ` Nathaniel Flath
2010-09-18 7:43 ` Nathaniel Flath
2010-09-21 12:48 ` Carsten Dominik
2010-09-21 16:46 ` Nicolas Goaziou
2010-09-26 17:36 ` Nicolas Goaziou
2010-09-26 22:16 ` Nathaniel Flath
2010-09-27 6:55 ` Nicolas Goaziou
2010-09-28 16:12 ` Carsten Dominik
2010-09-29 15:49 ` Carsten Dominik
2010-09-29 16:50 ` Nathaniel Flath
2010-09-29 17:46 ` Nicolas Goaziou
2010-10-01 1:13 ` Nathaniel Flath
2010-10-04 8:33 ` Carsten Dominik
2010-10-04 17:18 ` Nicolas Goaziou
2010-10-05 0:07 ` Sebastian Rose
2010-10-05 0:21 ` Nathaniel Flath
2010-10-05 7:40 ` Carsten Dominik
2010-10-21 4:44 ` Nathaniel Flath
2010-10-22 5:30 ` Nathaniel Flath
2010-10-22 8:13 ` Carsten Dominik
2010-10-23 1:04 ` Nathaniel Flath
2010-10-26 8:21 ` Nicolas Goaziou
2010-10-26 8:23 ` Carsten Dominik
2010-10-28 7:17 ` Nathaniel Flath
2010-11-11 7:16 ` Nathaniel Flath
2010-11-11 8:57 ` Nicolas Goaziou
2010-11-13 15:16 ` Nicolas Goaziou
2010-11-22 4:45 ` Nathaniel Flath
2010-11-22 13:37 ` Bernt Hansen
2010-11-22 18:37 ` Nicolas Goaziou
2010-11-27 4:39 ` Nathaniel Flath
2010-12-11 2:41 ` Nathaniel Flath
2010-12-20 18:25 ` Nicolas Goaziou
2011-01-12 20:05 ` Nathaniel Flath [this message]
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=AANLkTim9ATWcEUAgi+tTTEcj1S5PzNc9NqZ0j1uX8VG4@mail.gmail.com \
--to=flat0103@gmail.com \
--cc=bernt@norang.ca \
--cc=carsten.dominik@gmail.com \
--cc=emacs-orgmode@gnu.org \
--cc=jacob.d.mitchell@gmail.com \
--cc=n.goaziou@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).