Browse Source

ox-ascii/ox-latex/ox-html: Make use of optional title in toc

* lisp/ox-ascii.el (org-ascii--build-title): Add an argument.  Use
  optional title when building a toc line.
(org-ascii--build-toc): Call `org-ascii--build-title' with appropriate
arguments.
* lisp/ox-latex.el (org-latex-headline): Use optional title for table
  of contents.
* lisp/ox-html.el (org-html--toc-text): Renamed from
  `org-html-toc-text'.  Add docstring.
(org-html--format-toc-headline): Renamed from
`org-html-format-toc-headline'.  Add docstring.  Use optional title if
possible.
(org-html-toc): Add docstring.
Nicolas Goaziou 12 years ago
parent
commit
d790fbd489
3 changed files with 149 additions and 153 deletions
  1. 14 6
      lisp/ox-ascii.el
  2. 44 27
      lisp/ox-html.el
  3. 91 120
      lisp/ox-latex.el

+ 14 - 6
lisp/ox-ascii.el

@@ -536,7 +536,7 @@ INFO is a plist used as a communication channel."
 			   (org-list-get-bullet beg-item struct)))))))))))))
 
 (defun org-ascii--build-title
-  (element info text-width &optional underline notags)
+  (element info text-width &optional underline notags toc)
   "Format ELEMENT title and return it.
 
 ELEMENT is either an `headline' or `inlinetask' element.  INFO is
