emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* [ox, patch] Add #+SUBTITLE
@ 2015-03-20 23:23 Rasmus
  2015-03-21  2:26 ` Marcin Borkowski
                   ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Rasmus @ 2015-03-20 23:23 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 692 bytes --]

Hi,

This patch adds #+SUBTITLE to a couple of backends.  This property is
already supported in ox-texinfo and e.g. beamer.cls has a subtitles macro,
but ox-beamer.el has no #+SUBTITLE.  I have used subtitles in
e.g. applications for research funds.

The value-added is twofold:

    - It adds a consistent way to have subtitle across backends.  I'm
      explicitly assuming this is nice, but perhaps this is false.
    - Currently, it is, I believe, impossible to hack-up a subtitle in at
      least ox-odt.el.

It's not documented yet as I want make sure that it's not an undesirable
feature before progressing further.

WDTY?

—Rasmus 

-- 
The right to be left alone is a human right

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ox-Add-SUBTITLE-property-in-some-backends.patch --]
[-- Type: text/x-diff, Size: 17980 bytes --]

From 4b9ce6f4d260360847bf63f3bab9f98004bc7469 Mon Sep 17 00:00:00 2001
From: Rasmus <rasmus@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 style for SUBTITLE.
---
 contrib/lisp/ox-deck.el |  2 ++
 contrib/lisp/ox-s5.el   |  2 ++
 lisp/ox-ascii.el        | 23 ++++++++++++++++++-----
 lisp/ox-beamer.el       | 10 +++++++++-
 lisp/ox-html.el         | 26 ++++++++++++++++++++------
 lisp/ox-latex.el        | 35 +++++++++++++++++++++++++++++++++--
 lisp/ox-odt.el          | 32 +++++++++++++++++++++++++++++---
 lisp/ox-org.el          |  9 +++++++--
 8 files changed, 120 insertions(+), 19 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/lisp/ox-ascii.el b/lisp/ox-ascii.el
index 5711b53..4f6ecbe 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
+		       (or (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 (if utf8p "\n\n\n" "\n\n") author "\n" email))
diff --git a/lisp/ox-beamer.el b/lisp/ox-beamer.el
index 7c42c74..193ed96 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)
@@ -798,7 +799,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
+		    (or (plist-get info :subtitle) "")
+		    (org-element-restriction 'keyword))
+		   info)))
     (concat
      ;; 1. Time-stamp.
      (and (plist-get info :time-stamp-file)
@@ -865,6 +871,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 92fe3d9..2e4692c 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)
@@ -271,7 +272,7 @@ for the JavaScript code in this tag.
 (defconst org-html-style-default
   "<style type=\"text/css\">
  <!--/*--><![CDATA[/*><!--*/
-  .title  { text-align: center; }
+  .title, .subtitle  { text-align: center; }
   .todo   { font-family: monospace; color: red; }
   .done   { font-family: monospace; color: green; }
   .priority { font-family: monospace; color: orange; }
@@ -1210,6 +1211,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.
@@ -1274,6 +1276,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.
@@ -1726,6 +1729,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
+			     (or (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)))
@@ -1866,10 +1873,17 @@ 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
+		      (or (plist-get info :subtitle) "")
+		      (org-element-restriction 'keyword))))
+       (when title
+	 (concat
+	  (format "<h1 class=\"title\">%s</h1>\n"
+		  (org-export-data title info))
+	  (when subtitle
+	    (format "<h2 class=\"subtitle\">%s</h2>\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 44435f4..e755e3d 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
@@ -1230,6 +1243,11 @@ INFO is a plist used as a communication channel."
 			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
+		   (or (plist-get info :subtitle) "")
+		   (org-element-restriction 'keyword))
+		  info) ""))
       (?k . ,(org-export-data (org-latex--wrap-latex-math-block
 			       (org-element-parse-secondary-string
 				(or (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
+	      (or (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 e32ca26..abc2358 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
+		    (or (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))
@@ -1365,6 +1371,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"))
@@ -1510,6 +1520,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
+			    (or (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)))))
@@ -1521,10 +1537,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)
-- 
2.3.3


^ permalink raw reply related	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2015-03-28 15:15 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-20 23:23 [ox, patch] Add #+SUBTITLE Rasmus
2015-03-21  2:26 ` Marcin Borkowski
2015-03-21  2:32   ` Melanie Bacou
2015-03-22 14:02 ` Nicolas Goaziou
2015-03-22 15:29   ` Rasmus
2015-03-22 20:47     ` Marcin Borkowski
2015-03-22 21:21       ` Thomas S. Dye
2015-03-22 21:23       ` John Williams
2015-03-22 22:43       ` Rasmus
2015-03-22 23:19         ` Marcin Borkowski
2015-03-23  0:05           ` Rasmus
2015-03-23  8:32             ` Marcin Borkowski
2015-03-23  9:00       ` Sebastien Vauban
2015-03-24  9:05     ` Nicolas Goaziou
2015-03-24  9:37       ` Rasmus
2015-03-28 15:17         ` Nicolas Goaziou
2015-03-26  2:36       ` Melanie Bacou
2015-03-26  2:38         ` Melanie Bacou
2015-03-26 10:10         ` Rasmus
2015-03-22 14:34 ` Eric Abrahamsen
2015-03-22 15:32   ` Rasmus
2015-03-23  1:17     ` Eric Abrahamsen
2015-03-26  2:47       ` Melanie Bacou
2015-03-26  9:52         ` Rasmus
2015-03-26 10:42           ` Rasmus
2015-03-28  8:26             ` Melanie Bacou

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).