*** org-mode/lisp/org-list.el	Fri Oct 22 18:02:46 2010
--- src/org-mode/lisp/org-list.el	Thu Oct 21 22:28:04 2010
***************
*** 240,245 ****
--- 240,250 ----
    :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,300 ****
  If GENERAL is non-nil, return the general regexp independent of the value
  of `org-plain-list-ordered-item-terminator'."
    (cond
!    ((or general (eq org-plain-list-ordered-item-terminator t))
!     "\\([ \t]*\\([-+]\\|\\([0-9]+[.)]\\)\\)\\|[ \t]+\\*\\)\\([ \t]+\\|$\\)")
!    ((= org-plain-list-ordered-item-terminator ?.)
!     "\\([ \t]*\\([-+]\\|\\([0-9]+\\.\\)\\)\\|[ \t]+\\*\\)\\([ \t]+\\|$\\)")
!    ((= org-plain-list-ordered-item-terminator ?\))
!     "\\([ \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.")
--- 293,305 ----
  If GENERAL is non-nil, return the general regexp independent of the value
  of `org-plain-list-ordered-item-terminator'."
    (cond
!     ((or general (eq org-plain-list-ordered-item-terminator t))
!        "\\([ \t]*\\([-+]\\|\\(\\([0-9]+\\|[A-Za-z]\\)[.)]\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
!       ((= org-plain-list-ordered-item-terminator ?.)
!        "\\([ \t]*\\([-+]\\|\\(\\([0-9]+\\|[A-Za-z]\\)\\.\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
!     ((= org-plain-list-ordered-item-terminator ?\))
!      "\\([ \t]*\\([-+]\\|\\(\\([0-9]+\\|[A-Za-z]\\))\\)\\)\\|[ \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.")
***************
*** 530,537 ****
         (save-excursion
  	 (goto-char (match-end 0))
           ;; Ignore counter if any
!          (when (looking-at "\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?")
!            (goto-char (match-end 0)))
  	 (looking-at regexp))))
  
  (defun org-list-get-item-same-level (search-fun pos limit pre-move)
--- 535,542 ----
         (save-excursion
  	 (goto-char (match-end 0))
           ;; Ignore counter if any
!          (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)
***************
*** 1135,1145 ****
      (list (point-at-bol)
            (org-get-indentation)
            (progn
!             (looking-at "^[ \t]*\\([-+*0-9.)]+[ \t]+\\)")
              (match-string 1))
            (progn
              (goto-char (match-end 0))
!             (and (looking-at "\\[@\\(?:start:\\)?\\([0-9]+\\)\\]")
                   (match-string 1))))))
  
  (defun org-list-struct (begin end top bottom &optional outdent)
--- 1140,1150 ----
      (list (point-at-bol)
            (org-get-indentation)
            (progn
!             (looking-at "^[ \t]*\\([-+*0-9A-Za-z.)]+[ \t]+\\)")
              (match-string 1))
            (progn
              (goto-char (match-end 0))
!             (and (looking-at "\\[@\\(?:start:\\)?\\([0-9A-Za-z]+\\)\\]")
                   (match-string 1))))))
  
  (defun org-list-struct (begin end top bottom &optional outdent)
***************
*** 1259,1274 ****
  		     (let ((counter (nth 3 item))
  			   (bullet (org-list-bullet-string (nth 2 item))))
  		       (cond
! 			((and (string-match "[0-9]+" bullet) counter)
  			 (replace-match counter nil nil bullet))
  			((string-match "[0-9]+" 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))
  			  (replace-match counter nil nil bullet)
  			bullet))))
  	 (fix-bul
--- 1264,1283 ----
  		     (let ((counter (nth 3 item))
  			   (bullet (org-list-bullet-string (nth 2 item))))
  		       (cond
! 			((and (string-match "[0-9A-Za-z]+" bullet) counter)
  			 (replace-match counter nil nil bullet))
  			((string-match "[0-9]+" bullet)
  			 (replace-match "1" nil nil bullet))
+ 			((and (string-match "[A-Za-z]" bullet) (> 28 (length struct)))
+ 			 (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-9A-Za-z]+" bullet))
  			  (replace-match counter nil nil bullet)
  			bullet))))
  	 (fix-bul
***************
*** 1582,1594 ****
            " ")))
       nil nil bullet 1)))
  
  (defun org-list-inc-bullet-maybe (bullet)
    "Increment BULLET if applicable."
!   (if (string-match "[0-9]+" bullet)
        (replace-match
         (number-to-string (1+ (string-to-number (match-string 0 bullet))))
!        nil nil bullet)
!     bullet))
  
  (defun org-list-repair (&optional force-bullet top bottom)
    "Make sure all items are correctly indented, with the right bullet.
--- 1591,1640 ----
            " ")))
       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-inc-bullet-maybe (bullet)
    "Increment BULLET if applicable."
!   (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))
!      ((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.
***************
*** 1629,1642 ****
  is an integer, 0 means `-', 1 means `+' etc. If WHICH is
  'previous, cycle backwards."
    (interactive "P")
!   (let* ((top (org-list-top-point))
  	 (bullet (save-excursion
  		   (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
--- 1675,1703 ----
  is an integer, 0 means `-', 1 means `+' etc. If WHICH is
  'previous, cycle backwards."
    (interactive "P")
!    (let* ((top (org-list-top-point))
! 	  (alpha-possible (save-excursion
! 			    (goto-char (org-list-top-point))
! 			    (and org-alphabetical-lists
! 				 (let ((retn 1))
! 				  (condition-case nil
! 				      (progn (while (< retn 27)
! 					       (org-next-item)
! 					(setq retn (1+ retn))
! 					nil))
! 				    (error t))))))
  	 (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
***************
*** 1644,1654 ****
  					   (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)))
--- 1705,1725 ----
  					   (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)))
***************
*** 2028,2034 ****
      (while (org-search-forward-unenclosed org-item-beginning-re end t)
        (save-excursion
  	(beginning-of-line)
! 	(setq ltype (cond ((looking-at-p "^[ \t]*[0-9]") 'ordered)
  			  ((org-at-item-description-p) 'descriptive)
  			  (t 'unordered))))
        (let* ((indent1 (org-get-indentation))
--- 2099,2105 ----
      (while (org-search-forward-unenclosed org-item-beginning-re end t)
        (save-excursion
  	(beginning-of-line)
! 	(setq ltype (cond ((looking-at-p "^[ \t]*[0-9A-Za-z]+") 'ordered)
  			  ((org-at-item-description-p) 'descriptive)
  			  (t 'unordered))))
        (let* ((indent1 (org-get-indentation))
***************
*** 2037,2043 ****
  					       (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 ]\\)\\]"
  			item)
  		       (replace-match (if (equal (match-string 1 item) " ")
  					  "CBOFF"
--- 2108,2114 ----
  					       (org-end-of-item-or-at-child end))))
  	     (nextindent (if (= (point) end) 0 (org-get-indentation)))
  	     (item (if (string-match
! 			"^\\(?:\\[@\\(?:start:\\)?[0-9A-Za-z]+\\][ \t]*\\)?\\[\\([xX ]\\)\\]"
  			item)
  		       (replace-match (if (equal (match-string 1 item) " ")
  					  "CBOFF"
