1 ;;; ox-s5.el --- S5 Presentation Back-End for Org Export Engine
3 ;; Copyright (C) 2011-2013 Rick Frankel
5 ;; Author: Rick Frankel <emacs at rickster dot com>
6 ;; Keywords: outlines, hypermedia, S5, wp
8 ;; This program is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation, either version 3 of the License, or
11 ;; (at your option) any later version.
13 ;; This program is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
23 ;; This library implements an S5 Presentation back-end for the Org
28 ;; Get the s5 scripts from
29 ;; http://meyerweb.com/eric/tools/s5/
30 ;; (Note that the default s5 version is set for using the alpha, 1.2a2.
31 ;; Copy the ui dir to somewhere reachable from your published presentation
32 ;; The default (`org-s5-ui-url') is set to "ui" (e.g., in the
33 ;; same directory as the html file).
37 ;; Follow the general instructions at the above website. To generate
38 ;; incremental builds, you can set the HTML_CONTAINER_CLASS on an
39 ;; object to "incremental" to make it build. If you want an outline to
40 ;; build, set the` INCREMENTAL property on the parent headline.
44 ;; M-x org-s5-export-as-html
46 ;; in an Org mode buffer. See ox.el and ox-html.el for more details
47 ;; on how this exporter works.
51 (org-export-define-derived-backend s5 html
53 (?s
"Export to S5 HTML Presentation"
54 ((?H
"To temporary buffer" org-s5-export-as-html
)
55 (?h
"To file" org-s5-export-to-html
)
56 (?o
"To file and open"
58 (if a
(org-s5-export-to-html t s v b
)
59 (org-open-file (org-s5-export-to-html nil s v b
)))))))
61 ((:html-link-home
"HTML_LINK_HOME" nil nil
)
62 (:html-link-up
"HTML_LINK_UP" nil nil
)
63 (:html-mathjax
"HTML_MATHJAX" nil
"" space
)
64 (:html-postamble nil
"html-postamble" nil t
)
65 (:html-preamble nil
"html-preamble" nil t
)
66 (:html-style-extra
"HTML_STYLE" nil org-html-style-extra newline
)
67 (:html-style-include-default
"HTML_INCLUDE_DEFAULT" nil nil
)
68 (:html-style-include-scripts
"HTML_INCLUDE_SCRIPTS" nil nil
)
69 (:s5-version
"S5_VERSION" nil org-s5-version
)
70 (:s5-theme-file
"S5_THEME_FILE" nil org-s5-theme-file
)
71 (:s5-ui-url
"S5_UI_URL" nil org-s5-ui-url
))
73 ((headline . org-s5-headline
)
74 (plain-list . org-s5-plain-list
)
75 (template . org-s5-template
)))
77 (defgroup org-export-s5 nil
78 "Options for exporting Org mode files to S5 HTML Presentations."
80 :group
'org-export-html
)
82 (defcustom org-s5-version
"1.2a2"
83 "Version of s5 being used (for version metadata.) Defaults to
85 Can be overridden with S5_VERSION."
89 (defcustom org-s5-theme-file nil
90 "Url to S5 theme (slides.css) file. Can be overriden with the
91 S5_THEME_FILE property. If nil, defaults to
92 `org-s5-ui-url'/default/slides.css. If it starts with anything but
93 \"http\" or \"/\", it is used as-is. Otherwise the link in generated
94 relative to `org-s5-ui-url'.
95 The links for all other required stylesheets and scripts will be
96 generated relative to `org-s5-ui-url'/default."
100 (defcustom org-s5-ui-url
"ui"
101 "Base url to directory containing S5 \"default\" subdirectory
102 and the \"s5-notes.html\" file.
103 Can be overriden with the S5_UI_URL property."
104 :group
'org-export-s5
107 (defcustom org-s5-default-view
'slideshow
108 "Setting for \"defaultView\" meta info."
109 :group
'org-export-s5
110 :type
'(choice (const slideshow
) (const outline
)))
112 (defcustom org-s5-control-visibility
'hidden
113 "Setting for \"controlVis\" meta info."
114 :group
'org-export-s5
115 :type
'(choice (const hidden
) (const visibile
)))
117 (defcustom org-s5-footer-template
119 <h1>%author - %title</h1>
121 "Format template to specify footer div. Completed using
123 Optional keys include %author, %email, %file, %title and %date.
124 Note that the div id must be \"footer\"."
125 :group
'org-export-s5
128 (defcustom org-s5-header-template
"<div id=\"header\"></div>"
129 "Format template to specify footer div. Completed using
131 Optional keys include %author, %email, %file, %title and %date.
132 Note that the div id must be \"header\"."
133 :group
'org-export-s5
136 (defcustom org-s5-title-page-template
137 "<div class=\"slide title-page\">
143 "Format template to specify title page div. Completed using
145 Optional keys include %author, %email, %file, %title and %date.
146 Note that the wrapper div must include the class \"slide\"."
147 :group
'org-export-s5
151 (defun org-s5-toc (depth info
)
152 (let* ((headlines (org-export-collect-headlines info depth
))
154 (loop for headline in headlines collect
155 (list (org-html-format-headline--wrap
156 headline info
'org-html-format-toc-headline
)
157 (org-export-get-relative-level headline info
)))))
160 "<div id=\"table-of-contents\" class=\"slide\">\n"
161 (format "<h1>%s</h1>\n"
162 (org-html--translate "Table of Contents" info
))
163 "<div id=\"text-table-of-contents\">"
164 (org-html-toc-text toc-entries
)
168 (defun org-s5--build-style (info)
169 (let* ((dir (plist-get info
:s5-ui-url
))
170 (theme (or (plist-get info
:s5-theme-file
) "default/slides.css")))
174 "<!-- style sheet links -->"
179 "<link rel='stylesheet' href='%s/default/%s' type='text/css'"
180 " media='%s' id='%s' />")
181 dir
(nth 0 list
) (nth 1 list
) (nth 2 list
)))
183 '("outline.css" "screen" "outlineStyle")
184 '("print.css" "print" "slidePrint")
185 '("opera.css" "projection" "operaFix")) "\n")
187 "<link rel='stylesheet' href='%s' type='text/css'"
188 " media='screen' id='slideProj' />")
189 (if (string-match-p "^\\(http\\|/\\)" theme
) theme
190 (concat dir
"/" theme
)))
194 "/default/slides.js' type='text/javascript'></script>")) "\n")))
196 (defun org-s5--build-meta-info (info)
198 (org-html--build-meta-info info
)
199 (format "<meta name=\"version\" content=\"S5 %s\" />"
200 (plist-get info
:s5-version
))
201 "<meta name='defaultView' content='slideshow' />\n"
202 "<meta name='controlVis' content='hidden' />"))
204 (defun org-s5-headline (headline contents info
)
205 (let ((org-html-toplevel-hlevel 1))
207 (if (= 1 (+ (org-element-property :level headline
)
208 (plist-get info
:headline-offset
)))
209 (org-element-put-property
210 headline
:html-container-class
213 (org-element-property
214 :html-container-class headline
)
216 headline
) contents info
)))
218 (defun org-s5-plain-list (plain-list contents info
)
219 "Transcode a PLAIN-LIST element from Org to HTML.
220 CONTENTS is the contents of the list. INFO is a plist holding
221 contextual information.
222 If a containing headline has the property :incremental,
223 then the \"incremental\" class will be added to the to the list,
224 which will make the list into a \"build\"."
225 (let* ((type (org-element-property :type plain-list
))
229 (descriptive "dl"))))
232 "<%s class='org-%s%s'>" tag tag
233 (if (org-export-get-node-property :incremental plain-list t
)
235 contents
(org-html-end-plain-list type
))))
237 (defun org-s5-template-alist (info)
239 ("title" .
,(car (plist-get info
:title
)))
240 ("author" .
,(car (plist-get info
:author
)))
241 ("email" .
,(plist-get info
:email
))
242 ("date" .
,(substring (nth 0 (plist-get info
:date
)) 0 10))
243 ("file" .
,(plist-get info
:input-file
))))
245 (defun org-s5-template (contents info
)
246 "Return complete document string after HTML conversion.
247 CONTENTS is the transcoded contents string. INFO is a plist
248 holding export options."
252 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
253 \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
254 (format "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\">"
255 (plist-get info
:language
) (plist-get info
:language
))
257 (org-s5--build-meta-info info
)
258 (org-s5--build-style info
)
259 (org-html--build-style info
)
260 (org-html--build-mathjax-config info
)
263 "<div class=\"layout\">"
264 "<div id=\"controls\"><!-- no edit --></div>"
265 "<div id=\"currentSlide\"><!-- no edit --></div>"
267 org-s5-header-template
(org-s5-template-alist info
))
269 org-s5-footer-template
(org-s5-template-alist info
))
271 (format "<div id=\"%s\" class=\"presentation\">" (nth 1 org-html-divs
))
274 org-s5-title-page-template
(org-s5-template-alist info
))
275 (let ((depth (plist-get info
:with-toc
)))
276 (when depth
(org-s5-toc depth info
)))
282 (defun org-s5-export-as-html
283 (&optional async subtreep visible-only body-only ext-plist
)
284 "Export current buffer to an HTML buffer.
286 If narrowing is active in the current buffer, only export its
289 If a region is active, export that region.
291 A non-nil optional argument ASYNC means the process should happen
292 asynchronously. The resulting buffer should be accessible
293 through the `org-export-stack' interface.
295 When optional argument SUBTREEP is non-nil, export the sub-tree
296 at point, extracting information from the headline properties
299 When optional argument VISIBLE-ONLY is non-nil, don't export
300 contents of hidden elements.
302 When optional argument BODY-ONLY is non-nil, only write code
303 between \"<body>\" and \"</body>\" tags.
305 EXT-PLIST, when provided, is a property list with external
306 parameters overriding Org default settings, but still inferior to
309 Export is done in a buffer named \"*Org S5 Export*\", which
310 will be displayed when `org-export-show-temporary-export-buffer'
314 (org-export-async-start
316 (with-current-buffer (get-buffer-create "*Org S5 Export*")
319 (goto-char (point-min))
321 (org-export-add-to-stack (current-buffer) 's5
)))
322 `(org-export-as 's5
,subtreep
,visible-only
,body-only
',ext-plist
))
323 (let ((outbuf (org-export-to-buffer
324 's5
"*Org S5 Export*"
325 subtreep visible-only body-only ext-plist
)))
327 (with-current-buffer outbuf
(nxml-mode))
328 (when org-export-show-temporary-export-buffer
329 (switch-to-buffer-other-window outbuf
)))))
331 (defun org-s5-export-to-html
332 (&optional async subtreep visible-only body-only ext-plist
)
333 "Export current buffer to a S5 HTML file.
335 If narrowing is active in the current buffer, only export its
338 If a region is active, export that region.
340 A non-nil optional argument ASYNC means the process should happen
341 asynchronously. The resulting file should be accessible through
342 the `org-export-stack' interface.
344 When optional argument SUBTREEP is non-nil, export the sub-tree
345 at point, extracting information from the headline properties
348 When optional argument VISIBLE-ONLY is non-nil, don't export
349 contents of hidden elements.
351 When optional argument BODY-ONLY is non-nil, only write code
352 between \"<body>\" and \"</body>\" tags.
354 EXT-PLIST, when provided, is a property list with external
355 parameters overriding Org default settings, but still inferior to
358 Return output file's name."
360 (let* ((extension (concat "." org-html-extension
))
361 (file (org-export-output-file-name extension subtreep
))
362 (org-export-coding-system org-html-coding-system
))
364 (org-export-async-start
365 (lambda (f) (org-export-add-to-stack f
's5
))
366 (let ((org-export-coding-system org-html-coding-system
))
369 's5
,file
,subtreep
,visible-only
,body-only
',ext-plist
))))
370 (let ((org-export-coding-system org-html-coding-system
))
372 's5 file subtreep visible-only body-only ext-plist
)))))
374 (defun org-s5-publish-to-html (plist filename pub-dir
)
375 "Publish an org file to S5 HTML Presentation.
377 FILENAME is the filename of the Org file to be published. PLIST
378 is the property list for the given project. PUB-DIR is the
379 publishing directory.
381 Return output file name."
382 (org-publish-org-to 's5 filename
".html" plist pub-dir
))