--- /dev/null
+;;; demo-it-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
+\f
+;;;### (autoloads nil "demo-it" "demo-it.el" (22173 59614 0 0))
+;;; Generated autoloads from demo-it.el
+
+(autoload 'demo-it-start "demo-it" "\
+Start the current demonstration and kick off the first step.
+STEPS is a list of functions to execute. If non-nil, the
+optional ADVANCED-MODE turns on keybindings where <F6> advances
+the steps instead of space. This mode is better for more
+interactive demonstrations.
+
+\(fn STEPS &optional ADVANCED-MODE)" nil nil)
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; demo-it-autoloads.el ends here
--- /dev/null
+(define-package "demo-it" "20160116.1941" "Utility functions for creating demonstrations" 'nil :keywords '("demonstration" "presentation"))
--- /dev/null
+;;; demo-it.el --- Utility functions for creating demonstrations
+
+;; Copyright (C) 2014 Howard Abrams
+
+;; Author: Howard Abrams <howard.abramsNOSPAMgmail.com>
+;; Keywords: demonstration presentation
+;; Package-Version: 20160116.1941
+
+;; 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:
+
+;; When making demonstrations of new products, technologies and other
+;; geekery, I love the versatility of using Emacs to demonstrate the
+;; trifecta of sprint reviews, including:
+;;
+;; - Presentations explaining the technologies
+;; - Source code ... correctly highlighted
+;; - Executing the code in Eshell ... or similar demonstration
+;;
+;; However, I don't want to fat-finger, mentally burp, or even delay
+;; the gratification while I type, so I predefine each "step" as an
+;; Elisp function, and then have =demo-it= execute each function when I
+;; hit the F6 key.
+;;
+;; Using the library is a three step process:
+;;
+;; 1. Load the library in your own Elisp source code file
+;; 2. Create a collection of functions that "do things".
+;; 3. Call the =demo-it-start= function with the ordered list of
+;; functions.
+;;
+;; For instance:
+;;
+;; (load-library "demo-it") ;; Load this library of functions
+;;
+;; (defun my-demo/step-1 ()
+;; (delete-other-windows)
+;; (demo/org-presentation "~/presentations/my-demo/demo-start.org"))
+;;
+;; (defun my-demo/step-2 ()
+;; (demo-it-load-file "~/Work/my-proj/src/my-proj.py")
+;; (demo-it-presentation-return))
+;;
+;; (defun my-demo ()
+;; "My fabulous demonstration."
+;; (interactive)
+;; (demo-it-start (list
+;; 'my-demo/step-1
+;; 'my-demo/step-2
+;; ;; ...
+;; )))
+;;
+;; (my-demo) ;; Optionally start the demo when file is loaded.
+;;
+;; Each "step" is a series of Elisp functions that "do things".
+;; While this package has a collection of helping functions, the steps
+;; can use any Elisp command to show off a feature.
+;;
+;; I recommend installing these other Emacs packages:
+;;
+;; - https://github.com/takaxp/org-tree-slide
+;; - https://github.com/sabof/org-bullets
+;; - https://github.com/magnars/expand-region.el
+;; - https://github.com/Bruce-Connor/fancy-narrow
+;;
+;; See http://github.com/howardabrams/demo-it for more details and
+;; better examples. You will want to walk through the source code
+;; for all the utility functions.
+
+;;; Code:
+
+;; To begin, we need a "global" variable (shudder) that keeps track of
+;; the current state of the demonstration.
+
+(defvar demo-it--step 0 "Stores the current demo 'step' function.")
+(defvar demo-it--steps '() "List of functions to be executed in order.")
+
+;; The following functions come from other projects I like to use
+(declare-function fancy-narrow-to-region "ext:fancy-narrow")
+(declare-function fancy-narrow-to-defun "ext:fancy-narrow")
+(declare-function eshell-send-input "ext:eshell")
+(declare-function show-all "ext:eshell.c")
+(defvar org-tree-slide-heading-emphasis)
+(defvar org-hide-emphasis-markers)
+
+;; Starting a Demonstration
+;;
+;; When we start a demonstration, we would pass in a list of functions
+;; to call for each step, and then call =demo-step= to execute the
+;; first one on the list.
+(defvar demo-it-start-winconf nil
+ "Window configuration when starting demo.")
+
+;;;###autoload
+(defun demo-it-start (steps &optional advanced-mode)
+ "Start the current demonstration and kick off the first step.
+STEPS is a list of functions to execute. If non-nil, the
+optional ADVANCED-MODE turns on keybindings where <F6> advances
+the steps instead of space. This mode is better for more
+interactive demonstrations."
+ (setq demo-it-start-winconf (current-window-configuration))
+ (setq demo-it--step 0) ;; Reset the step to the beginning
+ (setq demo-it--steps steps) ;; Store the steps.
+ (delete-other-windows)
+ (if (not advanced-mode)
+ (demo-it-mode t) ;; Turn on global keymapping mode
+ (demo-it-mode-adv t))
+ (demo-it-step))
+
+(defun demo-it-end ()
+ "End the current demonstration by resetting the values inflicted on the presentation buffer as well as closing other windows."
+ (interactive)
+ (demo-it-disable-mode)
+ (demo-it-presentation-return-noadvance) ;; Close other windows
+ (demo-it-presentation-quit)
+ (set-window-configuration demo-it-start-winconf))
+
+;; Next Step
+;;
+;; Hitting the <F6> key should be bound to triggering the next step in
+;; the demonstration.
+
+(defun demo-it-step (&optional step)
+ "Execute the next step in the current demonstration. Just to a particular STEP if the optional parameter is given, i.e. C-6 <F6> to run the 6th step."
+ (interactive "P")
+ (if step
+ (setq demo-it--step step) ;; Changing Global state, yay!
+ (setq demo-it--step (1+ demo-it--step)))
+ (let
+ ;; At this point, step is 1-based, and I need it 0-based
+ ;; and f-step is the function to call for this step...
+ ((f-step (nth (1- demo-it--step) demo-it--steps)))
+ (if f-step
+ (funcall f-step)
+ (read-event "Finished the entire demonstration. Hit any key to return.")
+ (demo-it-end))))
+
+(defun demo-it-restep ()
+ "Execute the previous step in the current demonstration.
+
+Useful when the previous step failed, and you want to redo it."
+ (interactive)
+ (let
+ ;; At this point, step is 1-based, and I need it 0-based
+ ;; and f-step is the function to call for this step...
+ ((f-step (nth (1- demo-it--step) demo-it--steps)))
+ (if f-step
+ (funcall f-step)
+ (message "Finished the entire demonstration."))))
+
+;; Position or advance the slide? Depends...
+
+(defun demo-it-set-mouse-or-advance (evt)
+ "Advances to the next step if clicked on the right side of any window, otherwise, it position the point as expected. With EVT, function can be bound to the mouse click."
+ (interactive "e")
+ (if (posn-area (event-start evt)) ;; Clicked in special area?
+ (demo-it-step)
+ (let ((col (car (posn-col-row (event-start evt))))
+ (wid (window-width (posn-window (event-start evt)))))
+ (if (> col (- wid 4))
+ (demo-it-step)
+ (mouse-set-point evt)))))
+
+(defun demo-it-show-step ()
+ "Display the expected function to be run during the next step."
+ (interactive)
+ (let ((func (nth demo-it--step demo-it--steps)))
+ (message "Step: %d - Going to run: %s" demo-it--step func)))
+
+(defun demo-it-ignore-event (evt)
+ "Empty function that absorbs the EVT parameter to keep demonstration from flpping out."
+ (interactive "P")
+ (message ""))
+
+
+;; Fancy Region Highlighting
+;;
+;; While sometimes I want highlight some code, it is usually a
+;; function, so instead of remembering two key combinations, let's
+;; just have the =C-+= narrow to the region if active, otherwise,
+;; narrow to the function:
+
+(defun demo-it-highlight-section ()
+ "If the region is active, call 'fancy-narrow-to-region on it, otherwise, call 'fancy-narrow-to-defun, and see what happens."
+ (interactive)
+ (when (fboundp 'fancy-narrow-to-region)
+ (if (region-active-p)
+ (fancy-narrow-to-region (region-beginning) (region-end))
+ (fancy-narrow-to-defun))))
+
+;; Hiding the Modeline
+;;
+;; Call the demo-it-hide-mode-line when displaying images and
+;; org-mode files displayed as "presentations", so that we aren't
+;; bothered by the sight of the mode.
+
+(defvar demo-it--old-mode-line nil)
+(make-variable-buffer-local 'demo-it--old-mode-line)
+
+(defun demo-it-hide-mode-line ()
+ "Hide mode line for a particular buffer."
+ (interactive)
+ (when mode-line-format
+ (setq demo-it--old-mode-line mode-line-format)
+ (setq mode-line-format nil)))
+
+(defun demo-it-show-mode-line ()
+ "Show mode line for a particular buffer, if it was previously hidden with 'demo-it--hide-mode-line."
+ (interactive)
+ (if demo-it--old-mode-line
+ (setq mode-line-format demo-it--old-mode-line)))
+
+;; Making a Side Window
+;;
+;; Typically, we make a side window that is large enough to have some
+;; fun in, as the main window would serve as little more than an
+;; outline.
+
+(defun demo-it-make-side-window (&optional side)
+ "Splits the window horizontally and puts point on right side window. SIDE is either 'below or 'side (for the right side)."
+ (when side
+ (if (eq side 'below)
+ (split-window-vertically)
+ (split-window-horizontally)))
+ (other-window 1))
+
+;; Load a File in the Side Window
+;;
+;; Splits the window and loads a file on the right side of the screen.
+
+(defun demo-it-load-file (file &optional side size)
+ "Splits window and load FILE on the right side of the screen. If SIDE is non-nil, the source code file is place in a window either 'below or to the 'side. The SIZE can be used to scale the text font, which defaults to 1 step larger. This function is called with source code since the mode line is still shown."
+ (if side
+ (demo-it-make-side-window side))
+ (find-file file)
+ (if size (text-scale-set size)
+ (text-scale-set 1)))
+
+;; Load a File and Fancily Highlight Some Lines
+;;
+;; Would be nice to load up a file and automatically highlight some
+;; lines.
+
+(defun demo-it-load-fancy-file (file type line1 line2 &optional side size)
+ "Load FILE and use fancy narrow to highlight part of the buffer. If TYPE is 'char, LINE1 and LINE2 are position in buffer, otherwise LINE1 and LINE2 are start and ending lines to highlight. If SIDE is non-nil, the buffer is placed in a new side window, either 'below or to the 'side, and SIZE is the text scale, which defaults to 1."
+ (demo-it-load-file file side size)
+
+ ; If fancy-narrow hasn't been installed, this behaves
+ ; just like demo-it-load-file
+ (when (fboundp 'fancy-narrow-to-region)
+ (let ((start line1)
+ (end line2))
+ (unless (eq type 'char)
+ (goto-char (point-min)) (forward-line (1- line1)) ;; Heh: (goto-line line1)
+ (setq start (point))
+ (goto-char (point-min)) (forward-line line2)
+ (setq end (point)))
+ (fancy-narrow-to-region start end))))
+
+
+;; Display an Image (or other non-textual scaled file) on the Side
+
+(defun demo-it-show-image (file &optional side)
+ "Load FILE as image (or any other special file) replacing the current buffer. If SIDE is non-nil, the image is shown in another window, either 'below or to the 'side."
+ (demo-it-load-file file side)
+ (fringe-mode '(0 . 0))
+ (demo-it-hide-mode-line))
+
+
+;; Compare and Contrast Files
+;;
+;; Places two files next to each other so that you can diff
+;; or at least visually compare them. I suppose that after
+;; they are loaded, you can switch to them with something like:
+;; (pop-to-buffer "example.py")
+;; To further manipulate them.
+
+(defun demo-it-compare-files (file1 file2 &optional side size)
+ "Load FILE1 and FILE2 as either two windows on top of each other on the right side of the screen, or two windows below (depending on the value of SIDE). The SIZE specifies the text scaling of both buffers."
+ (if (eq side 'below)
+ (progn
+ (demo-it-load-file file1 'below size)
+ (demo-it-load-file file2 'side size))
+ (progn
+ (demo-it-load-file file1 'side size)
+ (demo-it-load-file file2 'below size))))
+
+
+;; Start an Eshell and Run Something
+;;
+;; This function assumes you want an Eshell instance running in the
+;; lower half of the window. Changes to a particular directory, and
+;; automatically runs something.
+
+(defun demo-it-start-eshell (&optional directory command name side size)
+ "Start Eshell instance, and change to DIRECTORY to execute COMMAND. NAME optionally labels the buffer. SIDE can be either 'below or to the 'side, and SIZE specifies the text scale, which defaults to 1 level larger."
+ (let ((title (if name (concat "Shell: " name) "Shell")))
+ (demo-it-make-side-window side)
+ (eshell "new")
+ (rename-buffer title)
+ (if size (text-scale-set size)
+ (text-scale-set 1))
+
+ (when directory
+ (insert (concat "cd " directory))
+ (eshell-send-input))
+ (erase-buffer)
+ (eshell-send-input)
+
+ (when command
+ (insert command)
+ (eshell-send-input))))
+
+(defun demo-it-run-in-eshell (command &optional name)
+ "Run shell command COMMAND in a previously initialized Eshell.
+If NAME is not specified, it defaults to `Shell'."
+ (let ((title (if name (concat "Shell: " name) "Shell")))
+ (pop-to-buffer title)
+ (insert command)
+ (eshell-send-input)))
+
+(defun demo-it-type-in-eshell (command &optional name)
+ "Run shell command COMMAND in a previously initialized Eshell.
+If NAME is not specified, it defaults to `Shell'."
+ (let ((title (if name (concat "Shell: " name) "Shell")))
+ (pop-to-buffer title)
+ (demo-it-insert-typewriter command)
+ (eshell-send-input)))
+
+;; Title Display
+;;
+;; Create a file to serve as a "title" as it will be displayed with a
+;; larger-than-life font.
+
+(defun demo-it-title-screen (file &optional size)
+ "Use FILE to serve as a presentation title, as it will be displayed with a larger-than-life font. SIZE specifies the text scale, which defaults to 5x."
+ (delete-other-windows)
+ (fringe-mode '(0 . 0))
+
+ (find-file file)
+ (show-all)
+ (demo-it-hide-mode-line)
+ (setq cursor-type nil)
+ (if (fboundp 'flyspell-mode)
+ (flyspell-mode -1))
+ (variable-pitch-mode 1)
+ (if size (text-scale-set size)
+ (text-scale-set 5))
+
+ (message "%s" "† This presentation is running within Emacs."))
+
+;; Starting an ORG Presentation
+;;
+;; Since I often have an org-mode file on the side of the screen to
+;; demonstrate an outline of what I will be demoing, I made it a
+;; function.
+
+;; Uses org-tree-slide if available.
+;; See https://github.com/takaxp/org-tree-slide
+
+(defvar demo-it--presentation-file "")
+(defvar demo-it--presentation-buffer nil)
+(defvar demo-it--presentation-prev-settings (make-hash-table))
+
+(defun demo-it-presentation (file &optional size)
+ "Load FILE (org-mode?) as presentation. Start org-tree-slide if available. SIZE specifies the text scale, and defaults to 2 steps larger."
+ (find-file file)
+ (setq demo-it--presentation-file file)
+ (setq demo-it--presentation-buffer (buffer-name))
+
+ (when (fboundp 'org-tree-slide-mode)
+ (setq org-tree-slide-heading-emphasis t)
+ (org-tree-slide-mode))
+
+ (when (fboundp 'flyspell-mode)
+ (flyspell-mode -1))
+ (setq cursor-type nil)
+ (variable-pitch-mode 1)
+
+ ;; Make the display of the org-mode file more presentable
+ (demo-it--presentation-display-set)
+
+ (demo-it-hide-mode-line)
+ (if size (text-scale-set size)
+ (text-scale-set 2))
+
+ (when (fboundp 'org-bullets-mode)
+ (org-bullets-mode 1)))
+
+
+(defun demo-it--presentation-display-set ()
+ "Change some typical `org-mode' display values to make more presentation-friendly. Store the changed values in a hashtable. See `demo-it--presentation-display-restore'."
+ (puthash :emphais-markers org-hide-emphasis-markers demo-it--presentation-prev-settings)
+ (setq org-hide-emphasis-markers t)
+
+ (puthash :table-inherit (face-attribute 'org-table :inherit)
+ demo-it--presentation-prev-settings)
+ (puthash :verbatim-inherit (face-attribute 'org-verbatim :inherit)
+ demo-it--presentation-prev-settings)
+ (puthash :block-inherit (face-attribute 'org-block-background :inherit)
+ demo-it--presentation-prev-settings)
+ (puthash :begin-block-height (face-attribute 'org-block-begin-line :height)
+ demo-it--presentation-prev-settings)
+ (puthash :begin-block-foregd (face-attribute 'org-block-begin-line :foreground)
+ demo-it--presentation-prev-settings)
+ (puthash :end-block-height (face-attribute 'org-block-end-line :height)
+ demo-it--presentation-prev-settings)
+ (puthash :end-block-foregd (face-attribute 'org-block-end-line :foreground)
+ demo-it--presentation-prev-settings)
+
+ (let ((begin-backgd (face-attribute 'org-block-begin-line :background))
+ (end-backgd (face-attribute 'org-block-end-line :background)))
+ (set-face-attribute 'org-table nil :inherit 'fixed-pitch)
+ (set-face-attribute 'org-verbatim nil :inherit 'fixed-pitch)
+ (set-face-attribute 'org-block-background nil :inherit 'fixed-pitch)
+ (set-face-attribute 'org-block-begin-line nil :height 1 :foreground begin-backgd)
+ (set-face-attribute 'org-block-end-line nil :height 1 :foreground end-backgd)))
+
+(defun demo-it--presentation-display-restore ()
+ "After `demo-it--presentation-display-set', call to restore previous settings."
+ (setq org-hide-emphasis-markers
+ (gethash :emphais-markers demo-it--presentation-prev-settings))
+
+ (set-face-attribute 'org-table nil :inherit
+ (gethash :table-inherit demo-it--presentation-prev-settings))
+ (set-face-attribute 'org-verbatim nil :inherit
+ (gethash :table-verbatim demo-it--presentation-prev-settings))
+ (set-face-attribute 'org-block-background nil :inherit
+ (gethash :block-inherit demo-it--presentation-prev-settings))
+ (set-face-attribute 'org-block-begin-line nil
+ :height (gethash :begin-block-height demo-it--presentation-prev-settings)
+ :foreground (gethash :begin-block-foregd demo-it--presentation-prev-settings))
+ (set-face-attribute 'org-block-end-line nil
+ :height (gethash :end-block-height demo-it--presentation-prev-settings)
+ :foreground (gethash :end-block-foregd demo-it--presentation-prev-settings)))
+
+;; Jumping Back to the Presentation
+;;
+;; In this case, we've been doing some steps, and the screen is
+;; "messed up", calling this function returns back to the
+;; presentation.
+
+(defun demo-it-presentation-return-noadvance ()
+ "Return to the presentation buffer and delete other windows."
+ (when demo-it--presentation-buffer
+ (switch-to-buffer demo-it--presentation-buffer))
+ (delete-other-windows))
+
+(defun demo-it-presentation-return ()
+ "Return to the presentation buffer, delete other windows, and advance to the next 'org-mode' section."
+ (when demo-it--presentation-buffer
+ (demo-it-presentation-return-noadvance)
+ (when (fboundp 'org-tree-slide-move-next-tree)
+ (org-tree-slide-move-next-tree))))
+
+(defun demo-it-single-presentation (file)
+ "Demonstration that presents on `org-mode' FILE as a full-screen presentation."
+ (interactive "fPresentation File: ")
+ (cl-flet ((present-it ()
+ (demo-it-frame-fullscreen)
+ (delete-other-windows)
+ (demo-it-presentation file)))
+ (demo-it-start (list #'present-it) t)))
+
+;; Advance Presentation without Changing Focus
+;;
+;; Advances the org-mode presentation, but after popping into that
+;; presentation buffer, returns to the window where our focus was
+;; initially.
+
+(defun demo-it-presentation-advance ()
+ "Advance the presentation to the next frame (if the buffer is an 'org-mode' and 'org-tree-slide' is available), but doesn't change focus or other windows. Only useful if using the org-tree-slide mode for the presentation buffer."
+ (interactive)
+ (when demo-it--presentation-buffer
+ (let ((orig-window (current-buffer)))
+ (switch-to-buffer demo-it--presentation-buffer)
+ (when (fboundp 'org-tree-slide-move-next-tree)
+ (org-tree-slide-move-next-tree))
+ (switch-to-buffer orig-window))))
+
+;; Clean up the Presentation
+;;
+;; The org-presentation-start function alters the way an org-mode file
+;; is displayed. This function returns it back to a normal, editable
+;; state.
+
+(defun demo-it-presentation-quit ()
+ "Undo display settings made to the presentation buffer."
+ (when demo-it--presentation-buffer
+ (switch-to-buffer demo-it--presentation-buffer)
+ (when (fboundp 'org-tree-slide-mode)
+ (org-tree-slide-mode -1))
+ (when (fboundp 'flyspell-mode)
+ (flyspell-mode t))
+ (setq cursor-type t)
+ (demo-it--presentation-display-restore) ; Restore previous changes
+ (variable-pitch-mode nil)
+ (demo-it-show-mode-line)
+ (text-scale-set 0)))
+
+;; Switch Framesize
+;;
+;; During a demonstration, it might be nice to toggle between
+;; full screen and "regular window" in a programmatic way:
+
+(defun demo-it-toggle-fullscreen ()
+ "Toggle the frame between full screen and normal size."
+ (interactive)
+ (set-frame-parameter
+ nil 'fullscreen
+ (when (not (frame-parameter nil 'fullscreen)) 'fullboth)))
+
+;; We can force the window to be full screen:
+
+(defun demo-it-frame-fullscreen ()
+ "Set the frame window to cover the full screen."
+ (interactive)
+ (set-frame-parameter nil 'fullscreen 'fullboth))
+
+;; Let's make a right-side frame window:
+
+(defun demo-it-frame-leftside ()
+ "Set the window frame to be exactly half the physical display screen, and place it on the left side of the screen. This can be helpful when showing off some other application."
+ (interactive)
+ (let* ((full-pixels (- (x-display-pixel-width) 16))
+ (full-width (/ full-pixels (frame-char-width)))
+ (dest-width (/ full-width 2)))
+ (set-frame-parameter nil 'fullscreen nil)
+ (set-frame-parameter nil 'width dest-width)
+ (set-frame-parameter nil 'left 0)))
+
+;; Helper Functions
+
+(defvar demo-it-text-entries (make-hash-table)
+ "Collection of insertable text and keys for `demo-it-insert-text'.
+Strings to insert Assign a collection of characters as keys and
+strings, and call the `C-c i` to insert the text string as if you
+were typing it.
+
+For instance:
+ (setq demo-it-text-entries #s(hash-table data
+ (?1 \"How about that?\"
+ ?2 \"Nah, this really ain't it.\")))")
+
+(defun demo-it-insert-text (key)
+ "Insert text into the current buffer based on a single character KEY.
+
+The text is inserted as if you were typing it. Make sure the
+`demo-it-text-entries' hash-table has been initialized with a
+character to be used as a key, and the text to insert."
+ (interactive "cInsert text from which key?")
+ (demo-it-insert-typewriter (gethash key demo-it-text-entries)))
+
+(defun demo-it-insert-typewriter (str)
+ "Insert STR into the current buffer as if you were typing it by hand."
+ (interactive "s")
+ (dolist (ch (string-to-list str))
+ (insert ch)
+ (sit-for (/ 1.0 (+ 10 (random 100))) nil)))
+
+
+(defun demo-it-message-keybinding (key command)
+ "Display message showing the KEY keybinding and its COMMAND."
+ (interactive)
+ (message "Typed: '%s' Command: '%s'" key command))
+
+;; Demo Mode
+;;
+;; Allows us to advance to the next step by pressing the
+;; space bar or return. Press the 'q' key to stop the mode.
+
+(defun demo-it-disable-mode ()
+ "Called when 'q' pressed to disable the 'demo-it-mode'."
+ (interactive)
+ (demo-it-mode -1)
+ (demo-it-mode-adv -1))
+
+(define-minor-mode demo-it-mode "Pressing 'space' advances demo."
+ :lighter " demo"
+ :require 'demo-it
+ :global t
+ :keymap '((" " . demo-it-step)
+ ("\r" . demo-it-step)
+ ("[down]" . demo-it-step)
+ ("[mouse-1]" . demo-it-set-mouse-or-advance)
+ ([nil mouse-1] . demo-it-step)
+ ([nil wheel-up] . demo-it-ignore-event)
+ ([nil wheel-down] . demo-it-ignore-event)
+ ([nil wheel-left] . demo-it-ignore-event)
+ ([nil wheel-right] . demo-it-ignore-event)
+ ("q" . demo-it-disable-mode)
+ ("Q" . demo-it-end)))
+
+(define-minor-mode demo-it-mode-adv "Pressing '<f12>' advances demo."
+ :lighter " demo-adv"
+ :require 'demo-it
+ :global t
+ :keymap (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "<f12>") 'demo-it-step)
+ (define-key map (kbd "s-<f12>") 'demo-it-insert-text)
+ (define-key map (kbd "A-<f12>") 'demo-it-insert-text)
+ (define-key map (kbd "M-<f12>") 'demo-it-end)
+ map))
+
+;; New Keybindings
+;;
+;; I have found the following keybindings quite useful, but your mileage may vary.
+
+(defun demo-it-keybindings ()
+ "Add a few global keybindings if some other packages are installed.
+You probably want to look at the source, and create
+your own version of this, but it does the following:
+
+- C-= Selects or increases the region using expand-region
+- M-C-= Highlights the region (dimming the rest) using fancy-narrow
+- M-C-+ Unhighlights buffer (by colorizing entire buffer) using fancy-narrow
+
+This function should never had been written, as it is better to
+just add your own keybindings to the demo-it-mode instead, as in:
+
+ (define-key demo-it-mode-map (kbd \"C-<f12>\") 'demo-it-presentation-advance)"
+ (declare (obsolete "Add keybinds to demo-it-mode directly." "Dec 2015"))
+ (interactive)
+
+ (when (fboundp 'er/expand-region)
+ (global-set-key (kbd "C-=") 'er/expand-region))
+ (when (fboundp 'fancy-widen)
+ (global-set-key (kbd "M-C-=") 'highlight-section)
+ (global-set-key (kbd "M-C-+") 'fancy-widen)))
+
+;; As a final harrah, we need to let other files know how to include
+;; this bad child.
+
+(provide 'demo-it)
+
+;;; demo-it.el ends here
--- /dev/null
+ When making demonstrations of new products, technologies and other
+ geekery, I love the versatility of using Emacs to demonstrate the
+ trifecta of sprint reviews, including:
+
+ - Presentations explaining the technologies
+ - Source code ... correctly highlighted
+ - Executing the code in Eshell ... or similar demonstration
+
+ However, I don't want to fat-finger, mentally burp, or even delay
+ the gratification while I type, so I predefine each "step" as an
+ Elisp function, and then have =demo-it= execute each function when I
+ hit the F6 key.
+
+ Using the library is a three step process:
+
+ 1. Load the library in your own Elisp source code file
+ 2. Create a collection of functions that "do things".
+ 3. Call the =demo-it-start= function with the ordered list of
+ functions.
+
+ For instance:
+
+ (load-library "demo-it") ;; Load this library of functions
+
+ (defun my-demo/step-1 ()
+ (delete-other-windows)
+ (demo/org-presentation "~/presentations/my-demo/demo-start.org"))
+
+ (defun my-demo/step-2 ()
+ (demo-it-load-file "~/Work/my-proj/src/my-proj.py")
+ (demo-it-presentation-return))
+
+ (defun my-demo ()
+ "My fabulous demonstration."
+ (interactive)
+ (demo-it-start (list
+ 'my-demo/step-1
+ 'my-demo/step-2
+ ;; ...
+ )))
+
+ (my-demo) ;; Optionally start the demo when file is loaded.
+
+ Each "step" is a series of Elisp functions that "do things".
+ While this package has a collection of helping functions, the steps
+ can use any Elisp command to show off a feature.
+
+ I recommend installing these other Emacs packages:
+
+ - https://github.com/takaxp/org-tree-slide
+ - https://github.com/sabof/org-bullets
+ - https://github.com/magnars/expand-region.el
+ - https://github.com/Bruce-Connor/fancy-narrow
+
+ See http://github.com/howardabrams/demo-it for more details and
+ better examples. You will want to walk through the source code
+ for all the utility functions.
--- /dev/null
+;;; org-tree-slide-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (or (file-name-directory #$) (car load-path)))
+\f
+;;;### (autoloads nil "org-tree-slide" "org-tree-slide.el" (22173
+;;;;;; 59637 0 0))
+;;; Generated autoloads from org-tree-slide.el
+
+(autoload 'org-tree-slide-mode "org-tree-slide" "\
+A presentation tool for org-mode.
+
+Usage:
+ - Set minimal recommendation settings in .emacs
+ (global-set-key (kbd \"<f8>\") 'org-tree-slide-mode)
+ (global-set-key (kbd \"S-<f8>\") 'org-tree-slide-skip-done-toggle)
+ - Open an org file
+ - Type <f8> to start org-tree-slide-mode
+ - Type <left>/<right> to move between trees
+ - To exit this minor mode, just type <f8> again.
+
+Profiles:
+
+ - [ Simple ]
+ => M-x `org-tree-slide-simple-profile'
+
+ 1. No header display
+ 2. No slide-in effect
+ 3. The cursor will move to the head of buffer when exit
+ 4. No slide number display in mode line
+ 5. Display every type of tree
+
+ - [ Presentation ]
+ => M-x `org-tree-slide-presentation-profile'
+
+ 1. Display header
+ 2. Enable slide-in effect
+ 3. The cursor will move to the head of buffer when exit
+ 4. Display slide number in mode line
+ 5. Display every type of tree
+
+ - [ TODO Pursuit with narrowing ]
+ => M-x `org-tree-slide-narrowing-control-profile'
+
+ 1. No header display
+ 2. No slide-in effect
+ 3. The cursor will keep the same position when exit
+ 4. Display slide number in mode line
+ 5. Display TODO trees only
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'org-tree-slide-play-with-timer "org-tree-slide" "\
+Start slideshow with setting a count down timer.
+
+\(fn)" t nil)
+
+(autoload 'org-tree-slide-without-init-play "org-tree-slide" "\
+Start slideshow without the init play. Just enter org-tree-slide-mode.
+
+\(fn)" t nil)
+
+(autoload 'org-tree-slide-content "org-tree-slide" "\
+Change the display for viewing content of the org file during
+ the slide view mode is active.
+
+\(fn)" t nil)
+
+(autoload 'org-tree-slide-simple-profile "org-tree-slide" "\
+Set variables for simple use.
+ `org-tree-slide-header' => nil
+ `org-tree-slide-slide-in-effect' => nil
+ `org-tree-slide-heading-emphasis' => nil
+ `org-tree-slide-cursor-init' => t
+ `org-tree-slide-modeline-display' => nil
+ `org-tree-slide-skip-done' => nil
+ `org-tree-slide-skip-comments' => t
+
+\(fn)" t nil)
+
+(autoload 'org-tree-slide-presentation-profile "org-tree-slide" "\
+Set variables for presentation use.
+ `org-tree-slide-header' => t
+ `org-tree-slide-slide-in-effect' => t
+ `org-tree-slide-heading-emphasis' => nil
+ `org-tree-slide-cursor-init' => t
+ `org-tree-slide-modeline-display' => 'outside
+ `org-tree-slide-skip-done' => nil
+ `org-tree-slide-skip-comments' => t
+
+\(fn)" t nil)
+
+(autoload 'org-tree-slide-narrowing-control-profile "org-tree-slide" "\
+Set variables for TODO pursuit with narrowing.
+ `org-tree-slide-header' => nil
+ `org-tree-slide-slide-in-effect' => nil
+ `org-tree-slide-heading-emphasis' => nil
+ `org-tree-slide-cursor-init' => nil
+ `org-tree-slide-modeline-display' => 'lighter
+ `org-tree-slide-skip-done' => t
+ `org-tree-slide-skip-comments' => t
+
+\(fn)" t nil)
+
+(autoload 'org-tree-slide-display-header-toggle "org-tree-slide" "\
+Toggle displaying the slide header
+
+\(fn)" t nil)
+
+(autoload 'org-tree-slide-slide-in-effect-toggle "org-tree-slide" "\
+Toggle using slide-in effect
+
+\(fn)" t nil)
+
+(autoload 'org-tree-slide-heading-emphasis-toggle "org-tree-slide" "\
+Toggle applying emphasis to heading
+
+\(fn)" t nil)
+
+(autoload 'org-tree-slide-skip-done-toggle "org-tree-slide" "\
+Toggle show TODO item only or not
+
+\(fn)" t nil)
+
+(autoload 'org-tree-slide-skip-comments-toggle "org-tree-slide" "\
+Toggle show COMMENT item or not
+
+\(fn)" t nil)
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; org-tree-slide-autoloads.el ends here
--- /dev/null
+(define-package "org-tree-slide" "20151222.2347" "A presentation tool for org-mode" 'nil :keywords '("org-mode" "presentation" "narrowing"))
--- /dev/null
+;;; org-tree-slide.el --- A presentation tool for org-mode
+;;
+;; Copyright (C) 2011-2015 Takaaki ISHIKAWA
+;;
+;; Author: Takaaki ISHIKAWA <takaxp at ieee dot org>
+;; Version: 2.8.4
+;; Package-Version: 20151222.2347
+;; Maintainer: Takaaki ISHIKAWA <takaxp at ieee dot org>
+;; Twitter: @takaxp
+;; Repository: https://github.com/takaxp/org-tree-slide
+;; Keywords: org-mode, presentation, narrowing
+;;
+;; Committers: Yuuki ARISAWA (@uk-ar)
+;; Eric S Fraga
+;; Eike Kettner
+;; Stefano BENNATI
+;;
+;; 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; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+;;
+
+;;; Commentary:
+
+;; Requirement:
+;; org-mode 6.33x or higher version
+;; The latest version of the org-mode is recommended.
+;; (see http://orgmode.org/)
+;;
+;; Usage:
+;; 1. Put this elisp into your load-path
+;; 2. Add (require 'org-tree-slide) in your .emacs
+;; 3. Open an org-mode file
+;; 4. Toggle org-tree-slide-mode (M-x org-tree-slide-mode)
+;; then Slideshow will start and you can find "TSlide" in mode line.
+;; 5. <left>/<right> will move between slides
+;; 6. `C-x s c' will show CONTENT of the org buffer
+;; Select a heading and type <right>, then Slideshow will start again.
+;; 7. Toggle org-tree-slide-mode again to exit this minor mode
+;;
+;; Recommended minimum settings:
+;; (global-set-key (kbd "<f8>") 'org-tree-slide-mode)
+;; (global-set-key (kbd "S-<f8>") 'org-tree-slide-skip-done-toggle)
+;;
+;; and three useful profiles are available.
+;;
+;; 1. Simple use
+;; M-x org-tree-slide-simple-profile
+;;
+;; 2. Presentation use
+;; M-x org-tree-slide-presentation-profile
+;;
+;; 3. TODO Pursuit with narrowing
+;; M-x org-tree-slide-narrowing-control-profile
+;;
+;; Type `C-h f org-tree-slide-mode', you can find more detail.
+;;
+;; Note:
+;; - Make sure key maps below when you introduce this elisp.
+;; - Customize variables, M-x customize-group ENT org-tree-slide ENT
+
+;;; Code:
+
+(require 'org)
+(require 'org-timer)
+;;(require 'org-clock) ; org-clock-in, -out, -clocking-p
+
+(defconst org-tree-slide "2.8.4"
+ "The version number of the org-tree-slide.el")
+
+(defgroup org-tree-slide nil
+ "User variables for org-tree-slide."
+ :group 'org-structure)
+
+(defcustom org-tree-slide-skip-outline-level 0
+ "Skip slides if a heading level is higher than or equal to this variable.
+ `0': never skip at any heading
+ e.g. set `4',
+ *** heading A ; display as a slide
+ entry
+ **** heading B ; skip! do not display as the next slide
+ **** heading C ; skip!
+ *** heading D ; display as the next slide
+"
+ :type 'integer
+ :group 'org-tree-slide)
+
+(defcustom org-tree-slide-fold-subtrees-skipped t
+ "If this flag is true, the subtrees in a slide will be displayed in fold.
+ When nil, the body of the subtrees will be revealed.
+"
+ :type 'boolean
+ :group 'org-tree-slide)
+
+(defcustom org-tree-slide-header t
+ "The status of displaying the slide header"
+ :type 'boolean
+ :group 'org-tree-slide)
+
+(defcustom org-tree-slide-slide-in-effect t
+ "Using a visual effect of slide-in for displaying trees."
+ :type 'boolean
+ :group 'org-tree-slide)
+
+(defcustom org-tree-slide-cursor-init t
+ "Specify a cursor position when exit slideshow.
+ `t': the cursor will move automatically to the head of buffer.
+ nil: keep the same position."
+ :type 'boolean
+ :group 'org-tree-slide)
+
+(defcustom org-tree-slide-slide-in-blank-lines 10
+ "Specify the number of blank lines, the slide will move from this line."
+ :type 'integer
+ :group 'org-tree-slide)
+
+(defcustom org-tree-slide-slide-in-waiting 0.02
+ "Specify the duration waiting the next update of overlay."
+ :type 'float
+ :group 'org-tree-slide)
+
+(defcustom org-tree-slide-heading-emphasis nil
+ "Specify to use a custom face heading, or not"
+ :type 'boolean
+ :group 'org-tree-slide)
+
+(defcustom org-tree-slide-never-touch-face nil
+ "If t, do NOT touch any face setting."
+ :type 'boolean
+ :group 'org-tree-slide)
+
+(defcustom org-tree-slide-skip-done nil
+ "Specify to show TODO item only or not."
+ :type 'boolean
+ :group 'org-tree-slide)
+
+(defcustom org-tree-slide-skip-comments t
+ "Specify to skip COMMENT item or not."
+ :type 'boolean
+ :group 'org-tree-slide)
+
+(defcustom org-tree-slide-activate-message
+ "Hello! This is org-tree-slide :-)"
+ "Message in mini buffer when org-tree-slide is activated."
+ :type 'string
+ :group 'org-tree-slide)
+
+(defcustom org-tree-slide-deactivate-message
+ "Quit, Bye!"
+ "Message in mini buffer when org-tree-slide is deactivated."
+ :type 'string
+ :group 'org-tree-slide)
+
+(defcustom org-tree-slide-modeline-display 'outside
+ "Specify how to display the slide number in mode line.
+ 'lighter: shown in lighter (update info actively, then it's slow)
+ 'outside: update infomation when moving to the next/previous slide
+ nil: nothing to be shown"
+ :type 'symbol
+ :group 'org-tree-slide)
+
+(defvar org-tree-slide-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-x s c") 'org-tree-slide-content)
+ ;; (define-key map (kbd "C-x s r") 'org-tree-slide-resume) ;; TODO
+ (define-key map (kbd "C-<") 'org-tree-slide-move-previous-tree)
+ (define-key map (kbd "C->") 'org-tree-slide-move-next-tree)
+ map)
+ "The keymap for `org-tree-slide'.")
+
+(defface org-tree-slide-heading-level-2-init
+ '((t (:inherit outline-2)))
+ "Level 2."
+ :group 'org-tree-slide)
+
+(defface org-tree-slide-heading-level-3-init
+ '((t (:inherit outline-3)))
+ "Level 3."
+ :group 'org-tree-slide)
+
+(defface org-tree-slide-heading-level-2
+ '((t (:inherit outline-2 :height 1.4 :bold t)))
+ "Level 2."
+ :group 'org-tree-slide)
+
+(defface org-tree-slide-heading-level-3
+ '((t (:inherit outline-3 :height 1.3 :bold t)))
+ "Level 3."
+ :group 'org-tree-slide)
+
+(defvar org-tree-slide-mode nil)
+;; These hooks was obsoleted, and will be deleted by Oct. 2015.
+(defvar org-tree-slide-mode-play-hook nil
+ "[obsolete] A hook run when org-tree-slide--play is evaluated to start the slide show")
+(defvar org-tree-slide-mode-stop-hook nil
+ "[obsolete] A hook run when org-tree-slide--stop is evaluated to stop the slide show")
+(defvar org-tree-slide-mode-before-narrow-hook nil
+ "[obsolete] A hook run before evaluating org-tree-slide--display-tree-with-narrow")
+(defvar org-tree-slide-mode-after-narrow-hook nil
+ "[obsolete] A hook run after evaluating org-tree-slide--display-tree-with-narrow")
+
+;; Updated hooks
+(defvar org-tree-slide-play-hook nil
+ "A hook run when org-tree-slide--play is evaluated to start the slide show")
+(defvar org-tree-slide-stop-hook nil
+ "A hook run when org-tree-slide--stop is evaluated to stop the slide show")
+(defvar org-tree-slide-before-narrow-hook nil
+ "A hook run before evaluating org-tree-slide--display-tree-with-narrow")
+(defvar org-tree-slide-after-narrow-hook nil
+ "A hook run after evaluating org-tree-slide--display-tree-with-narrow")
+(defvar org-tree-slide-before-move-next-hook nil
+ "A hook run before moving to the next slide")
+(defvar org-tree-slide-before-move-previous-hook nil
+ "A hook run before moving to the previous slide")
+
+;;;###autoload
+(define-minor-mode org-tree-slide-mode
+ "A presentation tool for org-mode.
+
+Usage:
+ - Set minimal recommendation settings in .emacs
+ (global-set-key (kbd \"<f8>\") 'org-tree-slide-mode)
+ (global-set-key (kbd \"S-<f8>\") 'org-tree-slide-skip-done-toggle)
+ - Open an org file
+ - Type <f8> to start org-tree-slide-mode
+ - Type <left>/<right> to move between trees
+ - To exit this minor mode, just type <f8> again.
+
+Profiles:
+
+ - [ Simple ]
+ => M-x `org-tree-slide-simple-profile'
+
+ 1. No header display
+ 2. No slide-in effect
+ 3. The cursor will move to the head of buffer when exit
+ 4. No slide number display in mode line
+ 5. Display every type of tree
+
+ - [ Presentation ]
+ => M-x `org-tree-slide-presentation-profile'
+
+ 1. Display header
+ 2. Enable slide-in effect
+ 3. The cursor will move to the head of buffer when exit
+ 4. Display slide number in mode line
+ 5. Display every type of tree
+
+ - [ TODO Pursuit with narrowing ]
+ => M-x `org-tree-slide-narrowing-control-profile'
+
+ 1. No header display
+ 2. No slide-in effect
+ 3. The cursor will keep the same position when exit
+ 4. Display slide number in mode line
+ 5. Display TODO trees only
+"
+ :init-value nil
+ :lighter (:eval (org-tree-slide--update-modeline))
+ :keymap org-tree-slide-mode-map
+ :group 'org-tree-slide
+ :require 'org
+ (if org-tree-slide-mode
+ (org-tree-slide--setup)
+ (org-tree-slide--abort)))
+
+;;;###autoload
+(defun org-tree-slide-play-with-timer ()
+ "Start slideshow with setting a count down timer."
+ (interactive)
+ (org-timer-set-timer)
+ (unless (org-tree-slide--active-p)
+ (org-tree-slide-mode)))
+
+;;;###autoload
+(defun org-tree-slide-without-init-play ()
+ "Start slideshow without the init play. Just enter org-tree-slide-mode."
+ (interactive)
+ (org-tree-slide-mode)
+ (widen)
+ (org-overview)
+ (goto-char 1))
+
+;;;###autoload
+(defun org-tree-slide-content ()
+ "Change the display for viewing content of the org file during
+ the slide view mode is active."
+ (interactive)
+ (when (org-tree-slide--active-p)
+ (org-tree-slide--hide-slide-header)
+ (org-tree-slide--move-to-the-first-heading)
+ (org-overview)
+ (org-content (if (> org-tree-slide-skip-outline-level 0)
+ (1- org-tree-slide-skip-outline-level)))
+ (message "<< CONTENT >>")))
+
+;;;###autoload
+(defun org-tree-slide-simple-profile ()
+ "Set variables for simple use.
+ `org-tree-slide-header' => nil
+ `org-tree-slide-slide-in-effect' => nil
+ `org-tree-slide-heading-emphasis' => nil
+ `org-tree-slide-cursor-init' => t
+ `org-tree-slide-modeline-display' => nil
+ `org-tree-slide-skip-done' => nil
+ `org-tree-slide-skip-comments' => t
+"
+ (interactive)
+ (setq org-tree-slide-header nil)
+ (setq org-tree-slide-slide-in-effect nil)
+ (setq org-tree-slide-heading-emphasis nil)
+ (setq org-tree-slide-cursor-init t)
+ (setq org-tree-slide-modeline-display nil)
+ (setq org-tree-slide-skip-done nil)
+ (setq org-tree-slide-skip-comments t)
+ (message "simple profile: ON"))
+
+;;;###autoload
+(defun org-tree-slide-presentation-profile ()
+ "Set variables for presentation use.
+ `org-tree-slide-header' => t
+ `org-tree-slide-slide-in-effect' => t
+ `org-tree-slide-heading-emphasis' => nil
+ `org-tree-slide-cursor-init' => t
+ `org-tree-slide-modeline-display' => 'outside
+ `org-tree-slide-skip-done' => nil
+ `org-tree-slide-skip-comments' => t
+"
+ (interactive)
+ (setq org-tree-slide-header t)
+ (setq org-tree-slide-slide-in-effect t)
+ (setq org-tree-slide-heading-emphasis nil)
+ (setq org-tree-slide-cursor-init t)
+ (setq org-tree-slide-modeline-display 'outside)
+ (setq org-tree-slide-skip-done nil)
+ (setq org-tree-slide-skip-comments t)
+ (message "presentation profile: ON"))
+
+;;;###autoload
+(defun org-tree-slide-narrowing-control-profile ()
+ "Set variables for TODO pursuit with narrowing.
+ `org-tree-slide-header' => nil
+ `org-tree-slide-slide-in-effect' => nil
+ `org-tree-slide-heading-emphasis' => nil
+ `org-tree-slide-cursor-init' => nil
+ `org-tree-slide-modeline-display' => 'lighter
+ `org-tree-slide-skip-done' => t
+ `org-tree-slide-skip-comments' => t
+"
+ (interactive)
+ (setq org-tree-slide-header nil)
+ (setq org-tree-slide-slide-in-effect nil)
+ (setq org-tree-slide-heading-emphasis nil)
+ (setq org-tree-slide-cursor-init nil)
+ (setq org-tree-slide-modeline-display 'lighter)
+ (setq org-tree-slide-skip-done t)
+ (setq org-tree-slide-skip-comments t)
+ (message "narrowing control profile: ON"))
+
+;;;###autoload
+(defun org-tree-slide-display-header-toggle ()
+ "Toggle displaying the slide header"
+ (interactive)
+ (setq org-tree-slide-header (not org-tree-slide-header))
+ (unless org-tree-slide-header
+ (org-tree-slide--hide-slide-header))
+ (org-tree-slide--display-tree-with-narrow))
+
+;;;###autoload
+(defun org-tree-slide-slide-in-effect-toggle ()
+ "Toggle using slide-in effect"
+ (interactive)
+ (setq org-tree-slide-slide-in-effect (not org-tree-slide-slide-in-effect))
+ (org-tree-slide--display-tree-with-narrow))
+
+;;;###autoload
+(defun org-tree-slide-heading-emphasis-toggle ()
+ "Toggle applying emphasis to heading"
+ (interactive)
+ (setq org-tree-slide-heading-emphasis (not org-tree-slide-heading-emphasis))
+ (org-tree-slide--apply-custom-heading-face org-tree-slide-heading-emphasis))
+
+(defvar org-tree-slide--previous-line 0)
+;;;###autoload
+(defun org-tree-slide-skip-done-toggle ()
+ "Toggle show TODO item only or not"
+ (interactive)
+ (setq org-tree-slide-skip-done (not org-tree-slide-skip-done))
+ (setq org-tree-slide--previous-line -1) ; to update modeline intentionally
+ (org-tree-slide--show-slide-header)
+ (if org-tree-slide-skip-done
+ (message "TODO Pursuit: ON") (message "TODO Pursuit: OFF")))
+
+;;;###autoload
+(defun org-tree-slide-skip-comments-toggle ()
+ "Toggle show COMMENT item or not"
+ (interactive)
+ (setq org-tree-slide-skip-comments (not org-tree-slide-skip-comments))
+ (if org-tree-slide-skip-comments
+ (message "COMMENT: HIDE") (message "COMMENT: SHOW")))
+
+(defun org-tree-slide-move-next-tree ()
+ "Display the next slide"
+ (interactive)
+ (when (org-tree-slide--active-p)
+ (unless (equal org-tree-slide-modeline-display 'outside)
+ (message " Next >>"))
+ (cond
+ ((and (org-tree-slide--narrowing-p) ;displaying a slide, not the contents
+ (org-tree-slide--last-tree-p (progn (beginning-of-line) (point)))) ;the last subtree
+ (org-tree-slide-content))
+ ((or
+ (or (and (org-tree-slide--before-first-heading-p)
+ (not (org-at-heading-p)))
+ (and (= (point-at-bol) 1) (not (org-tree-slide--narrowing-p))))
+ (or (org-tree-slide--first-heading-with-narrow-p)
+ (not (org-at-heading-p))))
+ (run-hooks 'org-tree-slide-before-move-next-hook)
+ (widen)
+ (org-tree-slide--outline-next-heading)
+ (org-tree-slide--display-tree-with-narrow))
+ ;; stay the same slide (for CONTENT MODE, on the subtrees)
+ (t nil (org-tree-slide--display-tree-with-narrow)))
+ ;; (when (and org-tree-slide-skip-done (looking-at (concat "^\\*+ " org-not-done-regexp))) (org-clock-in) )
+ ))
+
+(defun org-tree-slide-move-previous-tree ()
+ "Display the previous slide"
+ (interactive)
+ (when (org-tree-slide--active-p)
+ (unless (equal org-tree-slide-modeline-display 'outside)
+ (message "<< Previous"))
+ (org-tree-slide--hide-slide-header) ; for at the first heading
+ (run-hooks 'org-tree-slide-before-move-previous-hook)
+ (widen)
+ (cond
+ ((org-tree-slide--before-first-heading-p)
+ (message "before first heading (org-tree-slide)" ))
+ ((not (org-at-heading-p))
+ (org-tree-slide--outline-previous-heading)
+ (org-tree-slide--outline-previous-heading))
+ (t (org-tree-slide--outline-previous-heading)))
+ ;; (when (and org-tree-slide-skip-done (looking-at (concat "^\\*+ " org-not-done-regexp))) (org-clock-in) )
+ (org-tree-slide--display-tree-with-narrow)
+ ;; To avoid error of missing header in Emacs24
+ (if (= emacs-major-version 24)
+ (goto-char (point-min)))))
+
+;;; Internal functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defvar org-tree-slide--slide-number nil)
+(make-variable-buffer-local 'org-tree-slide--slide-number)
+
+(defvar org-tree-slide--lighter " TSlide"
+ "Lighter for org-tree-slide.
+This is displayed by default if `org-tree-slide-modeline-display' is `nil'.")
+
+(defun org-tree-slide--line-number-at-pos ()
+ (save-excursion
+ (save-restriction
+ (widen)
+ (line-number-at-pos))))
+
+(defun org-tree-slide--update-modeline ()
+ (when (org-tree-slide--active-p)
+ (cond
+ ((equal org-tree-slide-modeline-display 'lighter)
+ (setq org-tree-slide--slide-number
+ (format " %s" (org-tree-slide--count-slide (point))))
+ (setq org-tree-slide--previous-line (org-tree-slide--line-number-at-pos))
+ org-tree-slide--slide-number)
+ ;; just return the current org-tree-slide--slide-number quickly.
+ ((equal org-tree-slide-modeline-display 'outside)
+ org-tree-slide--slide-number)
+ (t org-tree-slide--lighter))))
+
+(defvar org-tree-slide--header-overlay nil
+ "Flag to check the status of overlay for a slide header.")
+
+(defun org-tree-slide--setup ()
+ (when (org-tree-slide--active-p)
+ (org-tree-slide--play)))
+
+(defun org-tree-slide--abort ()
+ (when (equal major-mode 'org-mode)
+ (org-tree-slide--stop)))
+
+(defun org-tree-slide--play ()
+ "Start slide view with the first tree of the org-mode buffer."
+ (run-hooks 'org-tree-slide-mode-play-hook)
+ (run-hooks 'org-tree-slide-play-hook)
+ (org-tree-slide--apply-local-header-to-slide-header)
+ (when org-tree-slide-heading-emphasis
+ (org-tree-slide--apply-custom-heading-face t))
+ (when (or org-tree-slide-cursor-init (org-tree-slide--before-first-heading-p))
+ (org-tree-slide--move-to-the-first-heading))
+ (org-tree-slide--beginning-of-tree)
+ (when (org-tree-slide--heading-skip-p)
+ (org-tree-slide--outline-next-heading))
+ (org-tree-slide--display-tree-with-narrow)
+ (when org-tree-slide-activate-message
+ (message "%s" org-tree-slide-activate-message)))
+
+(defvar org-tree-slide-startup "overview"
+ "If you have `#+STARTUP:' line in your org buffer, the org buffer will
+ be shown with corresponding status (content, showall, overview:default).")
+
+(defun org-tree-slide--stop ()
+ "Stop the slide view, and redraw the org-mode buffer with #+STARTUP:."
+ (widen)
+ (org-show-siblings)
+ (when (or org-tree-slide-cursor-init (org-tree-slide--before-first-heading-p))
+ (goto-char (point-min))
+ (org-overview)
+ (cond ((equal "content" org-tree-slide-startup)
+ (message "CONTENT: %s" org-tree-slide-startup)
+ (org-content))
+ ((equal "showall" org-tree-slide-startup)
+ (message "SHOW ALL: %s" org-tree-slide-startup)
+ (org-cycle '(64)))
+ (t nil)))
+ (org-tree-slide--hide-slide-header)
+ (when org-timer-start-time
+ (org-timer-stop))
+ (when org-tree-slide-heading-emphasis
+ (org-tree-slide--apply-custom-heading-face nil))
+ ;; (when (and org-tree-slide-skip-done (looking-at (concat "^\\*+ " org-not-done-regexp))) (when (org-clocking-p) (org-clock-out) ) )
+ (run-hooks 'org-tree-slide-mode-stop-hook)
+ (run-hooks 'org-tree-slide-stop-hook)
+ (when org-tree-slide-deactivate-message
+ (message "%s" org-tree-slide-deactivate-message)))
+
+(defun org-tree-slide--display-tree-with-narrow ()
+ "Show a tree with narrowing and also set a header at the head of slide."
+ (run-hooks 'org-tree-slide-mode-before-narrow-hook)
+ (run-hooks 'org-tree-slide-before-narrow-hook)
+ (when (equal org-tree-slide-modeline-display 'outside)
+ (setq org-tree-slide--slide-number
+ (format " %s" (org-tree-slide--count-slide (point))))
+ (setq org-tree-slide--previous-line (org-tree-slide--line-number-at-pos)))
+ (goto-char (point-at-bol))
+ (unless (org-tree-slide--before-first-heading-p)
+ (hide-subtree) ; support CONTENT (subtrees are shown)
+ (org-show-entry)
+ ;; If this is the last level to be displayed, show the full content
+ (if (and (not org-tree-slide-fold-subtrees-skipped)
+ (org-tree-slide--heading-level-skip-p (1+ (org-outline-level))))
+ (org-tree-slide--show-subtree)
+ (show-children))
+ ;; (org-cycle-hide-drawers 'all) ; disabled due to performance reduction
+ (org-narrow-to-subtree))
+ (when org-tree-slide-slide-in-effect
+ (org-tree-slide--slide-in org-tree-slide-slide-in-blank-lines))
+ (when org-tree-slide-header
+ (org-tree-slide--show-slide-header))
+ (run-hooks 'org-tree-slide-after-narrow-hook)
+ (run-hooks 'org-tree-slide-mode-after-narrow-hook))
+
+(defun org-tree-slide--show-subtree ()
+ "Show everything after this heading at deeper levels except COMMENT items."
+ (save-excursion
+ (outline-back-to-heading)
+ (outline-map-region
+ (lambda ()
+ (if (org-tree-slide--heading-skip-comment-p)
+ (hide-subtree)
+ (show-subtree)
+ (org-cycle-hide-drawers 'all)))
+ (point)
+ (progn (outline-end-of-subtree)
+ (if (eobp) (point-max) (1+ (point)))))))
+
+(defun org-tree-slide--outline-next-heading ()
+ (org-tree-slide--outline-select-method
+ (org-tree-slide--outline-skip-type
+ (if (outline-next-heading) t 'last)
+ (org-outline-level))
+ 'next))
+
+(defun org-tree-slide--outline-previous-heading ()
+ (org-tree-slide--outline-select-method
+ (org-tree-slide--outline-skip-type
+ (if (outline-previous-heading) t 'first)
+ (org-outline-level))
+ 'previous))
+
+(defvar org-tree-slide--all-skipped t
+ "A flag to know if all trees are skipped")
+
+(defun org-tree-slide--outline-select-method (action direction)
+ (cond ((and (equal action 'last) (equal direction 'next))
+ (unless org-tree-slide--all-skipped
+ (org-tree-slide--outline-previous-heading))) ; Return back.
+ ((and (equal action 'first) (equal direction 'previous))
+ (unless org-tree-slide--all-skipped
+ (org-tree-slide--move-to-the-first-heading))) ; Stay first heading
+ ((and (equal action 'skip) (equal direction 'next))
+ (org-tree-slide--outline-next-heading)) ; recursive call
+ ((and (equal action 'skip) (equal direction 'previous))
+ (org-tree-slide--outline-previous-heading)) ; recursive call
+ (t
+ (setq org-tree-slide--all-skipped nil)
+ nil)))
+
+(defun org-tree-slide--heading-skip-p ()
+ "This method assume the cursor exist at the heading.
+** COMMENT ; t
+ hoge ; nil
+ hoge ; nil
+*** hoge ; nil
+"
+ (or (or (org-tree-slide--heading-done-skip-p)
+ (org-tree-slide--heading-level-skip-p))
+ (org-tree-slide--heading-skip-comment-p)))
+
+(defun org-tree-slide--heading-level-skip-p (&optional level)
+ (and (> org-tree-slide-skip-outline-level 0)
+ (<= org-tree-slide-skip-outline-level (or level (org-outline-level)))))
+
+(defun org-tree-slide--heading-done-skip-p ()
+ (and org-tree-slide-skip-done
+ (not
+ (looking-at
+ ;; 6.33x does NOT support org-outline-regexp-bol
+ (concat "^\\*+ " org-not-done-regexp)))))
+
+(defun org-tree-slide--heading-skip-comment-p ()
+ (and org-tree-slide-skip-comments
+ (looking-at (concat "^\\*+ " org-comment-string))))
+
+(defun org-tree-slide--outline-skip-type (has-target-outline current-level)
+ (cond ((equal has-target-outline 'last) 'last)
+ ((equal has-target-outline 'first) 'first)
+ ((org-tree-slide--heading-skip-p) 'skip)
+ (t nil)))
+
+(defun org-tree-slide--slide-in (blank-lines)
+ (while (< 2 blank-lines)
+ (org-tree-slide--set-slide-header blank-lines)
+ (sit-for org-tree-slide-slide-in-waiting)
+ (org-tree-slide--hide-slide-header)
+ (setq blank-lines (1- blank-lines))))
+
+(defvar org-tree-slide-title nil
+ "If you have `#+TITLE:' line in your org buffer, it wil be used as a title
+ of the slide. If the buffer has no `#+TITLE:' line, the name of
+ current buffer will be displayed.")
+
+(defvar org-tree-slide-email nil
+ "If you have `#+EMAIL:' line in your org buffer, it will be used as
+ an address of the slide.")
+
+(defvar org-tree-slide-author nil
+ "If you have `#+AUTHOR:' line in your org buffer, it will be used as
+ a name of the slide author.")
+
+(defun org-tree-slide--apply-local-header-to-slide-header ()
+ (save-excursion
+ (org-tree-slide--move-to-the-first-heading)
+ (let ((limit (point)))
+ (org-tree-slide--set-header-var-by-regxep
+ 'org-tree-slide-title "#\\+TITLE:[ \t]*\\(.*\\)$" limit)
+ (org-tree-slide--set-header-var-by-regxep
+ 'org-tree-slide-author "#\\+AUTHOR:[ \t]*\\(.*\\)$" limit)
+ (org-tree-slide--set-header-var-by-regxep
+ 'org-tree-slide-email "#\\+EMAIL:[ \t]*\\(.*\\)$" limit)
+ (org-tree-slide--set-header-var-by-regxep
+ 'org-tree-slide-startup "#\\+STARTUP:[ \t]*\\(.*\\)$" limit))))
+
+(defun org-tree-slide--set-header-var-by-regxep (header-variable regexp limit)
+ (goto-char 1)
+ (set header-variable
+ (if (re-search-forward regexp limit t) (match-string 1) nil)))
+
+(defface org-tree-slide-header-overlay-face
+ '((((class color) (background dark))
+ (:bold t :foreground "white" :background "black"))
+ (((class color) (background light))
+ (:bold t :foreground "black" :background "white"))
+ (t (:bold t :foreground "black" :background "white")))
+ "Face for org-tree-slide--header-overlay")
+
+(defun org-tree-slide--set-slide-header (blank-lines)
+ (org-tree-slide--hide-slide-header)
+ (setq org-tree-slide--header-overlay
+ (make-overlay (point-min) (+ 1 (point-min))))
+ (overlay-put org-tree-slide--header-overlay 'after-string " ")
+ (overlay-put org-tree-slide--header-overlay
+ 'face
+ 'org-tree-slide-header-overlay-face)
+ (if org-tree-slide-header
+ (overlay-put org-tree-slide--header-overlay 'display
+ (concat (if org-tree-slide-title org-tree-slide-title
+ (buffer-name))
+ "\n"
+ (format-time-string "%Y-%m-%d") " "
+ (when org-tree-slide-author
+ (concat org-tree-slide-author " "))
+ (when org-tree-slide-email
+ (concat "<" org-tree-slide-email ">"))
+ (org-tree-slide--get-blank-lines blank-lines)))
+ (overlay-put org-tree-slide--header-overlay 'display
+ (org-tree-slide--get-blank-lines blank-lines))))
+
+(defun org-tree-slide--get-blank-lines (lines)
+ (let ((breaks ""))
+ (while (< 0 lines)
+ (setq lines (1- lines))
+ (setq breaks (concat breaks "\n")))
+ breaks))
+
+(defun org-tree-slide--show-slide-header ()
+ (org-tree-slide--set-slide-header 2)
+ (forward-char 1))
+
+(defun org-tree-slide--hide-slide-header ()
+ (when org-tree-slide--header-overlay
+ (delete-overlay org-tree-slide--header-overlay)))
+
+(defun org-tree-slide--move-to-the-first-heading ()
+ (setq org-tree-slide--all-skipped t)
+ (widen)
+ (goto-char 1)
+ (unless (looking-at "^\\*+ ")
+ (outline-next-heading))
+ (when (org-tree-slide--heading-skip-p)
+ (setq org-tree-slide--all-skipped t)
+ (org-tree-slide--outline-next-heading)))
+
+(defun org-tree-slide--apply-custom-heading-face (status)
+ "Change status of heading face."
+ (unless org-tree-slide-never-touch-face
+ (cond (status
+ (custom-set-faces
+ '(org-level-2 ((t (:inherit org-tree-slide-heading-level-2))))
+ '(org-level-3 ((t (:inherit org-tree-slide-heading-level-3))))))
+ (t
+ (custom-set-faces
+ '(org-level-2 ((t (:inherit org-tree-slide-heading-level-2-init))))
+ '(org-level-3 ((t (:inherit org-tree-slide-heading-level-3-init)))))
+ ))))
+
+(defun org-tree-slide--count-slide (&optional pos)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (point-min))
+ (let ((count 0)
+ (current-slide 0)
+ (current-point (or pos (point))))
+ (when (and (looking-at "^\\*+ ") (not (org-tree-slide--heading-skip-p)))
+ (setq count 1)
+ (setq current-slide 1))
+ (while (outline-next-heading)
+ (when (not (org-tree-slide--heading-skip-p))
+ (setq count (1+ count))
+ (when (>= current-point (point))
+ (setq current-slide (1+ current-slide)))))
+ (cond
+ ((= count 0) "[-/-]") ; no headings
+ ((= current-slide 0) (format "[-/%d]" count)) ; before first heading
+ (t
+ (format "[%d/%d]" current-slide count)))))))
+
+(defun org-tree-slide--active-p ()
+ (and org-tree-slide-mode (equal major-mode 'org-mode)))
+
+(defun org-tree-slide--narrowing-p ()
+ "Check the current status if narrowing or not"
+ (not (and (= (point-min) 1) (= (point-max) (1+ (buffer-size))))))
+
+(defun org-tree-slide--before-first-heading-p ()
+ "Extension of org-before-first-heading-p to support org 6.33x.
+#+TITLE: title ; t
+#+STARTUP: content ; t
+* first ; t
+ hoge ; nil
+** second ; nil
+** third ; nil
+"
+ (and (org-before-first-heading-p) (not (org-tree-slide--narrowing-p))))
+
+(defun org-tree-slide--first-heading-with-narrow-p ()
+ "Check the current point is on the first heading with narrowing.
+** first ; t
+ hoge ; nil
+ hoge ; nil
+*** second ; nil
+ hoge ; nil
+*** third ; nil
+"
+ (and (org-tree-slide--narrowing-p) (= (point-at-bol) (point-min))))
+
+(defun org-tree-slide--last-tree-p (target)
+ "Check if the target point is in the last heading or it's body.
+** n-1 ; nil
+** n ; t
+ hoge ; t
+"
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char target)
+ (if (org-tree-slide--beginning-of-tree)
+ (= (point) (org-tree-slide--last-heading-position))
+ nil))))
+
+(defun org-tree-slide--last-heading-position ()
+ "Return the position of the last heading. If the position does not exist in the buffer, then return nil."
+ (save-excursion
+ (save-restriction
+ (goto-char (buffer-size))
+ (org-tree-slide--beginning-of-tree))))
+
+(defun org-tree-slide--beginning-of-tree ()
+ "Return beginning point of the line, or t. If the position does not exist in the buffer, then return nil."
+ (beginning-of-line)
+ (if (and (not (org-tree-slide--heading-skip-p)) ;if the header has to be skipped
+ (org-at-heading-p))
+ (point)
+ (progn
+ (outline-previous-heading) ;go to previous heading
+ (org-tree-slide--beginning-of-tree)) ;recursion until a visible heading is found
+ )) ; return position or nil.
+
+(provide 'org-tree-slide)
+
+;;; org-tree-slide.el ends here
--- /dev/null
+Requirement:
+ org-mode 6.33x or higher version
+ The latest version of the org-mode is recommended.
+ (see http://orgmode.org/)
+
+Usage:
+ 1. Put this elisp into your load-path
+ 2. Add (require 'org-tree-slide) in your .emacs
+ 3. Open an org-mode file
+ 4. Toggle org-tree-slide-mode (M-x org-tree-slide-mode)
+ then Slideshow will start and you can find "TSlide" in mode line.
+ 5. <left>/<right> will move between slides
+ 6. `C-x s c' will show CONTENT of the org buffer
+ Select a heading and type <right>, then Slideshow will start again.
+ 7. Toggle org-tree-slide-mode again to exit this minor mode
+
+Recommended minimum settings:
+ (global-set-key (kbd "<f8>") 'org-tree-slide-mode)
+ (global-set-key (kbd "S-<f8>") 'org-tree-slide-skip-done-toggle)
+
+ and three useful profiles are available.
+
+ 1. Simple use
+ M-x org-tree-slide-simple-profile
+
+ 2. Presentation use
+ M-x org-tree-slide-presentation-profile
+
+ 3. TODO Pursuit with narrowing
+ M-x org-tree-slide-narrowing-control-profile
+
+ Type `C-h f org-tree-slide-mode', you can find more detail.
+
+Note:
+ - Make sure key maps below when you introduce this elisp.
+ - Customize variables, M-x customize-group ENT org-tree-slide ENT