changeset 66987:4da59b0dd54b

(org-table-sort-lines): New command. (org-tbl-menu): Add entry for `org-table-sort-lines'. (org-add-file): Command removed, use `org-agenda-file-to-front' instead. (org-export-icalendar): Use `org-icalendar-combined-name'. (org-cycle-agenda-files, org-agenda-file-to-end) (org-agenda-file-to-front): New commands. (org-table-tab-jumps-over-hlines,org-export-html-style): New options. (org-table-next-field): Use `org-table-tab-jumps-over-hlines'. (org-at-table.el-p, org-set-autofill-regexps,org-html-protect): New functions. (org-fill-paragraph): Call `org-table-align' in tables. (org-mode): Call `org-set-autofill-regexps'. (org-export-as-html): Support for local handformatted lists. Modified to produce valid HTML 4.0. Use `org-export-html-style'. (org-export-local-list-max-depth): New option. (org-html-expand): Use `org-html-protect'.
author Carsten Dominik <dominik@science.uva.nl>
date Fri, 18 Nov 2005 16:08:29 +0000
parents 24b9342c0182
children 578b7f9692c4
files lisp/textmodes/org.el
diffstat 1 files changed, 447 insertions(+), 214 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/textmodes/org.el	Fri Nov 18 13:57:25 2005 +0000
+++ b/lisp/textmodes/org.el	Fri Nov 18 16:08:29 2005 +0000
@@ -1,11 +1,11 @@
-;;; org.el --- Outline-based notes management and organizer
+;;; org.el --- Outline-based notes management and organize
 ;; Carstens outline-mode for keeping track of everything.
 ;; Copyright (c) 2004, 2005 Free Software Foundation
 ;;
 ;; Author: Carsten Dominik <dominik at science dot uva dot nl>
 ;; Keywords: outlines, hypermedia, calendar
 ;; Homepage: http://www.astro.uva.nl/~dominik/Tools/org/
-;; Version: 3.19
+;; Version: 3.20
 ;;
 ;; This file is part of GNU Emacs.
 ;;
@@ -80,6 +80,20 @@
 ;;
 ;; Changes:
 ;; -------
