Hi, I'm starting a new thread as the previous discussion attracted much dissuasion not directly related to the patch in question. Changes:
- Html subtitles now follow the W3 recommendations, I think/hope. It would be great if somebody who knows css would check the styling. - The texinfo subtitle is interpreted. - Documentation and NEWS is added. Note: *the patch does not touch ox.el*. SUBTITLE is *only* supported in a tiny fraction of the backends, namely ox-latex, ox-ascii, ox-html, and ox-odt. —Rasmus -- Er du tosset for noge' lårt!
>From 6d4e46af0b9ef5623c1a638c4659997fb735350b Mon Sep 17 00:00:00 2001 From: Rasmus <ras...@gmx.us> Date: Sun, 1 Mar 2015 22:09:19 +0100 Subject: [PATCH] ox: Add SUBTITLE property in some backends * ox-ascii.el (org-ascii-template--document-title) (org-ascii-template--document-title) ox-deck.el (org-deck-title-slide-template) ox-s5.el (org-s5-title-slide-template) ox-html.el (org-html--build-meta-info, org-html-format-spec) (org-html--build-meta-info, org-html-format-spec) (org-html--build-meta-info, org-html-format-spec) ox-org.el (org), (org-org-keyword): Use SUBTITLE. * ox-beamer.el (org-beamer-template) ox-html (org-html-template) ox-latex.el (org-latex-template) ox-org (org-org-template): Insert SUBTITLE. * ox-html (org-html-preamble-format) (org-html-postamble-format): Update docstring. * ox-html (org-html-style-default): Add .subtitle style and change .title style. * ox-texinfo.el (org-texinfo-template): Interpret subtitle. * org.texi (Export settings): Document SUBTITLE. * ORG-NEWS: Add entry on SUBTITLE. The patch adds a #+SUBTITLE keyword to ox-ascii, ox-latex, ox-html and ox-odt. --- contrib/lisp/ox-deck.el | 2 ++ contrib/lisp/ox-s5.el | 2 ++ doc/org.texi | 7 ++++++- etc/ORG-NEWS | 3 +++ lisp/ox-ascii.el | 23 ++++++++++++++++++----- lisp/ox-beamer.el | 10 +++++++++- lisp/ox-html.el | 37 +++++++++++++++++++++++++++++++------ lisp/ox-latex.el | 41 ++++++++++++++++++++++++++++++++++++----- lisp/ox-odt.el | 32 +++++++++++++++++++++++++++++--- lisp/ox-org.el | 9 +++++++-- lisp/ox-texinfo.el | 10 +++++++--- 11 files changed, 150 insertions(+), 26 deletions(-) diff --git a/contrib/lisp/ox-deck.el b/contrib/lisp/ox-deck.el index 0ebde41..a76384b 100644 --- a/contrib/lisp/ox-deck.el +++ b/contrib/lisp/ox-deck.el @@ -259,6 +259,7 @@ Defaults to styles for the title page." (defcustom org-deck-title-slide-template "<h1>%t</h1> +<h2>%s</h2> <h2>%a</h2> <h2>%e</h2> <h2>%d</h2>" @@ -446,6 +447,7 @@ holding export options." ;; title page (format "<%s id='title-slide' class='slide'>" (plist-get info :html-container)) + ;; TODO: format-spec isn't great for missing details. (format-spec org-deck-title-slide-template (org-html-format-spec info)) (format "</%s>" (plist-get info :html-container)) ;; toc page diff --git a/contrib/lisp/ox-s5.el b/contrib/lisp/ox-s5.el index b003919..8b28692 100644 --- a/contrib/lisp/ox-s5.el +++ b/contrib/lisp/ox-s5.el @@ -174,6 +174,7 @@ or an empty string." (defcustom org-s5-title-slide-template "<h1>%t</h1> +<h2>%s</h2> <h2>%a</h2> <h3>%e</h3> <h4>%d</h4>" @@ -329,6 +330,7 @@ holding export options." ;; title page (format "<%s id='title-slide' class='slide'>" (plist-get info :html-container)) + ;; TODO: format-spec isn't great for missing details. (format-spec org-s5-title-slide-template (org-html-format-spec info)) (format "</%s>" (plist-get info :html-container)) ;; table of contents. diff --git a/doc/org.texi b/doc/org.texi index 6b56c4a..64a34e5 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -10711,6 +10711,12 @@ default value is @code{:export:}. Within a subtree tagged with below). When headlines are selectively exported with @code{:export:} anywhere in a file, text before the first headline is ignored. +@item SUBTITLE +@cindex #+SUBTITLE +The document subtitle. The keyword is supported by by @LaTeX{}-backends, +HTML backends, ASCII backends, the texinfo backend, and the ODT backend. You +can use several such keywords for long subtitles. + @item EXCLUDE_TAGS @cindex #+EXCLUDE_TAGS @vindex org-export-exclude-tags @@ -13174,7 +13180,6 @@ to define your own class in @code{org-texinfo-classes}, which see. Set @subsubheading Title and copyright page @cindex #+TEXINFO_PRINTED_TITLE -@cindex #+SUBTITLE The default template includes a title page for hard copy output. The title and author displayed on this page are extracted from, respectively, @code{#+TITLE} and @code{#+AUTHOR} keywords (@pxref{Export settings}). It is diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index 9c262f4..7f53123 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -323,6 +323,9 @@ leading spaces within table cells. *** New MathJax configuration options. Org uses the MathJax CDN by default. See the manual and the docstring of ~org-html-mathjax-options~ for details. +*** New ~#+SUBTITLE~ keyword +Org can now typeset a subtitle in some backends. See the manual for +details. ** Miscellaneous *** Strip all meta data from ITEM special property ITEM special property does not contain TODO, priority or tags anymore. diff --git a/lisp/ox-ascii.el b/lisp/ox-ascii.el index b7d8425..e9d5b55 100644 --- a/lisp/ox-ascii.el +++ b/lisp/ox-ascii.el @@ -121,7 +121,8 @@ org-ascii-filter-comment-spacing) (:filter-section . org-ascii-filter-headline-blank-lines)) :options-alist - '((:ascii-bullets nil nil org-ascii-bullets) + '((:subtitle "SUBTITLE" nil nil space) + (:ascii-bullets nil nil org-ascii-bullets) (:ascii-caption-above nil nil org-ascii-caption-above) (:ascii-charset nil nil org-ascii-charset) (:ascii-global-margin nil nil org-ascii-global-margin) @@ -969,9 +970,15 @@ INFO is a plist used as a communication channel." ;; Links in the title will not be resolved later, so we make ;; sure their path is located right after them. (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 + (org-element-parse-secondary-string + (plist-get info :subtitle) + (org-element-restriction 'keyword))) + info)) (author (and (plist-get info :with-author) (let ((auth (plist-get info :author))) (and auth (org-export-data auth info))))) @@ -1014,8 +1021,12 @@ INFO is a plist used as a communication channel." (let* ((utf8p (eq (plist-get info :ascii-charset) 'utf-8)) ;; Format TITLE. It may be filled if it is too wide, ;; that is wider than the two thirds of the total width. - (title-len (min (length title) (/ (* 2 text-width) 3))) + (title-len (min (max (length title) + (length subtitle)) + (/ (* 2 text-width) 3))) (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 (make-string (min (+ (max title-len @@ -1027,6 +1038,8 @@ INFO is a plist used as a communication channel." (concat line "\n" (unless utf8p "\n") (upcase formatted-title) + (when formatted-subtitle + (concat "\n" formatted-subtitle)) (cond ((and (org-string-nw-p author) (org-string-nw-p email)) (concat "\n\n" author "\n" email)) diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el index 5d0b55d..7d69d45 100644 --- a/lisp/ox-beamer.el +++ b/lisp/ox-beamer.el @@ -233,6 +233,7 @@ Return overlay specification, as a string, or nil." :options-alist '((:headline-levels nil "H" org-beamer-frame-level) (:latex-class "LATEX_CLASS" nil "beamer" t) + (:latex-subtitle-format nil nil "\\subtitle{%s}") (:beamer-column-view-format "COLUMNS" nil org-beamer-column-view-format) (:beamer-theme "BEAMER_THEME" nil org-beamer-theme) (:beamer-color-theme "BEAMER_COLOR_THEME" nil nil t) @@ -810,7 +811,12 @@ information." "Return complete document string after Beamer conversion. CONTENTS is the transcoded contents string. INFO is a plist 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 ;; 1. Time-stamp. (and (plist-get info :time-stamp-file) @@ -877,6 +883,8 @@ holding export options." (format "\\date{%s}\n" (org-export-data date info))) ;; 7. Title (format "\\title{%s}\n" title) + (when (org-string-nw-p subtitle) + (format (plist-get info :latex-subtitle-format) subtitle)) ;; 8. Beamer-header (let ((beamer-header (plist-get info :beamer-header))) (when beamer-header diff --git a/lisp/ox-html.el b/lisp/ox-html.el index 7ed73f6..6b0f757 100644 --- a/lisp/ox-html.el +++ b/lisp/ox-html.el @@ -108,7 +108,8 @@ (if a (org-html-export-to-html t s v b) (org-open-file (org-html-export-to-html nil s v b))))))) :options-alist - '((:html-doctype "HTML_DOCTYPE" nil org-html-doctype) + '((:subtitle "SUBTITLE" nil nil space) + (:html-doctype "HTML_DOCTYPE" nil org-html-doctype) (:html-container "HTML_CONTAINER" nil org-html-container-element) (:html-html5-fancy nil "html5-fancy" org-html-html5-fancy) (:html-link-use-abs-url nil "html-link-use-abs-url" org-html-link-use-abs-url) @@ -270,7 +271,12 @@ for the JavaScript code in this tag. (defconst org-html-style-default "<style type=\"text/css\"> <!--/*--><![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; } .done { font-family: monospace; color: green; } .priority { font-family: monospace; color: orange; } @@ -1209,6 +1215,7 @@ The second element of each list is a format string to format the postamble itself. This format string can contain these elements: %t stands for the title. + %s will be replaced by the export subtitle. %a stands for the author's name. %e stands for the author's email. %d stands for the date. @@ -1273,6 +1280,7 @@ The second element of each list is a format string to format the preamble itself. This format string can contain these elements: %t stands for the title. + %s will be replaced by the export subtitle. %a stands for the author's name. %e stands for the author's email. %d stands for the date. @@ -1725,6 +1733,10 @@ INFO is a plist used as a communication channel." "Return format specification for elements that can be used in the preamble or postamble." `((?t . ,(org-export-data (plist-get info :title) info)) + (?s . ,(org-export-data (org-element-parse-secondary-string + (plist-get info :subtitle) + (org-element-restriction 'keyword)) + info)) (?d . ,(org-export-data (org-export-get-date info) info)) (?T . ,(format-time-string (plist-get info :html-metadata-timestamp-format))) @@ -1865,10 +1877,23 @@ holding export options." (format "<%s id=\"%s\">\n" (nth 1 div) (nth 2 div))) ;; Document 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 (org-element-parse-secondary-string + (plist-get info :subtitle) + (org-element-restriction 'keyword)))) + (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 (format "</%s>\n" (nth 1 (assq 'content (plist-get info :html-divs)))) ;; Postamble. diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el index 9e86863..b7acfcc 100644 --- a/lisp/ox-latex.el +++ b/lisp/ox-latex.el @@ -110,6 +110,7 @@ (:latex-class-options "LATEX_CLASS_OPTIONS" nil nil t) (:latex-header "LATEX_HEADER" nil nil newline) (:latex-header-extra "LATEX_HEADER_EXTRA" nil nil newline) + (:subtitle "SUBTITLE" nil nil space) ;; Other variables. (:latex-active-timestamp-format nil nil org-latex-active-timestamp-format) (:latex-caption-above nil nil org-latex-caption-above) @@ -135,6 +136,8 @@ (:latex-listings-options nil nil org-latex-listings-options) (:latex-minted-langs nil nil org-latex-minted-langs) (: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-tables-booktabs nil nil org-latex-tables-booktabs) (:latex-tables-centered nil nil org-latex-tables-centered) @@ -388,6 +391,7 @@ This format string may contain these elements: %a for AUTHOR keyword %t for TITLE keyword + %s for SUBTITLE keyword %k for KEYWORDS line %d for DESCRIPTION line %c for CREATOR line @@ -403,6 +407,14 @@ precedence over this variable." :group 'org-export-latex :type '(string :tag "Format string")) +(defcustom org-latex-subtitle-format "\\\\\\smallskip\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.") + +(defcustom org-latex-subtitle-separate nil + "Non-nil means the subtitle is not typeset as part of title.") + (defcustom org-latex-toc-command "\\tableofcontents\n\n" "LaTeX command to set the table of contents, list of figures, etc. This command only applies to the table of contents generated with @@ -419,6 +431,7 @@ This format string may contain these elements: %a for AUTHOR keyword %t for TITLE keyword + %s for SUBTITLE keyword %k for KEYWORDS line %d for DESCRIPTION line %c for CREATOR line @@ -1227,9 +1240,14 @@ INFO is a plist used as a communication channel." verbatim)) (language (let ((lang (plist-get info :language))) (or (cdr (assoc lang org-latex-babel-language-alist)) - lang)))) - `((?a . ,(org-export-data (plist-get info :author) info)) - (?t . ,(org-export-data (plist-get info :title) info)) + lang "")))) + `((?a . ,(or (org-export-data (plist-get info :author) info) "")) + (?t . ,(or (org-export-data (plist-get info :title) info) "")) + (?s . ,(or (org-export-data + (org-element-parse-secondary-string + (plist-get info :subtitle) + (org-element-restriction 'keyword)) + info) "")) (?k . ,(org-export-data (org-latex--wrap-latex-math-block (org-element-parse-secondary-string (plist-get info :keywords) objects) @@ -1297,8 +1315,21 @@ holding export options." ;; Date. (let ((date (and (plist-get info :with-date) (org-export-get-date info)))) (format "\\date{%s}\n" (org-export-data date info))) - ;; Title - (format "\\title{%s}\n" title) + ;; Title and subtitle. + (let* ((subtitle + (org-element-parse-secondary-string + (plist-get info :subtitle) + (org-element-restriction 'keyword))) + (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) formatted-subtitle))) + ;; Hyperref options. (let ((template (plist-get info :latex-hyperref-template))) (and (stringp template) diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el index 02d3f44..5923d4a 100644 --- a/lisp/ox-odt.el +++ b/lisp/ox-odt.el @@ -96,7 +96,8 @@ (if a (org-odt-export-to-odt t s v) (org-open-file (org-odt-export-to-odt nil s v) 'system)))))) :options-alist - '((:odt-styles-file "ODT_STYLES_FILE" nil nil t) + '((:subtitle "SUBTITLE" nil nil space) + (:odt-styles-file "ODT_STYLES_FILE" nil nil t) ;; Other variables. (:odt-content-template-file nil nil org-odt-content-template-file) (:odt-display-outline-level nil nil org-odt-display-outline-level) @@ -1326,6 +1327,11 @@ CONTENTS is the transcoded contents string. RAW-DATA is the original parsed data. INFO is a plist holding export options." ;; Write meta file. (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)) (author (let ((author (plist-get info :author))) (if (not author) "" (org-export-data author info)))) (email (plist-get info :email)) @@ -1363,6 +1369,10 @@ original parsed data. INFO is a plist holding export options." (format "<meta:keyword>%s</meta:keyword>\n" keywords) (format "<dc:subject>%s</dc:subject>\n" description) (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>" + subtitle)) "\n" " </office:meta>\n" "</office:document-meta>") nil (concat org-odt-zip-dir "meta.xml")) @@ -1508,6 +1518,12 @@ original parsed data. INFO is a plist holding export options." (insert (let* ((title (and (plist-get info :with-title) (org-export-data (plist-get info :title) info))) + (subtitle (when title + (org-export-data + (org-element-parse-secondary-string + (plist-get info :subtitle) + (org-element-restriction 'keyword)) + info))) (author (and (plist-get info :with-author) (let ((auth (plist-get info :author))) (and auth (org-export-data auth info))))) @@ -1519,10 +1535,20 @@ original parsed data. INFO is a plist holding export options." ;; Title. (when (org-string-nw-p title) (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)) ;; 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\"/>")))) (cond ((and author (not email)) ;; Author only. diff --git a/lisp/ox-org.el b/lisp/ox-org.el index b0eb279..21824ff 100644 --- a/lisp/ox-org.el +++ b/lisp/ox-org.el @@ -102,6 +102,7 @@ setting of `org-html-htmlize-output-type' is 'css." (underline . org-org-identity) (verbatim . org-org-identity) (verse-block . org-org-identity)) + :options-alist '((:subtitle "SUBTITLE" nil nil space)) :menu-entry '(?O "Export to Org" ((?O "As Org buffer" org-org-export-as-org) @@ -139,7 +140,7 @@ CONTENTS is nil. INFO is ignored." (let ((key (org-element-property :key keyword))) (unless (member key '("AUTHOR" "CREATOR" "DATE" "DESCRIPTION" "EMAIL" "KEYWORDS" - "OPTIONS" "TITLE")) + "OPTIONS" "TITLE" "SUBTITLE")) (org-element-keyword-interpreter keyword nil)))) (defun org-org-link (link contents info) @@ -165,7 +166,11 @@ as a communication channel." (org-element-property :value k))))) "\n")) (and (plist-get info :with-title) - (format "#+TITLE: %s\n" (org-export-data (plist-get info :title) info))) + (let ((title (org-string-nw-p (org-export-data (plist-get info :title) info))) + (subtitle (org-string-nw-p (org-export-data (plist-get info :subtitle) info)))) + (concat + (and title (format "#+TITLE: %s\n" title)) + (and subtitle (format "#+SUBTITLE: %s\n" subtitle))))) (and (plist-get info :with-date) (let ((date (org-export-data (org-export-get-date info) info))) (and (org-string-nw-p date) diff --git a/lisp/ox-texinfo.el b/lisp/ox-texinfo.el index bdf0c83..c8ef480 100644 --- a/lisp/ox-texinfo.el +++ b/lisp/ox-texinfo.el @@ -572,9 +572,13 @@ holding export options." (concat (format "@title %s\n" (or (plist-get info :texinfo-printed-title) title "")) (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 + (org-element-parse-secondary-string + subtitle + (org-element-restriction 'keyword)) + info)))))) (when (plist-get info :with-author) (concat ;; Primary author. -- 2.3.4