dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

ox-deck.el (22926B)


      1 ;;; ox-deck.el --- deck.js Presentation Back-End for Org Export Engine
      2 
      3 ;; Copyright (C) 2013, 2014, 2021  Rick Frankel
      4 
      5 ;; Author: Rick Frankel <emacs at rickster dot com>
      6 ;; Keywords: outlines, hypermedia, slideshow
      7 
      8 ;; This file is not part of GNU Emacs.
      9 
     10 ;; This program is free software; you can redistribute it and/or modify
     11 ;; it under the terms of the GNU General Public License as published by
     12 ;; the Free Software Foundation, either version 3 of the License, or
     13 ;; (at your option) any later version.
     14 
     15 ;; This program is distributed in the hope that it will be useful,
     16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18 ;; GNU General Public License for more details.
     19 
     20 ;; You should have received a copy of the GNU General Public License
     21 ;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
     22 
     23 ;;; Commentary:
     24 
     25 ;; This library implements a deck.js presentation back-end for the Org
     26 ;; generic exporter.
     27 
     28 ;; Installation
     29 ;; -------------
     30 ;; Get a copy of deck.js from http://imakewebthings.com/deck.js/ or
     31 ;; the gitub repository at https://github.com/imakewebthings/deck.js.
     32 ;;
     33 ;; Add the path to the extracted code to the variable
     34 ;; `org-deck-directories' There are a number of customization in the
     35 ;; org-export-deck group, most of which can be overridden with buffer
     36 ;; local customization (starting with DECK_.)
     37 
     38 ;; See ox.el and ox-html.el for more details on how this exporter
     39 ;; works (it is derived from ox-html.)
     40 
     41 ;; TODOs
     42 ;; ------
     43 ;; The title page is formatted using format-spec.  This is error prone
     44 ;; when details are missing and may insert empty tags, like <h2></h2>,
     45 ;; for missing values.
     46 
     47 (require 'ox-html)
     48 (eval-when-compile (require 'cl))
     49 
     50 (org-export-define-derived-backend 'deck 'html
     51   :menu-entry
     52   '(?d "Export to deck.js HTML Presentation"
     53        ((?H "To temporary buffer" org-deck-export-as-html)
     54 	(?h "To file" org-deck-export-to-html)
     55 	(?o "To file and open"
     56 	    (lambda (a s v b)
     57 	      (if a (org-deck-export-to-html t s v b)
     58 		(org-open-file (org-deck-export-to-html nil s v b)))))))
     59   :options-alist
     60   '((:description "DESCRIPTION" nil nil newline)
     61     (:keywords "KEYWORDS" nil nil space)
     62     (:html-link-home "HTML_LINK_HOME" nil nil)
     63     (:html-link-up "HTML_LINK_UP" nil nil)
     64     (:deck-postamble "DECK_POSTAMBLE" nil org-deck-postamble newline)
     65     (:deck-preamble "DECK_PREAMBLE" nil org-deck-preamble newline)
     66     (:html-head-include-default-style "HTML_INCLUDE_DEFAULT_STYLE" "html-style" nil)
     67     (:html-head-include-scripts "HTML_INCLUDE_SCRIPTS" nil nil)
     68     (:deck-base-url "DECK_BASE_URL" nil org-deck-base-url)
     69     (:deck-theme "DECK_THEME" nil org-deck-theme)
     70     (:deck-transition "DECK_TRANSITION" nil org-deck-transition)
     71     (:deck-include-extensions "DECK_INCLUDE_EXTENSIONS" nil
     72 			      org-deck-include-extensions split)
     73     (:deck-exclude-extensions "DECK_EXCLUDE_EXTENSIONS" nil
     74 			      org-deck-exclude-extensions split))
     75   :translate-alist
     76   '((headline . org-deck-headline)
     77     (inner-template . org-deck-inner-template)
     78     (item . org-deck-item)
     79     (link . org-deck-link)
     80     (template . org-deck-template)))
     81 
     82 (defgroup org-export-deck nil
     83   "Options for exporting Org mode files to deck.js HTML Presentations."
     84   :tag "Org Export DECK"
     85   :group 'org-export-html)
     86 
     87 (defcustom org-deck-directories '("./deck.js")
     88   "Directories to search for deck.js components (jquery,
     89 modernizr; core, extensions and themes directories.)"
     90   :group 'org-export-deck
     91   :type '(repeat (string :tag "Directory")))
     92 
     93 (defun org-deck--cleanup-components (components)
     94   (remove-duplicates
     95    (car (remove 'nil components))
     96    :test (lambda (x y)
     97            (string= (file-name-nondirectory x)
     98                     (file-name-nondirectory y)))))
     99 
    100 (defun org-deck--find-extensions ()
    101   "Returns a unique list of all extensions found in
    102 in the extensions directories under `org-deck-directories'"
    103   (org-deck--cleanup-components
    104    (mapcar                              ; extensions under existing dirs
    105     (lambda (dir)
    106       (when (file-directory-p dir) (directory-files dir t "^[^.]")))
    107     (mapcar                           ; possible extension directories
    108      (lambda (x) (expand-file-name "extensions" x))
    109      org-deck-directories))))
    110 
    111 (defun org-deck--find-css (type)
    112   "Return a unique list of all the css stylesheets in the themes/TYPE
    113 directories under `org-deck-directories'."
    114   (org-deck--cleanup-components
    115    (mapcar
    116     (lambda (dir)
    117       (let ((css-dir (expand-file-name
    118                       (concat (file-name-as-directory "themes") type) dir)))
    119         (when (file-directory-p css-dir)
    120           (directory-files css-dir t  "\\.css$"))))
    121     org-deck-directories)))
    122 
    123 (defun org-deck-list-components ()
    124   "List all available deck extensions, styles and
    125 transitions (with full paths) to a temporary buffer."
    126   (interactive)
    127   (let ((outbuf (get-buffer-create "*deck.js Extensions*")))
    128     (with-current-buffer outbuf
    129       (erase-buffer)
    130       (insert "Extensions\n----------\n")
    131       (insert (mapconcat 'identity (org-deck--find-extensions) "\n"))
    132       (insert "\n\nStyles\n------\n")
    133       (insert (mapconcat 'identity (org-deck--find-css "style") "\n"))
    134       (insert "\n\nTransitions\n----------\n")
    135       (insert (mapconcat 'identity (org-deck--find-css "transition") "\n")))
    136     (switch-to-buffer-other-window outbuf)))
    137 
    138 (defcustom org-deck-include-extensions nil
    139   "If non-nil, list of extensions to include instead of all available.
    140 Can be overridden or set with the DECK_INCLUDE_EXTENSIONS property.
    141 During output generation, the extensions found by
    142 `org-deck--find-extensions' are searched for the appropriate
    143 files (scripts and/or stylesheets) to include in the generated
    144 html. The href/src attributes are created relative to `org-deck-base-url'."
    145   :group 'org-export-deck
    146   :type '(repeat (string :tag "Extension")))
    147 
    148 (defcustom org-deck-exclude-extensions nil
    149   "If non-nil, list of extensions to exclude.
    150 Can be overridden or set with the DECK_EXCLUDE_EXTENSIONS property."
    151   :group 'org-export-deck
    152   :type '(repeat (string :tag "Extension")))
    153 
    154 (defcustom org-deck-theme "swiss.css"
    155   "deck.js theme. Can be overridden with the DECK_THEME property.
    156 If this value contains a path component (\"/\"), it is used as a
    157 literal path (url). Otherwise it is prepended with
    158 `org-deck-base-url'/themes/style/."
    159   :group 'org-export-deck
    160   :type 'string)
    161 
    162 (defcustom org-deck-transition "fade.css"
    163   "deck.js transition theme. Can be overridden with the
    164 DECK_TRANSITION property.
    165 If this value contains a path component (\"/\"), it is used as a
    166 literal path (url). Otherwise it is prepended with
    167 `org-deck-base-url'/themes/transition/."
    168   :group 'org-export-deck
    169   :type 'string)
    170 
    171 (defcustom org-deck-base-url "deck.js"
    172   "Url prefix to deck.js base directory containing the core, extensions
    173 and themes directories.
    174 Can be overridden with the DECK_BASE_URL property."
    175   :group 'org-export-deck
    176   :type 'string)
    177 
    178 (defvar org-deck-pre/postamble-styles
    179   `((both "left: 5px; width: 100%;")
    180     (preamble "position: absolute; top: 10px;")
    181     (postamble ""))
    182   "Alist of css styles for the preamble, postamble and both respectively.
    183 Can be overridden in `org-deck-styles'. See also `org-html-divs'.")
    184 
    185 (defcustom org-deck-postamble "<h1>%a - %t</h1>"
    186   "Non-nil means insert a postamble in HTML export.
    187 
    188 When set to a string, use this string
    189 as the postamble.  When t, insert a string as defined by the
    190 formatting string in `org-html-postamble-format'.
    191 
    192 When set to a function, apply this function and insert the
    193 returned string.  The function takes the property list of export
    194 options as its only argument.
    195 
    196 This is included in the document at the bottom of the content
    197 section, and uses the postamble element and id from
    198 `org-html-divs'. The default places the author and presentation
    199 title at the bottom of each slide.
    200 
    201 The css styling is controlled by `org-deck-pre/postamble-styles'.
    202 
    203 Setting :deck-postamble in publishing projects will take
    204 precedence over this variable."
    205   :group 'org-export-deck
    206   :type '(choice (const :tag "No postamble" nil)
    207                  (const :tag "Default formatting string" t)
    208                  (string :tag "Custom formatting string")
    209                  (function :tag "Function (must return a string)")))
    210 
    211 (defcustom org-deck-preamble nil
    212   "Non-nil means insert a preamble in HTML export.
    213 
    214 When set to a string, use this string
    215 as the preamble.  When t, insert a string as defined by the
    216 formatting string in `org-html-preamble-format'.
    217 
    218 When set to a function, apply this function and insert the
    219 returned string.  The function takes the property list of export
    220 options as its only argument.
    221 
    222 This is included in the document at the top of  content section, and
    223 uses the preamble element and id from `org-html-divs'. The css
    224 styling is controlled by `org-deck-pre/postamble-styles'.
    225 
    226 Setting :deck-preamble in publishing projects will take
    227 precedence over this variable."
    228   :group 'org-export-deck
    229   :type '(choice (const :tag "No preamble" nil)
    230                  (const :tag "Default formatting string" t)
    231                  (string :tag "Custom formatting string")
    232                  (function :tag "Function (must return a string)")))
    233 
    234 (defvar org-deck-toc-styles
    235   (mapconcat
    236    'identity
    237    (list
    238     "#table-of-contents a {color: inherit;}"
    239     "#table-of-contents ul {margin-bottom: 0;}"
    240     "#table-of-contents li {padding: 0;}") "\n")
    241   "Default css styles used for formatting a table of contents slide.
    242 Can be overridden in `org-deck-styles'.
    243 Note that when the headline numbering option is true, a \"list-style: none\"
    244 is automatically added to avoid both numbers and bullets on the toc entries.")
    245 
    246 (defcustom org-deck-styles
    247   "
    248 #title-slide h1 {
    249     position: static; padding: 0;
    250     margin-top: 10%;
    251     -webkit-transform: none;
    252     -moz-transform: none;
    253     -ms-transform: none;
    254     -o-transform: none;
    255     transform: none;
    256 }
    257 #title-slide h2 {
    258     text-align: center;
    259     border:none;
    260     padding: 0;
    261     margin: 0;
    262 }"
    263   "Deck specific CSS styles to include in exported html.
    264 Defaults to styles for the title page."
    265   :group 'org-export-deck
    266   :type 'string)
    267 
    268 (defcustom org-deck-title-slide-template
    269   "<h1>%t</h1>
    270 <h2>%s</h2>
    271 <h2>%a</h2>
    272 <h2>%e</h2>
    273 <h2>%d</h2>"
    274   "Format template to specify title page section.
    275 See `org-html-postamble-format' for the valid elements which
    276 can be included.
    277 
    278 It will be wrapped in the element defined in the :html-container
    279 property, and defaults to the value of `org-html-container-element',
    280 and have the id \"title-slide\"."
    281   :group 'org-export-deck
    282   :type 'string)
    283 
    284 (defun org-deck-toc (depth info)
    285   (concat
    286    (format "<%s id='table-of-contents' class='slide'>\n"
    287            (plist-get info :html-container))
    288    (format "<h2>%s</h2>\n" (org-html--translate "Table of Contents" info))
    289    (org-html--toc-text
    290     (mapcar
    291      (lambda (headline)
    292        (let* ((class (org-element-property :HTML_CONTAINER_CLASS headline))
    293               (section-number
    294                (when
    295                    (and (not (org-export-low-level-p headline info))
    296                         (org-export-numbered-headline-p headline info))
    297                  (concat
    298                   (mapconcat
    299                    'number-to-string
    300                    (org-export-get-headline-number headline info) ".") ". ")))
    301               (title
    302                (concat
    303                 section-number
    304                 (replace-regexp-in-string ; remove any links in headline...
    305                  "</?a[^>]*>" ""
    306                  (org-export-data
    307                   (org-element-property :title headline) info)))))
    308          (cons
    309           (if (and class (string-match-p "\\<slide\\>" class))
    310               (format
    311                "<a href='#outline-container-%s'>%s</a>"
    312                (or (org-element-property :CUSTOM_ID headline)
    313 		   (concat
    314 		    "sec-"
    315 		    (mapconcat
    316 		     'number-to-string
    317 		     (org-export-get-headline-number headline info) "-")))
    318                title)
    319             title)
    320           (org-export-get-relative-level headline info))))
    321      (org-export-collect-headlines info depth)))
    322    (format "</%s>\n" (plist-get info :html-container))))
    323 
    324 (defun org-deck--get-packages (info)
    325   (let ((prefix (concat (plist-get info :deck-base-url) "/"))
    326         (theme (plist-get info :deck-theme))
    327         (transition (plist-get info :deck-transition))
    328         (include (plist-get info :deck-include-extensions))
    329         (exclude (plist-get info :deck-exclude-extensions))
    330         (scripts '()) (sheets '()) (snippets '()))
    331     (add-to-list 'scripts (concat prefix "jquery.min.js"))
    332     (add-to-list 'scripts (concat prefix "core/deck.core.js"))
    333     (add-to-list 'scripts (concat prefix "modernizr.custom.js"))
    334     (add-to-list 'sheets  (concat prefix "core/deck.core.css"))
    335     (mapc
    336      (lambda (extdir)
    337        (let* ((name (file-name-nondirectory extdir))
    338               (dir (file-name-as-directory extdir))
    339               (path (concat prefix "extensions/" name "/"))
    340               (base (format "deck.%s." name)))
    341          (when (and (or (eq nil include) (member name include))
    342                     (not (member name exclude)))
    343            (when (file-exists-p (concat dir base "js"))
    344              (add-to-list 'scripts (concat path base "js")))
    345            (when (file-exists-p (concat dir base "css"))
    346              (add-to-list 'sheets (concat path base "css")))
    347            (when (file-exists-p (concat dir base "html"))
    348              (add-to-list 'snippets (concat dir base "html"))))))
    349      (org-deck--find-extensions))
    350     (if (not (string-match-p "^[[:space:]]*$" theme))
    351         (add-to-list 'sheets
    352                      (if (file-name-directory theme) theme
    353                        (format "%sthemes/style/%s" prefix theme))))
    354     (if (not (string-match-p "^[[:space:]]*$" transition))
    355         (add-to-list
    356          'sheets
    357          (if (file-name-directory transition) transition
    358            (format "%sthemes/transition/%s" prefix transition))))
    359     (list :scripts (nreverse scripts) :sheets (nreverse sheets)
    360           :snippets snippets)))
    361 
    362 (defun org-deck-inner-template (contents info)
    363   "Return body of document string after HTML conversion.
    364 CONTENTS is the transcoded contents string.  INFO is a plist
    365 holding export options."
    366   (concat contents "\n"))
    367 
    368 (defun org-deck-headline (headline contents info)
    369   (let ((org-html-toplevel-hlevel 2)
    370         (class (or (org-element-property :HTML_CONTAINER_CLASS headline) ""))
    371         (level (org-export-get-relative-level headline info)))
    372     (when (and (= 1 level) (not (string-match-p "\\<slide\\>" class)))
    373       (org-element-put-property headline :HTML_CONTAINER_CLASS (concat class " slide")))
    374     (org-html-headline headline contents info)))
    375 
    376 (defun org-deck-item (item contents info)
    377   "Transcode an ITEM element from Org to HTML.
    378 CONTENTS holds the contents of the item.  INFO is a plist holding
    379 contextual information.
    380 If the containing headline has the property :STEP, then
    381 the \"slide\" class will be added to the to the list element,
    382  which will make the list into a \"build\"."
    383   (let ((text (org-html-item item contents info)))
    384     (if (org-export-get-node-property :STEP item t)
    385 	(progn
    386 	  (replace-regexp-in-string "^<li>" "<li class='slide'>" text)
    387 	  (replace-regexp-in-string "^<li class='checkbox'>" "<li class='checkbox slide'>" text))
    388       text)))
    389 
    390 (defun org-deck-link (link desc info)
    391   (replace-regexp-in-string "href=\"#" "href=\"#outline-container-"
    392 			    (org-export-with-backend 'html link desc info)))
    393 
    394 (defun org-deck-template (contents info)
    395   "Return complete document string after HTML conversion.
    396 CONTENTS is the transcoded contents string.  INFO is a plist
    397 holding export options."
    398   (let ((pkg-info (org-deck--get-packages info))
    399 	(org-html--pre/postamble-class "deck-status")
    400 	(info (plist-put
    401 	       (plist-put info :html-preamble (plist-get info :deck-preamble))
    402 	       :html-postamble (plist-get info :deck-postamble))))
    403     (mapconcat
    404      'identity
    405      (list
    406       (org-html-doctype info)
    407       (let ((lang (plist-get info :language)))
    408         (mapconcat
    409          (lambda (x)
    410            (apply
    411             'format
    412             "<!--%s <html %s lang='%s' xmlns='http://www.w3.org/1999/xhtml'> %s<![endif]-->"
    413             x))
    414          (list `("[if lt IE 7]>" "class='no-js ie6'" ,lang "")
    415                `("[if IE 7]>" "class='no-js ie7'" ,lang "")
    416                `("[if IE 8]>" "class='no-js ie8'" ,lang "")
    417                `("[if gt IE 8]><!-->" "" ,lang "<!--")) "\n"))
    418       "<head>"
    419       (org-deck--build-meta-info info)
    420       (mapconcat
    421        (lambda (sheet)
    422          (format
    423           "<link rel='stylesheet' href='%s' type='text/css' />" sheet))
    424        (plist-get pkg-info :sheets) "\n")
    425       (mapconcat
    426        (lambda (script)
    427          (format
    428           "<script src='%s'></script>" script))
    429        (plist-get pkg-info :scripts) "\n")
    430       (org-html--build-mathjax-config info)
    431       "<script>"
    432       "  $(document).ready(function () { $.deck('.slide'); });"
    433       "</script>"
    434       (org-html--build-head info)
    435       "<style type='text/css'>"
    436       org-deck-toc-styles
    437       (when (plist-get info :section-numbers)
    438         "#table-of-contents ul li {list-style-type: none;}")
    439       (format "#%s, #%s {%s}"
    440               (nth 2 (assq 'preamble org-html-divs))
    441               (nth 2 (assq 'postamble org-html-divs))
    442               (nth 1 (assq 'both org-deck-pre/postamble-styles)))
    443       (format "#%s {%s}"
    444               (nth 2 (assq 'preamble org-html-divs))
    445               (nth 1 (assq 'preamble org-deck-pre/postamble-styles)))
    446       (format "#%s {%s}"
    447               (nth 2 (assq 'postamble org-html-divs))
    448               (nth 1 (assq 'postamble org-deck-pre/postamble-styles)))
    449       org-deck-styles
    450       "</style>"
    451       "</head>"
    452       "<body>"
    453       (format "<%s id='%s' class='deck-container'>"
    454               (nth 1 (assq 'content org-html-divs))
    455               (nth 2 (assq 'content org-html-divs)))
    456       (org-html--build-pre/postamble 'preamble info)
    457       ;; title page
    458       (format "<%s id='title-slide' class='slide'>"
    459               (plist-get info :html-container))
    460       (format-spec org-deck-title-slide-template (org-html-format-spec info))
    461       (format "</%s>" (plist-get info :html-container))
    462       ;; toc page
    463       (let ((depth (plist-get info :with-toc)))
    464         (when depth (org-deck-toc depth info)))
    465       contents
    466       (mapconcat
    467        (lambda (snippet)
    468          (with-temp-buffer (insert-file-contents snippet)
    469                            (buffer-string)))
    470        (plist-get pkg-info :snippets) "\n")
    471       (org-html--build-pre/postamble 'postamble info)
    472       (format "</%s>" (nth 1 (assq 'content org-html-divs)))
    473       "</body>"
    474       "</html>\n") "\n")))
    475 
    476 (defun org-deck--build-meta-info (info)
    477   "Return meta tags for exported document.
    478 INFO is a plist used as a communication channel."
    479   (let* ((title (org-export-data (plist-get info :title) info))
    480          (author (and (plist-get info :with-author)
    481                       (let ((auth (plist-get info :author)))
    482                         (and auth (org-export-data auth info)))))
    483          (date (and (plist-get info :with-date)
    484                     (let ((date (org-export-get-date info)))
    485                       (and date (org-export-data date info)))))
    486          (description (plist-get info :description))
    487          (keywords (plist-get info :keywords)))
    488     (mapconcat
    489      'identity
    490      (list
    491       (format "<title>%s</title>" title)
    492       (format "<meta http-equiv='Content-Type' content='text/html; charset=%s'/>"
    493               (or (and org-html-coding-system
    494                        (fboundp 'coding-system-get)
    495                        (coding-system-get
    496                         org-html-coding-system 'mime-charset))
    497                   "iso-8859-1"))
    498       (mapconcat
    499        (lambda (attr)
    500          (when (< 0 (length (car attr)))
    501            (format "<meta name='%s' content='%s'/>\n"
    502                    (nth 1 attr) (car attr))))
    503        (list '("Org-mode" "generator")
    504              `(,author "author")
    505              `(,description "description")
    506              `(,keywords "keywords")) "")) "\n")))
    507 (defun org-deck-export-as-html
    508   (&optional async subtreep visible-only body-only ext-plist)
    509   "Export current buffer to an HTML buffer.
    510 
    511 If narrowing is active in the current buffer, only export its
    512 narrowed part.
    513 
    514 If a region is active, export that region.
    515 
    516 A non-nil optional argument ASYNC means the process should happen
    517 asynchronously.  The resulting buffer should be accessible
    518 through the `org-export-stack' interface.
    519 
    520 When optional argument SUBTREEP is non-nil, export the sub-tree
    521 at point, extracting information from the headline properties
    522 first.
    523 
    524 When optional argument VISIBLE-ONLY is non-nil, don't export
    525 contents of hidden elements.
    526 
    527 When optional argument BODY-ONLY is non-nil, only write code
    528 between \"<body>\" and \"</body>\" tags.
    529 
    530 EXT-PLIST, when provided, is a property list with external
    531 parameters overriding Org default settings, but still inferior to
    532 file-local settings.
    533 
    534 Export is done in a buffer named \"*Org deck.js Export*\", which
    535 will be displayed when `org-export-show-temporary-export-buffer'
    536 is non-nil."
    537   (interactive)
    538   (org-export-to-buffer 'deck "*Org deck.js Export*"
    539     async subtreep visible-only body-only ext-plist (lambda () (nxml-mode))))
    540 
    541 (defun org-deck-export-to-html
    542   (&optional async subtreep visible-only body-only ext-plist)
    543   "Export current buffer to a deck.js HTML file.
    544 
    545 If narrowing is active in the current buffer, only export its
    546 narrowed part.
    547 
    548 If a region is active, export that region.
    549 
    550 A non-nil optional argument ASYNC means the process should happen
    551 asynchronously.  The resulting file should be accessible through
    552 the `org-export-stack' interface.
    553 
    554 When optional argument SUBTREEP is non-nil, export the sub-tree
    555 at point, extracting information from the headline properties
    556 first.
    557 
    558 When optional argument VISIBLE-ONLY is non-nil, don't export
    559 contents of hidden elements.
    560 
    561 When optional argument BODY-ONLY is non-nil, only write code
    562 between \"<body>\" and \"</body>\" tags.
    563 
    564 EXT-PLIST, when provided, is a property list with external
    565 parameters overriding Org default settings, but still inferior to
    566 file-local settings.
    567 
    568 Return output file's name."
    569   (interactive)
    570   (let* ((extension (concat "." org-html-extension))
    571          (file (org-export-output-file-name extension subtreep))
    572 	 (org-export-coding-system org-html-coding-system))
    573     (org-export-to-file 'deck file
    574       async subtreep visible-only body-only ext-plist)))
    575 
    576 (defun org-deck-publish-to-html (plist filename pub-dir)
    577   "Publish an org file to deck.js HTML Presentation.
    578 FILENAME is the filename of the Org file to be published.  PLIST
    579 is the property list for the given project.  PUB-DIR is the
    580 publishing directory. Returns output file name."
    581   (org-publish-org-to 'deck filename ".html" plist pub-dir))
    582 
    583 (provide 'ox-deck)
    584 
    585 ;;; ox-deck.el ends here