From 238fa41446db51a8111650b696a7b495e0b5761b Mon Sep 17 00:00:00 2001 From: yjwen Date: Sun, 28 Apr 2013 15:45:05 +0800 Subject: [PATCH] Initial version. --- Readme.org | 233 ++++++++++++++++++++++++ images/hlevel.png | Bin 0 -> 3254 bytes images/hlevel2.png | Bin 0 -> 2868 bytes ox-reveal.el | 433 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 666 insertions(+) create mode 100644 Readme.org create mode 100644 images/hlevel.png create mode 100644 images/hlevel2.png create mode 100644 ox-reveal.el diff --git a/Readme.org b/Readme.org new file mode 100644 index 0000000..941ee45 --- /dev/null +++ b/Readme.org @@ -0,0 +1,233 @@ +#+Title: Introduction to Org-Reveal +#+Author: Yujie Wen +#+Email: yjwen.ty@gmail.com + +#+OPTIONS: reveal_center:nil +#+REVEAL_TRANS: cube +#+REVEAL_THEME: moon +#+REVEAL_HLEVEL: 2 + +* Reveal.js and Org-Reveal + + - *Reveal.js* is a tool for creating good look HTML presentations, + authored by Hakim El Hattab. \\ + For an example of reveal.js presentation, click [[http://lab.hakim.se/reveal-js/#/][here]]. + - *Org-Reveal* exports your Org documents to reveal.js + presentations.\\ + So you can create beautiful presentations with 3D effects from + simple but powerful org contents. + +* Requirements and Installation + + - Reveal.js. + - Latest org-mode. + - ox-reveal.el. + - And, of course, emacs. + +** Obtain Reveal.js + + Download Reveal.js packages from [[https://github.com/hakimel/reveal.js/][here]]. + + Extract reveal.js folders from the downloaded zip file. + +** Obtain org-mode + + *Note*: Org-reveal relies on the LATEST org-mode export frame work. + Pre-packaged org-mode may be out-of-date. + + If not sure, use the freshest development codes from git repository. +#+BEGIN_SRC sh +$ git clone git://orgmode.org/org-mode.git +#+END_SRC + + Follow the [[http://orgmode.org/worg/dev/org-build-system.html][online instruction]] to build and install Org-mode. + +** TODO Obtain Org-reveal + + Obtain latest Org-reveal from github. + + Copy =ox-reveal.el= to the Org-mode install directory. + + Add the following statement to your =.emacs= file. +#+BEGIN_SRC lisp +(require 'ox-reveal) +#+END_SRC + +* Configuration + +** Set the location of Reveal.js + + Org-reveal must know where reveal.js is before exporting Org + contents. + + Default location is =./reveal.js=, relative to the Org file. + + Change variable =org-reveal-root= 's value will change the location + globally. For example, add the following statement to your .emacs + file: +#+BEGIN_SRC lisp +(setq org-reveal-root "d:/reveal.js") +#+END_SRC + + By setting option =REVEAL_ROOT=, the location is only affected + within the Org file. + +#+BEGIN_SRC org +,#+REVEAL_ROOT: d:/reveal.js +#+END_SRC + +** First Try + + Modifications to =.emacs= will take effect at next time Emacs + starts up. + + To wake-up Org-reveal now, type "M-x load-library", then type + "ox-reveal". + + Now you can export this manual into Reveal.js presentation by + typing "C-c C-e R R". + + Open the generated "Readme.html" in your browser and enjoy the + cool slides. + +** The HLevel + + Org-reveal maps each heading and its contents to one Reveal.js + slides. Since Reveal.js arrange slides into a 2-dimentional matrix, + Org-reveal use *HLevel* value to decide map headings to hozirontal + or vertical slides. + + * Headings of level less or equal to HLevel are mapped to hozirontal + slides. + * Headings of deeper levels are mapped to vertical slides. + + HLevel's default value is 1, means only level 1 headings are arranged + horizontally, deeper headings are mapped to vertical slides below its + parent level 1 heading. + +*** HLevel's Affects on Slides Layout + + Assume we have a simple Org file as below: +#+BEGIN_SRC org +,* H1 +,* H2 +,** H2.1 +,*** H2.1.1 +,* H3 +#+END_SRC + + If HLevel is 1, the default value, headings H2.1 and H2.1.1 will + be mapping to vertical slides below the slides of heading H2. + + [[./images/hlevel.png]] + + If HLevel is changed to 2, slide of heading H2.1 will be changed + to the main hozirontal queue, and slide of heading H2.1.1 will be + a vertical slide below it. + + [[./images/hlevel2.png]] + +*** Configure HLevel's Value + + * Change variable =org-reveal-hlevel='s value to set HLevel globally.\\ + For example, add the following statement to your =.emacs= file. +#+BEGIN_SRC lisp +(setq org-reveal-hlevel 2) +#+END_SRC + + * Setting Org files local HLevel to option =REVEAL_HLEVEL=. +#+BEGIN_SRC org +,#+REVEAL_HLEVEL 2 +#+END_SRC + +** Select Theme and Transition + + Themes and transitions are set globally throughout the whole file by + setting options =REVEAL_THEME= and =REVEAL_TRANS=. + + For example, check the heading parting of this documents. + + Available themes can be find in "css/theme/" in the reveal.js directory. + + Available transitions are: default|cube|page|concave|zoom|linear|fade|none. + +** Fragmented Contents + + Make contents fragmented, show up one-by-one, by setting option =ATTR_REVEAL= with + property ":frag frag-style", as illustrated below. + +#+ATTR_REVEAL: :frag roll-in + Paragraphs can be fragmented. + +#+ATTR_REVEAL: :frag roll-in + Items can be fragmented, too. + + Availabe fragment styles are: +#+ATTR_REVEAL: :frag grow + * grow +#+ATTR_REVEAL: :frag shrink + * shrink +#+ATTR_REVEAL: :frag roll-in + * roll-in +#+ATTR_REVEAL: :frag fade-out + * fade-out +#+ATTR_REVEAL: :frag highlight-red + * highlight-red +#+ATTR_REVEAL: :frag highlight-green + * highlight-green +#+ATTR_REVEAL: :frag highlight-blue + * highlight-blue + +** Data State + :PROPERTIES: + :reveal_data_state: alert + :END: + + Set property =reveal_data_state= to headings to change this slide's + style, as illustrated above. + +** Plug-ins + + Reveal.js provides several plug-in functions. + + - reveal-control : Show/hide browse control pad. + - reveal-progress : Show/hide progress bar. + - reveal-history : Enable/disable slide history track. + - reveal-center : Enable/disable slide centering. + +*** Configure Plug-ins + + Each plug-ins can be set on/off by adding =#+OPTIONS= tags or + settinng custom variables. + + - =#+OPTIONS= tags:\\ + =reveal_control=, =reveal_progress=, =reveal_history=, + =reveal_center= + - Custom variables:\\ + =org-reveal-control=, =org-reveal-progress=, + =org-reveal-history=, =org-reveal-center= + +** Source Codes + + Org-reveal use Org-Babel to highlight source codes. + + Codes copied from [[http://www.haskell.org/haskellwiki/The_Fibonacci_sequence][Haskell Wiki]]. +#+BEGIN_SRC haskell + + fibs = 0 : 1 : next fibs + where next (a : t@(b:_)) = (a+b) : next t +#+END_SRC + + If you saw odd indentation, please set variable =org-html-indent= + to nil and export again. + +* Thanks + + Courtesy to: + +#+ATTR_REVEAL: :frag roll-in + the powerfull Org-mode, +#+ATTR_REVEAL: :frag roll-in + and the impressive Reveal.js + + diff --git a/images/hlevel.png b/images/hlevel.png new file mode 100644 index 0000000000000000000000000000000000000000..93564cdbe942ae8cf20c4f76eef57c05545d9bf1 GIT binary patch literal 3254 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 literal 0 HcmV?d00001 diff --git a/images/hlevel2.png b/images/hlevel2.png new file mode 100644 index 0000000000000000000000000000000000000000..9f0c22ffca6ac55bab613e4f18febc42066b71e1 GIT binary patch literal 2868 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 literal 0 HcmV?d00001 diff --git a/ox-reveal.el b/ox-reveal.el new file mode 100644 index 0000000..d3fe101 --- /dev/null +++ b/ox-reveal.el @@ -0,0 +1,433 @@ +;; ox-reveal --- reveal.js Presentation Back-End for Org Export Engine + +;; Copyright (C) 2013 Yujie Wen + +;; Author: Yujie Wen +;; Keywords: outlines, hypermedia, slideshow, presentation + +;; This file is not part of GNU Emacs. + +;; 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 GNU Emacs. If not, see . + +;; Please see "Readme.org" for detail introductions. + +(require 'ox-html) +(eval-when-compile (require 'cl)) + +(org-export-define-derived-backend reveal html + + :menu-entry + (?R "Export to reveal.js HTML Presentation" + ((?R "To file" org-reveal-export-to-html))) + + :options-alist + ((:reveal-control nil "reveal_control" org-reveal-control t) + (:reveal-progress nil "reveal_progress" org-reveal-progress t) + (:reveal-history nil "reveal_history" org-reveal-history t) + (:reveal-center nil "reveal_center" org-reveal-center t) + (:reveal-root "REVEAL_ROOT" nil org-reveal-root t) + (:reveal-trans "REVEAL_TRANS" nil org-reveal-transition t) + (:reveal-theme "REVEAL_THEME" nil org-reveal-theme t) + (:reveal-hlevel "REVEAL_HLEVEL" nil nil t) + ) + + :translate-alist + ((headline . org-reveal-headline) + (inner-template . org-reveal-inner-template) + (item . org-reveal-item) + (paragraph . org-reveal-paragraph) + (template . org-reveal-template))) + +(defcustom org-reveal-root "./reveal.js" + "The root directory of reveal.js packages. It is the directory + within which js/reveal.min.js is." + :group 'org-export-reveal) + +(defcustom org-reveal-hlevel 1 + "The minimum level of headings that should be grouped into +vertical slides." + :group 'org-export-reveal + :type 'integer) + +(defun org-reveal--get-hlevel (info) + "Get HLevel value safely. +If option \"REVEAL_HLEVEL\" is set, retrieve integer value from it, +else get value from custom variable `org-reveal-hlevel'." + (let ((hlevel-str (plist-get info :reveal-hlevel))) + (if hlevel-str (string-to-int hlevel-str) + org-reveal-hlevel))) + +(defcustom org-reveal-title-slide-template + "

