Browse Source

Merge branch 'master' of git://repo.or.cz/org-mode

Dan Davison 15 years ago
parent
commit
9bdf58e6ce
8 changed files with 297 additions and 31 deletions
  1. 9 0
      doc/ChangeLog
  2. 27 2
      doc/org.texi
  3. 50 0
      lisp/ChangeLog
  4. 6 2
      lisp/org-compat.el
  5. 8 4
      lisp/org-html.el
  6. 47 14
      lisp/org-list.el
  7. 112 7
      lisp/org-publish.el
  8. 38 2
      lisp/org.el

+ 9 - 0
doc/ChangeLog

@@ -1,3 +1,12 @@
+2010-04-23  Carsten Dominik  <carsten.dominik@gmail.com>
+
+	* org.texi (Plain lists): Document the commands to promote/demote
+	an item without affecting children.
+
+2010-04-22  Carsten Dominik  <carsten.dominik@gmail.com>
+
+	* org.texi (Sitemap): Document sitemap sorting.
+
 2010-04-12  Carsten Dominik  <carsten.dominik@gmail.com>
 2010-04-12  Carsten Dominik  <carsten.dominik@gmail.com>
 
 
 	* org.texi (Repeated tasks): Document that the user can determine
 	* org.texi (Repeated tasks): Document that the user can determine

+ 27 - 2
doc/org.texi

@@ -1321,6 +1321,11 @@ similar effect.
 Move the item including subitems up/down (swap with previous/next item
 Move the item including subitems up/down (swap with previous/next item
 of same indentation).  If the list is ordered, renumbering is
 of same indentation).  If the list is ordered, renumbering is
 automatic.
 automatic.
+@kindex M-@key{left}
+@kindex M-@key{right}
+@item M-@key{left}
+@itemx M-@key{right}
+Decrease/increase the indentation of an item, leaving children alone.
 @kindex M-S-@key{left}
 @kindex M-S-@key{left}
 @kindex M-S-@key{right}
 @kindex M-S-@key{right}
 @item M-S-@key{left}
 @item M-S-@key{left}
@@ -10444,7 +10449,7 @@ file is part of any project in @code{org-publish-project-alist}.
 The following properties may be used to control publishing of 
 The following properties may be used to control publishing of 
 a map of files for a given project.
 a map of files for a given project.
 
 
-@multitable @columnfractions 0.25 0.75
+@multitable @columnfractions 0.35 0.65
 @item @code{:auto-sitemap}
 @item @code{:auto-sitemap}
 @tab When non-nil, publish a sitemap during @code{org-publish-current-project}
 @tab When non-nil, publish a sitemap during @code{org-publish-current-project}
 or @code{org-publish-all}.
 or @code{org-publish-all}.
@@ -10460,6 +10465,19 @@ becomes @file{sitemap.html}).
 @tab Plug-in function to use for generation of the sitemap.
 @tab Plug-in function to use for generation of the sitemap.
 Defaults to @code{org-publish-org-sitemap}, which generates a plain list
 Defaults to @code{org-publish-org-sitemap}, which generates a plain list
 of links to all files in the project.
 of links to all files in the project.
+
+@item @code{:sitemap-sort-folders}
+@tab Where folders should appear in the sitemap.  Set this to @code{first}
+(default) or @code{last} to display folders first or last,
+respectively.  Any other value will mix files and folders.
+
+@item @code{:sitemap-alphabetically}
+@tab The site map is normally sorted alphabetically.  Set this explicitly to
+@code{nil} to turn off sorting.
+
+@item @code{:sitemap-ignore-case}
+@tab Should sorting be case-sensitively?  Default @code{nil}.
+
 @end multitable
 @end multitable
 
 
 @node Generating an index,  , Sitemap, Configuration
 @node Generating an index,  , Sitemap, Configuration
@@ -12641,7 +12659,7 @@ also acted as mailing list moderator for some time.
 @item
 @item
 @i{Sebastian Rose} wrote @file{org-info.js}, a Java script for displaying
 @i{Sebastian Rose} wrote @file{org-info.js}, a Java script for displaying
 webpages derived from Org using an Info-like or a folding interface with
 webpages derived from Org using an Info-like or a folding interface with
-single-key navigation.
+single-key navigation, and make lots of improvements to the HTML exporter.
 @item
 @item
 @i{Frank Ruell} solved the mystery of the @code{keymapp nil} bug, a
 @i{Frank Ruell} solved the mystery of the @code{keymapp nil} bug, a
 conflict with @file{allout.el}.
 conflict with @file{allout.el}.
