emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* [PATH] [NEW EXPORTER] two slide backends for contrib
@ 2013-02-20  0:18 Rick Frankel
  2013-02-20 15:34 ` Bastien
  0 siblings, 1 reply; 6+ messages in thread
From: Rick Frankel @ 2013-02-20  0:18 UTC (permalink / raw)
  To: emacs-orgmode

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

Attached are:

	 - ox-deck.el
	 - ox-s5.el

Which, respectively, provide deck.js and s5 backends for the new
exporter. I would be happy for these to be included in contrib. Note
that I have already signed the FSF assignment documents, so they can
be safely included in the core if so desired.

rick 

[-- Attachment #2: ox-deck.el --]
[-- Type: text/plain, Size: 20013 bytes --]

;;; ox-deck.el --- deck.js Presentation Back-End for Org Export Engine

;; Copyright (C) 2013  Free Software Foundation, Inc.

;; Author: Rick Frankel <emacs at rickster dot com>
;; Keywords: outlines, hypermedia, slideshow

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;; This library implements a deck.js presentation back-end for the Org
;; generic exporter.

;; Installation
;; -------------
;; Get a copy of deck.js from http://imakewebthings.com/deck.js/ or
;; the gitub repository at https://github.com/imakewebthings/deck.js.
;;
;; Add the path to the extracted code to the variable
;; `org-deck-directories' There are a number of customization in the
;; org-export-deck group, most of which can be overrriden with buffer
;; local customization (starting with DECK_.)

;; See ox.el and ox-html.el for more details on how this exporter
;; works (it is derived from ox-html.)