@@ -547,8 +547,11 @@ When optional argument UNDERLINE is non-nil, underline title,
 without the tags, according to `org-ascii-underline'
 specifications.
 
-if optional argument NOTAGS is nil, no tags will be added to the
-title."
+If optional argument NOTAGS is non-nil, no tags will be added to
+the title.
+
+When optional argument TOC is non-nil, use optional title if
+possible."
   (let* ((headlinep (eq (org-element-type element) 'headline))
 	 (numbers
 	  ;; Numbering is specific to headlines.
@@ -559,8 +562,11 @@ title."
 		 'number-to-string
 		 (org-export-get-headline-number element info) ".")
 		" ")))
-	 (text (org-trim
-		(org-export-data (org-element-property :title element) info)))
+	 (text
+	  (org-trim
+	   (org-export-data
+	    (or (and toc headlinep (org-export-get-optional-title element info))
+		(org-element-property :title element)) info)))
 	 (todo
 	  (and (plist-get info :with-todo-keywords)
 	       (let ((todo (org-element-property :todo-keyword element)))
@@ -652,7 +658,9 @@ which the table of contents generation has been initiated."
 	     (unless (zerop indent) (concat (make-string (1- indent) ?.) " "))
 	     (org-ascii--build-title
 	      headline info (- text-width indent) nil
-	      (eq (plist-get info :with-tags) 'not-in-toc)))))
+	      (or (not (plist-get info :with-tags))
+		  (eq (plist-get info :with-tags) 'not-in-toc))
+	      'toc))))
 	(org-export-collect-headlines info n) "\n")))))
 
 (defun org-ascii--list-listings (keyword info)

+ 44 - 27
lisp/ox-html.el

@@ -1116,7 +1116,10 @@ produce code that uses these same face definitions."
   "Build a string by concatenating N times STRING."
   (let (out) (dotimes (i n out) (setq out (concat string out)))))
 
-(defun org-html-toc-text (toc-entries)
+(defun org-html--toc-text (toc-entries)
+  "Return innards of a table of contents, as a string.
+TOC-ENTRIES is an alist where key is a headline title, as
+a string, and value is its relative level, as an integer."
   (let* ((prev-level (1- (nth 1 (car toc-entries))))
 	 (start-level prev-level))
     (concat
@@ -1138,36 +1141,50 @@ produce code that uses these same face definitions."
       toc-entries "")
      (org-html--make-string (- prev-level start-level) "</li>\n</ul>\n"))))
 
-(defun* org-html-format-toc-headline
-    (todo todo-type priority text tags
-	  &key level section-number headline-label &allow-other-keys)
-  (let ((headline (concat
-		   section-number (and section-number ". ")
-		   text
-		   (and tags "&nbsp;&nbsp;&nbsp;") (org-html--tags tags))))
+(defun org-html--format-toc-headline (headline info)
+  "Return an appropriate table of contents entry for HEADLINE.
+INFO is a plist used as a communication channel."
+  (let* ((headline-number (org-export-get-headline-number headline info))
+	 (section-number
+	  (and (not (org-export-low-level-p headline info))
+	       (org-export-numbered-headline-p headline info)
+	       (concat (mapconcat 'number-to-string headline-number ".") ". ")))
+	 (tags (and (eq (plist-get info :with-tags) t)
+		    (org-export-get-tags headline info))))
     (format "<a href=\"#%s\">%s</a>"
-	    (org-export-solidify-link-text headline-label)
-	    (if (not nil) headline
-	      (format "<span class=\"%s\">%s</span>" todo-type headline)))))
+	    ;; Label.
+	    (org-export-solidify-link-text
+	     (or (org-element-property :CUSTOM_ID headline)
+		 (concat "sec-" (mapconcat 'number-to-string
+					   headline-number "-"))))
+	    ;; Body.
+	    (concat section-number
+		    (org-export-data
+		     (or (org-export-get-optional-title headline info)
+			 (org-element-property :title headline))
+		     info)
+		    (and tags "&nbsp;&nbsp;&nbsp;") (org-html--tags tags)))))
 
 (defun org-html-toc (depth info)
-  (let* ((headlines (org-export-collect-headlines info depth))
-	 (toc-entries
-	  (loop for headline in headlines collect
-		(list (org-html-format-headline--wrap
-		       headline info 'org-html-format-toc-headline)
-		      (org-export-get-relative-level headline info)))))
+  "Build table of contents.
+DEPTH is an integer specifying the depth of the table. INFO is
+a plist used as a communication channel.  Return nil if table of
+contents is empty."
+  (let ((toc-entries
+	 (mapcar (lambda (headline)
+		   (list (org-html--format-toc-headline headline info)
+			 (org-export-get-relative-level headline info)))
+		 (org-export-collect-headlines info depth))))
     (when toc-entries
-      (concat
-       "<div id=\"table-of-contents\">\n"
-       (format "<h%d>%s</h%d>\n"
-	       org-html-toplevel-hlevel
-	       (org-html--translate "Table of Contents" info)
-	       org-html-toplevel-hlevel)
-       "<div id=\"text-table-of-contents\">"
-       (org-html-toc-text toc-entries)
-       "</div>\n"
-       "</div>\n"))))
+      (concat "<div id=\"table-of-contents\">\n"
+	      (format "<h%d>%s</h%d>\n"
+		      org-html-toplevel-hlevel
+		      (org-html--translate "Table of Contents" info)
+		      org-html-toplevel-hlevel)
+	      "<div id=\"text-table-of-contents\">"
+	      (org-html--toc-text toc-entries)
+	      "</div>\n"
+	      "</div>\n"))))
 
 (defun org-html-fix-class-name (kwd) 	; audit callers of this function
   "Turn todo keyword into a valid class name.

+ 91 - 120
lisp/ox-latex.el

@@ -1406,126 +1406,97 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
   "Transcode a HEADLINE element from Org to LaTeX.
 CONTENTS holds the contents of the headline.  INFO is a plist
 holding contextual information."
-  (let* ((class (plist-get info :latex-class))
-	 (level (org-export-get-relative-level headline info))
-	 (numberedp (org-export-numbered-headline-p headline info))
-	 (class-sectionning (assoc class org-latex-classes))
-	 ;; Section formatting will set two placeholders: one for the
-	 ;; title and the other for the contents.
-	 (section-fmt
-	  (let ((sec (if (functionp (nth 2 class-sectionning))
-			 (funcall (nth 2 class-sectionning) level numberedp)
-		       (nth (1+ level) class-sectionning))))
-	    (cond
-	     ;; No section available for that LEVEL.
-	     ((not sec) nil)
-	     ;; Section format directly returned by a function.  Add
-	     ;; placeholder for contents.
-	     ((stringp sec) (concat sec "\n%s"))
-	     ;; (numbered-section . unnumbered-section)
-	     ((not (consp (cdr sec)))
-	      (concat (funcall (if numberedp #'car #'cdr) sec) "\n%s"))
-	     ;; (numbered-open numbered-close)
-	     ((= (length sec) 2)
-	      (when numberedp (concat (car sec) "\n%s" (nth 1 sec))))
-	     ;; (num-in num-out no-num-in no-num-out)
-	     ((= (length sec) 4)
-	      (if numberedp (concat (car sec) "\n%s" (nth 1 sec))
-		(concat (nth 2 sec) "\n%s" (nth 3 sec)))))))
-	 (text (org-export-data (org-element-property :title headline) info))
-	 (todo
-	  (and (plist-get info :with-todo-keywords)
-	       (let ((todo (org-element-property :todo-keyword headline)))
-		 (and todo (org-export-data todo info)))))
-	 (todo-type (and todo (org-element-property :todo-type headline)))
-	 (tags (and (plist-get info :with-tags)
-		    (org-export-get-tags headline info)))
-	 (priority (and (plist-get info :with-priority)
-			(org-element-property :priority headline)))
-	 ;; Create the headline text along with a no-tag version.  The
-	 ;; latter is required to remove tags from table of contents.
-	 (full-text (if (functionp org-latex-format-headline-function)
-			;; User-defined formatting function.
-			(funcall org-latex-format-headline-function
-				 todo todo-type priority text tags)
-		      ;; Default formatting.
-		      (concat
-		       (when todo
-			 (format "\\textbf{\\textsf{\\textsc{%s}}} " todo))
-		       (when priority (format "\\framebox{\\#%c} " priority))
-		       text
-		       (when tags
-			 (format "\\hfill{}\\textsc{:%s:}"
-				 (mapconcat 'identity tags ":"))))))
-	 (full-text-no-tag
-	  (if (functionp org-latex-format-headline-function)
-	      ;; User-defined formatting function.
-	      (funcall org-latex-format-headline-function
-		       todo todo-type priority text nil)
-	    ;; Default formatting.
-	    (concat
-	     (when todo (format "\\textbf{\\textsf{\\textsc{%s}}} " todo))
-	     (when priority (format "\\framebox{\\#%c} " priority))
-	     text)))
-	 ;; Associate some \label to the headline for internal links.
-	 (headline-label
-	  (format "\\label{sec-%s}\n"
-		  (mapconcat 'number-to-string
-			     (org-export-get-headline-number headline info)
-			     "-")))
-	 (pre-blanks
-	  (make-string (org-element-property :pre-blank headline) 10)))
-    (cond
-     ;; Case 1: This is a footnote section: ignore it.
-     ((org-element-property :footnote-section-p headline) nil)
-     ;; Case 2. This is a deep sub-tree: export it as a list item.
-     ;;         Also export as items headlines for which no section
-     ;;         format has been found.
-     ((or (not section-fmt) (org-export-low-level-p headline info))
-      ;; Build the real contents of the sub-tree.
-      (let ((low-level-body
-	     (concat
-	      ;; If the headline is the first sibling, start a list.
-	      (when (org-export-first-sibling-p headline info)
-		(format "\\begin{%s}\n" (if numberedp 'enumerate 'itemize)))
-	      ;; Itemize headline
-	      "\\item " full-text "\n" headline-label pre-blanks contents)))
-	;; If headline is not the last sibling simply return
-	;; LOW-LEVEL-BODY.  Otherwise, also close the list, before any
-	;; blank line.
-	(if (not (org-export-last-sibling-p headline info)) low-level-body
-	  (replace-regexp-in-string
-	   "[ \t\n]*\\'"
-	   (format "\n\\\\end{%s}" (if numberedp 'enumerate 'itemize))
-	   low-level-body))))
-     ;; Case 3. Standard headline.  Export it as a section.
-     (t
-      (cond
-       ((not (and tags (eq (plist-get info :with-tags) 'not-in-toc)))
-	;; Regular section.  Use specified format string.
-	(format section-fmt full-text
-		(concat headline-label pre-blanks contents)))
-       ((string-match "\\`\\\\\\(.*?\\){" section-fmt)
-	;; If tags should be removed from table of contents, insert
-	;; title without tags as an alternative heading in sectioning
-	;; command.
-	(format (replace-match (concat (match-string 1 section-fmt) "[%s]")
-			       nil nil section-fmt 1)
-		;; Replace square brackets with parenthesis since
-		;; square brackets are not supported in optional
-		;; arguments.
-		(replace-regexp-in-string
-		 "\\[" "("
-		 (replace-regexp-in-string
-		  "\\]" ")"
-		  full-text-no-tag))
-		full-text
-		(concat headline-label pre-blanks contents)))
-       (t
-	;; Impossible to add an alternative heading.  Fallback to
-	;; regular sectioning format string.
-	(format section-fmt full-text
-		(concat headline-label pre-blanks contents))))))))
+  (unless (org-element-property :footnote-section-p headline)
+    (let* ((class (plist-get info :latex-class))
+	   (level (org-export-get-relative-level headline info))
+	   (numberedp (org-export-numbered-headline-p headline info))
+	   (class-sectionning (assoc class org-latex-classes))
+	   ;; Section formatting will set two placeholders: one for
+	   ;; the title and the other for the contents.
+	   (section-fmt
+	    (let ((sec (if (functionp (nth 2 class-sectionning))
+			   (funcall (nth 2 class-sectionning) level numberedp)
+			 (nth (1+ level) class-sectionning))))
+	      (cond
+	       ;; No section available for that LEVEL.
+	       ((not sec) nil)
+	       ;; Section format directly returned by a function.  Add
+	       ;; placeholder for contents.
+	       ((stringp sec) (concat sec "\n%s"))
+	       ;; (numbered-section . unnumbered-section)
+	       ((not (consp (cdr sec)))
+		(concat (funcall (if numberedp #'car #'cdr) sec) "\n%s"))
+	       ;; (numbered-open numbered-close)
+	       ((= (length sec) 2)
+		(when numberedp (concat (car sec) "\n%s" (nth 1 sec))))
+	       ;; (num-in num-out no-num-in no-num-out)
+	       ((= (length sec) 4)
+		(if numberedp (concat (car sec) "\n%s" (nth 1 sec))
+		  (concat (nth 2 sec) "\n%s" (nth 3 sec)))))))
+	   (text (org-export-data (org-element-property :title headline) info))
+	   (todo
+	    (and (plist-get info :with-todo-keywords)
+		 (let ((todo (org-element-property :todo-keyword headline)))
+		   (and todo (org-export-data todo info)))))
+	   (todo-type (and todo (org-element-property :todo-type headline)))
+	   (tags (and (plist-get info :with-tags)
+		      (org-export-get-tags headline info)))
+	   (priority (and (plist-get info :with-priority)
+			  (org-element-property :priority headline)))
+	   ;; Create the headline text along with a no-tag version.
+	   ;; The latter is required to remove tags from toc.
+	   (full-text (funcall org-latex-format-headline-function
+			       todo todo-type priority text tags))
+	   ;; Associate \label to the headline for internal links.
+	   (headline-label
+	    (format "\\label{sec-%s}\n"
+		    (mapconcat 'number-to-string
+			       (org-export-get-headline-number headline info)
+			       "-")))
+	   (pre-blanks
+	    (make-string (org-element-property :pre-blank headline) 10)))
+      (if (or (not section-fmt) (org-export-low-level-p headline info))
+	  ;; This is a deep sub-tree: export it as a list item.  Also
+	  ;; export as items headlines for which no section format has
+	  ;; been found.
+	  (let ((low-level-body
+		 (concat
+		  ;; If headline is the first sibling, start a list.
+		  (when (org-export-first-sibling-p headline info)
+		    (format "\\begin{%s}\n" (if numberedp 'enumerate 'itemize)))
+		  ;; Itemize headline
+		  "\\item " full-text "\n" headline-label pre-blanks contents)))
+	    ;; If headline is not the last sibling simply return
+	    ;; LOW-LEVEL-BODY.  Otherwise, also close the list, before
+	    ;; any blank line.
+	    (if (not (org-export-last-sibling-p headline info)) low-level-body
+	      (replace-regexp-in-string
+	       "[ \t\n]*\\'"
+	       (format "\n\\\\end{%s}" (if numberedp 'enumerate 'itemize))
+	       low-level-body)))
+	;; This is a standard headline.  Export it as a section.  Add
+	;; an alternative heading when possible.
+	(let ((opt-title
+	       (funcall org-latex-format-headline-function
+			todo todo-type priority
+			(org-export-data
+			 (or (org-export-get-optional-title headline info)
+			     (org-element-property :title headline))
+			 info)
+			(and (eq (plist-get info :with-tags) t) tags))))
+	  (if (and opt-title (string-match "\\`\\\\\\(.*?\\){" section-fmt))
+	      (format (replace-match "\\1[%s]" nil nil section-fmt 1)
+		      ;; Replace square brackets with parenthesis
+		      ;; since square brackets are not supported in
+		      ;; optional arguments.
+		      (replace-regexp-in-string
+		       "\\[" "(" (replace-regexp-in-string "\\]" ")" opt-title))
+		      full-text
+		      (concat headline-label pre-blanks contents))
+	    ;; Impossible to add an alternative heading.  Fallback to
+	    ;; regular sectioning format string.
+	    (format section-fmt full-text
+		    (concat headline-label pre-blanks contents))))))))
 
 (defun org-latex-format-headline-default-function
   (todo todo-type priority text tags)