%t

+

%a

+

%e

+

%d

" + "Format template to specify title page slide. +See `org-html-postamble-format' for the valid elements which +can be include." + :group 'org-export-reveal + :type 'string) + +(defcustom org-reveal-transition + "default" + "Reveal transistion style." + :group 'org-export-reveal + :type 'string) + +(defcustom org-reveal-theme + "default" + "Reveal theme." + :group 'org-export-reveal + :type 'string) + +(defcustom org-reveal-control t + "Reveal control applet." + :group 'org-export-reveal + :type 'string) + +(defcustom org-reveal-progress t + "Reveal progress applit." + :group 'org-export-reveal + :type 'boolean) + +(defcustom org-reveal-history t + "Reveal history applit." + :group 'org-export-reveal + :type 'boolean) + +(defcustom org-reveal-center t + "Reveal center applit." + :group 'org-export-reveal + :type 'boolean) + +(defun if-format (fmt val) + (if val (format fmt val) "")) + +(defun org-reveal-headline (headline contents info) + "Transcode a HEADLINE element from Org to HTML. +CONTENTS holds the contents of the headline. INFO is a plist +holding contextual information." + ;; First call org-html-headline to get the formatted HTML contents. + ;; Then add enclosing
tags to mark slides. + (setq contents (or contents "")) + (let* ((numberedp (org-export-numbered-headline-p headline info)) + (level (org-export-get-relative-level headline info)) + (text (org-export-data (org-element-property :title headline) info)) + (todo (and (plist-get info :with-todo-keywords) + (let ((todo (org-element-property :todo-keyword headline))) + (and todo (org-export-data todo info))))) + (todo-type (and todo (org-element-property :todo-type headline))) + (tags (and (plist-get info :with-tags) + (org-export-get-tags headline info))) + (priority (and (plist-get info :with-priority) + (org-element-property :priority headline))) + (section-number (and (org-export-numbered-headline-p headline info) + (mapconcat 'number-to-string + (org-export-get-headline-number + headline info) "."))) + ;; Create the headline text. + (full-text (org-html-format-headline--wrap headline info))) + (cond + ;; Case 1: This is a footnote section: ignore it. + ((org-element-property :footnote-section-p headline) nil) + ;; Case 2. This is a deep sub-tree: export it as a list item. + ;; Also export as items headlines for which no section + ;; format has been found. + ((org-export-low-level-p headline info) + ;; Build the real contents of the sub-tree. + (let* ((type (if numberedp 'ordered 'unordered)) + (itemized-body (org-reveal-format-list-item + contents type nil nil 'none full-text))) + (concat + (and (org-export-first-sibling-p headline info) + (org-html-begin-plain-list type)) + itemized-body + (and (org-export-last-sibling-p headline info) + (org-html-end-plain-list type))))) + ;; Case 3. Standard headline. Export it as a section. + (t + (let* ((section-number (mapconcat 'number-to-string + (org-export-get-headline-number + headline info) "-")) + (ids (remove 'nil + (list (org-element-property :CUSTOM_ID headline) + (concat "sec-" section-number) + (org-element-property :ID headline)))) + (extra-ids (cdr ids)) + (level1 (+ level (1- org-html-toplevel-hlevel))) + (hlevel (org-reveal--get-hlevel info)) + (first-content (car (org-element-contents headline)))) + (concat + (if (or (/= level 1) + (not (org-export-first-sibling-p headline info))) + ;; Stop previous slide. + "
\n") + (if (eq level hlevel) + ;; Add an extra "
" to group following slides + ;; into vertical ones. + "
\n") + ;; Start a new slide. + (format "\n" + (if-format " data-state=\"%s\"" (org-element-property :REVEAL_DATA_STATE headline))) + ;; The HTML content of this headline. + (format "\n%s%s\n" + level1 + (if-format " class=\"fragment %s\"" + (org-element-property :REVEAL-FRAG headline)) + (mapconcat + (lambda (x) + (let ((id (org-export-solidify-link-text + (if (org-uuidgen-p x) (concat "ID-" x) + x)))) + (org-html--anchor id))) + extra-ids "") + full-text + level1) + ;; When there is no section, pretend there is an empty + ;; one to get the correct
" to stop vertical slide + ;; grouping. + "
\n") + (if (and (= level 1) + (org-export-last-sibling-p headline info)) + ;; Last head 1. Stop all slides. + "
"))))))) + +(defgroup org-export-reveal nil + "Options for exporting Orgmode files to reveal.js HTML pressentations." + :tag "Org Export reveal") + +(defun org-reveal--append-path (dir-name path-name) + "Append `path-name' to the end of `dir-name' to form a legal path name." + (concat (file-name-as-directory dir-name) path-name)) + +(defun org-reveal--append-pathes (dir-name pathes) + "Append all the path names in `pathes' to the end of `dir-name' +to form a legal path name." + (if pathes + (org-reveal--append-pathes + (org-reveal--append-path dir-name (car pathes)) + (cdr pathes)) + dir-name)) + + +(defun org-reveal-stylesheets (info) + "Return the HTML contents for decalaring reveal stylesheets +using custom variable `org-reveal-root'." + (let* ((root-path (plist-get info :reveal-root)) + (css-dir-name (org-reveal--append-path root-path "css")) + (min-css-file-name (org-reveal--append-path css-dir-name "reveal.min.css")) + (theme-file (format "%s.css" (plist-get info :reveal-theme))) + (theme-path (org-reveal--append-path css-dir-name "theme")) + (theme-full (org-reveal--append-path theme-path theme-file))) + (format " + " + min-css-file-name theme-full))) + + +(defun org-reveal-scripts (info) + "Return the necessary scripts for initializing reveal.js using +custom variable `org-reveal-root'." + (let* ((root-path (plist-get info :reveal-root)) + (root-dir-name (file-name-as-directory root-path)) + (lib-dir-name (org-reveal--append-path root-path "lib")) + (lib-js-dir-name (org-reveal--append-path lib-dir-name "js")) + (plugin-dir-name (org-reveal--append-path root-path "plugin")) + (markdown-dir-name (org-reveal--append-path plugin-dir-name "markdown"))) + (concat + (format "\n\n" + (org-reveal--append-path lib-js-dir-name "head.min.js") + (org-reveal--append-pathes root-path '("js" "reveal.min.js"))) + "\n"))) + +(defun org-reveal-toc (depth info) + "Build a slide of table of contents." + (concat + "
\n" + (org-html-toc depth info) + "
\n")) + +(defun org-reveal-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-reveal-toc depth info))) + ;; Document contents. + contents)) + +(defun org-reveal-format-list-item + (content type checkbox &optional term-counter-id frag headline) + "Format a list item into Reveal.js HTML." + (let ((checkbox (concat (org-html-checkbox checkbox) (and checkbox " ")))) + (concat + (case type + (ordered + (concat + "" + (if headline (concat headline "
")))) + (unordered + (concat + "" + (if headline (concat headline "
")))) + (descriptive + (concat + "" + (concat checkbox (or term-counter-id "(no term)")) + "
"))) + (unless (eq type 'descriptive) checkbox) + contents + (case type + (ordered "") + (unordered "") + (descriptive "
"))))) + +(defun org-reveal--headline-property (property blob) + "Get property from BLOB's parent headline and return." + (let ((headline (if (eq (org-element-type blob) 'headline) blob + (org-export-get-parent-headline blob)))) + (org-element-property property headline))) + + +(defun org-reveal--get-frag (info) + "Get Reveal fragment settings from context." + (let ((frag (plist-get info :reveal-frag))) + (if (eq frag "none") nil frag))) + +(defun org-reveal-item (item contents info) + "Transcode an ITEM element from Org to Reveal. +CONTENTS holds the contents of the item. INFO is aplist holding +contextual information." + (let* ((plain-list (org-export-get-parent item)) + (type (org-element-property :type plain-list)) + (counter (org-element-property :counter item)) + (checkbox (org-element-property :checkbox item)) + (tag (let ((tag (org-element-property :tag item))) + (and tag (org-export-data tag info)))) + (frag (org-export-read-attribute :attr_reveal plain-list :frag))) + (org-reveal-format-list-item + contents type checkbox (or tag counter) frag))) + +(defun org-reveal-paragraph (paragraph contents info) + "Transcode a PARAGRAPH element from Org to Reveal HTML. +CONTENTS is the contents of the paragraph, as a string. INFO is +the plist used as a communication channel." + (let ((parent (org-export-get-parent paragraph))) + (cond + ((and (eq (org-element-type parent) 'item) + (= (org-element-property :begin paragraph) + (org-element-property :contents-begin parent))) + ;; leading paragraph in a list item have no tags + contents) + ((org-html-standalone-image-p paragraph info) + ;; standalone image + contents) + (t (format "\n%s

" + (if-format " class=\"fragment %s\"" + (org-export-read-attribute :attr_reveal paragraph :frag)) + contents))))) + + +(defun org-reveal-template (contents info) + "Return complete document string after HTML conversion. +contents is the transcoded contents string. +info is a plist holding export options." + (concat + (format "\n\n\n" + (if-format " lang=\"%s\"" (plist-get info :language))) + (if-format "%s\n" (plist-get info :title)) + (if-format "\n" (plist-get info :author)) + (if-format "\n" (plist-get info :description)) + (if-format "\n" (plist-get info :keywords)) + (org-reveal-stylesheets info) + " + +
+
+
+" + (format-spec org-reveal-title-slide-template (org-html-format-spec info)) + "
\n" + contents + "
+
\n" + (org-reveal-scripts info) + " +\n")) + + + +(defun org-reveal-export-to-html + (&optional async subtreep visible-only body-only ext-plist) + "Export current buffer to a reveal.js HTML file." + (interactive) + (let* ((extension (concat "." org-html-extension)) + (file (org-export-output-file-name extension subtreep))) + (org-export-to-file + 'reveal file subtreep visible-only body-only ext-plist))) + +(provide 'ox-reveal)