(require 'ox-html)

(org-export-define-derived-backend deck html
  :menu-entry
  (?s "Export to deck.js HTML Presentation"
      ((?H "To temporary buffer" org-deck-export-as-html)
       (?h "To file" org-deck-export-to-html)
       (?o "To file and open"
	   (lambda (a s v b)
	     (if a (org-deck-export-to-html t s v b)
	       (org-open-file (org-deck-export-to-html nil s v b)))))))
  :options-alist
  ((:html-link-home "HTML_LINK_HOME" nil nil)
   (:html-link-up "HTML_LINK_UP" nil nil)
   (:html-mathjax "HTML_MATHJAX" nil "" space)
   (:html-postamble nil "html-postamble" nil t)
   (:html-preamble nil "html-preamble" nil t)
   (:html-style-extra "HTML_STYLE" nil org-html-style-extra newline)
   (:html-style-include-default "HTML_INCLUDE_DEFAULT" nil nil)
   (:html-style-include-scripts "HTML_INCLUDE_SCRIPTS" nil nil)
   (:deck-base-url "DECK_BASE_URL" nil org-deck-base-url)
   (:deck-theme "DECK_THEME" nil org-deck-theme)
   (:deck-transition "DECK_TRANSITION" nil org-deck-transition)
   (:deck-include-extensions "DECK_INCLUDE_EXTENSIONS" nil
		     org-deck-include-extensions split)
   (:deck-exclude-extensions "DECK_EXCLUDE_EXTENSIONS" nil
			     org-deck-exclude-extensions split)
   (:deck-directories "DECK_DIRECTORIES" nil
			   org-deck-directories split))
  :translate-alist
  ((headline . org-deck-headline)
   (inner-template . org-deck-inner-template)
   (item . org-deck-item)
   (template . org-deck-template)))

(defgroup org-export-deck nil
  "Options for exporting Org mode files to deck.js HTML Presentations."
  :tag "Org Export DECK"
  :group 'org-export-html)

(defcustom org-deck-directories nil
  "Directories to search for deck.js components (jquery,
modernizr; core, extensions and themes directories.)"
  :group 'org-export-deck
  :type '(repeat (string :tag "Directory")))

(defun org-deck--cleanup-components (components)
  (remove-duplicates 
   (car (remove 'nil components))
   :test (lambda (x y)
	   (string= (file-name-nondirectory x)
		    (file-name-nondirectory y)))))
  
(defun org-deck--find-extensions ()
  "Returns a unique list of all extensions found in
in the extensions directories under `org-deck-directories'"
  (org-deck--cleanup-components
     (mapcar				; extensions under existing dirs
      (lambda (dir)
	(when (file-directory-p dir) (directory-files dir t "^[^.]")))
      (mapcar 	 			; possible extension directories
       (lambda (x) (expand-file-name "extensions" x))
       org-deck-directories))))

(defun org-deck--find-css (type)
  "Return a unique list of all the css stylesheets in the themes/TYPE
directories under `org-deck-directories'."
  (org-deck--cleanup-components
   (mapcar
    (lambda (dir)
      (let ((css-dir (expand-file-name
		      (concat (file-name-as-directory "themes") type) dir)))
	(when (file-directory-p css-dir)
	  (directory-files css-dir t  "\\.css$"))))
      org-deck-directories)))

(defun org-deck-list-components ()
  "List all available deck extensions, styles and
transitions (with full paths) to a temporary buffer."
  (interactive)
  (let ((outbuf (get-buffer-create "*deck.js Extensions*")))
    (with-current-buffer outbuf
      (erase-buffer)
      (insert "Extensions\n----------\n")
      (insert (mapconcat 'identity (org-deck--find-extensions) "\n"))
      (insert "\n\nStyles\n------\n")
      (insert (mapconcat 'identity (org-deck--find-css "style") "\n"))
      (insert "\n\nTransitions\n----------\n")
      (insert (mapconcat 'identity (org-deck--find-css "transition") "\n")))
    (switch-to-buffer-other-window outbuf)))

(defcustom org-deck-include-extensions nil
  "If non-nil, list of extensions to include instead of all available.
Can be overriden or set with the DECK_INCLUDE_EXTENSIONS property.
During output generation, the extensions found by
`org-deck--find-extensions' are searched for the appropriate
files (scripts and/or stylesheets) to include in the generated
html. The href/src attributes are created relative to `org-deck-base-url'."
  :group 'org-export-deck
  :type '(repeat (string :tag "Extension")))

(defcustom org-deck-exclude-extensions nil
  "If non-nil, list of extensions to exclude.
Can be overriden or set with the DECK_EXCLUDE_EXTENSIONS property."
  :group 'org-export-deck
  :type '(repeat (string :tag "Extension")))

(defcustom org-deck-theme "swiss.css"
  "deck.js theme. Can be overriden with the DECK_THEME property.
If this value contains a path component (\"/\"), it is used as a
literal path (url). Otherwise it is prepended with
`org-deck-base-url'/themes/style/."
  :group 'org-export-deck
  :type 'string)

(defcustom org-deck-transition "fade.css"
  "deck.js transition theme. Can be overriden with the 
DECK_TRANSITION property.
If this value contains a path component (\"/\"), it is used as a
literal path (url). Otherwise it is prepended with
`org-deck-base-url'/themes/transition/."
  :group 'org-export-deck
  :type 'string)

(defcustom org-deck-base-url "deck.js"
  "Url prefix to deck.js base directory containing the core, extensions
and themes directories.
Can be overriden with the DECK_BASE_URL property."
  :group 'org-export-deck
  :type 'string)

(defcustom org-deck-footer-template
"<h1>%author - %title</h1>"
  "Format template to specify footer div.
Completed using `org-fill-template'.
Optional keys include %author, %email, %file, %title and %date.
This is included in a <footer> section."
  :group 'org-export-deck
  :type 'string)

(defcustom org-deck-header-template ""
  "Format template to specify page. Completed using `org-fill-template'.
Optional keys include %author, %email, %file, %title and %date.
This is included in a <header> section."
  :group 'org-export-deck
  :type 'string)

(defcustom org-deck-title-page-style
  "<style type='text/css'>
    header, footer { left: 5px; width: 100% }
    header { position: absolute; top: 10px; }
    #title-slide h1 {
        position: static; padding: 0;
        margin-top: 10%;
	-webkit-transform: none;
	-moz-transform: none;
	-ms-transform: none;
	-o-transform: none;
	transform: none;
    }
    #title-slide h2 {
        text-align: center;
        border:none;
        padding: 0;
        margin: 0;
    }
</style>"
  "CSS styles to use for title page"
  :group 'org-export-deck
  :type 'string)

(defcustom org-deck-title-page-template
  "<div class='slide' id='title-slide'>
<h1>%title</h1>
<h2>%author</h2>
<h2>%email</h2>
<h2>%date</h2>
</div>"
  "Format template to specify title page div.
Completed using `org-fill-template'.
Optional keys include %author, %email, %file, %title and %date.
Note that the wrapper div must include the class \"slide\"."
  :group 'org-export-deck
  :type 'string)

(defcustom org-deck-toc-style
  "<style type='text/css'>
    header, footer { left: 5px; width: 100% }
    header { position: absolute; top: 10px; }
    #table-of-contents h1 {
        position: static; padding: 0;
        margin-top: 10%;
	-webkit-transform: none;
	-moz-transform: none;
	-ms-transform: none;
	-o-transform: none;
	Transform: none;
    }
    #title-slide h2 {
        text-align: center;
        border:none;
        padding: 0;
        margin: 0;
    }
</style>"
  "CSS styles to use for title page"
  :group 'org-export-deck
  :type 'string)

(defun org-deck-toc (depth info)
  (concat
    "<div id=\"table-of-contents\" class=\"slide\">\n"
    (format "<h2>%s</h2>\n"
	    (org-html--translate "Table of Contents" info))
    (org-html-toc-text
     (mapcar 
      (lambda (headline)
	(let* ((class (org-element-property :html-container-class headline))
	       (section-number
		(when
		    (and (not (org-export-low-level-p headline info))
			 (org-export-numbered-headline-p headline info))
		  (concat
		   (mapconcat 
		    'number-to-string 
		    (org-export-get-headline-number headline info) ".") ". ")))
	      (title 
	       (concat 
		section-number
		(replace-regexp-in-string ; remove any links in headline...
		 "</?a[^>]*>" ""
		 (org-export-data
		  (org-element-property :title headline) info)))))
	  (list 
	   (if (and class (string-match-p "\\<slide\\>" class))
	       (format 
		"<a href='#outline-container-%s'>%s</a>"
		(or (org-element-property :custom-id headline)
		    (mapconcat 
		     'number-to-string
		     (org-export-get-headline-number headline info) "-"))
		title)
	     title)
	   (org-export-get-relative-level headline info))))
      (org-export-collect-headlines info depth)))
    "</div>\n" ))

(defun org-deck--get-packages (info)
  (let ((prefix (concat (plist-get info :deck-base-url) "/"))
	(theme (plist-get info :deck-theme))
	(transition (plist-get info :deck-transition))
	(include (plist-get info :deck-include-extensions))
	(exclude (plist-get info :deck-exclude-extensions))
	(scripts '()) (sheets '()) (snippets '()))
    (add-to-list 'scripts (concat prefix "jquery-1.7.2.min.js"))
    (add-to-list 'scripts (concat prefix "core/deck.core.js"))
    (add-to-list 'scripts (concat prefix "modernizr.custom.js"))
    (add-to-list 'sheets  (concat prefix "core/deck.core.css"))
     (mapc
      (lambda (extdir)
	(let* ((name (file-name-nondirectory extdir))
	       (dir (file-name-as-directory extdir))
	       (path (concat prefix "extensions/" name "/"))
	       (base (format "deck.%s." name)))
	  (when (and (or (eq nil include) (member name include))
		     (not (member name exclude)))
	    (when (file-exists-p (concat dir base "js"))
	      (add-to-list 'scripts (concat path base "js")))
	    (when (file-exists-p (concat dir base "css"))
	      (add-to-list 'sheets (concat path base "css")))
	    (when (file-exists-p (concat dir base "html"))
	      (add-to-list 'snippets (concat dir base "html"))))))
      (org-deck--find-extensions))
     (add-to-list 'sheets
		  (if (file-name-directory theme) theme
		    (format "%sthemes/style/%s" prefix theme)))
     (add-to-list
      'sheets
      (if (file-name-directory transition) transition
	(format "%sthemes/transition/%s" prefix transition)))
     (list :scripts (nreverse scripts) :sheets (nreverse sheets)
	   :snippets snippets)))

(defun org-html-inner-template (contents info)
  "Return body of document string after HTML conversion.
CONTENTS is the transcoded contents string.  INFO is a plist
holding export options."
  (concat
   ;; Table of contents.
   (let ((depth (plist-get info :with-toc)))
     (when depth (org-deck-toc depth info)))
   ;; Document contents.
   contents
   "\n"))

(defun org-deck-headline (headline contents info)
  (let ((org-html-toplevel-hlevel 2))
    (org-html-headline
     (if (= 1 (+ (org-element-property :level headline)
		 (plist-get info :headline-offset)))
         (org-element-put-property headline :html-container-class "slide")
       headline) contents info)))

(defun org-deck-item (item contents info)
  "Transcode an ITEM element from Org to HTML.
CONTENTS holds the contents of the item.  INFO is a plist holding
contextual information.
If the containing headline has the property :slide, then
the \"slide\" class will be added to the to the list element,
 which will make the list into a \"build\"."
  (let ((text (org-html-item item contents info)))
    (if (org-export-get-node-property :step item t)
	(replace-regexp-in-string "^<li>" "<li class='slide'>" text)
      text)))

(defun org-deck-template-alist (info)
  (list
   `("title"  . ,(car (plist-get info :title)))
   `("author" . ,(car (plist-get info :author)))
   `("email"  . ,(plist-get info :email))
   `("date"   . ,(nth 0 (plist-get info :date)))
   `("file"   . ,(plist-get info :input-file))))

(defun org-deck-template (contents info)
  "Return complete document string after HTML conversion.
CONTENTS is the transcoded contents string.  INFO is a plist
holding export options."
  (let ((pkg-info (org-deck--get-packages info)))
  (mapconcat
   'identity
   (list
    "<!DOCTYPE html>"
    (let ((lang (plist-get info :language)))
      (mapconcat
       (lambda (x)
	 (apply
	  'format
	  "<!--%s <html class='no-js %s' lang='%s'> %s<![endif]-->"
	  x))
       (list `("[if lt IE 7]>" "ie6" ,lang "")
	     `("[if IE 7]>" "ie7" ,lang "")
	     `("[if IE 8]>" "ie8" ,lang "")
	     `("[if gt IE 8]><!-->" "" ,lang "<!--")) "\n"))
    "<head>"
    (org-deck--build-meta-info info)
    (mapconcat
     (lambda (sheet)
       (format
	"<link rel='stylesheet' href='%s' type='text/css' />" sheet))
     (plist-get pkg-info :sheets) "\n")
    "<style type='text/css'>"
    "#table-of-contents a {color: inherit;}"
    "#table-of-contents ul {margin-bottom: 0;}"
    (when (plist-get info :section-numbers)
      "#table-of-contents ul li {list-style-type: none;}")
    "</style>"
    ""
    (mapconcat
     (lambda (script)
       (format
	"<script src='%s' type='text/javascript'></script>" script))
     (plist-get pkg-info :scripts) "\n")
    (org-html--build-mathjax-config info)
    "<script type='text/javascript'>"
    "  $(document).ready(function () { $.deck('.slide'); });"
    "</script>"
    (org-html--build-style info)
    org-deck-title-page-style
    "</head>"
    "<body>"
    "<header class='deck-status'>"
    (org-fill-template
     org-deck-header-template (org-deck-template-alist info))
    "</header>"
    "<div class='deck-container'>"
    ;; title page
    (org-fill-template
     org-deck-title-page-template (org-deck-template-alist info))
    ;; toc page
    (let ((depth (plist-get info :with-toc)))
      (when depth (org-deck-toc depth info)))
    contents
    (mapconcat
     (lambda (snippet)
       (with-temp-buffer (insert-file-contents snippet)
			 (buffer-string)))
     (plist-get pkg-info :snippets) "\n")
    "<footer class='deck-status'>"
    (org-fill-template
     org-deck-footer-template (org-deck-template-alist info))
    "</footer>"
    "</div>"
    "</body>"
    "</html>\n") "\n")))

(defun org-deck--build-meta-info (info)
  "Return meta tags for exported document.
INFO is a plist used as a communication channel."
  (let* ((title (org-export-data (plist-get info :title) info))
	 (author (and (plist-get info :with-author)
		      (let ((auth (plist-get info :author)))
			(and auth (org-export-data auth info)))))
	 (date (and (plist-get info :with-date)
		    (let ((date (plist-get info :date)))
		      (and date (org-export-data date info)))))
	 (description (plist-get info :description))
	 (keywords (plist-get info :keywords)))
    (mapconcat
     'identity
     (list
      (format "<title>%s</title>" title)
      (format "<meta charset='%s' />"
	      (or (and org-html-coding-system
		       (fboundp 'coding-system-get)
		       (coding-system-get
			org-html-coding-system 'mime-charset))
		  "iso-8859-1"))
      (mapconcat
       (lambda (attr)
	 (when (< 0 (length (car attr)))
	   (format "<meta name='%s' content='%s'/>\n"
		   (nth 1 attr) (car attr))))
       (list '("Org-mode" "generator")
	     `(,author "author")
	     `(,description "description")
	     `(,keywords "keywords")) "")) "\n")))
(defun org-deck-export-as-html
  (&optional async subtreep visible-only body-only ext-plist)
  "Export current buffer to an HTML buffer.

If narrowing is active in the current buffer, only export its
narrowed part.

If a region is active, export that region.

A non-nil optional argument ASYNC means the process should happen
asynchronously.  The resulting buffer should be accessible
through the `org-export-stack' interface.

When optional argument SUBTREEP is non-nil, export the sub-tree
at point, extracting information from the headline properties
first.

When optional argument VISIBLE-ONLY is non-nil, don't export
contents of hidden elements.

When optional argument BODY-ONLY is non-nil, only write code
between \"<body>\" and \"</body>\" tags.

EXT-PLIST, when provided, is a property list with external
parameters overriding Org default settings, but still inferior to
file-local settings.

Export is done in a buffer named \"*Org deck.js Export*\", which
will be displayed when `org-export-show-temporary-export-buffer'
is non-nil."
  (interactive)
  (if async
      (org-export-async-start
	  (lambda (output)
	    (with-current-buffer (get-buffer-create "*Org deck.js Export*")
	      (erase-buffer)
	      (insert output)
	      (goto-char (point-min))
	      (nxml-mode)
	      (org-export-add-to-stack (current-buffer) 'deck)))
	`(org-export-as 'deck ,subtreep ,visible-only ,body-only ',ext-plist))
    (let ((outbuf (org-export-to-buffer
		   'deck "*Org deck.js Export*"
		   subtreep visible-only body-only ext-plist)))
      ;; Set major mode.
      (with-current-buffer outbuf (nxml-mode))
      (when org-export-show-temporary-export-buffer
	(switch-to-buffer-other-window outbuf)))))

(defun org-deck-export-to-html
  (&optional async subtreep visible-only body-only ext-plist)
  "Export current buffer to a deck.js HTML file.

If narrowing is active in the current buffer, only export its
narrowed part.

If a region is active, export that region.

A non-nil optional argument ASYNC means the process should happen
asynchronously.  The resulting file should be accessible through
the `org-export-stack' interface.

When optional argument SUBTREEP is non-nil, export the sub-tree
at point, extracting information from the headline properties
first.

When optional argument VISIBLE-ONLY is non-nil, don't export
contents of hidden elements.

When optional argument BODY-ONLY is non-nil, only write code
between \"<body>\" and \"</body>\" tags.

EXT-PLIST, when provided, is a property list with external
parameters overriding Org default settings, but still inferior to
file-local settings.

Return output file's name."
  (interactive)
  (let* ((extension (concat "." org-html-extension))
	 (file (org-export-output-file-name extension subtreep))
	 (org-export-coding-system org-html-coding-system))
    (if async
	(org-export-async-start
	    (lambda (f) (org-export-add-to-stack f 'deck))
	  (let ((org-export-coding-system org-html-coding-system))
	    `(expand-file-name
	      (org-export-to-file
	       'deck ,file ,subtreep ,visible-only ,body-only ',ext-plist))))
      (let ((org-export-coding-system org-html-coding-system))
	(org-export-to-file
	 'deck file subtreep visible-only body-only ext-plist)))))

(defun org-deck-publish-to-html (plist filename pub-dir)
  "Publish an org file to deck.js HTML Presentation.
FILENAME is the filename of the Org file to be published.  PLIST
is the property list for the given project.  PUB-DIR is the
publishing directory. Returns output file name."
  (org-publish-org-to 'deck filename ".html" plist pub-dir))

(provide 'ox-deck)

[-- Attachment #3: ox-s5.el --]
[-- Type: text/plain, Size: 13322 bytes --]

;;; ox-s5.el --- S5 Presentation Back-End for Org Export Engine

;; Copyright (C) 2011-2013  Free Software Foundation, Inc.

;; Author: Rick Frankel <emacs at rickster dot com>
;; Keywords: outlines, hypermedia, S5, wp

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;; This library implements an S5 Presentation back-end for the Org
;; generic exporter.

;; Installation
;; ------------
;; Get the s5 scripts from
;;    http://meyerweb.com/eric/tools/s5/
;; (Note that the default s5 version is set for using the alpha, 1.2a2.
;; Copy the ui dir to somewhere reachable from your published presentation
;; The default (`org-s5-ui-url') is set to "ui" (e.g., in the
;; same directory as the html file).

;; Usage
;; -----
;; Follow the general instructions at the above website. To generate
;; incremental builds, you can set the HTML_CONTAINER_CLASS on an
;; object to "incremental" to make it build. If you want an outline to
;; build, set the` INCREMENTAL property on the parent headline.

;; To test it, run:
;;
;;   M-x org-s5-export-as-html
;;
;; in an Org mode buffer.  See ox.el and ox-html.el for more details
;; on how this exporter works.

(require 'ox-html)

(org-export-define-derived-backend s5 html
  :menu-entry
  (?s "Export to S5 HTML Presentation"
      ((?H "To temporary buffer" org-s5-export-as-html)
       (?h "To file" org-s5-export-to-html)
       (?o "To file and open"
	   (lambda (a s v b)
	     (if a (org-s5-export-to-html t s v b)
	       (org-open-file (org-s5-export-to-html nil s v b)))))))
  :options-alist
  ((:html-link-home "HTML_LINK_HOME" nil nil)
   (:html-link-up "HTML_LINK_UP" nil nil)
   (:html-mathjax "HTML_MATHJAX" nil "" space)
   (:html-postamble nil "html-postamble" nil t)
   (:html-preamble nil "html-preamble" nil t)
   (:html-style-extra "HTML_STYLE" nil org-html-style-extra newline)
   (:html-style-include-default "HTML_INCLUDE_DEFAULT" nil nil)
   (:html-style-include-scripts "HTML_INCLUDE_SCRIPTS" nil nil)
   (:s5-version "S5_VERSION" nil org-s5-version)
   (:s5-theme-file "S5_THEME_FILE" nil org-s5-theme-file)
   (:s5-ui-url "S5_UI_URL" nil org-s5-ui-url))
  :translate-alist
  ((headline . org-s5-headline)
   (plain-list . org-s5-plain-list)
   (template . org-s5-template)))

(defgroup org-export-s5 nil
  "Options for exporting Org mode files to S5 HTML Presentations."
  :tag "Org Export S5"
  :group 'org-export-html)

(defcustom org-s5-version "1.2a2"
  "Version of s5 being used (for version metadata.) Defaults to
s5 v2 alpha 2.
Can be overridden with S5_VERSION."
  :group 'org-export-s5
  :type 'string)

(defcustom org-s5-theme-file nil
"Url to S5 theme (slides.css) file. Can be overriden with the
S5_THEME_FILE property. If nil, defaults to
`org-s5-ui-url'/default/slides.css. If it starts with anything but
\"http\" or \"/\", it is used as-is. Otherwise the link in generated
relative to `org-s5-ui-url'.
The links for all other required stylesheets and scripts will be
generated relative to `org-s5-ui-url'/default."
  :group 'org-export-s5
  :type 'string)

(defcustom org-s5-ui-url "ui"
  "Base url to directory containing S5 \"default\" subdirectory
and the \"s5-notes.html\" file.
Can be overriden with the S5_UI_URL property."
  :group 'org-export-s5
  :type 'string)

(defcustom org-s5-default-view 'slideshow
  "Setting for \"defaultView\" meta info."
  :group 'org-export-s5
  :type '(choice (const slideshow) (const outline)))

(defcustom org-s5-control-visibility 'hidden
  "Setting for \"controlVis\" meta info."
  :group 'org-export-s5
  :type '(choice (const hidden) (const visibile)))

(defcustom org-s5-footer-template
  "<div id=\"footer\">
<h1>%author - %title</h1>
</div>"
  "Format template to specify footer div. Completed using
`org-fill-template'.
Optional keys include %author, %email, %file, %title and %date.
Note that the div id must be \"footer\"."
  :group 'org-export-s5
  :type 'string)

(defcustom org-s5-header-template "<div id=\"header\"></div>"
  "Format template to specify footer div. Completed using
`org-fill-template'.
Optional keys include %author, %email, %file, %title and %date.
Note that the div id must be \"header\"."
  :group 'org-export-s5
  :type 'string)

(defcustom org-s5-title-page-template
  "<div class=\"slide title-page\">
<h1>%title</h1>
<h1>%author</h1>
<h1>%email</h1>
<h1>%date</h1>
</div>"
  "Format template to specify title page div. Completed using
`org-fill-template'.
Optional keys include %author, %email, %file, %title and %date.
Note that the wrapper div must include the class \"slide\"."
  :group 'org-export-s5
  :type 'string)


(defun org-s5-toc (depth info)
  (let* ((headlines (org-export-collect-headlines info depth))
	 (toc-entries
	  (loop for headline in headlines collect
		(list (org-html-format-headline--wrap
		       headline info 'org-html-format-toc-headline)
		      (org-export-get-relative-level headline info)))))
    (when toc-entries
      (concat
       "<div id=\"table-of-contents\" class=\"slide\">\n"
       (format "<h1>%s</h1>\n"
	       (org-html--translate "Table of Contents" info))
       "<div id=\"text-table-of-contents\">"
       (org-html-toc-text toc-entries)
       "</div>\n"
       "</div>\n"))))

(defun org-s5--build-style (info)
  (let* ((dir (plist-get info :s5-ui-url))
	 (theme (or (plist-get info :s5-theme-file) "default/slides.css")))
    (mapconcat
     'identity
     (list
      "<!-- style sheet links -->"
      (mapconcat
       (lambda (list)
	 (format
	  (concat
	   "<link rel='stylesheet' href='%s/default/%s' type='text/css'"
	   " media='%s' id='%s' />")
	  dir (nth 0 list) (nth 1 list) (nth 2 list)))
       (list
	'("outline.css" "screen" "outlineStyle")
	'("print.css" "print" "slidePrint")
	'("opera.css" "projection" "operaFix")) "\n")
      (format (concat
	       "<link rel='stylesheet' href='%s' type='text/css'"
	       " media='screen' id='slideProj' />")
	      (if (string-match-p "^\\(http\\|/\\)" theme) theme
		(concat dir "/" theme)))
      "<!-- S5 JS -->"
      (concat
       "<script src='" dir
       "/default/slides.js' type='text/javascript'></script>")) "\n")))

(defun org-s5--build-meta-info (info)
  (concat
   (org-html--build-meta-info info)
   (format "<meta name=\"version\" content=\"S5 %s\" />"
	   (plist-get info :s5-version))
   "<meta name='defaultView' content='slideshow' />\n"
   "<meta name='controlVis' content='hidden' />"))

(defun org-s5-headline (headline contents info)
  (let ((org-html-toplevel-hlevel 1))
    (org-html-headline
     (if (= 1 (+ (org-element-property :level headline)
		 (plist-get info :headline-offset)))
         (org-element-put-property
	  headline :html-container-class
	  (mapconcat 'identity
		     (list
		      (org-element-property
		       :html-container-class headline)
		      "slide") " "))
	  headline) contents info)))

(defun org-s5-plain-list (plain-list contents info)
  "Transcode a PLAIN-LIST element from Org to HTML.
CONTENTS is the contents of the list.  INFO is a plist holding
contextual information.
If a containing headline has the property :incremental,
then the \"incremental\" class will be added to the to the list,
which will make the list into a \"build\"."
  (let* ((type (org-element-property :type plain-list))
	(tag (case type
	       (ordered "ol")
	       (unordered "ul")
	       (descriptive "dl"))))
    (format "%s\n%s%s"
	    (format
	     "<%s class='org-%s%s'>" tag tag
	     (if (org-export-get-node-property :incremental plain-list t)
		 " incremental" ""))
	    contents (org-html-end-plain-list type))))

(defun org-s5-template-alist (info)
  `(
   ("title"  . ,(car (plist-get info :title)))
   ("author" . ,(car (plist-get info :author)))
   ("email"  . ,(plist-get info :email))
   ("date"   . ,(substring (nth 0 (plist-get info :date)) 0 10))
   ("file"   . ,(plist-get info :input-file))))

(defun org-s5-template (contents info)
  "Return complete document string after HTML conversion.
CONTENTS is the transcoded contents string.  INFO is a plist
holding export options."
  (mapconcat
   'identity
   (list
    "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" 
	\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
    (format "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"%s\" xml:lang=\"%s\">"
	    (plist-get info :language) (plist-get info :language))
    "<head>"
    (org-s5--build-meta-info info)
    (org-s5--build-style info)
    (org-html--build-style info)
    (org-html--build-mathjax-config info)
    "</head>"
    "<body>"
    "<div class=\"layout\">"
    "<div id=\"controls\"><!-- no edit --></div>"
    "<div id=\"currentSlide\"><!-- no edit --></div>"
    (org-fill-template
     org-s5-header-template (org-s5-template-alist info))
    (org-fill-template
     org-s5-footer-template (org-s5-template-alist info))
    "</div>"
    (format "<div id=\"%s\" class=\"presentation\">" (nth 1 org-html-divs))
    ;; title page
    (org-fill-template
     org-s5-title-page-template (org-s5-template-alist info))
    (let ((depth (plist-get info :with-toc)))
      (when depth (org-s5-toc depth info)))
    contents
    "</div>"
    "</body>"
    "</html>\n") "\n"))

(defun org-s5-export-as-html
  (&optional async subtreep visible-only body-only ext-plist)
  "Export current buffer to an HTML buffer.

If narrowing is active in the current buffer, only export its
narrowed part.

If a region is active, export that region.

A non-nil optional argument ASYNC means the process should happen
asynchronously.  The resulting buffer should be accessible
through the `org-export-stack' interface.

When optional argument SUBTREEP is non-nil, export the sub-tree
at point, extracting information from the headline properties
first.

When optional argument VISIBLE-ONLY is non-nil, don't export
contents of hidden elements.

When optional argument BODY-ONLY is non-nil, only write code
between \"<body>\" and \"</body>\" tags.

EXT-PLIST, when provided, is a property list with external
parameters overriding Org default settings, but still inferior to
file-local settings.

Export is done in a buffer named \"*Org S5 Export*\", which
will be displayed when `org-export-show-temporary-export-buffer'
is non-nil."
  (interactive)
  (if async
      (org-export-async-start
	  (lambda (output)
	    (with-current-buffer (get-buffer-create "*Org S5 Export*")
	      (erase-buffer)
	      (insert output)
	      (goto-char (point-min))
	      (nxml-mode)
	      (org-export-add-to-stack (current-buffer) 's5)))
	`(org-export-as 's5 ,subtreep ,visible-only ,body-only ',ext-plist))
    (let ((outbuf (org-export-to-buffer
		   's5 "*Org S5 Export*"
		   subtreep visible-only body-only ext-plist)))
      ;; Set major mode.
      (with-current-buffer outbuf (nxml-mode))
      (when org-export-show-temporary-export-buffer
	(switch-to-buffer-other-window outbuf)))))

(defun org-s5-export-to-html
  (&optional async subtreep visible-only body-only ext-plist)
  "Export current buffer to a S5 HTML file.

If narrowing is active in the current buffer, only export its
narrowed part.

If a region is active, export that region.

A non-nil optional argument ASYNC means the process should happen
asynchronously.  The resulting file should be accessible through
the `org-export-stack' interface.

When optional argument SUBTREEP is non-nil, export the sub-tree
at point, extracting information from the headline properties
first.

When optional argument VISIBLE-ONLY is non-nil, don't export
contents of hidden elements.

When optional argument BODY-ONLY is non-nil, only write code
between \"<body>\" and \"</body>\" tags.

EXT-PLIST, when provided, is a property list with external
parameters overriding Org default settings, but still inferior to
file-local settings.

Return output file's name."
  (interactive)
  (let* ((extension (concat "." org-html-extension))
	 (file (org-export-output-file-name extension subtreep))
	 (org-export-coding-system org-html-coding-system))
    (if async
	(org-export-async-start
	    (lambda (f) (org-export-add-to-stack f 's5))
	  (let ((org-export-coding-system org-html-coding-system))
	    `(expand-file-name
	      (org-export-to-file
	       's5 ,file ,subtreep ,visible-only ,body-only ',ext-plist))))
      (let ((org-export-coding-system org-html-coding-system))
	(org-export-to-file
	 's5 file subtreep visible-only body-only ext-plist)))))

(defun org-s5-publish-to-html (plist filename pub-dir)
  "Publish an org file to S5 HTML Presentation.

FILENAME is the filename of the Org file to be published.  PLIST
is the property list for the given project.  PUB-DIR is the
publishing directory.

Return output file name."
  (org-publish-org-to 's5 filename ".html" plist pub-dir))

(provide 'ox-s5)

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

* Re: [PATH] [NEW EXPORTER] two slide backends for contrib
  2013-02-20  0:18 [PATH] [NEW EXPORTER] two slide backends for contrib Rick Frankel
@ 2013-02-20 15:34 ` Bastien
  2013-08-27  4:41   ` Matt Price
  0 siblings, 1 reply; 6+ messages in thread
From: Bastien @ 2013-02-20 15:34 UTC (permalink / raw)
  To: Rick Frankel; +Cc: emacs-orgmode

Hi Rick,

Rick Frankel <rick@rickster.com> writes:

> Attached are:
>
> 	 - ox-deck.el
> 	 - ox-s5.el
>
> Which, respectively, provide deck.js and s5 backends for the new
> exporter. I would be happy for these to be included in contrib. Note
> that I have already signed the FSF assignment documents, so they can
> be safely included in the core if so desired.

Added to contrib/, thanks a lot!  

I modified the Copyright line to tell that the copyright is your own,
you don't need to assign copyright to the FSF for code in contrib/.

If you have time, please mention those packages in Worg:
  http://orgmode.org/worg/org-contrib/

(Just send me your public key to get push access to Worg.)

All best,

-- 
 Bastien

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

* Re: [PATH] [NEW EXPORTER] two slide backends for contrib
  2013-02-20 15:34 ` Bastien
@ 2013-08-27  4:41   ` Matt Price
  2013-08-27 14:12     ` Rick Frankel
  0 siblings, 1 reply; 6+ messages in thread
From: Matt Price @ 2013-08-27  4:41 UTC (permalink / raw)
  To: Bastien; +Cc: Rick Frankel, Org Mode

I just came across this, having missed it in February.  Rick, I was
wondering if you had thought about enabling some of deck.js's snazzier
features -- transitions for text elements, for instance, like we see
in the intro deck here: http://imakewebthings.com/deck.js/#intro

I'm mostly asking because I'd like to try and copy your work to make
an exporter for impress.js (https://github.com/bartaz/impress.js).
Kinjo has written one, but it uses the old exporter and no longer
works with current versions of org, so I thought I would start with
your deck.js work.

I know that's not very specific, but if you've thought about these
issues I would love to learn wat you've figured out.  Thanks!
Matt


On Wed, Feb 20, 2013 at 10:34 AM, Bastien <bzg@altern.org> wrote:
> Hi Rick,
>
> Rick Frankel <rick@rickster.com> writes:
>
>> Attached are:
>>
>>        - ox-deck.el
>>        - ox-s5.el
>>
>> Which, respectively, provide deck.js and s5 backends for the new
>> exporter. I would be happy for these to be included in contrib. Note
>> that I have already signed the FSF assignment documents, so they can
>> be safely included in the core if so desired.
>
> Added to contrib/, thanks a lot!
>
> I modified the Copyright line to tell that the copyright is your own,
> you don't need to assign copyright to the FSF for code in contrib/.
>
> If you have time, please mention those packages in Worg:
>   http://orgmode.org/worg/org-contrib/
>
> (Just send me your public key to get push access to Worg.)
>
> All best,
>
> --
>  Bastien
>

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

* Re: [PATH] [NEW EXPORTER] two slide backends for contrib
  2013-08-27  4:41   ` Matt Price
@ 2013-08-27 14:12     ` Rick Frankel
  2013-08-28  3:41       ` Matt Price
  0 siblings, 1 reply; 6+ messages in thread
From: Rick Frankel @ 2013-08-27 14:12 UTC (permalink / raw)
  To: Matt Price; +Cc: Bastien, Org Mode

On 2013-08-27 00:41, Matt Price wrote:
> I just came across this, having missed it in February.  Rick, I was
> wondering if you had thought about enabling some of deck.js's snazzier
> features -- transitions for text elements, for instance, like we see
> in the intro deck here: http://imakewebthings.com/deck.js/#intro
> 
> I'm mostly asking because I'd like to try and copy your work to make
> an exporter for impress.js (https://github.com/bartaz/impress.js).
> Kinjo has written one, but it uses the old exporter and no longer
> works with current versions of org, so I thought I would start with
> your deck.js work.
> 
> I know that's not very specific, but if you've thought about these
> issues I would love to learn wat you've figured out.  Thanks!

All the fancy transitions and builds in the deck.js intro are handled
via CSS. So, the exporter will handle them easily.

If you look at the source for the intro, you will see that all the
builds and transitions are defined in home.css, and applied based on
slide id and/or class.

If you look at the documentation for ox-deck
@https://github.com/cybercode/org-slides, you will see that you can
specify per-slide classes via the HTML_CONTAINER_CLASS property on the
headline (and any headline can be build by setting the "slide" class
on the headline).

Taking a quick look @ the impress.js docs, i noticed that there is an
S9 template for impress.js
(http://slideshow-s9.github.io/slideshow-impress.js), and that
everything is specified w/ slide properties (x, y, z, scale and
rotate), so I would use headline PROPERTIES ( :IMPRESS_X, etc) to
define the slideshow.

Also note that it might be easier to inherit from  ox-s5 instead of
ox-deck as it is more generic (and add a wrapper around
`org-s5-headline') to process the additional properties.

rick

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

* Re: [PATH] [NEW EXPORTER] two slide backends for contrib
  2013-08-27 14:12     ` Rick Frankel
@ 2013-08-28  3:41       ` Matt Price
  2013-08-28 11:52         ` Rick Frankel
  0 siblings, 1 reply; 6+ messages in thread
From: Matt Price @ 2013-08-28  3:41 UTC (permalink / raw)
  To: Rick Frankel, Org Mode

On Tue, Aug 27, 2013 at 10:12 AM, Rick Frankel <rick@rickster.com> wrote:
> On 2013-08-27 00:41, Matt Price wrote:
>>
>> I just came across this, having missed it in February.  Rick, I was
>> wondering if you had thought about enabling some of deck.js's snazzier
>> features -- transitions for text elements, for instance, like we see
>> in the intro deck here: http://imakewebthings.com/deck.js/#intro
>>
>> I'm mostly asking because I'd like to try and copy your work to make
>> an exporter for impress.js (https://github.com/bartaz/impress.js).
>> Kinjo has written one, but it uses the old exporter and no longer
>> works with current versions of org, so I thought I would start with
>> your deck.js work.
>>
>> I know that's not very specific, but if you've thought about these
>> issues I would love to learn wat you've figured out.  Thanks!
>
>
> All the fancy transitions and builds in the deck.js intro are handled
> via CSS. So, the exporter will handle them easily.
>
> If you look at the source for the intro, you will see that all the
> builds and transitions are defined in home.css, and applied based on
> slide id and/or class.

ah, I wish I understood css transforms better!  But yes, I can see
that they are being defined in home.css and attached to individual
classes/ids for slides.  That's very helpful.

>
> If you look at the documentation for ox-deck
> @https://github.com/cybercode/org-slides, you will see that you can
> specify per-slide classes via the HTML_CONTAINER_CLASS property on the
> headline (and any headline can be build by setting the "slide" class
> on the headline).

ah, I get it now.  Thank you.

>
> Taking a quick look @ the impress.js docs, i noticed that there is an
> S9 template for impress.js
> (http://slideshow-s9.github.io/slideshow-impress.js), and that
> everything is specified w/ slide properties (x, y, z, scale and
> rotate), so I would use headline PROPERTIES ( :IMPRESS_X, etc) to
> define the slideshow.

I'll give that a try, if I end up having time (argh).  I'm actually
liking deck, though.  Am wondering if it would be very hard to add
support for the codemirror extension to your deck code.  Maybe I'll
try that first...

>
> Also note that it might be easier to inherit from  ox-s5 instead of
> ox-deck as it is more generic (and add a wrapper around
> `org-s5-headline') to process the additional properties.

Thanks again, very very helpful.

Matt

>
> rick

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

* Re: [PATH] [NEW EXPORTER] two slide backends for contrib
  2013-08-28  3:41       ` Matt Price
@ 2013-08-28 11:52         ` Rick Frankel
  0 siblings, 0 replies; 6+ messages in thread
From: Rick Frankel @ 2013-08-28 11:52 UTC (permalink / raw)
  To: Matt Price; +Cc: Org Mode

On Tue, Aug 27, 2013 at 11:41:20PM -0400, Matt Price wrote:
> On Tue, Aug 27, 2013 at 10:12 AM, Rick Frankel <rick@rickster.com> wrote:
> > On 2013-08-27 00:41, Matt Price wrote:
> >>
> >> I just came across this, having missed it in February.  Rick, I was
> >> wondering if you had thought about enabling some of deck.js's snazzier
> >> features -- transitions for text elements, for instance, like we see
> >> in the intro deck here: http://imakewebthings.com/deck.js/#intro

> > If you look at the documentation for ox-deck
> > @https://github.com/cybercode/org-slides, you will see that you can
> > specify per-slide classes via the HTML_CONTAINER_CLASS property on the
> > headline (and any headline can be build by setting the "slide" class
> > on the headline).

> I'll give that a try, if I end up having time (argh).  I'm actually
> liking deck, though.  Am wondering if it would be very hard to add
> support for the codemirror extension to your deck code.  Maybe I'll
> try that first...

I find deck.js to be my favorite also... (impress is a bit to
impressive for me :) If you look at the Customization
(https://github.com/cybercode/org-slides#customization) section of the
documentation, you will see that ANY deck.js extension in any of the
extension under a directory specified in `org-deck-directories'
(defaults to './deck.js'), will be included by default, so, just add
the extension to the ./deck.js/extensions directory and the css to the
./deck.js/themes directory.

rick

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

end of thread, other threads:[~2013-08-28 11:53 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-20  0:18 [PATH] [NEW EXPORTER] two slide backends for contrib Rick Frankel
2013-02-20 15:34 ` Bastien
2013-08-27  4:41   ` Matt Price
2013-08-27 14:12     ` Rick Frankel
2013-08-28  3:41       ` Matt Price
2013-08-28 11:52         ` Rick Frankel

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).