瀏覽代碼

ox: Add #+SUBTITLE property in some backends

* ox-texinfo.el (texinfo, org-texinfo-template): Parse subtitle.
* ox-s5.el (org-s5-title-slide-template):
* ox-deck.el (org-deck-title-slide-template):
* ox-odt.el (odt, org-odt-template):
* ox-latex.el (latex, org-latex-template):
* ox-html.el (html, org-html-format-spec, org-html-template):
* ox-ascii.el (ascii, org-ascii-template--document-title):
* ox-beamer.el (beamer, org-beamer-template): Support #+SUBTITLE.
* ox-html.el (org-html-postamble-format)
(org-html-preamble-format):
* ox-latex.el (org-latex-title-command)
(org-latex-hyperref-template): Update docstring.
* ox-html.el (org-html-style-default): New .subtitle css property.
* ox-beamer.el (org-beamer-subtitle-format):
* ox-latex.el (org-latex-subtitle-format)
(org-latex-subtitle-separate): New variable.
* org.texi (ASCII/Latin-1/UTF-8 export)
(Beamer specific export settings)
(HTML Specific export settings)
(@LaTeX{} specific export settings, CSS support)
(ODT specific export settings)
(Texinfo specific export settings, Document preamble)
(Publishing options, Publishing options): Document #+SUBTITLE.

The patch adds a #+SUBTITLE keyword to ox-ascii, ox-latex, ox-html and
ox-odt.
Rasmus 10 年之前
父節點
當前提交
a780080fcf
共有 10 個文件被更改,包括 175 次插入23 次删除
  1. 7 0
      contrib/lisp/ox-deck.el
  2. 7 0
      contrib/lisp/ox-s5.el
  3. 43 2
      doc/org.texi
  4. 3 0
      etc/ORG-NEWS
  5. 13 5
      lisp/ox-ascii.el
  6. 18 1
      lisp/ox-beamer.el
  7. 25 5
      lisp/ox-html.el
  8. 35 4
      lisp/ox-latex.el
  9. 20 2
      lisp/ox-odt.el
  10. 4 4
      lisp/ox-texinfo.el

+ 7 - 0
contrib/lisp/ox-deck.el

@@ -38,6 +38,12 @@
 ;; See ox.el and ox-html.el for more details on how this exporter
 ;; See ox.el and ox-html.el for more details on how this exporter
 ;; works (it is derived from ox-html.)
 ;; works (it is derived from ox-html.)
 
 