@@ -12680,12 +12698,19 @@ tweaks and features.
 @i{Adam Spiers} asked for global linking commands, inspired the link
 @i{Adam Spiers} asked for global linking commands, inspired the link
 extension system, added support for mairix, and proposed the mapping API.
 extension system, added support for mairix, and proposed the mapping API.
 @item
 @item
+@i{Ulf Stegemann} created the table to translate special symbols to HTML,
+LaTeX, UTF-8, Latin-1 and ASCII.
+@item
 @i{Andy Stewart} contributed code to @file{org-w3m.el}, to copy HTML content
 @i{Andy Stewart} contributed code to @file{org-w3m.el}, to copy HTML content
 with links transformation to Org syntax.
 with links transformation to Org syntax.
 @item
 @item
 @i{David O'Toole} wrote @file{org-publish.el} and drafted the manual
 @i{David O'Toole} wrote @file{org-publish.el} and drafted the manual
 chapter about publishing.
 chapter about publishing.
 @item
 @item
+@i{Stefan Vollmar} organized a video-recorded talk at the
+Max-PLanck-Institute for Neurology.  He also inspired the creation of a
+concept index for HTML export.
+@item
 @i{J@"urgen Vollmer} contributed code generating the table of contents
 @i{J@"urgen Vollmer} contributed code generating the table of contents
 in HTML output.
 in HTML output.
 @item
 @item

+ 50 - 0
lisp/ChangeLog

@@ -1,3 +1,53 @@
+2010-04-23  Carsten Dominik  <carsten.dominik@gmail.com>
+
+	* org.el (org-shiftmetaleft, org-shiftmetaright): Call the subtree
+	indentation commands.
+	(org-hidden-tree-error): New defsubst.
+	(org-metaleft, org-metaright): Check for hidden stuff and throw an
+	error.
+	(org-check-for-hidden): New function.
+
+	* org-list.el (org-item-re): New function.
+	(org-at-item-p): Use `org-item-re'.
+	(org-end-of-item-text-before-children): New function.
+	(org-outdent-item, org-indent-item): Arrange for leaving the
+	subtree alone.
+	(org-outdent-item-tree, org-indent-item-tree): New argument
+	NO-SUBTREE.
+	(org-indent-item-tree): Use `org-end-of-item-text-before-children'
+	to find the end for processing while ignoring the subtree.
+
+	* org-publish.el (org-publish-sitemap-sort-alphabetically)
+	(org-publish-sitemap-sort-folders)
+	(org-publish-sitemap-sort-ignore-case): New options.
+
+2010-04-22  Carsten Dominik  <carsten.dominik@gmail.com>
+
+	* org-publish.el (org-publish-compare-directory-files): Fix sorting.
+
+	* org-compat.el (org-get-x-clipboard-compat): Use (featurep 'xemacs).
+
+	* org-publish.el (org-publish-project-alist): Update docstring.
+	(org-publish-file-title-cache): New variable.
+	(org-publish-initialize-files-alist): Initialize
+	`org-publish-initialize-files-alist' to nil.
+	(org-publish-sort-directory-files): New function.
+	(org-publish-projects): Access the new properties.
+	(org-publish-find-title): Use the file title cache.
+	(org-publish-find-title): Build the file title cache.
+	(org-publish-get-base-files-1): Sort files.
+	(org-publish-aux-preprocess): Do not throw an error when before
+	the first headline.  Allow an empty target, meaning to link just
+	to the file.
+	(org-publish-index-generate-theindex.inc): Check if there is
+	actually a target and only then add it to the link.
+	(org-publish-projects): Fix a remaining issue with the last commit
+
+	* org-html.el (org-export-as-html): Treat verse as open/close
+	paragraph.
+	(org-export-html-close-lists-maybe): Allow to splice raw HTML into
+	and out of lists.
+
 2010-04-21  Carsten Dominik  <carsten.dominik@gmail.com>
 2010-04-21  Carsten Dominik  <carsten.dominik@gmail.com>
 
 
 	* org-src.el (org-edit-src-find-region-and-lang): Test for
 	* org-src.el (org-edit-src-find-region-and-lang): Test for

+ 6 - 2
lisp/org-compat.el

@@ -39,7 +39,10 @@
 (declare-function find-library-name "find-func"  (library))
 (declare-function find-library-name "find-func"  (library))
 (declare-function w32-focus-frame "term/w32-win" (frame))
 (declare-function w32-focus-frame "term/w32-win" (frame))
 
 
-(defconst org-xemacs-p (featurep 'xemacs)) ; not used by org.el itself
+;; The following constant is for backward compatibility.  We do not use
+;; it in org-mode, because the Byte compiler evaluates (featurep 'xemacs)
+;; at compilation time and can therefore optimize code better.
+(defconst org-xemacs-p (featurep 'xemacs))
 (defconst org-format-transports-properties-p
 (defconst org-format-transports-properties-p
   (let ((x "a"))
   (let ((x "a"))
     (add-text-properties 0 1 '(test t) x)
     (add-text-properties 0 1 '(test t) x)
@@ -235,7 +238,8 @@ Works on both Emacs and XEmacs."
 
 
 (defun org-get-x-clipboard-compat (value)
 (defun org-get-x-clipboard-compat (value)
   "Get the clipboard value on XEmacs or Emacs 21"
   "Get the clipboard value on XEmacs or Emacs 21"
-  (cond (org-xemacs-p (org-no-warnings (get-selection-no-error value)))
+  (cond ((featurep 'xemacs)
+	 (org-no-warnings (get-selection-no-error value)))
 	((fboundp 'x-get-selection)
 	((fboundp 'x-get-selection)
 	 (condition-case nil
 	 (condition-case nil
 	     (or (x-get-selection value 'UTF8_STRING)
 	     (or (x-get-selection value 'UTF8_STRING)

+ 8 - 4
lisp/org-html.el

@@ -959,10 +959,12 @@ lang=\"%s\" xml:lang=\"%s\">
 	  (when (equal "ORG-VERSE-START" line)
 	  (when (equal "ORG-VERSE-START" line)
 	    (org-close-par-maybe)
 	    (org-close-par-maybe)
 	    (insert "\n<p class=\"verse\">\n")
 	    (insert "\n<p class=\"verse\">\n")
+	    (setq org-par-open t)
 	    (setq inverse t)
 	    (setq inverse t)
 	    (throw 'nextline nil))
 	    (throw 'nextline nil))
 	  (when (equal "ORG-VERSE-END" line)
 	  (when (equal "ORG-VERSE-END" line)
 	    (insert "</p>\n")
 	    (insert "</p>\n")
+	    (setq org-par-open nil)
 	    (org-open-par)
 	    (org-open-par)
 	    (setq inverse nil)
 	    (setq inverse nil)
 	    (throw 'nextline nil))
 	    (throw 'nextline nil))
@@ -1996,10 +1998,12 @@ If there are links in the string, don't modify these."
 (defvar local-list-indent)
 (defvar local-list-indent)
 (defvar local-list-type)
 (defvar local-list-type)
 (defun org-export-html-close-lists-maybe (line)
 (defun org-export-html-close-lists-maybe (line)
-  (let ((ind (or (get-text-property 0 'original-indentation line)))
+  (let* ((rawhtml (and in-local-list
-;		 (and (string-match "\\S-" line)
+		       (get-text-property 0 'org-protected line)))
-;		      (org-get-indentation line))))
+         (ind (if rawhtml
-	didclose)
+		  (org-get-indentation line)
+		(or (get-text-property 0 'original-indentation line))))
+	 didclose)
     (when ind
     (when ind
       (while (and in-local-list
       (while (and in-local-list
 		  (<= ind (car local-list-indent)))
 		  (<= ind (car local-list-indent)))

+ 47 - 14
lisp/org-list.el

@@ -197,17 +197,25 @@ list, obtained by prompting the user."
 
 
 ;;; Plain list items
 ;;; Plain list items
 
 
+(defun org-item-re (&optional general)
+  "Return the correct regular expression for plain lists.
+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]+\\*\\)\\( \\|$\\)")
+   ((= org-plain-list-ordered-item-terminator ?.)
+    "\\([ \t]*\\([-+]\\|\\([0-9]+\\.\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
+   ((= org-plain-list-ordered-item-terminator ?\))
+    "\\([ \t]*\\([-+]\\|\\([0-9]+)\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
+   (t (error "Invalid value of `org-plain-list-ordered-item-terminator'"))))
+
 (defun org-at-item-p ()
 (defun org-at-item-p ()
   "Is point in a line starting a hand-formatted item?"
   "Is point in a line starting a hand-formatted item?"
-  (let ((llt org-plain-list-ordered-item-terminator))
+
-    (save-excursion
+  (save-excursion
-      (goto-char (point-at-bol))
+    (goto-char (point-at-bol))
-      (looking-at
+    (looking-at (org-item-re))))
-       (cond
-	((eq llt t)  "\\([ \t]*\\([-+]\\|\\([0-9]+[.)]\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
-	((= llt ?.)  "\\([ \t]*\\([-+]\\|\\([0-9]+\\.\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
-	((= llt ?\)) "\\([ \t]*\\([-+]\\|\\([0-9]+)\\)\\)\\|[ \t]+\\*\\)\\( \\|$\\)")
-	(t (error "Invalid value of `org-plain-list-ordered-item-terminator'")))))))
 
 
 (defun org-at-item-bullet-p ()
 (defun org-at-item-bullet-p ()
   "Is point at the bullet of a plain list item?"
   "Is point at the bullet of a plain list item?"
@@ -590,6 +598,16 @@ If the cursor is not in an item, throw an error."
       (goto-char pos)
       (goto-char pos)
       (error "Not in an item"))))
       (error "Not in an item"))))
 
 
+(defun org-end-of-item-text-before-children ()
+  "Move to the end of the item text, stops before the first child if any.
+Assumes that the cursor is in the first ine of an item."
+  (goto-char
+   (min (save-excursion (org-end-of-item) (point))
+	(save-excursion
+	  (goto-char (point-at-eol))
+	  (re-search-forward (concat "^" (org-item-re t)) nil t)
+	  (match-beginning 0)))))
+
 (defun org-next-item ()
 (defun org-next-item ()
   "Move to the beginning of the next item in the current plain list.
   "Move to the beginning of the next item in the current plain list.
 Error if not at a plain list, or if this is the last item in the list."
 Error if not at a plain list, or if this is the last item in the list."
@@ -961,12 +979,24 @@ I.e. to the text after the last item."
 (defvar org-last-indent-end-marker (make-marker))
 (defvar org-last-indent-end-marker (make-marker))
 
 
 (defun org-outdent-item (arg)
 (defun org-outdent-item (arg)
-  "Outdent a local list item."
+  "Outdent a local list item, but not its children."
   (interactive "p")
   (interactive "p")
-  (org-indent-item (- arg)))
+  (org-indent-item-tree (- arg) 'no-subtree))
 
 
 (defun org-indent-item (arg)
 (defun org-indent-item (arg)
-  "Indent a local list item."
+  "Indent a local list item, but not its children."
+  (interactive "p")
+  (org-indent-item-tree arg 'no-subtree))
+
+(defun org-outdent-item-tree (arg &optional no-subtree)
+  "Outdent a local list item including its children.
+If NO-SUBTREE is set, only outdend the item itself, not its children."
+  (interactive "p")
+  (org-indent-item-tree (- arg) no-subtree))
+
+(defun org-indent-item-tree (arg &optional no-subtree)
+  "Indent a local list item including its children.
+If NO-SUBTREE is set, only indent the item itself, not its children."
   (interactive "p")
   (interactive "p")
   (and (org-region-active-p) (org-cursor-to-region-beginning))
   (and (org-region-active-p) (org-cursor-to-region-beginning))
   (unless (org-at-item-p)
   (unless (org-at-item-p)
@@ -975,12 +1005,15 @@ I.e. to the text after the last item."
     (setq firstp (org-first-list-item-p))
     (setq firstp (org-first-list-item-p))
     (save-excursion
     (save-excursion
       (setq end (and (org-region-active-p) (region-end)))
       (setq end (and (org-region-active-p) (region-end)))
-      (if (memq last-command '(org-shiftmetaright org-shiftmetaleft))
+      (if (and (memq last-command '(org-shiftmetaright org-shiftmetaleft))
+	       (memq this-command '(org-shiftmetaright org-shiftmetaleft)))
 	  (setq beg org-last-indent-begin-marker
 	  (setq beg org-last-indent-begin-marker
 		end org-last-indent-end-marker)
 		end org-last-indent-end-marker)
 	(org-beginning-of-item)
 	(org-beginning-of-item)
 	(setq beg (move-marker org-last-indent-begin-marker (point)))
 	(setq beg (move-marker org-last-indent-begin-marker (point)))
-	(org-end-of-item)
+	(if no-subtree
+	    (org-end-of-item-text-before-children)
+	  (org-end-of-item))
 	(setq end (move-marker org-last-indent-end-marker (or end (point)))))
 	(setq end (move-marker org-last-indent-end-marker (or end (point)))))
       (goto-char beg)
       (goto-char beg)
       (setq ind-bul (org-item-indent-positions)
       (setq ind-bul (org-item-indent-positions)

+ 112 - 7
lisp/org-publish.el

@@ -174,7 +174,21 @@ sitemap of files or summary page for a given project.
                          of the titles of the files involved) or
                          of the titles of the files involved) or
                          `tree' (the directory structure of the source
                          `tree' (the directory structure of the source
                          files is reflected in the sitemap).  Defaults to
                          files is reflected in the sitemap).  Defaults to
-                         `tree'."
+                         `tree'.
+
+  If you create a sitemap file, adjust the sorting like this:
+
+  :sitemap-sort-folders    Where folders should appear in the sitemap.
+                           Set this to `first' (default) or `last' to
+                           display folders first or last, respectively.
+                           Any other value will mix files and folders.
+  :sitemap-alphabetically  The site map is normally sorted alphabetically.
+                           Set this explicitly to nil to turn off sorting.
+  :sitemap-ignore-case     Should sorting be case-sensitively?  Default nil.
+
+The following properties control the creation of a concept index.
+
+  :makeindex             Create a concept index."
   :group 'org-publish
   :group 'org-publish
   :type 'alist)
   :type 'alist)
 
 
@@ -208,6 +222,34 @@ Any changes made by this hook will be saved."
   :group 'org-publish
   :group 'org-publish
   :type 'hook)
   :type 'hook)
 
 
+(defcustom org-publish-sitemap-sort-alphabetically t
+  "Should sitemaps be sorted alphabetically by default?
+
+You can overwrite this default per project in your
+`org-publish-project-alist', using `:sitemap-alphabetically'."
+  :group 'org-publish
+  :type 'boolean)
+
+(defcustom org-publish-sitemap-sort-folders 'first
+  "A symbol, denoting if folders are sorted first in sitemaps.
+Possible values are `first', `last', and nil.
+If `first', folders will be sorted before files.
+If `last', folders are sorted to the end after the files.
+Any other value will not mix files and folders.
+
+You can overwrite this default per project in your
+`org-publish-project-alist', using `:sitemap-sort-folders'."
+  :group 'org-publish
+  :type 'symbol)
+
+(defcustom org-publish-sitemap-sort-ignore-case nil
+  "Sort sitemaps case insensitively by default?
+
+You can overwrite this default per project in your
+`org-publish-project-alist', using `:sitemap-ignore-case'."
+  :group 'org-publish
+  :type 'boolean)
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Timestamp-related functions
 ;;; Timestamp-related functions
 
 
@@ -287,11 +329,16 @@ Each element of this alist is of the form:
 (defvar org-publish-temp-files nil
 (defvar org-publish-temp-files nil
   "Temporary list of files to be published.")
   "Temporary list of files to be published.")
 
 
+;; Here, so you find the variable right before it's used the first time:
+(defvar org-publish-file-title-cache nil
+  "List of absolute filenames and titles.")
+
 (defun org-publish-initialize-files-alist (&optional refresh)
 (defun org-publish-initialize-files-alist (&optional refresh)
   "Set `org-publish-files-alist' if it is not set.
   "Set `org-publish-files-alist' if it is not set.
 Also set it if the optional argument REFRESH is non-nil."
 Also set it if the optional argument REFRESH is non-nil."
   (interactive "P")
   (interactive "P")
   (when (or refresh (not org-publish-files-alist))
   (when (or refresh (not org-publish-files-alist))
+    (setq org-publish-file-title-cache nil)
     (setq org-publish-files-alist
     (setq org-publish-files-alist
 	  (org-publish-get-files org-publish-project-alist))))
 	  (org-publish-get-files org-publish-project-alist))))
 
 
@@ -355,6 +402,38 @@ This splices all the components into the list."
 	(push p rtn)))
 	(push p rtn)))
     (nreverse (org-publish-delete-dups (delq nil rtn)))))
     (nreverse (org-publish-delete-dups (delq nil rtn)))))
 
 
+(defun org-publish-compare-directory-files (a b)
+  "Predicate for `sort', that sorts folders-first/last and
+eventually alphabetically."
+  (let ((retval t))
+    (when (or sitemap-alphabetically sitemap-sort-folders)
+      ;; First we sort alphabetically:
+      (when sitemap-alphabetically
+        (let* ((adir (file-directory-p a))
+               (aorg (and (string-match "\\.org$" a) (not adir)))
+               (bdir (file-directory-p b))
+               (borg (and (string-match "\\.org$" b) (not bdir)))
+               (A (if aorg
+                      (concat (file-name-directory a)
+                              (org-publish-find-title a)) a))
+               (B (if borg
+                      (concat (file-name-directory b)
+                              (org-publish-find-title b)) b)))
+          (setq retval (if sitemap-ignore-case
+			   (not (string-lessp (upcase B) (upcase A)))
+			 (not (string-lessp B A))))))
+
+      ;; Directory-wise wins:
+      (when sitemap-sort-folders
+        ;; a is directory, b not:
+        (cond
+         ((and (file-directory-p a) (not (file-directory-p b)))
+          (setq retval (equal sitemap-sort-folders 'first)))
+          ;; a is not a directory, but b is:
+         ((and (not (file-directory-p a)) (file-directory-p b))
+          (setq retval (equal sitemap-sort-folders 'last))))))
+    retval))
+
 (defun org-publish-get-base-files-1 (base-dir &optional recurse match skip-file skip-dir)
 (defun org-publish-get-base-files-1 (base-dir &optional recurse match skip-file skip-dir)
   "Set `org-publish-temp-files' with files from BASE-DIR directory.
   "Set `org-publish-temp-files' with files from BASE-DIR directory.
 If RECURSE is non-nil, check BASE-DIR recursively.  If MATCH is
 If RECURSE is non-nil, check BASE-DIR recursively.  If MATCH is
@@ -374,7 +453,8 @@ matching the regexp SKIP-DIR when recursing through BASE-DIR."
 			  (not (file-exists-p (file-truename f)))
 			  (not (file-exists-p (file-truename f)))
 			  (not (string-match match fnd)))
 			  (not (string-match match fnd)))
 		(pushnew f org-publish-temp-files)))))
 		(pushnew f org-publish-temp-files)))))
-	(directory-files base-dir t (unless recurse match))))
+	(sort (directory-files base-dir t (unless recurse match))
+	      'org-publish-compare-directory-files)))
 
 
 (defun org-publish-get-base-files (project &optional exclude-regexp)
 (defun org-publish-get-base-files (project &optional exclude-regexp)
   "Return a list of all files in PROJECT.
   "Return a list of all files in PROJECT.
@@ -386,9 +466,27 @@ matching filenames."
 	 (include-list (plist-get project-plist :include))
 	 (include-list (plist-get project-plist :include))
 	 (recurse (plist-get project-plist :recursive))
 	 (recurse (plist-get project-plist :recursive))
 	 (extension (or (plist-get project-plist :base-extension) "org"))
 	 (extension (or (plist-get project-plist :base-extension) "org"))
+     ;; sitemap-... variables are dynamically scoped for
+     ;; org-publish-compare-directory-files:
+     (sitemap-sort-folders
+	   (if (plist-member project-plist :sitemap-sort-folders)
+	       (plist-get project-plist :sitemap-sort-folders)
+	     org-publish-sitemap-sort-folders))
+     (sitemap-alphabetically
+      (if (plist-member project-plist :sitemap-alphabetically)
+          (plist-get project-plist :sitemap-alphabetically)
+        org-publish-sitemap-sort-alphabetically))
+	  (sitemap-ignore-case
+       (if (plist-member project-plist :sitemap-ignore-case)
+           (plist-get project-plist :sitemap-ignore-case)
+         org-publish-sitemap-sort-ignore-case))
 	 (match (if (eq extension 'any)
 	 (match (if (eq extension 'any)
                     "^[^\\.]"
                     "^[^\\.]"
 		  (concat "^[^\\.].*\\.\\(" extension "\\)$"))))
 		  (concat "^[^\\.].*\\.\\(" extension "\\)$"))))
+    ;; Make sure sitemap-sort-folders' has an accepted value
+    (unless (memq sitemap-sort-folders '(first last))
+      (setq sitemap-sort-folders nil))
+
     (setq org-publish-temp-files nil)
     (setq org-publish-temp-files nil)
     (org-publish-get-base-files-1 base-dir recurse match
     (org-publish-get-base-files-1 base-dir recurse match
 				  ;; FIXME distinguish exclude regexp
 				  ;; FIXME distinguish exclude regexp
@@ -640,6 +738,8 @@ Default for SITEMAP-FILENAME is 'sitemap.org'."
 
 
 (defun org-publish-find-title (file)
 (defun org-publish-find-title (file)
   "Find the title of file in project."
   "Find the title of file in project."
+  (if (member file org-publish-file-title-cache)
+      (cadr (member file org-publish-file-title-cache))
   (let* ((visiting (find-buffer-visiting file))
   (let* ((visiting (find-buffer-visiting file))
 	 (buffer (or visiting (find-file-noselect file)))
 	 (buffer (or visiting (find-file-noselect file)))
 	 title)
 	 title)
@@ -654,7 +754,9 @@ Default for SITEMAP-FILENAME is 'sitemap.org'."
 		  (file-name-nondirectory (file-name-sans-extension file))))))
 		  (file-name-nondirectory (file-name-sans-extension file))))))
     (unless visiting
     (unless visiting
       (kill-buffer buffer))
       (kill-buffer buffer))
-    title))
+    (setq org-publish-file-title-cache
+          (append org-publish-file-title-cache (list file title)))
+    title)))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Interactive publishing functions
 ;;; Interactive publishing functions
@@ -736,11 +838,11 @@ the project."
       (when (eq backend 'latex)
       (when (eq backend 'latex)
 	(replace-match (format "\\index{%s}" entry) t t))
 	(replace-match (format "\\index{%s}" entry) t t))
       (save-excursion
       (save-excursion
-	(org-back-to-heading t)
+	(ignore-errors (org-back-to-heading t))
 	(setq target (get-text-property (point) 'target))
 	(setq target (get-text-property (point) 'target))
 	(setq target (or (cdr (assoc target org-export-preferred-target-alist))
 	(setq target (or (cdr (assoc target org-export-preferred-target-alist))
 			 (cdr (assoc target org-export-id-target-alist))
 			 (cdr (assoc target org-export-id-target-alist))
-			 target))
+			 target ""))
 	(push (cons entry target) index)))
 	(push (cons entry target) index)))
     (with-temp-file
     (with-temp-file
 	(concat (file-name-sans-extension org-current-export-file) ".orgx")
 	(concat (file-name-sans-extension org-current-export-file) ".orgx")
@@ -760,7 +862,7 @@ the project."
 			full-files))
 			full-files))
 	 (default-directory directory)
 	 (default-directory directory)
 	 index origfile buf target entry ibuffer
 	 index origfile buf target entry ibuffer
-	 main last-main letter last-letter file sub link)
+	 main last-main letter last-letter file sub link tgext)
     ;; `files' contains the list of relative file names
     ;; `files' contains the list of relative file names
     (dolist (file files)
     (dolist (file files)
       (setq origfile (substring file 0 -1))
       (setq origfile (substring file 0 -1))
@@ -781,6 +883,9 @@ the project."
       (setq last-letter nil)
       (setq last-letter nil)
       (dolist (idx index)
       (dolist (idx index)
 	(setq entry (car idx) file (nth 1 idx) target (nth 2 idx))
 	(setq entry (car idx) file (nth 1 idx) target (nth 2 idx))
+	(if (and (stringp target) (string-match "\\S-" target))
+	    (setq tgext (concat "::#" target))
+	  (setq tgext ""))
 	(setq letter (upcase (substring entry 0 1)))
 	(setq letter (upcase (substring entry 0 1)))
 	(when (not (equal letter last-letter))
 	(when (not (equal letter last-letter))
 	  (insert "** " letter "\n")
 	  (insert "** " letter "\n")
@@ -792,7 +897,7 @@ the project."
 	(when (and main (not (equal main last-main)))
 	(when (and main (not (equal main last-main)))
 	  (insert "   - " main "\n")
 	  (insert "   - " main "\n")
 	  (setq last-main main))
 	  (setq last-main main))
-	(setq link (concat "[[file:" file "::#" target "]"
+	(setq link (concat "[[file:" file tgext "]"
 			   "[" (or sub entry) "]]"))
 			   "[" (or sub entry) "]]"))
 	(if (and main sub)
 	(if (and main sub)
 	    (insert "     - " link "\n")
 	    (insert "     - " link "\n")

+ 38 - 2
lisp/org.el

@@ -15970,7 +15970,7 @@ See the individual commands for more information."
    ((run-hook-with-args-until-success 'org-shiftmetaleft-hook))
    ((run-hook-with-args-until-success 'org-shiftmetaleft-hook))
    ((org-at-table-p) (call-interactively 'org-table-delete-column))
    ((org-at-table-p) (call-interactively 'org-table-delete-column))
    ((org-on-heading-p) (call-interactively 'org-promote-subtree))
    ((org-on-heading-p) (call-interactively 'org-promote-subtree))
-   ((org-at-item-p) (call-interactively 'org-outdent-item))
+   ((org-at-item-p) (call-interactively 'org-outdent-item-tree))
    (t (org-modifier-cursor-error))))
    (t (org-modifier-cursor-error))))
 
 
 (defun org-shiftmetaright ()
 (defun org-shiftmetaright ()
@@ -15983,7 +15983,7 @@ See the individual commands for more information."
    ((run-hook-with-args-until-success 'org-shiftmetaright-hook))
    ((run-hook-with-args-until-success 'org-shiftmetaright-hook))
    ((org-at-table-p) (call-interactively 'org-table-insert-column))
    ((org-at-table-p) (call-interactively 'org-table-insert-column))
    ((org-on-heading-p) (call-interactively 'org-demote-subtree))
    ((org-on-heading-p) (call-interactively 'org-demote-subtree))
-   ((org-at-item-p) (call-interactively 'org-indent-item))
+   ((org-at-item-p) (call-interactively 'org-indent-item-tree))
    (t (org-modifier-cursor-error))))
    (t (org-modifier-cursor-error))))
 
 
 (defun org-shiftmetaup (&optional arg)
 (defun org-shiftmetaup (&optional arg)
@@ -16012,6 +16012,10 @@ commands for more information."
    ((org-at-item-p) (call-interactively 'org-move-item-down))
    ((org-at-item-p) (call-interactively 'org-move-item-down))
    (t (org-modifier-cursor-error))))
    (t (org-modifier-cursor-error))))
 
 
+(defsubst org-hidden-tree-error ()
+  (error
+   "Hidden subtree, open with TAB or use subtree command M-S-<left>/<right>"))
+
 (defun org-metaleft (&optional arg)
 (defun org-metaleft (&optional arg)
   "Promote heading or move table column to left.
   "Promote heading or move table column to left.
 Calls `org-do-promote' or `org-table-move-column', depending on context.
 Calls `org-do-promote' or `org-table-move-column', depending on context.
@@ -16026,12 +16030,14 @@ See the individual commands for more information."
 	     (save-excursion
 	     (save-excursion
 	       (goto-char (region-beginning))
 	       (goto-char (region-beginning))
 	       (org-on-heading-p))))
 	       (org-on-heading-p))))
+    (when (org-check-for-hidden 'headlines) (org-hidden-tree-error))
     (call-interactively 'org-do-promote))
     (call-interactively 'org-do-promote))
    ((or (org-at-item-p)
    ((or (org-at-item-p)
 	(and (org-region-active-p)
 	(and (org-region-active-p)
 	     (save-excursion
 	     (save-excursion
 	       (goto-char (region-beginning))
 	       (goto-char (region-beginning))
 	       (org-at-item-p))))
 	       (org-at-item-p))))
+    (when (org-check-for-hidden 'items) (org-hidden-tree-error))
     (call-interactively 'org-outdent-item))
     (call-interactively 'org-outdent-item))
    (t (call-interactively 'backward-word))))
    (t (call-interactively 'backward-word))))
 
 
@@ -16049,15 +16055,45 @@ See the individual commands for more information."
 	     (save-excursion
 	     (save-excursion
 	       (goto-char (region-beginning))
 	       (goto-char (region-beginning))
 	       (org-on-heading-p))))
 	       (org-on-heading-p))))
+    (when (org-check-for-hidden 'headlines) (org-hidden-tree-error))
     (call-interactively 'org-do-demote))
     (call-interactively 'org-do-demote))
    ((or (org-at-item-p)
    ((or (org-at-item-p)
 	(and (org-region-active-p)
 	(and (org-region-active-p)
 	     (save-excursion
 	     (save-excursion
 	       (goto-char (region-beginning))
 	       (goto-char (region-beginning))
 	       (org-at-item-p))))
 	       (org-at-item-p))))
+    (when (org-check-for-hidden 'items) (org-hidden-tree-error))
     (call-interactively 'org-indent-item))
     (call-interactively 'org-indent-item))
    (t (call-interactively 'forward-word))))
    (t (call-interactively 'forward-word))))
 
 
+(defun org-check-for-hidden (what)
+  "Check if there are hidden headlines/items in the current visual line.
+WHAT can be either `headlines' or `items'.  If the current line is
+an outline or item heading and it has a folded subtree below it,
+this fucntion returns t, nil otherwise."
+  (let ((re (cond
+	     ((eq what 'headlines) (concat "^" org-outline-regexp))
+	     ((eq what 'items) (concat "^" (org-item-re t)))
+	     (t (error "This should not happen"))))
+	beg end)
+    (save-excursion
+      (catch 'exit
+	(if (org-region-active-p)
+	    (setq beg (region-beginning) end (region-end))
+	  (setq beg (point-at-bol))
+	  (beginning-of-line 2)
+	  (while (and (not (eobp)) ;; this is like `next-line'
+		      (get-char-property (1- (point)) 'invisible))
+	    (beginning-of-line 2))
+	  (setq end (point)))
+	(goto-char beg)
+	(goto-char (point-at-eol))
+	(setq end (max end (point)))
+	(while (re-search-forward re end t)
+	  (if (get-char-property (match-beginning 0) 'invisible)
+	      (throw 'exit t)))
+	nil))))
+
 (defun org-metaup (&optional arg)
 (defun org-metaup (&optional arg)
   "Move subtree up or move table row up.
   "Move subtree up or move table row up.
 Calls `org-move-subtree-up' or `org-table-move-row' or
 Calls `org-move-subtree-up' or `org-table-move-row' or