+;; Version 3.20
+;;    - There is finally an option to make TAB jump over horizontal lines
+;;      in tables instead of creating a new line before that line.
+;;      The option is `org-table-tab-jumps-over-hlines', default nil.
+;;    - New command for sorting tables, on `C-c ^'.
+;;    - Changes to the HTML exporter
+;;      - hand-formatted lists are exported correctly, similar to
+;;        markdown lists.  Nested lists are possible.  See the docstring
+;;        of the variable `org-export-local-list-max-depth'.
+;;      - cleaned up to produce valid HTML 4.0 (transitional).
+;;      - support for cascading style sheets.
+;;    - New command to cycle through all agenda files, on C-,
+;;    - C-c [ can now also be used to change the sequence of agenda files.
+;;
 ;; Version 3.19
 ;;    - Bug fixes
 ;;
@@ -220,7 +234,7 @@
 
 ;;; Customization variables
 
-(defvar org-version "3.19"
+(defvar org-version "3.20"
   "The version number of the file org.el.")
 (defun org-version ()
   (interactive)
@@ -530,7 +544,7 @@
 
 (defcustom org-agenda-files nil
   "A list of org files for agenda/diary display.
-Entries are added to this list with \\[org-add-file] and removed with
+Entries are added to this list with \\[org-agenda-file-to-front] and removed with
 \\[org-remove-file].  You can also use customize to edit the list."
   :group 'org-agenda
   :type '(repeat file))
@@ -1128,6 +1142,17 @@
 	  (const :tag "on" t)
 	  (const :tag "on, optimized" optimized)))
 
+;; FIXME: We could have a third option which makes it jump onle over the first
+;; hline in a table.
+(defcustom org-table-tab-jumps-over-hlines t
+  "Non-nil means, tab in the last column of a table with jump over a hline.
+If a horizontal separator line is following the current line,
+`org-table-next-field' can either create a new row before that line, or jump
+over the line.  When this option is nil, a new line will be created before
+this line."
+  :group 'org-table
+  :type 'boolean)
+
 (defcustom org-table-auto-blank-field t
   "Non-nil means, automatically blank table field when starting to type into it.
 This only happens when typing immediately after a field motion
@@ -1313,7 +1338,28 @@
 
 (defcustom org-export-default-language "en"
   "The default language of HTML export, as a string.
-This should have an association in `org-export-language-setup'"
+This should have an association in `org-export-language-setup'."
+  :group 'org-export
+  :type 'string)
+
+(defcustom org-export-html-style ""
+  "The default style specification for exported HTML files.
+Since there are different ways of setting style information, this variable
+needs to contain the full HTML structure to provide a style, including the
+surrounding HTML tags.  For example, legal values would be
+
+   <style type=\"text/css\">
+       p {font-weight: normal; color: gray; }
+       h1 {color: black; }
+   </style>
+
+or
+
+   <link rel=\"stylesheet\" type=\"text/css\" href=\"mystyles.css\">
+
+As the value of this option simply gets inserted into the HTML <head> header,
+you can \"misuse\" it to add arbitrary text to the header.
+"
   :group 'org-export
   :type 'string)
 
@@ -1347,6 +1393,30 @@
   :group 'org-export
   :type 'boolean)
 
+(defcustom org-export-local-list-max-depth 1
+  "Maximum depth of hand-formatted lists in HTML export.
+Org-mode parses hand-formatted enumeration and bullet lists and
+transforms them to HTML open export.  Different indentation of the bullet
+or number indicates different list nesting levels.  To avoid confusion,
+only a single level is allowed by default.  This means that a list is started
+with an item, and that all further items are consitered as long as the
+indentation is larger or equal to the indentation of the first item.  When this
+is larger than 1, deeper indentation leads to deeper list nesting.
+If you are careful with hand formatting, you can increase this limit and
+get lists of arbitrary depth.  For example, by setting this option to 3, the
+following list would look correct in HTML:
+
+  * Fruit
+    - Apple
+    - Banana
+      1. from Africa
+      2. from South America
+    - Pineapple
+  * Bread
+  * Dairy products"
+  :group 'org-export
+  :type 'integer)
+
 (defcustom org-export-preserve-breaks nil
   "Non-nil means, preserve all line breaks when exporting.
 Normally, in HTML output paragraphs will be reformatted.  In ASCII
@@ -1874,19 +1944,8 @@
   (make-local-hook 'before-change-functions)  ;; needed for XEmacs
   (add-hook 'before-change-functions 'org-before-change-function nil
 	    'local)
-  ;; Paragraph regular expressions
-  (set (make-local-variable 'paragraph-separate) "\f\\|[ 	]*$\\|\\([*\f]+\\)")
-  (set (make-local-variable 'paragraph-start) "\f\\|[ 	]*$\\|\\([*\f]+\\)")
-  ;; Inhibit auto-fill for headers, tables and fixed-width lines.
-  (set (make-local-variable 'auto-fill-inhibit-regexp)
-       (concat "\\*\\|#"
-	       (if (or org-enable-table-editor org-enable-fixed-width-editor)
-		   (concat
-		    "\\|[ \t]*["
-		    (if org-enable-table-editor "|" "")
-		   (if org-enable-fixed-width-editor ":"  "")
-		   "]"))))
-  (set (make-local-variable 'fill-paragraph-function) 'org-fill-paragraph)
+  ;; Paragraphs and auto-filling
+  (org-set-autofill-regexps)
   ;; Settings for Calc embedded mode
   (set (make-local-variable 'calc-embedded-open-formula) "|\\|\n")
   (set (make-local-variable 'calc-embedded-close-formula) "|\\|\n")
@@ -1918,12 +1977,6 @@
 	(let ((this-command 'org-cycle) (last-command 'org-cycle))
 	  (org-cycle '(4)) (org-cycle '(4))))))))
 
-(defun org-fill-paragraph (&optional justify)
-  "Re-align a table, pass through to fill-paragraph if no table."
-  (save-excursion
-    (beginning-of-line 1)
-    (looking-at "\\s-*\\(|\\|\\+-+\\)")))
-
 (defsubst org-current-line (&optional pos)
   (+ (if (bolp) 1 0) (count-lines (point-min) (or pos (point)))))
 
@@ -4230,34 +4283,53 @@
       (error
        (add-to-diary-list original-date  "Org-mode dummy" "" nil)))))
 
-(defun org-add-file (&optional file)
-  "Add current file to the list of files in variable `org-agenda-files'.
-These are the files which are being checked for agenda entries.
-Optional argument FILE means, use this file instead of the current.
-It is possible (but not recommended) to add this function to the
-`org-mode-hook'."
-  (interactive)
-  (catch 'exit
-    (let* ((file (or file (buffer-file-name)
-		     (if (interactive-p)
-			 (error "Buffer is not visiting a file")
-		       (throw 'exit nil))))
-	   (true-file (file-truename file))
-	   (afile (abbreviate-file-name file))
-	   (present (delq nil (mapcar
-			       (lambda (x)
-				 (equal true-file (file-truename x)))
-			       org-agenda-files))))
-      (if (not present)
-	  (progn
-	    (setq org-agenda-files
-		  (cons afile org-agenda-files))
-	    ;; Make sure custom.el does not end up with Org-mode
-	    (let ((org-mode-hook nil) (default-major-mode 'fundamental-mode))
-	      (customize-save-variable 'org-agenda-files org-agenda-files))
-	    (org-install-agenda-files-menu)
-	    (message "Added file: %s" afile))
-	(message "File was already in list: %s" afile)))))
+(defun org-cycle-agenda-files ()
+  "Cycle through the files in `org-agenda-files'.
+If the current buffer visits an agenda file, find the next one in the list.
+If the current buffer does not, find the first agenda file."
+  (interactive)
+  (let ((files (append org-agenda-files (list (car org-agenda-files))))
+	(tcf (if (buffer-file-name) (file-truename (buffer-file-name))))
+	file)
+    (unless files (error "No agenda files"))
+    (catch 'exit
+      (while (setq file (pop files))
+	(if (equal (file-truename file) tcf)
+	    (when (car files)
+	      (find-file (car files))
+	      (throw 'exit t))))
+      (find-file (car org-agenda-files)))))
+
+(defun org-agenda-file-to-end (&optional file)
+  "Move/add the current file to the end of the agenda fiole list.
+I the file is not present in the list, it is appended ot the list.  If it is
+present, it is moved there."
+  (interactive)
+  (org-agenda-file-to-front 'to-end file))
+
+(defun org-agenda-file-to-front (&optional to-end file)
+  "Move/add the current file to the top of the agenda file list.
+If the file is not present in the list, it is added to the front.  If it is
+present, it is moved there.  With optional argument TO-END, add/move to the
+end of the list."
+  (interactive "P")
+  (let ((file-alist (mapcar (lambda (x)
+			      (cons (file-truename x) x))
+			    org-agenda-files))
+	(ctf (file-truename (buffer-file-name)))
+	x had)
+    (setq x (assoc ctf file-alist) had x)
+
+    (if (not x) (setq x (cons ctf (abbreviate-file-name (buffer-file-name)))))
+    (if to-end
+	(setq file-alist (append (delq x file-alist) (list x)))
+      (setq file-alist (cons x (delq x file-alist))))
+    (setq org-agenda-files (mapcar 'cdr file-alist))
+    (let ((org-mode-hook nil) (default-major-mode 'fundamental-mode))
+      (customize-save-variable 'org-agenda-files org-agenda-files))
+    (org-install-agenda-files-menu)
+    (message "File %s to %s of agenda file list"
+	     (if had "moved" "added") (if to-end "end" "front"))))
 
 (defun org-remove-file (&optional file)
   "Remove current file from the list of files in variable `org-agenda-files'.
@@ -6300,7 +6372,7 @@
 	(goto-char pos))))))
 
 (defun org-table-next-field ()
-  "Go to the next field in the current table.
+  "Go to the next field in the current table, creating new lines as needed.
 Before doing so, re-align the table if necessary."
   (interactive)
   (org-table-maybe-eval-formula)
@@ -6308,20 +6380,25 @@
   (if (and org-table-automatic-realign
 	   org-table-may-need-update)
       (org-table-align))
-  (if (org-at-table-hline-p)
-      (end-of-line 1))
-  (condition-case nil
-      (progn
-	(re-search-forward "|" (org-table-end))
-	(if (looking-at "[ \t]*$")
-	    (re-search-forward "|" (org-table-end)))
-	(if (looking-at "-")
-	    (progn
-	      (beginning-of-line 0)
-	      (org-table-insert-row 'below))
-	  (if (looking-at " ") (forward-char 1))))
-    (error
-     (org-table-insert-row 'below))))
+  (let ((end (org-table-end)))
+    (if (org-at-table-hline-p)
+	(end-of-line 1))
+    (condition-case nil
+	(progn
+	  (re-search-forward "|" end)
+	  (if (looking-at "[ \t]*$")
+	      (re-search-forward "|" end))
+	  (if (and (looking-at "-")
+		   org-table-tab-jumps-over-hlines
+		   (re-search-forward "^[ \t]*|\\([^-]\\)" end t))
+	      (goto-char (match-beginning 1)))
+	  (if (looking-at "-")
+	      (progn
+		(beginning-of-line 0)
+		(org-table-insert-row 'below))
+	    (if (looking-at " ") (forward-char 1))))
+      (error
+       (org-table-insert-row 'below)))))
 
 (defun org-table-previous-field ()
   "Go to the previous field in the table.
@@ -6472,6 +6549,7 @@
 of the field.
 If there are less than N fields, just go to after the last delimiter.
 However, when FORCE is non-nil, create new columns if necessary."
+  (interactive "p")
   (let ((pos (point-at-eol)))
     (beginning-of-line 1)
     (when (> n 0)
@@ -6490,7 +6568,7 @@
 
 (defun org-at-table-p (&optional table-type)
   "Return t if the cursor is inside an org-type table.
-If TABLE-TYPE is non-nil, also chack for table.el-type tables."
+If TABLE-TYPE is non-nil, also check for table.el-type tables."
   (if org-enable-table-editor
       (save-excursion
 	(beginning-of-line 1)
@@ -6498,6 +6576,13 @@
 		      org-table-line-regexp)))
     nil))
 
+(defun org-at-table.el-p ()
+  "Return t if and only if we are at a table.el table."
+  (and (org-at-table-p 'any)
+       (save-excursion
+	 (goto-char (org-table-begin 'any))
+	 (looking-at org-table1-hline-regexp))))
+
 (defun org-table-recognize-table.el ()
   "If there is a table.el table nearby, recognize it and move into it."
   (if org-table-tab-recognizes-table.el
@@ -6524,15 +6609,6 @@
 	nil)
     nil))
 
-(defun org-at-table.el-p ()
-  "Return t if the cursor is inside a table.el-type table."
-  (save-excursion
-    (if (org-at-table-p 'any)
-	(progn
-	  (goto-char (org-table-begin 'any))
-	  (looking-at org-table1-hline-regexp))
-      nil)))
-
 (defun org-at-table-hline-p ()
   "Return t if the cursor is inside a hline in a table."
   (if org-enable-table-editor
@@ -6745,6 +6821,49 @@
     (if (not (org-at-table-p)) (beginning-of-line 0))
     (move-to-column col)))
 
+(defun org-table-sort-lines (beg end numericp)
+  "Sort table lines in region.
+Point and mark define the first and last line to include.  Both point and
+mark should be in the column that is used for sorting.  For example, to
+sort according to column 3, put the mark in the first line to sort, in
+table column 3.  Put point into the last line to be included in the sorting,
+also in table column 3. The command will prompt for the sorting method (n for
+numerical, a for alphanumeric)."
+  (interactive "r\nsSorting method: [n]=numeric [a]=alpha: ")
+  (setq numericp (string-match "[nN]" numericp))
+  (org-table-align) ;; Just to be safe
+  (let* (bcol ecol cmp column lns)
+    (goto-char beg)
+    (org-table-check-inside-data-field)
+    (setq column (org-table-current-column)
+	  beg (move-marker (make-marker) (point-at-bol)))
+    (goto-char end)
+    (org-table-check-inside-data-field)
+    (setq end (move-marker (make-marker) (1+ (point-at-eol))))
+    (untabify beg end)
+    (goto-char beg)
+    (org-table-goto-column column)
+    (skip-chars-backward "^|")
+    (setq bcol (current-column))
+    (org-table-goto-column (1+ column))
+    (skip-chars-backward "^|")
+    (setq ecol (1- (current-column)))
+    (setq cmp (if numericp
+		  (lambda (a b) (< (car a) (car b)))
+		(lambda (a b) (string< (car a) (car b)))))
+    (setq lns (mapcar (lambda(x) (cons (org-trim (substring x bcol ecol)) x))
+		      (split-string (buffer-substring beg end) "\n")))
+    (if numericp
+	(setq lns (mapcar (lambda(x)
+			      (cons (string-to-number (car x)) (cdr x)))
+			    lns)))
+    (delete-region beg end)
+    (move-marker beg nil)
+    (move-marker end nil)
+    (insert (mapconcat 'cdr (setq lns (sort lns cmp)) "\n") "\n")
+    (message "%d lines sorted %s based on column %d"
+	     (length lns)
+	     (if numericp "numerically" "alphabetically") column)))
 
 (defun org-table-cut-region (beg end)
   "Copy region in table to the clipboard and blank all relevant fields."
@@ -8013,6 +8132,7 @@
 	  '("\C-c="              org-table-eval-formula)
 	  '("\C-c'"              org-table-edit-formulas)
 	  '("\C-c*"              org-table-recalculate)
+	  '("\C-c^"              org-table-sort-lines)
 	  '([(control ?#)]       org-table-rotate-recalc-marks)))
 	elt key fun cmd)
     (while (setq elt (pop bindings))
@@ -8063,6 +8183,7 @@
 	 ["Move Row Down" org-metadown :active (org-at-table-p) :keys "M-<down>"]
 	 ["Delete Row" org-shiftmetaup :active (org-at-table-p) :keys "M-S-<up>"]
 	 ["Insert Row" org-shiftmetadown :active (org-at-table-p) :keys "M-S-<down>"]
+	 ["Sort lines in region" org-table-sort-lines (org-at-table-p) :keys "C-c ^"]
 	 "--"
 	 ["Insert Hline" org-table-insert-hline :active (org-at-table-p) :keys "C-c -"])
 	("Rectangle"
@@ -8838,7 +8959,8 @@
   (setq-default org-todo-line-regexp org-todo-line-regexp)
   (setq-default org-deadline-line-regexp org-deadline-line-regexp)
   (setq-default org-done-string org-done-string)
-  (let* ((region-p (org-region-active-p))
+  (let* ((style org-export-html-style)
+	 (region-p (org-region-active-p))
          (region
           (buffer-substring
            (if region-p (region-beginning) (point-min))
@@ -8859,6 +8981,10 @@
          (options     nil)
 	 (quote-re    (concat "^\\*+[ \t]*" org-quote-string "\\>"))
 	 (inquote     nil)
+	 (infixed     nil)
+	 (in-local-list nil)
+	 (local-list-num nil)
+	 (local-list-indent nil)
 	 (email       user-mail-address)
          (language    org-export-default-language)
 	 (text        nil)
@@ -8875,6 +9001,7 @@
 		       (coding-system-get coding-system 'mime-charset)))
 	 table-open type
 	 table-buffer table-orig-buffer
+	 ind start-is-num starter
 	 )
     (message "Exporting...")
 
@@ -8899,16 +9026,19 @@
 
       ;; File header
       (insert (format
-               "<html lang=\"%s\"><head>
+               "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"
+ \"http://www.w3.org/TR/REC-html40/loose.dtd\">
+<html lang=\"%s\"><head>
 <title>%s</title>
 <meta http-equiv=\"Content-Type\" content=\"text/html;charset=%s\">
 <meta name=generator content=\"Org-mode\">
 <meta name=generated content=\"%s %s\">
 <meta name=author content=\"%s\">
+%s
 </head><body>
 "
 	       language (org-html-expand title) (or charset "iso-8859-1")
-	       date time author))
+	       date time author style))
       (if title     (insert (concat "<H1 align=\"center\">"
 				    (org-html-expand title) "</H1>\n")))
       (if author    (insert (concat (nth 1 lang-words) ": " author "\n")))
@@ -8959,8 +9089,8 @@
 				   (insert
 				    (format
 				     (if todo
-					 "<li><a href=\"#sec-%d\"><span style='color:red'>%s</span></a></li>\n"
-				       "<li><a href=\"#sec-%d\">%s</a></li>\n")
+					 "<li><a href=\"#sec-%d\"><span style='color:red'>%s</span></a>\n"
+				       "<li><a href=\"#sec-%d\">%s</a>\n")
 				     head-count txt))
 				   (setq org-last-level level))
 			       ))))
@@ -8973,15 +9103,30 @@
       (org-init-section-numbers)
 
       (while (setq line (pop lines) origline line)
-	;; end of quote?
-	(when (and inquote (string-match "^\\*+" line))
-	  (insert "</pre>\n")
-	  (setq inquote nil))
-	;; inquote
-	(if inquote
-	    (progn
-	      (insert line "\n")
-	      (setq line (org-html-expand line))) ;;????? FIXME: not needed?
+	(catch 'nextline
+
+	  ;; end of quote section?
+	  (when (and inquote (string-match "^\\*+" line))
+	    (insert "</pre>\n")
+	    (setq inquote nil))
+	  ;; inside a quote section?
+	  (when inquote
+	    (insert (org-html-protect line) "\n")
+	    (throw 'nextline nil))
+
+	  ;; verbatim lines
+	  (when (and org-export-with-fixed-width
+		     (string-match "^[ \t]*:\\(.*\\)" line))
+	    (when (not infixed)
+	      (setq infixed t)
+	      (insert "<pre>\n"))
+	    (insert (org-html-protect (match-string 1 line)) "\n")
+	    (when (and lines
+		       (not (string-match "^[ \t]+\\(:.*\\)"
+					  (car lines))))
+	      (setq infixed nil)
+	      (insert "</pre>\n"))
+	    (throw 'nextline nil))
 
 	  ;; Protect the links
 	  (setq start 0)
@@ -8991,121 +9136,145 @@
 			(concat "\000" (match-string 1 line) "\000")
 			t t line)))
 
-	  ;; replace "<" and ">" by "&lt;" and "&gt;"
+	  ;; replace "&" by "&amp;", "<" and ">" by "&lt;" and "&gt;"
 	  ;; handle @<..> HTML tags (replace "@&gt;..&lt;" by "<..>")
 	  (setq line (org-html-expand line))
 
-	  ;; Verbatim lines
-	  (if (and org-export-with-fixed-width
-		   (string-match "^[ \t]*:\\(.*\\)" line))
-	      (progn
-		(let ((l (match-string 1 line)))
-		  (while (string-match " " l)
-		    (setq l (replace-match "&nbsp;" t t l)))
-		  (insert "\n<span style='font-family:Courier'>"
-			  l "</span>"
-			  (if (and lines
-				   (not (string-match "^[ \t]+\\(:.*\\)"
-						      (car lines))))
-			      "<br>\n" "\n"))))
-
-	    (setq start 0)
-	    (while (string-match org-protected-link-regexp line start)
-	      (setq start (- (match-end 0) 2))
-	      (setq type (match-string 1 line))
-	      (cond
-	       ((member type '("http" "https" "ftp" "mailto" "news"))
-		;; standard URL
-		(setq line (replace-match
+	  ;; Format the links
+	  (setq start 0)
+	  (while (string-match org-protected-link-regexp line start)
+	    (setq start (- (match-end 0) 2))
+	    (setq type (match-string 1 line))
+	    (cond
+	     ((member type '("http" "https" "ftp" "mailto" "news"))
+	      ;; standard URL
+	      (setq line (replace-match
 					;                          "<a href=\"\\1:\\2\">&lt;\\1:\\2&gt;</a>"
-			    "<a href=\"\\1:\\2\">\\1:\\2</a>"
-			    nil nil line)))
-	       ((string= type "file")
-		;; FILE link
-		(let* ((filename (match-string 2 line))
-		       (abs-p (file-name-absolute-p filename))
-		       (thefile (if abs-p (expand-file-name filename) filename))
-		       (thefile (save-match-data
-				  (if (string-match ":[0-9]+$" thefile)
-				      (replace-match "" t t thefile)
-				    thefile)))
-		       (file-is-image-p
-			(save-match-data
-			  (string-match (org-image-file-name-regexp) thefile))))
-		  (setq line (replace-match
-			      (if (and org-export-html-inline-images
-				       file-is-image-p)
-				  (concat "<img src=\"" thefile "\"/>")
-				(concat "<a href=\"" thefile "\">\\1:\\2</a>"))
-			      nil nil line))))
-
-	       ((member type '("bbdb" "vm" "wl" "rmail" "gnus" "shell"))
+			  "<a href=\"\\1:\\2\">\\1:\\2</a>"
+			  nil nil line)))
+	     ((string= type "file")
+	      ;; FILE link
+	      (let* ((filename (match-string 2 line))
+		     (abs-p (file-name-absolute-p filename))
+		     (thefile (if abs-p (expand-file-name filename) filename))
+		     (thefile (save-match-data
+				(if (string-match ":[0-9]+$" thefile)
+				    (replace-match "" t t thefile)
+				  thefile)))
+		     (file-is-image-p
+		      (save-match-data
+			(string-match (org-image-file-name-regexp) thefile))))
 		(setq line (replace-match
-			    "<i>&lt;\\1:\\2&gt;</i>" nil nil line)))))
-
-	    ;; TODO items
-	    (if (and (string-match org-todo-line-regexp line)
-		     (match-beginning 2))
-		(if (equal (match-string 2 line) org-done-string)
-		    (setq line (replace-match
-				"<span style='color:green'>\\2</span>"
-				nil nil line 2))
-		  (setq line (replace-match "<span style='color:red'>\\2</span>"
-					    nil nil line 2))))
-
-	    ;; DEADLINES
-	    (if (string-match org-deadline-line-regexp line)
-		(progn
-		  (if (save-match-data
-			(string-match "<a href"
-				      (substring line 0 (match-beginning 0))))
-		      nil     ; Don't do the replacement - it is inside a link
-		    (setq line (replace-match "<span style='color:red'>\\&</span>"
-					      nil nil line 1)))))
-
-
-	    (cond
-	     ((string-match "^\\(\\*+\\)[ \t]*\\(.*\\)" line)
-	      ;; This is a headline
-	      (setq level (- (match-end 1) (match-beginning 1))
-		    txt (match-string 2 line))
-	      (if (<= level umax) (setq head-count (+ head-count 1)))
-	      (org-html-level-start level txt umax
-				    (and org-export-with-toc (<= level umax))
-				    head-count)
-	      ;; QUOTES
-	      (when (string-match quote-re line)
-		(insert "<pre>")
-		(setq inquote t)))
-
-	     ((and org-export-with-tables
-		   (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)" line))
-	      (if (not table-open)
-		  ;; New table starts
-		  (setq table-open t table-buffer nil table-orig-buffer nil))
-	      ;; Accumulate lines
-	      (setq table-buffer (cons line table-buffer)
-		    table-orig-buffer (cons origline table-orig-buffer))
-	      (when (or (not lines)
-			(not (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)"
-					   (car lines))))
-		(setq table-open nil
-		      table-buffer (nreverse table-buffer)
-		      table-orig-buffer (nreverse table-orig-buffer))
-		(insert (org-format-table-html table-buffer table-orig-buffer))))
-	     (t
-	      ;; Normal lines
-	      ;; Lines starting with "-", and empty lines make new paragraph.
-	      ;; FIXME: Should we add + and *?
-	      (if (string-match "^ *-\\|^[ \t]*$" line) (insert "<p>"))
-	      (insert line (if org-export-preserve-breaks "<br>\n" "\n"))))
-	    )))
-	(if org-export-html-with-timestamp
-	    (insert org-export-html-html-helper-timestamp))
-	(insert "</body>\n</html>\n")
-	(normal-mode)
-	(save-buffer)
-	(goto-char (point-min)))))
+			    (if (and org-export-html-inline-images
+				     file-is-image-p)
+				(concat "<img src=\"" thefile "\"/>")
+			      (concat "<a href=\"" thefile "\">\\1:\\2</a>"))
+			    nil nil line))))
+
+	     ((member type '("bbdb" "vm" "wl" "rmail" "gnus" "shell"))
+	      (setq line (replace-match
+			  "<i>&lt;\\1:\\2&gt;</i>" nil nil line)))))
+
+	  ;; TODO items
+	  (if (and (string-match org-todo-line-regexp line)
+		   (match-beginning 2))
+	      (if (equal (match-string 2 line) org-done-string)
+		  (setq line (replace-match
+			      "<span style='color:green'>\\2</span>"
+			      nil nil line 2))
+		(setq line (replace-match "<span style='color:red'>\\2</span>"
+					  nil nil line 2))))
+
+	  ;; DEADLINES
+	  (if (string-match org-deadline-line-regexp line)
+	      (progn
+		(if (save-match-data
+		      (string-match "<a href"
+				    (substring line 0 (match-beginning 0))))
+		    nil     ; Don't do the replacement - it is inside a link
+		  (setq line (replace-match "<span style='color:red'>\\&</span>"
+					    nil nil line 1)))))
+
+	  (cond
+	   ((string-match "^\\(\\*+\\)[ \t]*\\(.*\\)" line)
+	    ;; This is a headline
+	    (setq level (- (match-end 1) (match-beginning 1))
+		  txt (match-string 2 line))
+	    (if (<= level umax) (setq head-count (+ head-count 1)))
+	    (when in-local-list
+	      ;; Close any local lists before inserting a new header line
+	      (while local-list-num
+		(insert (if (car local-list-num) "</ol>\n" "</ul>"))
+		(pop local-list-num))
+	      (setq local-list-indent nil
+		    in-local-list nil))
+	    (org-html-level-start level txt umax
+				  (and org-export-with-toc (<= level umax))
+				  head-count)
+	    ;; QUOTES
+	    (when (string-match quote-re line)
+	      (insert "<pre>")
+	      (setq inquote t)))
+
+	   ((and org-export-with-tables
+		 (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)" line))
+	    (if (not table-open)
+		;; New table starts
+		(setq table-open t table-buffer nil table-orig-buffer nil))
+	    ;; Accumulate lines
+	    (setq table-buffer (cons line table-buffer)
+		  table-orig-buffer (cons origline table-orig-buffer))
+	    (when (or (not lines)
+		      (not (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)"
+					 (car lines))))
+	      (setq table-open nil
+		    table-buffer (nreverse table-buffer)
+		    table-orig-buffer (nreverse table-orig-buffer))
+	      (insert (org-format-table-html table-buffer table-orig-buffer))))
+	   (t
+	    ;; Normal lines
+	    (when (and (> org-export-local-list-max-depth 0)
+		       (string-match
+			"^\\( *\\)\\(\\([-+*]\\)\\|\\([0-9]+\\.\\)\\)? *\\([^ \t\n\r]\\)"
+			line))
+	      (setq ind (- (match-end 1) (match-beginning 1))
+		    start-is-num (match-beginning 4)
+		    starter (if (match-beginning 2) (match-string 2 line)))
+	      (while (and in-local-list
+			  (or (and (= ind (car local-list-indent))
+				   (not starter))
+			      (< ind (car local-list-indent))))
+		(insert (if (car local-list-num) "</ol>\n" "</ul>"))
+		(pop local-list-num) (pop local-list-indent)
+		(setq in-local-list local-list-indent))
+
+	      (cond
+	       ((and starter
+		     (or (not in-local-list)
+			 (> ind (car local-list-indent)))
+		     (< (length local-list-indent)
+			org-export-local-list-max-depth))
+		;; Start new (level of ) list
+		(insert (if start-is-num "<ol>\n<li>\n" "<ul>\n<li>\n"))
+		(push start-is-num local-list-num)
+		(push ind local-list-indent)
+		(setq in-local-list t))
+	       (starter
+		;; continue current list
+		(insert "<li>\n")))
+	      (setq line (substring line (match-beginning 5))))
+	    ;; Empty lines start a new paragraph.  If hand-formatted lists
+	    ;; are not fully interpreted, lines starting with "-", "+", "*"
+	    ;; also start a new paragraph.
+	    (if (string-match "^ [-+*]-\\|^[ \t]*$" line) (insert "<p>"))
+	    (insert line (if org-export-preserve-breaks "<br>\n" "\n"))))
+	  ))
+      (if org-export-html-with-timestamp
+	  (insert org-export-html-html-helper-timestamp))
+      (insert "</body>\n</html>\n")
+      (normal-mode)
+      (save-buffer)
+      (goto-char (point-min)))))
 
 (defun org-format-table-html (lines olines)
   "Find out which HTML converter to use and return the HTML code."
@@ -9235,18 +9404,28 @@
     (set-buffer " org-tmp2 ")
     (buffer-substring (point-min) (point-max))))
 
+(defun org-html-protect (s)
+  ;; convert & to &amp;, < to &lt; and > to &gt;
+  (let ((start 0))
+    (while (string-match "&" s start)
+      (setq s (replace-match "&amp;" t t s)
+	    start (1+ (match-beginning 0))))
+    (while (string-match "<" s)
+      (setq s (replace-match "&lt;" t t s)))
+    (while (string-match ">" s)
+      (setq s (replace-match "&gt;" t t s))))
+  s)
+
 (defun org-html-expand (string)
   "Prepare STRING for HTML export.  Applies all active conversions."
   ;; First check if there is a link in the line - if yes, apply conversions
   ;; only before the start of the link.
+  ;; FIXME: This is no longer correct, because links now have an end.
   (let* ((m (string-match org-link-regexp string))
 	 (s (if m (substring string 0 m) string))
 	 (r (if m (substring string m) "")))
-    ;; convert < to &lt; and > to &gt;
-    (while (string-match "<" s)
-      (setq s (replace-match "&lt;" t t s)))
-    (while (string-match ">" s)
-      (setq s (replace-match "&gt;" t t s)))
+    ;; convert & to &amp;, < to &lt; and > to &gt;
+    (setq s (org-html-protect s))
     (if org-export-html-expand
 	(while (string-match "@&lt;\\([^&]*\\)&gt;" s)
 	  (setq s (replace-match "<\\1>" nil nil s))))
@@ -9446,9 +9625,6 @@
     string))
 
 
-
-
-
 (defun org-export-icalendar-this-file ()
   "Export current file as an iCalendar file.
 The iCalendar file will be located in the same directory as the Org-mode
@@ -9496,7 +9672,7 @@
 	  (let ((standard-output ical-buffer))
 	    (if combine
 		(and (not started) (setq started t)
-		     (org-start-icalendar-file "OrgMode"))
+		     (org-start-icalendar-file org-icalendar-combined-name))
 	      (org-start-icalendar-file category))
 	    (org-print-icalendar-entries combine category)
 	    (when (or (and combine (not files)) (not combine))
@@ -9540,7 +9716,7 @@
 		donep (org-entry-is-done-p)))
 	(if (or (string-match org-tr-regexp hd)
 		(string-match org-ts-regexp hd))
-	    (setq hd (replace-match "" t t hd)))		
+	    (setq hd (replace-match "" t t hd)))
 	(if combine
 	    (setq hd (concat hd " (category " category ")")))
 	(if deadlinep (setq hd (concat "DL: " hd " This is a deadline")))
@@ -9693,10 +9869,12 @@
 (define-key org-mode-map "\C-c\C-y" 'org-evaluate-time-range)
 (define-key org-mode-map "\C-c>"    'org-goto-calendar)
 (define-key org-mode-map "\C-c<"    'org-date-from-calendar)
-(define-key org-mode-map "\C-c["    'org-add-file)
+(define-key org-mode-map [(control ?,)]     'org-cycle-agenda-files)
+(define-key org-mode-map "\C-c["    'org-agenda-file-to-front)
 (define-key org-mode-map "\C-c]"    'org-remove-file)
 (define-key org-mode-map "\C-c\C-r"       'org-timeline)
 (define-key org-mode-map "\C-c-"          'org-table-insert-hline)
+(define-key org-mode-map "\C-c^"          'org-table-sort-lines)
 (define-key org-mode-map "\C-c\C-c"       'org-ctrl-c-ctrl-c)
 (define-key org-mode-map "\C-m"           'org-return)
 (define-key org-mode-map "\C-c?"          'org-table-current-column)
@@ -9807,7 +9985,7 @@
       (if (fboundp 'command-remapping)
 	  (define-key map (vector 'remap old) new)
 	(substitute-key-definition old new map global-map)))))
-  
+
 (when (eq org-enable-table-editor 'optimized)
   ;; If the user wants maximum table support, we need to hijack
   ;; some standard editing functions
@@ -10044,6 +10222,7 @@
      ["Move Row Down" org-metadown (org-at-table-p)]
      ["Delete Row" org-shiftmetaup (org-at-table-p)]
      ["Insert Row" org-shiftmetadown (org-at-table-p)]
+     ["Sort lines in region" org-table-sort-lines (org-at-table-p)]
      "--"
      ["Insert Hline" org-table-insert-hline (org-at-table-p)])
     ("Rectangle"
@@ -10185,8 +10364,9 @@
    (append
     (list
      ["Edit File List" (customize-variable 'org-agenda-files) t]
-     ["Add Current File to List" org-add-file t]
+     ["Add/Move Current File to Front of List" org-agenda-file-to-front t]
      ["Remove Current File from List" org-remove-file t]
+     ["Cycle through agenda files" org-cycle-agenda-files t]
      "--")
     (mapcar 'org-file-menu-entry org-agenda-files))))
 
@@ -10243,6 +10423,58 @@
     (goto-char pos)
     (move-to-column col)))
 
+;; Paragraph filling stuff.
+;; We want this to be just right, so use the full arsenal.
+;; FIXME:  This very likely does not work correctly for XEmacs, because the
+;; filladapt package works slightly differently.
+
+(defun org-set-autofill-regexps ()
+  (interactive)
+  ;; In the paragraph separator we include headlines, because filling
+  ;; text in a line directly attached to a headline would otherwise
+  ;; fill the headline as well.
+  (set (make-local-variable 'paragraph-separate) "\f\\|\\*\\|[ 	]*$\\|[ \t]*[:|]")
+  ;; The paragraph starter includes hand-formatted lists.
+  (set (make-local-variable 'paragraph-start)
+       "\f\\|[ 	]*$\\|\\([*\f]+\\)\\|[ \t]*\\([-+*]\\|[0-9]+\\.[ \t]+\\)\\|[ \t]*[:|]")
+  ;; Inhibit auto-fill for headers, tables and fixed-width lines.
+  ;; But only if the user has not turned off tables or fixed-width regions
+  (set (make-local-variable 'auto-fill-inhibit-regexp)
+       (concat "\\*\\|#"
+	       (if (or org-enable-table-editor org-enable-fixed-width-editor)
+		   (concat
+		    "\\|[ \t]*["
+		    (if org-enable-table-editor "|" "")
+		    (if org-enable-fixed-width-editor ":"  "")
+		    "]"))))
+  ;; We use our own fill-paragraph function, to make sure that tables
+  ;; and fixed-width regions are not wrapped.  That function will pass
+  ;; through to `fill-paragraph' when appropriate.
+  (set (make-local-variable 'fill-paragraph-function) 'org-fill-paragraph)
+  ;; Adaptive filling: To get full control, first make sure that
+  ;; `adaptive-fill-regexp' never matches.  Then install our won matcher.
+  (setq adaptive-fill-regexp "\000")
+  (setq adaptive-fill-function 'org-adaptive-fill-function))
+
+(defun org-fill-paragraph (&optional justify)
+  "Re-align a table, pass through to fill-paragraph if no table."
+  (let ((table-p (org-at-table-p))
+	(table.el-p (org-at-table.el-p)))
+    (cond ((equal (char-after (point-at-bol)) ?*) t) ; skip headlines
+	  (table.el-p t)                             ; skip table.el tables
+	  (table-p (org-table-align) t)              ; align org-mode tables
+	  (t nil))))                                 ; call paragraph-fill
+
+;; For reference, this is the default value of adaptive-fill-regexp
+;;  "[ \t]*\\([-|#;>*]+[ \t]*\\|(?[0-9]+[.)][ \t]*\\)*"
+
+(defun org-adaptive-fill-function ()
+  "Return a fill prefix for org-mode files.
+In particular, this makes sure hanging paragraphs for hand-formatted lists
+work correctly."
+  (if (looking-at " *\\([-*+] \\|[0-9]+\\. \\)?")
+      (make-string (- (match-end 0) (match-beginning 0)) ?\ )))
+
 ;; Functions needed for Emacs/XEmacs region compatibility
 
 (defun org-region-active-p ()
@@ -10474,3 +10706,4 @@
 
 ;; arch-tag: e77da1a7-acc7-4336-b19e-efa25af3f9fd
 ;;; org.el ends here
+