+;; TODOs
+;; ------
+;; The title page is formatted using format-spec.  This is error prone
+;; when details are missing and may insert empty tags, like <h2></h2>,
+;; for missing values.
+
 (require 'ox-html)
 (require 'ox-html)
 (eval-when-compile (require 'cl))
 (eval-when-compile (require 'cl))
 
 
@@ -261,6 +267,7 @@ Defaults to styles for the title page."
 
 
 (defcustom org-deck-title-slide-template
 (defcustom org-deck-title-slide-template
   "<h1>%t</h1>
   "<h1>%t</h1>
+<h2>%s</h2>
 <h2>%a</h2>
 <h2>%a</h2>
 <h2>%e</h2>
 <h2>%e</h2>
 <h2>%d</h2>"
 <h2>%d</h2>"

+ 7 - 0
contrib/lisp/ox-s5.el

@@ -48,6 +48,12 @@
 ;; in an Org mode buffer.  See ox.el and ox-html.el for more details
 ;; in an Org mode buffer.  See ox.el and ox-html.el for more details
 ;; on how this exporter works.
 ;; on how this exporter works.
 
 
+;; TODOs
+;; ------
+;; The title page is formatted using format-spec.  This is error prone
+;; when details are missing and may insert empty tags, like <h2></h2>,
+;; for missing values.
+
 (require 'ox-html)
 (require 'ox-html)
 (eval-when-compile (require 'cl))
 (eval-when-compile (require 'cl))
 
 
@@ -174,6 +180,7 @@ or an empty string."
 
 
 (defcustom org-s5-title-slide-template
 (defcustom org-s5-title-slide-template
   "<h1>%t</h1>
   "<h1>%t</h1>
+<h2>%s</h2>
 <h2>%a</h2>
 <h2>%a</h2>
 <h3>%e</h3>
 <h3>%e</h3>
 <h4>%d</h4>"
 <h4>%d</h4>"

+ 43 - 2
doc/org.texi

@@ -10926,6 +10926,17 @@ When the original file is @file{myfile.txt}, the resulting file becomes
 Export to a temporary buffer.  Do not create a file.
 Export to a temporary buffer.  Do not create a file.
 @end table
 @end table
 
 
+@subheading ASCII specific export settings
+
+ASCII export introduces a single of keywords, similar to the general options
+settings described in @ref{Export settings}.
+
+@table @samp
+@item SUBTITLE
+@cindex #+SUBTITLE (ASCII)
+The document subtitle.
+@end table
+
 @subheading Header and sectioning structure
 @subheading Header and sectioning structure
 
 
 In the exported version, the first three outline levels become headlines,
 In the exported version, the first three outline levels become headlines,
@@ -11063,6 +11074,14 @@ inserted as metadata using @samp{hyperref}.  Document metadata can be
 configured via @code{org-latex-hyperref-template}.  Description can also be
 configured via @code{org-latex-hyperref-template}.  Description can also be
 typeset as part of the front matter via @code{org-latex-title-command}.  You
 typeset as part of the front matter via @code{org-latex-title-command}.  You
 can use several @code{#+KEYWORDS} if the description is is long.
 can use several @code{#+KEYWORDS} if the description is is long.
+
+@item SUBTITLE
+@cindex #+SUBTITLE (Beamer)
+@vindex org-beamer-subtitle-format
+The document subtitle.  This is typeset using the format string
+@code{org-beamer-subtitle-format}.  It can also access via
+@code{org-latex-hyperref-template} or typeset as part of the front
+matter via @code{org-latex-title-command}.
 @end table
 @end table
 
 
 @node Sectioning Frames and Blocks in Beamer
 @node Sectioning Frames and Blocks in Beamer
@@ -11352,6 +11371,11 @@ is long.
 @cindex #+LATEX_HEADER (HTML)
 @cindex #+LATEX_HEADER (HTML)
 Arbitrary lines appended to the preamble used when transcoding @LaTeX{}
 Arbitrary lines appended to the preamble used when transcoding @LaTeX{}
 fragments to images.  See @ref{Math formatting in HTML export} for details.
 fragments to images.  See @ref{Math formatting in HTML export} for details.
+
+@item SUBTITLE
+@cindex #+SUBTILE (HTML)
+The document subtitle.  The formatting depends on whether HTML5 in used
+and on the @samp{subtitle} CSS class.
 @end table
 @end table
 
 
 These keywords are treated in details in the following sections.
 These keywords are treated in details in the following sections.
@@ -11700,6 +11724,7 @@ p.author            @r{author information, including email}
 p.date              @r{publishing date}
 p.date              @r{publishing date}
 p.creator           @r{creator info, about org mode version}
 p.creator           @r{creator info, about org mode version}
 .title              @r{document title}
 .title              @r{document title}
+.subtitle           @r{document subtitle}
 .todo               @r{TODO keywords, all not-done states}
 .todo               @r{TODO keywords, all not-done states}
 .done               @r{the DONE keywords, all states that count as done}
 .done               @r{the DONE keywords, all states that count as done}
 .WAITING            @r{each TODO keyword also uses a class named after itself}
 .WAITING            @r{each TODO keyword also uses a class named after itself}
@@ -11921,6 +11946,16 @@ inserted as metadata using @samp{hyperref}.  Document metadata can be
 configured via @code{org-latex-hyperref-template}.  Description can also be
 configured via @code{org-latex-hyperref-template}.  Description can also be
 typeset as part of the front matter via @code{org-latex-title-command}.  You
 typeset as part of the front matter via @code{org-latex-title-command}.  You
 can use several @code{#+KEYWORDS} if the description is is long.
 can use several @code{#+KEYWORDS} if the description is is long.
+
+@item SUBTITLE
+@cindex #+SUBTITLE (@LaTeX{})
+@vindex org-latex-subtitle-separate
+@vindex org-latex-subtitle-format
+The document subtitle.  This is typeset according to
+@code{org-latex-subtitle-format}.  If @code{org-latex-subtitle-separate}
+is non-@code{nil} it is typed as part of the @samp{\title}-macro.  It
+can also access via @code{org-latex-hyperref-template} or typeset as
+part of the front matter via @code{org-latex-title-command}.
 @end table
 @end table
 
 
 These keywords are treated in details in the following sections.
 These keywords are treated in details in the following sections.
@@ -12410,6 +12445,10 @@ document metadata.  You can use several such keywords if the list is long.
 @vindex org-odt-styles-file
 @vindex org-odt-styles-file
 The style file of the document (@code{org-odt-styles-file}).  See
 The style file of the document (@code{org-odt-styles-file}).  See
 @ref{Applying custom styles} for details.
 @ref{Applying custom styles} for details.
+
+@item SUBTITLE
+@cindex SUBTITLE (ODT)
+The document subtitle.
 @end table
 @end table
 
 
 @node Extending ODT export
 @node Extending ODT export
@@ -13321,7 +13360,7 @@ options settings described in @ref{Export settings}.
 @table @samp
 @table @samp
 
 
 @item SUBTITLE
 @item SUBTITLE
-@cindex #+SUBTITLE
+@cindex #+SUBTITLE (Texinfo)
 The document subtitle.
 The document subtitle.
 
 
 @item SUBAUTHOR
 @item SUBAUTHOR
@@ -13401,7 +13440,6 @@ to define your own class in @code{org-texinfo-classes}, which see.  Set
 @subsubheading Title and copyright page
 @subsubheading Title and copyright page
 
 
 @cindex #+TEXINFO_PRINTED_TITLE
 @cindex #+TEXINFO_PRINTED_TITLE
-@cindex #+SUBTITLE
 The default template includes a title page for hard copy output.  The title
 The default template includes a title page for hard copy output.  The title
 and author displayed on this page are extracted from, respectively,
 and author displayed on this page are extracted from, respectively,
 @code{#+TITLE} and @code{#+AUTHOR} keywords (@pxref{Export settings}).  It is
 @code{#+TITLE} and @code{#+AUTHOR} keywords (@pxref{Export settings}).  It is
@@ -14207,6 +14245,7 @@ however, override everything.
 @item @code{:beamer-frame-default-options} @tab @code{org-beamer-frame-default-options}
 @item @code{:beamer-frame-default-options} @tab @code{org-beamer-frame-default-options}
 @item @code{:beamer-outline-frame-options} @tab @code{org-beamer-outline-frame-options}
 @item @code{:beamer-outline-frame-options} @tab @code{org-beamer-outline-frame-options}
 @item @code{:beamer-outline-frame-title}   @tab @code{org-beamer-outline-frame-title}
 @item @code{:beamer-outline-frame-title}   @tab @code{org-beamer-outline-frame-title}
+@item @code{:beamer-subtitle-format}       @tab @code{org-beamer-subtitle-format}
 @end multitable
 @end multitable
 
 
 @subsubheading HTML specific properties
 @subsubheading HTML specific properties
@@ -14292,6 +14331,8 @@ however, override everything.
 @item @code{:latex-listings}                   @tab @code{org-latex-listings}
 @item @code{:latex-listings}                   @tab @code{org-latex-listings}
 @item @code{:latex-minted-langs}               @tab @code{org-latex-minted-langs}
 @item @code{:latex-minted-langs}               @tab @code{org-latex-minted-langs}
 @item @code{:latex-minted-options}             @tab @code{org-latex-minted-options}
 @item @code{:latex-minted-options}             @tab @code{org-latex-minted-options}
+@item @code{:latex-subtitle-format}            @tab @code{org-latex-subtitle-format}
+@item @code{:latex-subtitle-separate}          @tab @code{org-latex-subtitle-separate}
 @item @code{:latex-table-scientific-notation}  @tab @code{org-latex-table-scientific-notation}
 @item @code{:latex-table-scientific-notation}  @tab @code{org-latex-table-scientific-notation}
 @item @code{:latex-tables-booktabs}            @tab @code{org-latex-tables-booktabs}
 @item @code{:latex-tables-booktabs}            @tab @code{org-latex-tables-booktabs}
 @item @code{:latex-tables-centered}            @tab @code{org-latex-tables-centered}
 @item @code{:latex-tables-centered}            @tab @code{org-latex-tables-centered}

+ 3 - 0
etc/ORG-NEWS

@@ -356,6 +356,9 @@ keywords and properties.
 *** Viewport support in html export
 *** Viewport support in html export
 Viewport for mobile-optimized website is now automatically inserted
 Viewport for mobile-optimized website is now automatically inserted
 when exporting to html.  See ~org-html-viewport~ for details.
 when exporting to html.  See ~org-html-viewport~ for details.
+*** New ~#+SUBTITLE~ export keyword
+Org can typeset a subtitle in some export backends.  See the manual
+for details.
 ** Miscellaneous
 ** Miscellaneous
 *** Strip all meta data from ITEM special property
 *** Strip all meta data from ITEM special property
 ITEM special property does not contain TODO, priority or tags anymore.
 ITEM special property does not contain TODO, priority or tags anymore.

+ 13 - 5
lisp/ox-ascii.el

@@ -119,7 +119,8 @@
 				       org-ascii-filter-comment-spacing)
 				       org-ascii-filter-comment-spacing)
 		   (:filter-section . org-ascii-filter-headline-blank-lines))
 		   (:filter-section . org-ascii-filter-headline-blank-lines))
   :options-alist
   :options-alist
-  '((:ascii-bullets nil nil org-ascii-bullets)
+  '((:subtitle "SUBTITLE" nil nil parse)
+    (:ascii-bullets nil nil org-ascii-bullets)
     (:ascii-caption-above nil nil org-ascii-caption-above)
     (:ascii-caption-above nil nil org-ascii-caption-above)
     (:ascii-charset nil nil org-ascii-charset)
     (:ascii-charset nil nil org-ascii-charset)
     (:ascii-global-margin nil nil org-ascii-global-margin)
     (:ascii-global-margin nil nil org-ascii-global-margin)
@@ -967,9 +968,11 @@ INFO is a plist used as a communication channel."
 	 ;; Links in the title will not be resolved later, so we make
 	 ;; Links in the title will not be resolved later, so we make
 	 ;; sure their path is located right after them.
 	 ;; sure their path is located right after them.
 	 (info (org-combine-plists info '(:ascii-links-to-notes nil)))
 	 (info (org-combine-plists info '(:ascii-links-to-notes nil)))
-	 (title (if (plist-get info :with-title)
-		    (org-export-data (plist-get info :title) info)
-		  ""))
+	 (with-title (plist-get info :with-title))
+	 (title (org-export-data
+		 (when with-title (plist-get info :title)) info))
+	 (subtitle (org-export-data
+		    (when with-title (plist-get info :subtitle)) info))
 	 (author (and (plist-get info :with-author)
 	 (author (and (plist-get info :with-author)
 		      (let ((auth (plist-get info :author)))
 		      (let ((auth (plist-get info :author)))
 			(and auth (org-export-data auth info)))))
 			(and auth (org-export-data auth info)))))
@@ -1013,9 +1016,13 @@ INFO is a plist used as a communication channel."
 	     ;; Format TITLE.  It may be filled if it is too wide,
 	     ;; Format TITLE.  It may be filled if it is too wide,
 	     ;; that is wider than the two thirds of the total width.
 	     ;; that is wider than the two thirds of the total width.
 	     (title-len (min (apply #'max
 	     (title-len (min (apply #'max
-				    (mapcar #'length (org-split-string title "\n")))
+				    (mapcar #'length
+					    (org-split-string
+					     (concat title "\n" subtitle) "\n")))
 			     (/ (* 2 text-width) 3)))
 			     (/ (* 2 text-width) 3)))
 	     (formatted-title (org-ascii--fill-string title title-len info))
 	     (formatted-title (org-ascii--fill-string title title-len info))
+	     (formatted-subtitle (when (org-string-nw-p subtitle)
+				   (org-ascii--fill-string subtitle title-len info)))
 	     (line
 	     (line
 	      (make-string
 	      (make-string
 	       (min (+ (max title-len
 	       (min (+ (max title-len
@@ -1027,6 +1034,7 @@ INFO is a plist used as a communication channel."
 	 (concat line "\n"
 	 (concat line "\n"
 		 (unless utf8p "\n")
 		 (unless utf8p "\n")
 		 (upcase formatted-title)
 		 (upcase formatted-title)
+		 (and formatted-subtitle (concat "\n" formatted-subtitle))
 		 (cond
 		 (cond
 		  ((and (org-string-nw-p author) (org-string-nw-p email))
 		  ((and (org-string-nw-p author) (org-string-nw-p email))
 		   (concat "\n\n" author "\n" email))
 		   (concat "\n\n" author "\n" email))

+ 18 - 1
lisp/ox-beamer.el

@@ -133,6 +133,15 @@ You might want to put e.g. \"allowframebreaks=0.9\" here."
   :type '(string :tag "Outline frame options"))
   :type '(string :tag "Outline frame options"))
 
 
 
 
+(defcustom org-beamer-subtitle-format "\\subtitle{%s}"
+  "Format string used for transcoded subtitle.
+The format string should have at most one \"%s\"-expression,
+which is replaced with the subtitle."
+  :group 'org-export-beamer
+  :version "25.1"
+  :package-version '(Org . "8.3")
+  :type '(string :tag "Format string"))
+
 
 
 ;;; Internal Variables
 ;;; Internal Variables
 
 
@@ -233,6 +242,7 @@ Return overlay specification, as a string, or nil."
   :options-alist
   :options-alist
   '((:headline-levels nil "H" org-beamer-frame-level)
   '((:headline-levels nil "H" org-beamer-frame-level)
     (:latex-class "LATEX_CLASS" nil "beamer" t)
     (:latex-class "LATEX_CLASS" nil "beamer" t)
+    (:beamer-subtitle-format nil nil org-beamer-subtitle-format)
     (:beamer-column-view-format "COLUMNS" nil org-beamer-column-view-format)
     (:beamer-column-view-format "COLUMNS" nil org-beamer-column-view-format)
     (:beamer-theme "BEAMER_THEME" nil org-beamer-theme)
     (:beamer-theme "BEAMER_THEME" nil org-beamer-theme)
     (:beamer-color-theme "BEAMER_COLOR_THEME" nil nil t)
     (:beamer-color-theme "BEAMER_COLOR_THEME" nil nil t)
@@ -810,7 +820,12 @@ information."
   "Return complete document string after Beamer conversion.
   "Return complete document string after Beamer conversion.
 CONTENTS is the transcoded contents string.  INFO is a plist
 CONTENTS is the transcoded contents string.  INFO is a plist
 holding export options."
 holding export options."
-  (let ((title (org-export-data (plist-get info :title) info)))
+  (let ((title (org-export-data (plist-get info :title) info))
+	(subtitle (org-export-data
+		   (org-element-parse-secondary-string
+		    (plist-get info :subtitle)
+		    (org-element-restriction 'keyword))
+		   info)))
     (concat
     (concat
      ;; 1. Time-stamp.
      ;; 1. Time-stamp.
      (and (plist-get info :time-stamp-file)
      (and (plist-get info :time-stamp-file)
@@ -877,6 +892,8 @@ holding export options."
        (format "\\date{%s}\n" (org-export-data date info)))
        (format "\\date{%s}\n" (org-export-data date info)))
      ;; 7. Title
      ;; 7. Title
      (format "\\title{%s}\n" title)
      (format "\\title{%s}\n" title)
+     (when (org-string-nw-p subtitle)
+       (concat (format (plist-get info :beamer-subtitle-format) subtitle) "\n"))
      ;; 8. Beamer-header
      ;; 8. Beamer-header
      (let ((beamer-header (plist-get info :beamer-header)))
      (let ((beamer-header (plist-get info :beamer-header)))
        (when beamer-header
        (when beamer-header

+ 25 - 5
lisp/ox-html.el

@@ -122,6 +122,7 @@
     (:html-preamble nil "html-preamble" org-html-preamble)
     (:html-preamble nil "html-preamble" org-html-preamble)
     (:html-head "HTML_HEAD" nil org-html-head newline)
     (:html-head "HTML_HEAD" nil org-html-head newline)
     (:html-head-extra "HTML_HEAD_EXTRA" nil org-html-head-extra newline)
     (:html-head-extra "HTML_HEAD_EXTRA" nil org-html-head-extra newline)
+    (:subtitle "SUBTITLE" nil nil parse)
     (:html-head-include-default-style
     (:html-head-include-default-style
      nil "html-style" org-html-head-include-default-style)
      nil "html-style" org-html-head-include-default-style)
     (:html-head-include-scripts nil "html-scripts" org-html-head-include-scripts)
     (:html-head-include-scripts nil "html-scripts" org-html-head-include-scripts)
@@ -272,7 +273,12 @@ for the JavaScript code in this tag.
 (defconst org-html-style-default
 (defconst org-html-style-default
   "<style type=\"text/css\">
   "<style type=\"text/css\">
  <!--/*--><![CDATA[/*><!--*/
  <!--/*--><![CDATA[/*><!--*/
-  .title  { text-align: center; }
+  .title  { text-align: center;
+             margin-bottom: .2em; }
+  .subtitle { text-align: center;
+              font-size: medium;
+              font-weight: bold;
+              margin-top:0; }
   .todo   { font-family: monospace; color: red; }
   .todo   { font-family: monospace; color: red; }
   .done   { font-family: monospace; color: green; }
   .done   { font-family: monospace; color: green; }
   .priority { font-family: monospace; color: orange; }
   .priority { font-family: monospace; color: orange; }
@@ -1212,6 +1218,7 @@ The second element of each list is a format string to format the
 postamble itself.  This format string can contain these elements:
 postamble itself.  This format string can contain these elements:
 
 
   %t stands for the title.
   %t stands for the title.
+  %s stands for the subtitle.
   %a stands for the author's name.
   %a stands for the author's name.
   %e stands for the author's email.
   %e stands for the author's email.
   %d stands for the date.
   %d stands for the date.
@@ -1276,6 +1283,7 @@ The second element of each list is a format string to format the
 preamble itself.  This format string can contain these elements:
 preamble itself.  This format string can contain these elements:
 
 
   %t stands for the title.
   %t stands for the title.
+  %s stands for the subtitle.
   %a stands for the author's name.
   %a stands for the author's name.
   %e stands for the author's email.
   %e stands for the author's email.
   %d stands for the date.
   %d stands for the date.
@@ -1788,6 +1796,7 @@ INFO is a plist used as a communication channel."
   "Return format specification for elements that can be
   "Return format specification for elements that can be
 used in the preamble or postamble."
 used in the preamble or postamble."
   `((?t . ,(org-export-data (plist-get info :title) info))
   `((?t . ,(org-export-data (plist-get info :title) info))
+    (?s . ,(org-export-data (plist-get info :subtitle) info))
     (?d . ,(org-export-data (org-export-get-date info) info))
     (?d . ,(org-export-data (org-export-get-date info) info))
     (?T . ,(format-time-string
     (?T . ,(format-time-string
 	    (plist-get info :html-metadata-timestamp-format)))
 	    (plist-get info :html-metadata-timestamp-format)))
@@ -1928,10 +1937,21 @@ holding export options."
      (format "<%s id=\"%s\">\n" (nth 1 div) (nth 2 div)))
      (format "<%s id=\"%s\">\n" (nth 1 div) (nth 2 div)))
    ;; Document title.
    ;; Document title.
    (when (plist-get info :with-title)
    (when (plist-get info :with-title)
-     (let ((title (org-export-data
-		   (or (plist-get info :title) "") info)))
-       (when (org-string-nw-p title)
-	 (format "<h1 class=\"title\">%s</h1>\n" title))))
+     (let ((title (plist-get info :title))
+	   (subtitle (plist-get info :subtitle)))
+       (when title
+	 (format
+	  (if (plist-get info :html-html5-fancy)
+	      "<header>\n<h1 class=\"title\">%s</h1>\n%s</header>"
+	    "<h1 class=\"title\">%s%s</h1>\n")
+	  (org-export-data title info)
+	  (if subtitle
+	      (format
+	       (if (plist-get info :html-html5-fancy)
+		   "<p class=\"subtitle\">%s</p>\n"
+		 "\n<br>\n<span class=\"subtitle\">%s</span>\n")
+	       (org-export-data subtitle info))
+	    "")))))
    contents
    contents
    (format "</%s>\n" (nth 1 (assq 'content (plist-get info :html-divs))))
    (format "</%s>\n" (nth 1 (assq 'content (plist-get info :html-divs))))
    ;; Postamble.
    ;; Postamble.

+ 35 - 4
lisp/ox-latex.el

@@ -108,8 +108,9 @@
     (:latex-class-options "LATEX_CLASS_OPTIONS" nil nil t)
     (:latex-class-options "LATEX_CLASS_OPTIONS" nil nil t)
     (:latex-header "LATEX_HEADER" nil nil newline)
     (:latex-header "LATEX_HEADER" nil nil newline)
     (:latex-header-extra "LATEX_HEADER_EXTRA" nil nil newline)
     (:latex-header-extra "LATEX_HEADER_EXTRA" nil nil newline)
-    (:description "DESCRIPTION" nil nil parse)
-    (:keywords "KEYWORDS" nil nil parse)
+    (:description "DESCRIPTION" nil nil newline)
+    (:keywords "KEYWORDS" nil nil space)
+    (:subtitle "SUBTITLE" nil nil space)
     ;; Other variables.
     ;; Other variables.
     (:latex-active-timestamp-format nil nil org-latex-active-timestamp-format)
     (:latex-active-timestamp-format nil nil org-latex-active-timestamp-format)
     (:latex-caption-above nil nil org-latex-caption-above)
     (:latex-caption-above nil nil org-latex-caption-above)
@@ -135,6 +136,8 @@
     (:latex-listings-options nil nil org-latex-listings-options)
     (:latex-listings-options nil nil org-latex-listings-options)
     (:latex-minted-langs nil nil org-latex-minted-langs)
     (:latex-minted-langs nil nil org-latex-minted-langs)
     (:latex-minted-options nil nil org-latex-minted-options)
     (:latex-minted-options nil nil org-latex-minted-options)
+    (:latex-subtitle-format nil nil org-latex-subtitle-format)
+    (:latex-subtitle-separate nil nil org-latex-subtitle-separate)
     (:latex-table-scientific-notation nil nil org-latex-table-scientific-notation)
     (:latex-table-scientific-notation nil nil org-latex-table-scientific-notation)
     (:latex-tables-booktabs nil nil org-latex-tables-booktabs)
     (:latex-tables-booktabs nil nil org-latex-tables-booktabs)
     (:latex-tables-centered nil nil org-latex-tables-centered)
     (:latex-tables-centered nil nil org-latex-tables-centered)
@@ -388,6 +391,7 @@ This format string may contain these elements:
 
 
   %a for AUTHOR keyword
   %a for AUTHOR keyword
   %t for TITLE keyword
   %t for TITLE keyword
+  %s for SUBTITLE keyword
   %k for KEYWORDS line
   %k for KEYWORDS line
   %d for DESCRIPTION line
   %d for DESCRIPTION line
   %c for CREATOR line
   %c for CREATOR line
@@ -403,6 +407,22 @@ precedence over this variable."
   :group 'org-export-latex
   :group 'org-export-latex
   :type '(string :tag "Format string"))
   :type '(string :tag "Format string"))
 
 
+(defcustom org-latex-subtitle-format "\\\\\\medskip\n\\large %s"
+  "Format string used for transcoded subtitle.
+The format string should have at most one \"%s\"-expression,
+which is replaced with the subtitle."
+  :group 'org-export-latex
+  :version "25.1"
+  :package-version '(Org . "8.3")
+  :type '(string :tag "Format string"))
+
+(defcustom org-latex-subtitle-separate nil
+  "Non-nil means the subtitle is not typeset as part of title."
+  :group 'org-export-latex
+  :version "25.1"
+  :package-version '(Org . "8.3")
+  :type 'boolean)
+
 (defcustom org-latex-toc-command "\\tableofcontents\n\n"
 (defcustom org-latex-toc-command "\\tableofcontents\n\n"
   "LaTeX command to set the table of contents, list of figures, etc.
   "LaTeX command to set the table of contents, list of figures, etc.
 This command only applies to the table of contents generated with
 This command only applies to the table of contents generated with
@@ -419,6 +439,7 @@ This format string may contain these elements:
 
 
   %a for AUTHOR keyword
   %a for AUTHOR keyword
   %t for TITLE keyword
   %t for TITLE keyword
+  %s for SUBTITLE keyword
   %k for KEYWORDS line
   %k for KEYWORDS line
   %d for DESCRIPTION line
   %d for DESCRIPTION line
   %c for CREATOR line
   %c for CREATOR line
@@ -1288,8 +1309,18 @@ holding export options."
      ;; Date.
      ;; Date.
      (let ((date (and (plist-get info :with-date) (org-export-get-date info))))
      (let ((date (and (plist-get info :with-date) (org-export-get-date info))))
        (format "\\date{%s}\n" (org-export-data date info)))
        (format "\\date{%s}\n" (org-export-data date info)))
-     ;; Title
-     (format "\\title{%s}\n" title)
+     ;; Title and subtitle.
+     (let* ((subtitle (plist-get info :subtitle))
+	    (formatted-subtitle
+	     (when subtitle
+	       (format (plist-get info :latex-subtitle-format)
+		       (org-export-data subtitle info))))
+	    (separate (plist-get info :latex-subtitle-separate)))
+       (concat
+	(format "\\title{%s%s}\n" title
+		(if separate "" formatted-subtitle))
+	(when (and separate subtitle)
+	  (concat formatted-subtitle "\n"))))
      ;; Hyperref options.
      ;; Hyperref options.
      (let ((template (plist-get info :latex-hyperref-template)))
      (let ((template (plist-get info :latex-hyperref-template)))
        (and (stringp template)
        (and (stringp template)

+ 20 - 2
lisp/ox-odt.el

@@ -99,6 +99,7 @@
   '((:odt-styles-file "ODT_STYLES_FILE" nil nil t)
   '((:odt-styles-file "ODT_STYLES_FILE" nil nil t)
     (:description "DESCRIPTION" nil nil newline)
     (:description "DESCRIPTION" nil nil newline)
     (:keywords "KEYWORDS" nil nil space)
     (:keywords "KEYWORDS" nil nil space)
+    (:subtitle "SUBTITLE" nil nil parse)
     ;; Other variables.
     ;; Other variables.
     (:odt-content-template-file nil nil org-odt-content-template-file)
     (:odt-content-template-file nil nil org-odt-content-template-file)
     (:odt-display-outline-level nil nil org-odt-display-outline-level)
     (:odt-display-outline-level nil nil org-odt-display-outline-level)
@@ -1328,6 +1329,7 @@ CONTENTS is the transcoded contents string.  RAW-DATA is the
 original parsed data.  INFO is a plist holding export options."
 original parsed data.  INFO is a plist holding export options."
   ;; Write meta file.
   ;; Write meta file.
   (let ((title (org-export-data (plist-get info :title) info))
   (let ((title (org-export-data (plist-get info :title) info))
+	(subtitle (org-export-data (plist-get info :subtitle) info))
 	(author (let ((author (plist-get info :author)))
 	(author (let ((author (plist-get info :author)))
 		  (if (not author) "" (org-export-data author info))))
 		  (if (not author) "" (org-export-data author info))))
 	(email (plist-get info :email))
 	(email (plist-get info :email))
@@ -1365,6 +1367,10 @@ original parsed data.  INFO is a plist holding export options."
       (format "<meta:keyword>%s</meta:keyword>\n" keywords)
       (format "<meta:keyword>%s</meta:keyword>\n" keywords)
       (format "<dc:subject>%s</dc:subject>\n" description)
       (format "<dc:subject>%s</dc:subject>\n" description)
       (format "<dc:title>%s</dc:title>\n" title)
       (format "<dc:title>%s</dc:title>\n" title)
+      (when (org-string-nw-p subtitle)
+	(format
+	 "<meta:user-defined meta:name=\"subtitle\">%s</meta:user-defined>\n"
+	 subtitle))
       "\n"
       "\n"
       "  </office:meta>\n" "</office:document-meta>")
       "  </office:meta>\n" "</office:document-meta>")
      nil (concat org-odt-zip-dir "meta.xml"))
      nil (concat org-odt-zip-dir "meta.xml"))
@@ -1510,6 +1516,8 @@ original parsed data.  INFO is a plist holding export options."
       (insert
       (insert
        (let* ((title (and (plist-get info :with-title)
        (let* ((title (and (plist-get info :with-title)
 			  (org-export-data (plist-get info :title) info)))
 			  (org-export-data (plist-get info :title) info)))
+	      (subtitle (when title
+			  (org-export-data (plist-get info :subtitle) info)))
 	      (author (and (plist-get info :with-author)
 	      (author (and (plist-get info :with-author)
 			   (let ((auth (plist-get info :author)))
 			   (let ((auth (plist-get info :author)))
 			     (and auth (org-export-data auth info)))))
 			     (and auth (org-export-data auth info)))))
@@ -1521,10 +1529,20 @@ original parsed data.  INFO is a plist holding export options."
 	  ;; Title.
 	  ;; Title.
 	  (when (org-string-nw-p title)
 	  (when (org-string-nw-p title)
 	    (concat
 	    (concat
-	     (format "\n<text:p text:style-name=\"%s\">%s</text:p>"
+	     (format "\n<text:p text:style-name=\"%s\">%s</text:p>\n"
 		     "OrgTitle" (format "\n<text:title>%s</text:title>" title))
 		     "OrgTitle" (format "\n<text:title>%s</text:title>" title))
 	     ;; Separator.
 	     ;; Separator.
-	     "\n<text:p text:style-name=\"OrgTitle\"/>"))
+	     "\n<text:p text:style-name=\"OrgTitle\"/>\n"
+	     ;; Subtitle.
+	     (when (org-string-nw-p subtitle)
+	       (concat
+		(format "<text:p text:style-name=\"OrgSubtitle\">\n%s\n</text:p>\n"
+			(concat
+			 "<text:user-defined style:data-style-name=\"N0\" text:name=\"subtitle\">\n"
+			 subtitle
+			 "</text:user-defined>\n"))
+		;; Separator.
+		"<text:p text:style-name=\"OrgSubtitle\"/>\n"))))
 	  (cond
 	  (cond
 	   ((and author (not email))
 	   ((and author (not email))
 	    ;; Author only.
 	    ;; Author only.

+ 4 - 4
lisp/ox-texinfo.el

@@ -92,7 +92,7 @@
     (:texinfo-class "TEXINFO_CLASS" nil org-texinfo-default-class t)
     (:texinfo-class "TEXINFO_CLASS" nil org-texinfo-default-class t)
     (:texinfo-header "TEXINFO_HEADER" nil nil newline)
     (:texinfo-header "TEXINFO_HEADER" nil nil newline)
     (:texinfo-post-header "TEXINFO_POST_HEADER" nil nil newline)
     (:texinfo-post-header "TEXINFO_POST_HEADER" nil nil newline)
-    (:subtitle "SUBTITLE" nil nil newline)
+    (:subtitle "SUBTITLE" nil nil parse)
     (:subauthor "SUBAUTHOR" nil nil newline)
     (:subauthor "SUBAUTHOR" nil nil newline)
     (:texinfo-dircat "TEXINFO_DIR_CATEGORY" nil nil t)
     (:texinfo-dircat "TEXINFO_DIR_CATEGORY" nil nil t)
     (:texinfo-dirtitle "TEXINFO_DIR_TITLE" nil nil t)
     (:texinfo-dirtitle "TEXINFO_DIR_TITLE" nil nil t)
@@ -570,9 +570,9 @@ holding export options."
        (concat
        (concat
 	(format "@title %s\n" (or (plist-get info :texinfo-printed-title) title ""))
 	(format "@title %s\n" (or (plist-get info :texinfo-printed-title) title ""))
 	(let ((subtitle (plist-get info :subtitle)))
 	(let ((subtitle (plist-get info :subtitle)))
-	  (and subtitle
-	       (org-element-normalize-string
-		(replace-regexp-in-string "^" "@subtitle " subtitle))))))
+	  (when subtitle
+	    (format "@subtitle %s\n"
+		    (org-export-data subtitle info))))))
      (when (plist-get info :with-author)
      (when (plist-get info :with-author)
        (concat
        (concat
 	;; Primary author.
 	;; Primary author.