├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.org
├── LICENSE
├── README.org
├── demo-it-custom.el
├── demo-it-extras.el
├── demo-it-present.el
├── demo-it-tests.el
├── demo-it.el
├── demo-it.info
├── demo-it.org
├── demo-it.texi
├── demonstration
├── a-demo.el
└── a-demo.org
├── dir
├── example
├── error-example.el
├── example-code.el
├── example-code.py
├── example-code.rb
├── example-files.el
├── example-files.org
├── example-shell.el
├── example-shell.org
├── example-title.org
├── example.el
├── example.org
├── example.py
├── example.rb
├── kbd-example.el
├── pdx-emacs.png
└── setq-example.el
└── snippets
└── demo-it
/.gitignore:
--------------------------------------------------------------------------------
1 | /tags
2 | /TAGS
3 | *.elc
4 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Code of Conduct
2 |
3 | As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4 |
5 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6 |
7 | Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8 |
9 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10 |
11 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12 |
13 | This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
--------------------------------------------------------------------------------
/CONTRIBUTING.org:
--------------------------------------------------------------------------------
1 | #+TITLE: Contributing to this Project
2 | #+AUTHOR: Howard Abrams
3 | #+EMAIL: howard.abrams@gmail.com
4 | #+DATE: 2016 Oct 01
5 |
6 | I created this project based on my own needs and desires, and I'm
7 | mildly stunned that others are interested enough in creating
8 | demonstrations in Emacs, so I definitely want to work with others on
9 | this. So... contributions are always welcome, no matter how large or
10 | small. This file contains the guidelines I ask all contributors to
11 | follow.
12 |
13 | - For any contributions to my experimental =v2= track, please create a
14 | topic branch based off that =v2= branch, push said topic branch onto
15 | your fork and submit your pull request from that branch.
16 |
17 | - Wanna contribute a bug fix to my primary =1.x= track, please create
18 | a topic branch based off our =master= branch, push said topic branch
19 | onto your fork and submit your pull request from that branch.
20 |
21 | * Code of Conduct
22 |
23 | I want to keep this project open and inclusive. So I ask that before
24 | you contribute, you read and follow our [[file:CODE_OF_CONDUCT.md][Code of Conduct]].
25 |
26 | * Found an Issue?
27 |
28 | I definitely want to hear from you!
29 |
30 | If you find a bug in the source code or a mistake in the docs, you
31 | can help me by submitting an issue to the [[https://github.com/howardabrams/demo-it/issues][repository]].
32 |
33 | Want to contribute with a fix? Thank you. Please, submit a
34 | [[https://github.com/howardabrams/demo-it/pulls][pull request]].
35 |
36 | *Want a Feature?* Similarly to finding an issue, enter details for a
37 | [[https://github.com/howardabrams/demo-it/issues][feature request]], but feel free to fork this repository and try to
38 | give me more details with [[https://github.com/howardabrams/demo-it/pulls][pull request]].
39 |
40 | *Note:* While the [[file:demo-it-tests.el][unit tests]] are hardly sufficient, please make sure
41 | your PR doesn't break any. Better yet, add more to that!
42 |
43 | * Developing
44 |
45 | As you can imagine, testing this code is difficult to automate.
46 | Some tests for state-less functions can be found in
47 | [[file:demo-it-tests.el][demo-it-tests.el]].
48 |
49 | Since the base [[file:demo-it.el][demo-it.el]] code is now broken into multiple subfiles,
50 | issuing a =(require)= won't work without the following:
51 |
52 | #+BEGIN_SRC elisp :results silent
53 | (add-to-list 'load-path (expand-file-name "."))
54 | #+END_SRC
55 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/README.org:
--------------------------------------------------------------------------------
1 | At the end of each sprint, each of us demonstrate accomplishments.
2 | These reviews often incorporate the following trifecta:
3 |
4 | * Presentations explaining the technology and other frobnications
5 | * Source code, correctly highlighted and perhaps interactive
6 | * Executing the code, preferably in a shell to maintain nerd cred
7 |
8 | During my sprint reviews, I noticed I used my org-mode-formatted
9 | files, eshell and source code buffers... always in Emacs.
10 | However, fat-fingering or mentally burping delayed the
11 | gratification for my audience while I laboriously typed.
12 | I solved this problem by predefining each "step" as an Emacs Lisp
13 | function, and had another function execute each /step function/ when I
14 | hit an /advance/ key (=F12=).
15 |
16 | After I had amassed a small army of /helper functions/, I packaged it as
17 | =demo-it=, because I lack the imagination to come up with anything more
18 | clever.
19 |
20 | See the following videos as examples of what can be done:
21 |
22 | * [[http://www.youtube.com/watch?v=B6jfrrwR10k][Emacs: An Introduction for the Curious]]
23 | * [[https://www.youtube.com/watch?v=dljNabciEGg][Literate DevOps Programming]]
24 | * [[https://www.youtube.com/watch?v=_l1oj5CEh7k][Learn You Some Lisp for Great Good]]
25 |
26 | Click the following image for a quicker example:
27 |
28 | #+HTML:
29 |
30 | Using this project is a four step process:
31 |
32 | 1. Load the library in your own Elisp source code file
33 | 2. Create zero or more helper functions that "do things", or use the
34 | functions provided by this project.
35 | 3. Order the functions by calling =(demo-it-create step-1 step-2 ...)=
36 | 4. Call =demo-it-start= to kick off the fun.
37 |
38 | Press space for each step, or call =demo-it-end= to end earlier.
39 |
40 | For instance:
41 |
42 | #+BEGIN_SRC elisp
43 | (require 'demo-it) ;; Load this library of functions
44 |
45 | (defun my-demo-step/show-code ()
46 | "Helper demo function that displays some source code and
47 | advances the presentation at one time."
48 | (demo-it-load-file "example/example.py" :right)
49 | (demo-it-presentation-advance))
50 |
51 | ;; Order the functions and forms for this presentation:
52 | (demo-it-create (demo-it-presentation "example/example.org")
53 | my-demo-step/show-code
54 | demo-it-presentation-return ; close file and advance
55 | (demo-it-run-in-eshell "python example/example.py"))
56 |
57 | (demo-it-start)
58 | #+END_SRC
59 |
60 | Each "step" given to =demo-it-create= can be one of the following:
61 |
62 | - an expression typically calling a helper function
63 | - a name of a function to call that does multiple actions
64 | - a string referring to a key-binding to run
65 | - a property that affects demonstration behavior
66 |
67 | This package has a collection of helping functions, that can either be
68 | called directly as part of an expression, or embedded in a
69 | demonstration /step function/. For a more complete example, see
70 | [[file:example/example.el][example.el]] or the other examples in the [[file:example][example directory]].
71 |
72 | Finally, read the [[file:demo-it.org][documentation]] (which is available as an Info manual).
73 |
74 | * Historical Record
75 |
76 | The initial release, while published on MELPA, was rather an ad hoc
77 | collection of functions, poorly organized and barely documented.
78 | Sorry about that. I really didn't think any one would care enough to
79 | use it.
80 |
81 | *Version 2* of this project attempted to remedy those shortcomings,
82 | cleaning and standardizing the /interface/ of functions. Also included
83 | is the following features:
84 |
85 | - Simplification of a demonstration's construction. Originally
86 | each step essentially required a helper function, but now, we can
87 | specify full expressions directly into =demo-it-create=.
88 |
89 | - Default behavior is now based on customized preferences instead of
90 | hard-coded values. Functions still accept optional values to
91 | override those defaults. Also the =demo-it-create= macro accepts
92 | demo-level overrides of the customized preferences.
93 |
94 | - Described every function [[file:demo-it.org][both online]] and as an Info manual, with
95 | lots of examples for the step functions.
96 |
97 | *Version 3* is a plan to have each step more repeatable. Currently,
98 | each step assumes a state built by the previous steps, which makes
99 | developing, debugging, and reversing difficult.
100 |
--------------------------------------------------------------------------------
/demo-it-custom.el:
--------------------------------------------------------------------------------
1 | ;;; DEMO-IT-CUSTOM --- The project's custom variables
2 | ;;
3 | ;; Author: Howard Abrams
4 | ;; Copyright © 2016, Howard Abrams, all rights reserved.
5 | ;; Created: 19 September 2016
6 | ;;
7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 | ;;
9 | ;;; Commentary:
10 | ;;
11 | ;; Two ways to set default properties and demonstration settings.
12 | ;; First, by setting the value on customized values, and
13 | ;; Second, by passing in a mnemonic value with `demo-it-create',
14 | ;; See the `demo-it--set-property' for the mapping.
15 | ;;
16 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17 | ;;
18 | ;; This program is free software; you can redistribute it and/or
19 | ;; modify it under the terms of the GNU General Public License as
20 | ;; published by the Free Software Foundation; either version 3, or
21 | ;; (at your option) any later version.
22 | ;;
23 | ;; This program is distributed in the hope that it will be useful,
24 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
25 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 | ;; General Public License for more details.
27 | ;;
28 | ;; You should have received a copy of the GNU General Public License
29 | ;; along with this program; see the file COPYING. If not, write to
30 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
31 | ;; Floor, Boston, MA 02110-1301, USA.
32 | ;;
33 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
34 | ;;
35 | ;;; Code:
36 |
37 | (defgroup demo-it nil
38 | "Customizations and behaviors for demonstrations."
39 | :prefix "demo-it-"
40 | :group 'applications
41 | :link '(url-link :tag "Github" "https://github.com/howardabrams/demo-it"))
42 |
43 | (defcustom demo-it--keymap-mode-style :simple-mode
44 | "The keymap-specific minor mode to use when a demonstration
45 | starts. Should either be :simple-mode for using the space to
46 | advance to next step and `q' to exit the demonstration,
47 | or :advanced-mode, where advances."
48 | :type '(choice (const :tag "simple" :simple-mode)
49 | (const :tag "advanced" :advanced-mode))
50 | :group 'demo-it)
51 |
52 | (defcustom demo-it--shell-or-eshell :eshell
53 | "When opening up a shell, should this run the `shell' or `eshell' command."
54 | :type '(choice (const :tag "shell" :shell)
55 | (const :tag "eshell" :eshell))
56 | :group 'demo-it)
57 |
58 | (defcustom demo-it--open-windows :right
59 | "When opening side windows, split the frame on a particular
60 | side, like `:below' or on the `:right'."
61 | :type '(choice (const :tag "above" :above)
62 | (const :tag "below" :below)
63 | (const :tag "left" :left)
64 | (const :tag "right" :right))
65 | :group 'demo-it)
66 |
67 | (defcustom demo-it--open-windows-size 80
68 | "The size of the window to open. This is the width if the
69 | window is opened on one of the sides (:left or :right), or the
70 | height if the window is opened :above or :below."
71 | :type '(integer))
72 |
73 | (defcustom demo-it--text-scale 2
74 | "Sets the default text scale when opening files."
75 | :type '(choice integer
76 | (const :tag "small" -1)
77 | (const :tag "normal" 0)
78 | (const :tag "medium" 1)
79 | (const :tag "large" 2)
80 | (const :tag "x-large" 3)
81 | (const :tag "xx-large" 4)
82 | (const :tag "huge" 5))
83 | :group 'demo-it)
84 |
85 | (defcustom demo-it--start-fullscreen nil
86 | "If non-nil, start the demonstration with the frame in fullscreen mode."
87 | :type '(boolean)
88 | :group 'demo-it)
89 |
90 | (defcustom demo-it--start-single-window t
91 | "If non-nil, delete other windows to start the demonstration with a single buffer window."
92 | :type '(boolean)
93 | :group 'demo-it)
94 |
95 | (defcustom demo-it--presentation-hide-mode-line t
96 | "If non-nil, shows the mode-line during a presentation,
97 | otherwise the mode-line is hidden from view."
98 | :type '(boolean))
99 |
100 | (defcustom demo-it--presentation-hide-org-markers t
101 | "If non-nil, shows the surrounding asterisks, underlines and
102 | slashes that define an `org-mode' textual formats, otherwise
103 | these characters hidden, even though the effects of bolding and
104 | italics are shown."
105 | :type '(boolean))
106 |
107 | (defcustom demo-it--presentation-variable-width nil
108 | "If non-nil, uses a variable-width font for `org-mode' presentation files,
109 | otherwise the continues to use the standard fixed-width font."
110 | :type '(boolean))
111 |
112 | (defcustom demo-it--presentation-hide-org-blocks t
113 | "If non-nil, shows the `#+BEGIN_SRC' and `#+END_SRC' code
114 | blocks in an `org-mode' presentation file, otherwise these lines
115 | are hidden, but the contents within the blocks are still shown."
116 | :type '(boolean))
117 |
118 | (defun demo-it--presentation-variable-width-p (&optional style)
119 | "Predicate return `t' if STYLE is either `:variable' or `:both'
120 | or the customization setting,
121 | `demo-it--presentation-variable-width' is true. Otherwise, STYLE
122 | can be `:fixed'."
123 | (if (eq style :fixed)
124 | nil
125 | (when (or (eq style :variable)
126 | (eq style :both)
127 | demo-it--presentation-variable-width)
128 | t)))
129 |
130 | (defun demo-it--presentation-hide-blocks-p (&optional style)
131 | "Predicate return `t' if STYLE is either `:block' or `:both'
132 | or the customization setting, `demo-it--presentation-hide-org-blocks'
133 | is non-nil."
134 | (when (or (eq style :block) (eq style :blocks)
135 | (eq style :both)
136 | demo-it--presentation-hide-org-blocks)
137 | t))
138 |
139 | (defcustom demo-it--insert-text-speed :medium
140 | "The speed at which some functions insert text into the shell
141 | and other place. This can be :instant for instantaneous,
142 | or :slow, :medium or :fast.
143 |
144 | This can also be a tuple of two integer values for the random
145 | number of milliseconds between inserting each character."
146 | :type '(choice (const :tag "fast" :fast)
147 | (const :tag "faster" :faster)
148 | (const :tag "medium" :medium)
149 | (const :tag "slow" :slow)
150 | (const :tag "instant" :instant))
151 | :group 'demo-it)
152 |
153 | (defun demo-it--get-insert-text-speed (&optional speed)
154 | "The tuple of the lower and upper limits for the insert speed
155 | based on the symbol stored in `demo-it--insert-text-speed'.
156 | The optional value for SPEED override the default value."
157 | (let ((requested-speed (or speed demo-it--insert-text-speed)))
158 | (pcase requested-speed
159 | ((or :faster :insert-faster) '(1 . 10))
160 | ((or :fast :insert-fast) '(10 . 100))
161 | ((or :medium :insert-medium) '(30 . 500))
162 | ((or :slow :insert-slow) '(200 . 1000))
163 | (_ requested-speed))))
164 |
165 | (defun demo-it--get-text-scale (&optional size)
166 | "Returns SIZE if SIZE is an integer, otherwise, returns an
167 | integer matching the symbol specified by SIZE, e.g. `:large'."
168 | (let ((requested-size (or size demo-it--text-scale)))
169 | (pcase requested-size
170 | ((or :small :text-small) -1)
171 | ((or :normal :text-normal) 0)
172 | ((or :medium :text-medium) 1)
173 | ((or :large :text-large) 2)
174 | ((or :x-large :text-x-large) 3)
175 | ((or :xx-large :text-xx-large) 4)
176 | ((or :huge :text-huge) 5)
177 | (_ requested-size))))
178 |
179 | (defun demo-it--set-property (prop)
180 | "Sets a particular property, specified by keyword, PROP to t."
181 | (pcase prop
182 | (:simple-mode (setq demo-it--keymap-mode-style :simple-mode))
183 | (:advance-mode (setq demo-it--keymap-mode-style :advanced-mode))
184 | (:advanced-mode (setq demo-it--keymap-mode-style :advanced-mode))
185 |
186 | (:use-eshell (setq demo-it--shell-or-eshell :eshell))
187 | (:use-shell (setq demo-it--shell-or-eshell :shell))
188 | (:eshell (setq demo-it--shell-or-eshell :eshell))
189 | (:shell (setq demo-it--shell-or-eshell :shell))
190 |
191 | (:windows-on-side (setq demo-it--open-windows :right))
192 | (:windows-on-right (setq demo-it--open-windows :right))
193 | (:windows-on-left (setq demo-it--open-windows :left))
194 | (:windows-below (setq demo-it--open-windows :below))
195 | (:windows-above (setq demo-it--open-windows :above))
196 | (:windows-replace (setq demo-it--open-windows :none))
197 |
198 | (:fullscreen (setq demo-it--start-fullscreen t))
199 | (:full-screen (setq demo-it--start-fullscreen t))
200 | (:single-window (setq demo-it--start-single-window t))
201 |
202 | (:text-small (setq demo-it--text-scale -1))
203 | (:text-normal (setq demo-it--text-scale 0))
204 | (:text-medium (setq demo-it--text-scale 1))
205 | (:text-large (setq demo-it--text-scale 2))
206 | (:text-x-large (setq demo-it--text-scale 3))
207 | (:text-xx-large (setq demo-it--text-scale 4))
208 | (:text-huge (setq demo-it--text-scale 5))
209 |
210 | (:insert-quickly (setq demo-it--insert-text-speed :instant))
211 | (:insert-faster (setq demo-it--insert-text-speed :faster))
212 | (:insert-fast (setq demo-it--insert-text-speed :fast))
213 | (:insert-medium (setq demo-it--insert-text-speed :medium))
214 | (:insert-slow (setq demo-it--insert-text-speed :slow))
215 |
216 | (:show-mode-line (setq demo-it--presentation-hide-mode-line nil))
217 | (:hide-mode-line (setq demo-it--presentation-hide-mode-line t))
218 | (:show-org-markers (setq demo-it--presentation-hide-org-markers nil))
219 | (:hide-org-markers (setq demo-it--presentation-hide-org-markers t))
220 | (:variable-width (setq demo-it--presentation-variable-width t))
221 | (:fixed-width (setq demo-it--presentation-variable-width nil))
222 | (:show-block-headers (setq demo-it--presentation-hide-org-blocks nil))
223 | (:hide-block-headers (setq demo-it--presentation-hide-org-blocks t))))
224 |
225 | (provide 'demo-it-custom)
226 |
227 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
228 | ;;; demo-it-custom.el ends here
229 |
--------------------------------------------------------------------------------
/demo-it-extras.el:
--------------------------------------------------------------------------------
1 | ;;; DEMO-IT-EXTRAS --- Demo Functions that depend on other packages
2 | ;;
3 | ;; Author: Howard Abrams
4 | ;; Copyright © 2016, Howard Abrams, all rights reserved.
5 | ;; Created: 23 September 2016
6 | ;;
7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 | ;;
9 | ;;; Commentary:
10 | ;;
11 | ;; A collection of functions that depend on other packages available
12 | ;; from MELPA. While the functions check to see if the package is
13 | ;; available and loaded, it does not actually do the loading (or the
14 | ;; installing of the package).
15 | ;;
16 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17 | ;;
18 | ;; This program is free software; you can redistribute it and/or
19 | ;; modify it under the terms of the GNU General Public License as
20 | ;; published by the Free Software Foundation; either version 3, or
21 | ;; (at your option) any later version.
22 | ;;
23 | ;; This program is distributed in the hope that it will be useful,
24 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
25 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 | ;; General Public License for more details.
27 | ;;
28 | ;; You should have received a copy of the GNU General Public License
29 | ;; along with this program; see the file COPYING. If not, write to
30 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
31 | ;; Floor, Boston, MA 02110-1301, USA.
32 | ;;
33 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
34 | ;;
35 | ;;; Code:
36 |
37 | (require 'cl)
38 |
39 | (declare-function demo-it--get-section "demo-it")
40 | (declare-function demo-it-load-file "demo-it")
41 |
42 | (declare-function fancy-narrow-to-region "ext:fancy-narrow")
43 | (declare-function fancy-narrow-to-defun "ext:fancy-narrow")
44 |
45 | ;; ----------------------------------------------------------------------
46 | ;; FANCY HIGHLIGHTING
47 | ;;
48 | ;; A function useful for interactive work or as part of a
49 | ;; demonstration script, can use the tres cool highlighting feature
50 | ;; of `fancy-narrow' (see https://github.com/Malabarba/fancy-narrow)
51 |
52 | (defun demo-it-highlight-dwim (&optional type-or-fn start end)
53 | "Highlights or narrows to a particular 'section'.
54 |
55 | If TYPE-OR-FN is a string, it specifies the name of a function to
56 | highlight. If it is :line, then START and END specifies the
57 | beginning or ending lines. If TYPE-OR-FN is :char, then START and
58 | END are buffer positions. Finally, if TYPE-OR-FN is :regex, then
59 | START and END are regular expressions that refers to a match in
60 | the buffer.
61 |
62 | If TYPE-OR-FN is `nil', (or running interactively), then if a
63 | section is currently highlighted/narrowed, it is
64 | unhighlighted/widened. If the region is active, use, the region,
65 | otherwise, select the function the point is currently in.
66 |
67 | If the `fancy-narrow' package is installed, we'll call
68 | `fancy-narrow-to-region' or `fancy-narrow-to-defun', otherwise,
69 | we narrow to it."
70 | (interactive)
71 |
72 | (cl-flet ((hi-defun () ;; Highlight the current function
73 | (if (fboundp 'fancy-narrow-to-defun)
74 | (fancy-narrow-to-defun)
75 | (narrow-to-defun)))
76 |
77 | (hi-region (start end)
78 | (if (fboundp 'fancy-narrow-to-region)
79 | (fancy-narrow-to-region start end)
80 | (narrow-to-region start end))
81 | (if (region-active-p)
82 | (deactivate-mark)))
83 | (active-p ()
84 | (if (fboundp 'fancy-narrow-active-p)
85 | (fancy-narrow-active-p)
86 | (buffer-narrowed-p)))
87 | (unhighlight ()
88 | (if (fboundp 'fancy-narrow-to-region)
89 | (ignore-errors
90 | (fancy-widen))
91 | (widen))))
92 | (let ((should-highlight (not (active-p))))
93 | (unhighlight)
94 | (cond
95 | ;; Type is null, we assume we are interactive:
96 | ((null type-or-fn) (when should-highlight
97 | (if (region-active-p)
98 | (hi-region (region-beginning) (region-end))
99 | (hi-defun))))
100 |
101 | ;; With a specified type, we aren't interactive, and if we got a
102 | ;; symbol, then we can use `demo-it--get-section' for our bounds.
103 | ((symbolp type-or-fn)
104 | (let ((positions (demo-it--get-section type-or-fn start end)))
105 | (goto-char (car positions))
106 | (hi-region (car positions) (cdr positions))
107 | (recenter)))
108 |
109 | ;; With string, use `imenu' for matching:
110 | ((stringp type-or-fn) (imenu type-or-fn)
111 | (hi-defun))))))
112 |
113 | (defun demo-it-load-fancy-file (file type &optional start end side size)
114 | "Splits window and loads FILE in another window, and use fancy
115 | narrow to highlight part of the buffer.
116 |
117 | If TYPE is a string that specifies a function name (available via
118 | the `imenu' call), then it highlights that function.
119 |
120 | If TYPE is :char or 'char, START and END refers to specific
121 | character positions, but if TYPE is :line or 'line, this selects
122 | the point positions as if START and END are line numbers.
123 |
124 | If `fancy-narrow' is not installed, then simply narrows to the area."
125 | (demo-it-load-file file side size)
126 | (demo-it-highlight-dwim type start end))
127 |
128 |
129 | (provide 'demo-it-extras)
130 |
131 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
132 | ;;; demo-it-extras.el ends here
133 |
--------------------------------------------------------------------------------
/demo-it-present.el:
--------------------------------------------------------------------------------
1 | ;;; DEMO-IT-PRESENT --- Summary
2 | ;;
3 | ;; Author: Howard Abrams
4 | ;; Copyright © 2016, Howard Abrams, all rights reserved.
5 | ;; Created: 23 September 2016
6 | ;;
7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 | ;;
9 | ;;; Commentary:
10 | ;;
11 | ;; Since I often have an org-mode file on the side of the screen to
12 | ;; demonstrate an outline of what I will be demoing, I made it a
13 | ;; function.
14 | ;;
15 | ;; The file contains functions for displaying an org-mode file as a
16 | ;; presentation using the `org-tree-slide' project (see
17 | ;; https://github.com/takaxp/org-tree-slide).
18 | ;;
19 | ;; If `org-tree-slide' is not available, it simply shows the
20 | ;; org-mode file. We really need to look at a way to make the
21 | ;; display configurable.
22 | ;;
23 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24 | ;;
25 | ;; This program is free software; you can redistribute it and/or
26 | ;; modify it under the terms of the GNU General Public License as
27 | ;; published by the Free Software Foundation; either version 3, or
28 | ;; (at your option) any later version.
29 | ;;
30 | ;; This program is distributed in the hope that it will be useful,
31 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33 | ;; General Public License for more details.
34 | ;;
35 | ;; You should have received a copy of the GNU General Public License
36 | ;; along with this program; see the file COPYING. If not, write to
37 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
38 | ;; Floor, Boston, MA 02110-1301, USA.
39 | ;;
40 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
41 | ;;
42 | ;;; Code:
43 |
44 | (require 'cl)
45 |
46 | (declare-function org-tree-slide-content "ext:org-tree-slide")
47 | (declare-function org-tree-slide-move-next-tree "ext:org-tree-slide")
48 | (declare-function face-remap-add-relative "face-remap.el")
49 | (declare-function face-remap-remove-relative "face-remap.el")
50 |
51 | (defvar org-image-actual-width)
52 | (defvar org-tree-slide-heading-emphasis)
53 | (defvar org-hide-emphasis-markers)
54 |
55 | (defvar demo-it--text-scale)
56 | (defvar demo-it--presentation-hide-mode-line)
57 | (defvar demo-it--presentation-hide-org-markers)
58 | (defvar demo-it--presentation-variable-width)
59 | (defvar demo-it--presentation-hide-org-blocks)
60 |
61 | (declare-function demo-it--get-text-scale "demo-it-custom.el")
62 | (declare-function demo-it--presentation-variable-width-p "demo-it-custom.el")
63 | (declare-function demo-it--presentation-hide-blocks-p "demo-it-custom.el")
64 | (declare-function demo-it-hide-mode-line "demo-it.el")
65 | (declare-function demo-it-show-mode-line "demo-it.el")
66 | (declare-function demo-it-disable-mode "demo-it.el")
67 |
68 | (declare-function demo-it-create "demo-it.el")
69 | (declare-function demo-it-start "demo-it.el")
70 | (declare-function demo-it--setq-restore "demo-it.el")
71 |
72 | ;; ----------------------------------------------------------------------
73 |
74 | (defvar demo-it--presentation-file "")
75 | (defvar demo-it--presentation-buffer nil)
76 | (defvar demo-it--presentation-prev-settings (make-hash-table))
77 |
78 |
79 | (defun demo-it-presentation (file &optional size style section)
80 | "Load FILE (org-mode?) as presentation. Start `org-tree-slide'
81 | if available. SIZE specifies the text scale, and defaults to the
82 | value set in `demo-it--text-scale'.
83 |
84 | STYLE can either be `:variable' for variable font pitch,
85 | `:blocks' for diminished headers on org-blocks, or `:both' for
86 | both features. If nil, defaults to the customize variables,
87 | `demo-it--presentation-variable-width' and
88 | `demo-it--presentation-hide-org-blocks'.
89 |
90 | The SECTION is the name of an org-mode header to specify as the
91 | first section to display."
92 | (find-file file)
93 | (setq demo-it--presentation-file file)
94 | (setq demo-it--presentation-buffer (buffer-name))
95 |
96 | (when (fboundp 'org-tree-slide-mode)
97 | (setq org-tree-slide-heading-emphasis t)
98 | (org-tree-slide-mode))
99 |
100 | (when section
101 | (demo-it--presentation-section section))
102 |
103 | ;; Style things up correctly...
104 | (make-local-variable 'demo-it--presentation-prev-settings)
105 | (puthash :emphasis-markers org-hide-emphasis-markers demo-it--presentation-prev-settings)
106 | (setq org-hide-emphasis-markers demo-it--presentation-hide-org-markers)
107 |
108 | ;; Make the display of the org-mode file more presentable
109 | (when (demo-it--presentation-hide-blocks-p style)
110 | (demo-it--presentation-display-set))
111 | (when (demo-it--presentation-variable-width-p style)
112 | (variable-pitch-mode 1))
113 | (when demo-it--presentation-hide-mode-line
114 | (demo-it-hide-mode-line))
115 | (text-scale-set (demo-it--get-text-scale size))
116 |
117 | (when (fboundp 'org-bullets-mode)
118 | (org-bullets-mode 1))
119 | (when (fboundp 'flyspell-mode)
120 | (flyspell-mode -1))
121 | (setq cursor-type nil))
122 |
123 | (defun demo-it--presentation-display-set ()
124 | "Change some typical `org-mode' display values to make more
125 | presentation-friendly. Store the changed values in a hashtable.
126 | See `demo-it--presentation-display-restore'."
127 | ;; Save everything that is interesting into a hash table:
128 | (puthash :restore t demo-it--presentation-prev-settings)
129 | ;; Allow us to resize our images:
130 | (setq org-image-actual-width nil)
131 | (let* ((backgd (face-attribute 'default :background))
132 | (border (list (list :foreground backgd :background backgd :height 1))))
133 | (cl-flet ((set-attr (attr values)
134 | (puthash attr
135 | (face-remap-add-relative attr values)
136 | demo-it--presentation-prev-settings)))
137 | (set-attr 'org-block-begin-line border)
138 | (set-attr 'org-block-end-line border)
139 | (set-attr 'org-meta-line border)
140 | (set-attr 'org-special-keyword border)
141 | (set-attr 'org-block '((:family "monospace")))
142 | (set-attr 'org-verbatim '((:family "monospace")))
143 | (set-attr 'org-code '((:family "monospace")))
144 | (set-attr 'org-table '((:family "monospace")))
145 | (set-attr 'org-special-keyword '((:family "monospace"))))))
146 |
147 | (defun demo-it--presentation-display-restore ()
148 | "After `demo-it--presentation-display-set', call to restore previous settings."
149 | (setq org-hide-emphasis-markers
150 | (gethash :emphasis-markers demo-it--presentation-prev-settings))
151 | (when (gethash :restore demo-it--presentation-prev-settings)
152 | (remhash :restore demo-it--presentation-prev-settings)
153 | (cl-flet ((rest-attr (attr) (face-remap-remove-relative
154 | (gethash attr demo-it--presentation-prev-settings))))
155 | (mapcar #'rest-attr (list 'org-block-begin-line 'org-block-end-line 'org-block 'org-meta-line
156 | 'org-verbatim 'org-code 'org-table 'org-special-keyword)))))
157 |
158 | ;; Specify a section in the presentation
159 |
160 | (defun demo-it--presentation-section (section)
161 | "Moves the displayed presentation to a SECTION header."
162 | (interactive "s")
163 | (when demo-it--presentation-buffer
164 | (switch-to-buffer demo-it--presentation-buffer)
165 |
166 | (when (fboundp 'org-tree-slide-mode)
167 | (org-tree-slide-content))
168 |
169 | (goto-char (point-min))
170 | (re-search-forward (format "^\*+ +%s" section))
171 |
172 | (when (fboundp 'org-tree-slide-mode)
173 | (org-tree-slide-move-next-tree))))
174 |
175 | ;; Jumping Back to the Presentation
176 | ;;
177 | ;; In this case, we've been doing some steps, and the screen is
178 | ;; "messed up", calling this function returns back to the
179 | ;; presentation.
180 |
181 | (defun demo-it-presentation-return-noadvance ()
182 | "Return to the presentation buffer and delete other windows."
183 | (when demo-it--presentation-buffer
184 | (switch-to-buffer demo-it--presentation-buffer))
185 | (delete-other-windows))
186 |
187 | (defun demo-it-presentation-return ()
188 | "Return to the presentation buffer, delete other windows, and
189 | advance to the next 'org-mode' section."
190 | (when demo-it--presentation-buffer
191 | (demo-it-presentation-return-noadvance)
192 | (when (fboundp 'org-tree-slide-move-next-tree)
193 | (org-tree-slide-move-next-tree))))
194 |
195 | ;; Advance Presentation without Changing Focus
196 | ;;
197 | ;; Advances the org-mode presentation, but after popping into that
198 | ;; presentation buffer, returns to the window where our focus was
199 | ;; initially.
200 |
201 | (defun demo-it-presentation-advance ()
202 | "Advance the presentation to the next frame (if the buffer is
203 | an `org-mode' and `org-tree-slide' is available), but doesn't
204 | change focus to the window."
205 | (interactive)
206 | (when demo-it--presentation-buffer
207 | (let ((orig-window (current-buffer)))
208 | (switch-to-buffer demo-it--presentation-buffer)
209 | (when (fboundp 'org-tree-slide-move-next-tree)
210 | (org-tree-slide-move-next-tree))
211 | (switch-to-buffer orig-window))))
212 |
213 | (defun demo-it-presentation-highlight-phrase (phrase &optional color)
214 | "Highlight a PHRASE (based on a regular expression) in the
215 | presentation buffer. This is useful to highlight bullet point
216 | items while executing appropriate code."
217 | (when demo-it--presentation-buffer
218 | (let ((orig-window (current-buffer))
219 | (hilite-color (if (null color) 'hi-green-b color)))
220 | (switch-to-buffer demo-it--presentation-buffer)
221 | (hi-lock-unface-buffer t)
222 | (hi-lock-face-phrase-buffer phrase hilite-color)
223 | (switch-to-buffer orig-window))))
224 |
225 | (define-obsolete-function-alias 'demo-it--presentation-highlight-phrase
226 | 'demo-it-presentation-highlight-phrase "2016-Oct")
227 |
228 | (defun demo-it-presentation-unhighlight-all ()
229 | "Remove all highlighted values in a presentation previously set
230 | by a call to `demo-it-presentation-highlight-phrase'."
231 | (when demo-it--presentation-buffer
232 | (let ((orig-window (current-buffer)))
233 | (switch-to-buffer demo-it--presentation-buffer)
234 | (hi-lock-unface-buffer t)
235 | (switch-to-buffer orig-window))))
236 |
237 | (define-obsolete-function-alias 'demo-it--presentation-unhighlight-all
238 | 'demo-it-presentation-unhighlight-all "2016-Oct")
239 |
240 | ;; Clean up the Presentation
241 | ;;
242 | ;; The org-presentation-start function alters the way an org-mode file
243 | ;; is displayed. This function returns it back to a normal, editable
244 | ;; state.
245 |
246 | (defun demo-it-presentation-quit ()
247 | "Undo display settings made to the presentation buffer."
248 | (interactive)
249 | (demo-it--setq-restore)
250 | (when demo-it--presentation-buffer
251 | (switch-to-buffer demo-it--presentation-buffer)
252 | (when (fboundp 'org-tree-slide-mode)
253 | (org-tree-slide-mode -1))
254 | (when (fboundp 'flyspell-mode)
255 | (flyspell-mode t))
256 | (setq cursor-type t)
257 | (demo-it--presentation-display-restore) ; Restore previous changes
258 | (variable-pitch-mode 0)
259 | (demo-it-show-mode-line)
260 | (text-scale-set 0)))
261 |
262 | ;; ----------------------------------------------------------------------
263 |
264 | ;;;###autoload
265 | (defun demo-it-single-presentation (file &optional size style section)
266 | "Demonstration that presents an `org-mode' FILE as a
267 | full-screen presentation. SIZE is the text scaling size, and STYLE is the presentation "
268 | (interactive "fPresentation File: ")
269 | (demo-it-create (demo-it-presentation file size style section))
270 | (demo-it-start)
271 |
272 | ;; Now that the presentation is going, let's change the mode:
273 | (demo-it-disable-mode)
274 | (demo-it-mode-pres t))
275 |
276 | (define-minor-mode demo-it-mode-pres "Pressing 'space' advances demo."
277 | :lighter " demo-p"
278 | :require 'demo-it
279 | :global t
280 | :keymap '((" " . demo-it-presentation-advance)
281 | ("
" . demo-it-presentation-advance)
282 | ("q" . demo-it-disable-mode)
283 | ("Q" . demo-it-end)))
284 |
285 | (provide 'demo-it-present)
286 |
287 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
288 | ;;; demo-it-present.el ends here
289 |
--------------------------------------------------------------------------------
/demo-it-tests.el:
--------------------------------------------------------------------------------
1 | ;;; DEMO-IT-TESTS --- Basic tests to help verify demo-it functions
2 | ;;
3 | ;; Author: Howard Abrams
4 | ;; Copyright © 2016, Howard Abrams, all rights reserved.
5 | ;; Created: 22 September 2016
6 | ;;
7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 | ;;
9 | ;;; Commentary:
10 | ;;
11 | ;; Obviously testing specific functions is easy with ERT, but
12 | ;; attempting to verify a _visual demonstration_ is a lot more
13 | ;; complicated.
14 | ;;
15 | ;; However, we'll do what we can.
16 | ;;
17 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18 | ;;
19 | ;; This program is free software; you can redistribute it and/or
20 | ;; modify it under the terms of the GNU General Public License as
21 | ;; published by the Free Software Foundation; either version 3, or
22 | ;; (at your option) any later version.
23 | ;;
24 | ;; This program is distributed in the hope that it will be useful,
25 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
26 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 | ;; General Public License for more details.
28 | ;;
29 | ;; You should have received a copy of the GNU General Public License
30 | ;; along with this program; see the file COPYING. If not, write to
31 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
32 | ;; Floor, Boston, MA 02110-1301, USA.
33 | ;;
34 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
35 | ;;
36 | ;;; Code:
37 |
38 | (require 'ert)
39 |
40 | (load-file "demo-it.el")
41 | (defvar demo-it--shell-or-eshell)
42 | (defvar demo-it--keymap-mode-style)
43 | (defvar demo-it--insert-text-speed)
44 | (defvar demo-it--start-fullscreen)
45 | (defvar demo-it--start-single-window)
46 | (defvar demo-it--text-scale)
47 | (defvar demo-it--open-windows)
48 |
49 | (declare-function demo-it-create "demo-it")
50 | (declare-function demo-it-start "demo-it")
51 | (declare-function demo-it-end "demo-it")
52 | (declare-function demo-it--set-property "demo-it-custom")
53 | (declare-function demo-it--get-section "demo-it-custom")
54 | (declare-function demo-it--get-insert-text-speed "demo-it-custom")
55 | (declare-function demo-it--get-text-scale "demo-it-custom")
56 |
57 |
58 | (defvar demo-it-tests--state 0)
59 | (defun demo-it-tests--step-1 (&optional state)
60 | "Just an initial step in a demonstration"
61 | (setq demo-it-tests--state (if state state 1)))
62 | (defun demo-it-tests--step-2 ()
63 | "Another step in a demonstration"
64 | (setq demo-it-tests--state 2))
65 |
66 | ;; ----------------------------------------------------------------------
67 |
68 | (ert-deftest basic-validation ()
69 | "Validate first step executes, but not the second."
70 | (setq demo-it-tests--state 0)
71 | (demo-it-create demo-it-tests--step-1
72 | demo-it-tests--step-2)
73 | (demo-it-start)
74 | (demo-it-end)
75 | (should (= 1 demo-it-tests--state)))
76 |
77 | (ert-deftest basic-form-validation ()
78 | "Validate first form executes, but not the second."
79 | (demo-it-create (demo-it-tests--step-1 5)
80 | demo-it-tests--step-2)
81 | (setq demo-it-tests--state 0)
82 | (demo-it-start)
83 | (demo-it-end)
84 | (should (= 5 demo-it-tests--state)))
85 |
86 | ;; ----------------------------------------------------------------------
87 | ;; Let's test some of the property values
88 |
89 | (ert-deftest test-demo-it--get-insert-text-speed ()
90 | (demo-it--set-property :insert-fast)
91 | (should (and (= 10 (car (demo-it--get-insert-text-speed)))
92 | (= 100 (cdr (demo-it--get-insert-text-speed)))))
93 |
94 | (demo-it--set-property :insert-medium)
95 | (should (and (= 30 (car (demo-it--get-insert-text-speed)))
96 | (= 500 (cdr (demo-it--get-insert-text-speed)))))
97 |
98 | (demo-it--set-property :insert-slow)
99 | (should (and (= 200 (car (demo-it--get-insert-text-speed)))
100 | (= 1000 (cdr (demo-it--get-insert-text-speed))))))
101 |
102 | (ert-deftest test-demo-it--get-text-scale ()
103 | (demo-it--set-property :text-small)
104 | (should (= -1 (demo-it--get-text-scale)))
105 | (demo-it--set-property :text-normal)
106 | (should (= 0 (demo-it--get-text-scale)))
107 | (demo-it--set-property :text-medium)
108 | (should (= 1 (demo-it--get-text-scale)))
109 | (demo-it--set-property :text-large)
110 | (should (= 2 (demo-it--get-text-scale)))
111 | (demo-it--set-property :text-x-large)
112 | (should (= 3 (demo-it--get-text-scale)))
113 | (demo-it--set-property :text-xx-large)
114 | (should (= 4 (demo-it--get-text-scale)))
115 | (demo-it--set-property :text-huge)
116 | (should (= 5 (demo-it--get-text-scale))))
117 |
118 | (ert-deftest test-demo-it--get-text-scale-unset ()
119 | (should (= -1 (demo-it--get-text-scale :small)))
120 | (should (= -1 (demo-it--get-text-scale :text-small)))
121 | (should (= 0 (demo-it--get-text-scale :normal)))
122 | (should (= 0 (demo-it--get-text-scale :text-normal)))
123 | (should (= 1 (demo-it--get-text-scale :medium)))
124 | (should (= 1 (demo-it--get-text-scale :text-medium)))
125 | (should (= 2 (demo-it--get-text-scale :large)))
126 | (should (= 2 (demo-it--get-text-scale :text-large)))
127 | (should (= 3 (demo-it--get-text-scale :x-large)))
128 | (should (= 3 (demo-it--get-text-scale :text-x-large)))
129 | (should (= 4 (demo-it--get-text-scale :xx-large)))
130 | (should (= 4 (demo-it--get-text-scale :text-xx-large)))
131 | (should (= 5 (demo-it--get-text-scale :huge)))
132 | (should (= 5 (demo-it--get-text-scale :text-huge)))
133 | (should (= 13 (demo-it--get-text-scale 13))))
134 |
135 | (ert-deftest test-demo-it--set-property ()
136 | (demo-it--set-property :simple-mode)
137 | (should (eq :simple-mode demo-it--keymap-mode-style))
138 | (demo-it--set-property :advance-mode)
139 | (should (eq :advanced-mode demo-it--keymap-mode-style))
140 | (demo-it--set-property :advanced-mode)
141 | (should (eq :advanced-mode demo-it--keymap-mode-style))
142 |
143 | (demo-it--set-property :use-shell)
144 | (should (eq :shell demo-it--shell-or-eshell))
145 | (demo-it--set-property :use-eshell)
146 | (should (eq :eshell demo-it--shell-or-eshell))
147 |
148 | (demo-it--set-property :windows-below)
149 | (should (eq :below demo-it--open-windows))
150 | (demo-it--set-property :windows-above)
151 | (should (eq :above demo-it--open-windows))
152 | (demo-it--set-property :windows-on-side)
153 | (should (eq :right demo-it--open-windows))
154 | (demo-it--set-property :windows-on-left)
155 | (should (eq :left demo-it--open-windows))
156 | (demo-it--set-property :windows-on-right)
157 | (should (eq :right demo-it--open-windows))
158 |
159 | (demo-it--set-property :fullscreen)
160 | (should demo-it--start-fullscreen)
161 | (demo-it--set-property :single-window)
162 | (should demo-it--start-single-window)
163 |
164 | (demo-it--set-property :text-small)
165 | (should (eq -1 demo-it--text-scale))
166 | (demo-it--set-property :text-normal)
167 | (should (eq 0 demo-it--text-scale))
168 | (demo-it--set-property :text-medium)
169 | (should (eq 1 demo-it--text-scale))
170 | (demo-it--set-property :text-large)
171 | (should (eq 2 demo-it--text-scale))
172 | (demo-it--set-property :text-x-large)
173 | (should (eq 3 demo-it--text-scale))
174 | (demo-it--set-property :text-xx-large)
175 | (should (eq 4 demo-it--text-scale))
176 | (demo-it--set-property :text-huge)
177 | (should (eq 5 demo-it--text-scale))
178 |
179 | (demo-it--set-property :insert-quickly)
180 | (should (eq :instant demo-it--insert-text-speed))
181 | (demo-it--set-property :insert-fast)
182 | (should (eq :fast demo-it--insert-text-speed))
183 | (demo-it--set-property :insert-medium)
184 | (should (eq :medium demo-it--insert-text-speed))
185 | (demo-it--set-property :insert-slow)
186 | (should (eq :slow demo-it--insert-text-speed)))
187 |
188 | (ert-deftest test-demo-it--get-section ()
189 | ;; The :char type should return the values given:
190 | (switch-to-buffer "demo-it-tests.el")
191 | (let* ((start 71)
192 | (end 212)
193 | (tuple (demo-it--get-section :char start end)))
194 | (should (and (= (car tuple) start)
195 | (= (cdr tuple) end))))
196 |
197 | ;; The :line type should return the points of the starting and
198 | ;; ending lines... don't change the comment section at the top of
199 | ;; this file without resetting the magic values:
200 | (let* ((line-1 3)
201 | (line-2 6)
202 | (tuple (demo-it--get-section :line line-1 line-2)))
203 | (should (and (= (car tuple) 71)
204 | (= (cdr tuple) 212)))))
205 |
206 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
207 | ;;; demo-it-tests.el ends here
208 |
--------------------------------------------------------------------------------
/demo-it.el:
--------------------------------------------------------------------------------
1 | ;;; demo-it.el --- Create demonstrations
2 | ;;
3 | ;; Author: Howard Abrams
4 | ;; Copyright (C) 2014 Howard Abrams
5 | ;; Keywords: demonstration presentation test
6 | ;; Version: 2.0.0
7 | ;;
8 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9 | ;;
10 | ;; This program is free software; you can redistribute it and/or modify
11 | ;; it under the terms of the GNU General Public License as published by
12 | ;; the Free Software Foundation, either version 3 of the License, or
13 | ;; (at your option) any later version.
14 | ;;
15 | ;; This program is distributed in the hope that it will be useful,
16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | ;; GNU General Public License for more details.
19 | ;;
20 | ;; You should have received a copy of the GNU General Public License
21 | ;; along with this program. If not, see .
22 | ;;
23 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24 | ;;
25 | ;;; Commentary:
26 | ;;
27 | ;; When making demonstrations of new products, technologies and other
28 | ;; geekery, I love the versatility of using Emacs to demonstrate the
29 | ;; trifecta of sprint reviews, including:
30 | ;;
31 | ;; - Presentations explaining the technologies
32 | ;; - Source code ... correctly highlighted
33 | ;; - Executing the code in Eshell ... or similar demonstration
34 | ;; - Test a new feature
35 | ;;
36 | ;; However, I don't want to fat-finger, mentally burp, or even delay
37 | ;; the gratification while I type, so I predefine each "step" as an
38 | ;; Elisp function or keyboard macro, and then have =demo-it= execute
39 | ;; each function when I hit either the SPACE key or the F12 key
40 | ;; (advanced minor mode).
41 | ;;
42 | ;; Using the library is a four step process:
43 | ;;
44 | ;; 1. Load the library in your own Elisp source code file
45 | ;; 2. Create a collection of functions that "do things".
46 | ;; 3. Create the ordered list of functions/steps with `demo-it-create'
47 | ;; 4. Start the demonstration with `demo-it-start'
48 | ;;
49 | ;; For instance:
50 | ;;
51 | ;; (require 'demo-it) ;; Load this library of functions
52 | ;;
53 | ;; (defun dit-load-source-code ()
54 | ;; "Load some source code in a side window."
55 | ;; (demo-it-presentation-advance)
56 | ;; (demo-it-load-fancy-file "example.py" :line 5 12 :side))
57 | ;;
58 | ;; (defun dit-run-code ()
59 | ;; "Execute our source code in an Eshell buffer."
60 | ;; ;; Close other windows and advance the presentation:
61 | ;; (demo-it-presentation-return)
62 | ;; (demo-it-start-shell)
63 | ;; (demo-it-run-in-shell "python example.py Snoopy"))
64 | ;;
65 | ;; (demo-it-create :single-window :insert-slow :full-screen
66 | ;; (demo-it-title-screen "example-title.org")
67 | ;; (demo-it-presentation "example.org")
68 | ;; dit-load-source-code
69 | ;; dit-run-code
70 | ;; (demo-it-run-in-shell "exit" nil :instant))
71 | ;;
72 | ;; (demo-it-start)
73 | ;;
74 | ;; Each "step" is a series of Elisp functions that "do things".
75 | ;; While this package has a collection of helping functions, the steps
76 | ;; can use any Elisp command to show off a feature.
77 | ;;
78 | ;; I recommend installing these other Emacs packages:
79 | ;;
80 | ;; - https://github.com/takaxp/org-tree-slide
81 | ;; - https://github.com/sabof/org-bullets
82 | ;; - https://github.com/magnars/expand-region.el
83 | ;; - https://github.com/Bruce-Connor/fancy-narrow
84 | ;;
85 | ;; See http://github.com/howardabrams/demo-it for more details and
86 | ;; better examples. You will want to walk through the source code
87 | ;; for all the utility functions.
88 | ;;
89 | ;;; Code:
90 |
91 | (require 'cl-lib)
92 |
93 | ;; Predefined necessary external functions:
94 | (defvar org-image-actual-width)
95 |
96 | ;; And functions from other projects I like to use...
97 | (declare-function eshell-send-input "ext:eshell")
98 | (declare-function show-all "ext:eshell.c")
99 |
100 | ;; Load our 'modules' from other files:
101 | (require 'demo-it-custom)
102 |
103 | ;; And specify the customization variables set in that module:
104 | (defvar demo-it--shell-or-eshell)
105 | (defvar demo-it--keymap-mode-style)
106 | (defvar demo-it--insert-text-speed)
107 | (defvar demo-it--open-windows)
108 | (defvar demo-it--open-windows-size)
109 | (defvar demo-it--text-scale)
110 | (defvar demo-it--start-fullscreen)
111 | (defvar demo-it--start-single-window)
112 | (declare-function demo-it--get-insert-text-speed "demo-it-custom.el")
113 | (declare-function demo-it--get-text-scale "demo-it-custom.el")
114 | (declare-function demo-it--set-property "demo-it-custom.el")
115 |
116 |
117 | ;; ----------------------------------------------------------------------
118 | ;; MINOR MODES
119 | ;;
120 | ;; We define two styles of minor modes for dealing with special keys
121 | ;; to advance the demonstration along ... a simple uses space and
122 | ;; return, and an 'advanced' mode that requires a special function
123 | ;; key...
124 |
125 | (define-minor-mode demo-it-mode "Pressing 'space' advances demo."
126 | :lighter " demo"
127 | :require 'demo-it
128 | :global t
129 | :keymap '((" " . demo-it-step)
130 | ("
" . demo-it-step)
131 | ("[down]" . demo-it-step)
132 | ("[mouse-1]" . demo-it-set-mouse-or-advance)
133 | ([nil mouse-1] . demo-it-step)
134 | ([nil wheel-up] . demo-it-ignore-event)
135 | ([nil wheel-down] . demo-it-ignore-event)
136 | ([nil wheel-left] . demo-it-ignore-event)
137 | ([nil wheel-right] . demo-it-ignore-event)
138 | ("q" . demo-it-disable-mode)
139 | ("Q" . demo-it-end)))
140 |
141 | (define-minor-mode demo-it-mode-adv "Pressing '' advances demo."
142 | :lighter " demo-adv"
143 | :require 'demo-it
144 | :global t
145 | :keymap (let ((map (make-sparse-keymap)))
146 | (define-key map (kbd "") 'demo-it-step)
147 | (define-key map (kbd "s-") 'demo-it-insert-text)
148 | (define-key map (kbd "A-") 'demo-it-insert-text)
149 | (define-key map (kbd "C-") 'demo-it-highlight-dwim)
150 | (define-key map (kbd "M-") 'demo-it-end)
151 | map))
152 |
153 | ;; Demo Mode
154 | ;;
155 | ;; Allows us to advance to the next step by pressing the
156 | ;; space bar or return. Press the 'q' key to stop the mode.
157 |
158 | (defun demo-it-disable-mode ()
159 | "Called when 'q' (or similar key) pressed to disable either the
160 | simple or advanced version of `demo-it-mode'."
161 | (interactive)
162 | (demo-it-mode -1)
163 | (demo-it-mode-adv -1))
164 |
165 | ;; ----------------------------------------------------------------------
166 | ;; DEMONSTRATION MAKER
167 | ;;
168 | ;; When we start a demonstration, we would pass in a list of functions
169 | ;; to call for each step, and then call =demo-step= to execute the
170 | ;; first one on the list.
171 |
172 | ;; A "global" variable (shudder) to track state of the demonstration:
173 | (defvar demo-it--step 0 "Stores the current demo 'step' function.")
174 | (defvar demo-it--steps '() "List of functions to be executed in order.")
175 | (defvar demo-it-start-winconf nil
176 | "Window configuration when starting demo. Used to restore
177 | buffer positions after demonstration is complete.")
178 |
179 | ;;;###autoload
180 | (defun demo-it-start (&optional steps advanced-mode)
181 | "Start the current demonstration and kick off the first step.
182 | STEPS is a list of functions or keystrokes to execute.
183 | If nil, the STEPS must be specified by a call to `demo-it-create'.
184 |
185 | The optional ADVANCED-MODE turns on keybindings where
186 | advances the steps instead of Space. This mode is better for
187 | more interactive demonstrations."
188 | (interactive)
189 | (when (or demo-it-mode demo-it-mode-adv)
190 | (error "Do not start new demonstrations DURING demonstration"))
191 |
192 | (setq demo-it-start-winconf (current-window-configuration))
193 | (setq demo-it--step 0) ;; Reset the step to the beginning
194 | (when steps
195 | (setq demo-it--steps steps)) ;; Store the steps.
196 |
197 | (if (or advanced-mode (eq demo-it--keymap-mode-style :advanced-mode))
198 | (demo-it-mode-adv t)
199 | (demo-it-mode t))
200 |
201 | (if demo-it--start-fullscreen
202 | (demo-it-frame-fullscreen))
203 | (if demo-it--start-single-window
204 | (delete-other-windows))
205 |
206 | (demo-it-step))
207 |
208 | ;;;###autoload
209 | (defmacro demo-it-create (&rest forms)
210 | "Create and store an ordered list of steps and configuration
211 | values. The FORMS can be either function names, expressions or
212 | keywords, like `:advanced-mode' and `:variable-width'."
213 | `(progn
214 | (demo-it--set-properties (cl-remove-if-not 'keywordp '(,@forms)))
215 | (setq demo-it--steps (cl-remove-if 'keywordp '(,@forms)))))
216 |
217 |
218 |
219 | (defun demo-it-end ()
220 | "End the current demonstration by resetting the values
221 | inflicted on the presentation buffer as well as closing other
222 | windows."
223 | (interactive)
224 | (demo-it-disable-mode)
225 | (demo-it-presentation-quit)
226 | (set-window-configuration demo-it-start-winconf))
227 |
228 | ;; Next Step
229 | ;;
230 | ;; Hitting the key should be bound to triggering the next step in
231 | ;; the demonstration.
232 |
233 | (defun demo-it-step (&optional step)
234 | "Execute the next step in the current demonstration. Jump to a
235 | particular STEP if the optional parameter is given, i.e. C-6
236 | to run the 6th step."
237 | (interactive "P")
238 | (if step
239 | (setq demo-it--step step) ;; Changing Global state, yay!
240 | (setq demo-it--step (1+ demo-it--step)))
241 | (let
242 | ;; At this point, step is 1-based, and I need it 0-based
243 | ;; and f-step is the function to call for this step...
244 | ((f-step (nth (1- demo-it--step) demo-it--steps)))
245 | (if f-step
246 | (demo-it--execute-step f-step)
247 | (read-event "Demonstration finished. Hit any key to return.")
248 | (demo-it-end))))
249 |
250 | (defun demo-it-restep ()
251 | "Execute the previous step in the current demonstration.
252 |
253 | Useful when the previous step failed, and you want to redo it."
254 | (interactive)
255 | (let
256 | ;; At this point, step is 1-based, and I need it 0-based
257 | ;; and f-step is the function to call for this step...
258 | ((f-step (nth (1- demo-it--step) demo-it--steps)))
259 | (if f-step
260 | (demo-it--execute-step f-step)
261 | (message "Finished the entire demonstration."))))
262 |
263 | (defun demo-it--execute-step (f-step)
264 | "Executes F-STEP depending on its type, e.g. expression, function, etc."
265 | (condition-case err
266 | (cond ((functionp f-step) (funcall f-step))
267 | ((listp f-step) (eval f-step)) ; An expression
268 | ((stringp f-step) (execute-kbd-macro (kbd f-step)))
269 | ((keywordp f-step) (demo-it--set-property f-step))
270 | (t (error "invaid step: %s" f-step)))
271 | (error (read-event (format "Abort the demonstration because of error. Hit any key to return.\n%S" err))
272 | (demo-it-end))))
273 |
274 | ;; Position or advance the slide? Depends...
275 |
276 | (defun demo-it-set-mouse-or-advance (evt)
277 | "Advances to the next step if clicked on the right side of any
278 | window, otherwise, it position the point as expected. With EVT,
279 | function can be bound to the mouse click."
280 | (interactive "e")
281 | (if (posn-area (event-start evt)) ;; Clicked in special area?
282 | (demo-it-step)
283 | (let ((col (car (posn-col-row (event-start evt))))
284 | (wid (window-width (posn-window (event-start evt)))))
285 | (if (> col (- wid 4))
286 | (demo-it-step)
287 | (mouse-set-point evt)))))
288 |
289 | (defun demo-it-show-step ()
290 | "Display the expected function to be run during the next step."
291 | (interactive)
292 | (let ((func (nth demo-it--step demo-it--steps)))
293 | (message "Step: %d - Going to run: %s" demo-it--step func)))
294 |
295 | (defun demo-it-ignore-event (evt)
296 | "Empty function that absorbs the EVT parameter to keep
297 | demonstration from flipping out."
298 | (interactive "P")
299 | (message ""))
300 |
301 |
302 | ;; ----------------------------------------------------------------------
303 | ;; HIDE MODELINE
304 | ;;
305 | ;; Call the `demo-it-hide-mode-line' when displaying images and
306 | ;; org-mode files displayed as "presentations", so that we aren't
307 | ;; bothered by the sight of the mode.
308 |
309 | (defvar demo-it--old-mode-line nil)
310 | (make-variable-buffer-local 'demo-it--old-mode-line)
311 |
312 | (defun demo-it-hide-mode-line ()
313 | "Hide mode line for a particular buffer."
314 | (interactive)
315 | (when mode-line-format
316 | (setq demo-it--old-mode-line mode-line-format)
317 | (setq mode-line-format nil)))
318 |
319 | (defun demo-it-show-mode-line ()
320 | "Show mode line for a particular buffer, if it was previously hidden with 'demo-it--hide-mode-line."
321 | (interactive)
322 | (if demo-it--old-mode-line
323 | (setq mode-line-format demo-it--old-mode-line)))
324 |
325 |
326 | ;; ----------------------------------------------------------------------
327 | ;; SIDE WINDOWS and HELPER FILES
328 | ;;
329 | ;; Typically, we make a side window that is large enough to have some
330 | ;; fun in, as the main window would serve as little more than an
331 | ;; outline or displaying a presentation.
332 | ;;
333 | ;; The `demo-it--make-side-window' function is a helper and
334 | ;; probably won't be called directly, but instead is called by
335 | ;; functions that load a file, image or start a shell...
336 |
337 | (defun demo-it--make-side-window (&optional side size)
338 | "Opens window on the side of the current frame and selects that window.
339 |
340 | SIDE is either `:above', `:below', `:left', `:right', `:side' (a
341 | synonym for `:right') or `:none' (for a window that occupies
342 | the entire frame). Defaults to the value of `demo-it--open-windows'
343 | (A value of `:none' acts as a no-op and doesn't open a window).
344 |
345 | SIZE specifies the width of the window if new window is on the
346 | side, or the height if the window is either `:above' or
347 | `:below'."
348 | ;; Since many functions call this, we need a way to actually /not/
349 | ;; split the screen, so passing in a `:none' overrides the default.
350 | (when (not (or (eq side 'none) (eq side :none)))
351 |
352 | (select-window (demo-it--new-root-window
353 | (or side demo-it--open-windows)
354 | (or size demo-it--open-windows-size)))))
355 |
356 | ;; Since the `make-side-window' shouldn't be called, it has two
357 | ;; dashes, but to maintain backward compatibility, we make an alias:
358 | (define-obsolete-function-alias 'demo-it-make-side-window
359 | 'demo-it--make-side-window "2016-Oct")
360 |
361 | (defun demo-it--new-root-window (direction size)
362 | "Split the main window in the DIRECTION where DIRECTION is a
363 | symbol with possible values of 'right, 'left, 'above or 'below
364 | and SIZE is the final size of the windows, if the window is split
365 | horizontally (i.e. DIRECTION 'below or 'above) SIZE is assumed to
366 | be the target height otherwise SIZE is assumed to be target
367 | width."
368 | (let* ((dir (pcase direction ;; Create synonyms!?
369 | (:left 'left)
370 | (:right 'right)
371 | (:side 'right)
372 | (:below 'below)
373 | (:above 'above)
374 | (_ direction)))
375 | (new-window (split-window (frame-root-window) nil dir))
376 | (horizontal (member dir '(right left))))
377 | (save-excursion
378 | (select-window new-window)
379 | (enlarge-window (- size (if horizontal
380 | (window-width)
381 | (window-height)))
382 | horizontal))
383 | new-window))
384 |
385 | (defun demo-it-load-file (file &optional side size width)
386 | "Splits root frame into a window and load FILE into it.
387 |
388 | SIDE can be `:above' or `:below' (for vertical split) or `:left'
389 | or `:right' (`:side' is a synomym for `:right'), or `:none' for
390 | load the file in the current buffer. This defaults to the
391 | customized value of `demo-it--open-windows'.
392 |
393 | SIZE can specify the text font scale, and if `nil', it uses the
394 | value of `demo-it--text-scale'. The WIDTH specifies the size of
395 | this new window, which is either the width of a side window, or
396 | the height if the window is `:above' or `:below'."
397 | (demo-it--make-side-window side width)
398 | (find-file file)
399 | (text-scale-set (demo-it--get-text-scale size)))
400 |
401 | (defun demo-it--get-section (type &optional start end)
402 | "Return tuple of beginning and end of a section of buffer.
403 |
404 | If TYPE is :char or 'char, START and END refers to specific
405 | character positions, but if TYPE is :line or 'line, this returns
406 | the point positions as if START and END are line numbers."
407 |
408 | (cond
409 | ;; LINE ... resets the START and END positions to be character
410 | ;; positions based on the line numbers given.
411 | ((or (eq type :line) (eq type 'line))
412 | (save-excursion
413 | ;; Re-implementing `goto-line' for the win!
414 | (goto-char (point-min)) (forward-line (1- start))
415 | (setq start (point))
416 | (goto-char (point-min)) (end-of-line end)
417 | (setq end (point))))
418 |
419 | ;; CHAR ... start and end should already be the positions. Unless
420 | ;; START or END are null, in which case, we can assume we are
421 | ;; looking at the end of the buffer.
422 | ((or (eq type :char) (eq type 'char))
423 | (when (null start)
424 | (setq start (point-min)))
425 | (when (null end)
426 | (setq end (point-max))))
427 |
428 | ;; REGEXP
429 | ((or (eq type :regex) (eq type :regexp))
430 | (save-excursion
431 | (goto-char (point-min))
432 | (re-search-forward start)
433 | (setq start (match-beginning 0))
434 | (re-search-forward end)
435 | (setq end (match-end 0))))
436 |
437 | ;; STRING
438 | ((or (eq type :str) (eq type :string))
439 | (save-excursion
440 | (goto-char (point-min))
441 | (search-forward start)
442 | (setq start (match-beginning 0))
443 | (search-forward end)
444 | (setq end (match-end 0)))))
445 |
446 | (cons start end))
447 |
448 | (defun demo-it-load-part-file (file type start end &optional side size width)
449 | "Splits window and loads FILE, but narrow to particular region.
450 |
451 | If TYPE is set to :line, then START and END refers to the first
452 | and last lines to narrow. If TYPE is set to :char, then START and
453 | END refer to specific character positions.
454 |
455 | See `demo-it-load-file' for an explanation of SIDE and SIZE.
456 | Also see `demo-it-load-fancy-file' for an alternative version."
457 | (demo-it-load-file file side size width)
458 | (let ((positions (demo-it--get-section type start end)))
459 | (narrow-to-region (car positions) (cdr positions))))
460 |
461 | (defun demo-it-show-image (file &optional side size width)
462 | "Load FILE as image (or any other special file) in another
463 | window without a mode line or fringe. SIDE can be either :side
464 | or :below, and if `nil', the default is to use the value of
465 | `demo-it--open-windows'."
466 | (demo-it-load-file file side size width)
467 | (fringe-mode '(0 . 0))
468 | (demo-it-hide-mode-line))
469 |
470 | ;; Compare and Contrast Files
471 | ;;
472 | ;; Places two files next to each other so that you can diff
473 | ;; or at least visually compare them. I suppose that after
474 | ;; they are loaded, you can switch to them with something like:
475 | ;; (pop-to-buffer "example.py")
476 | ;; To further manipulate them.
477 |
478 | (defun demo-it-compare-files (file1 file2 &optional side size)
479 | "Load FILE1 and FILE2 as either two windows on top of each
480 | other on the side of the screen, or two windows below (depending
481 | on the value of SIDE). The SIZE specifies the text scaling of
482 | both buffers."
483 | (if (null side)
484 | (setq side demo-it--open-windows))
485 | (if (null size)
486 | (setq size demo-it--text-scale))
487 |
488 | (cl-flet ((open-other-window (file side size)
489 | (if (or (eq side 'below) (eq side :below))
490 | (split-window-horizontally)
491 | (split-window-below))
492 | (find-file file)
493 | (text-scale-set (demo-it--get-text-scale size))))
494 | (demo-it-load-file file2 side size)
495 | (open-other-window file1 side size)))
496 |
497 | ;; ----------------------------------------------------------------------
498 | ;; SHELL WORK
499 | ;;
500 | ;; Kick off a shell in another window, change to a particular
501 | ;; directory, and automatically run something.
502 |
503 | (defun demo-it--erase-shell-buffer ()
504 | "Uses comint-clear-buffer in Emacs >=25, otherwise erase buffer. Better
505 | compatibility with read-only shell-mode prompts"
506 | (let ((inhibit-read-only t))
507 | (if (and (fboundp 'comint-clear-buffer)
508 | (derived-mode-p 'comint-mode))
509 | (progn
510 | (comint-clear-buffer)
511 | t)
512 | (erase-buffer))))
513 |
514 | (defun demo-it-start-shell (&optional directory command name
515 | side size width)
516 | "Start a shell or eshell instance, and change to DIRECTORY to
517 | execute COMMAND. NAME optionally labels the buffer, and defaults
518 | to `Shell'.
519 |
520 | SIDE can be `:above' or `:below' (for vertical split) or `:left'
521 | or `:right' (`:side' is a synomym for `:right'), or `:none' for
522 | load the file in the current buffer. This defaults to the
523 | customized value of `demo-it--open-windows'.
524 |
525 | SIZE can specify the text font scale, and if `nil', it uses the
526 | value of `demo-it--text-scale'. The WIDTH specifies the size of
527 | this new window, which is either the width of a side window, or
528 | the height if the window is `:above' or `:below'."
529 | (let* ((title (demo-it--shell-buffer-name name))
530 | (des-buf (get-buffer title)))
531 |
532 | (demo-it--make-side-window side width)
533 | (if des-buf
534 | (demo-it--start-shell-reuse title directory)
535 |
536 | ;; Otherwise, create a new shell buffer...
537 | (demo-it--start-shell-new title directory size))
538 |
539 | (when command
540 | (demo-it-insert-shell command))))
541 |
542 | (define-obsolete-function-alias 'demo-it-start-eshell 'demo-it-start-shell "2016-Oct")
543 |
544 | (defun demo-it--start-shell-new (title directory size)
545 | "Attempt to create a new shell/eshell with a buffer named TITLE
546 | in a particular DIRECTORY."
547 | (let ((default-directory (or directory
548 | (file-name-directory (buffer-file-name)))))
549 | (cond
550 | ((not (keywordp demo-it--shell-or-eshell))
551 | (funcall-interactively demo-it--shell-or-eshell title))
552 |
553 | ((eq demo-it--shell-or-eshell :shell) (shell title))
554 | (t (progn
555 | (eshell "new-shell")
556 | (rename-buffer title))))
557 |
558 | (read-only-mode -1)
559 | (text-scale-set (demo-it--get-text-scale size))
560 |
561 | (unless (demo-it--erase-shell-buffer)
562 | (demo-it-insert-shell "" :instant))))
563 |
564 | (defun demo-it--start-shell-reuse (title directory)
565 | "Attempt to re-use existing shell/eshell with a buffer named
566 | TITLE in a particular DIRECTORY."
567 | (switch-to-buffer title)
568 | (when directory
569 | (goto-char (point-max))
570 | (demo-it-insert-shell (format "cd %s" directory) :instant)
571 | (unless (demo-it--erase-shell-buffer)
572 | (demo-it-insert-shell "" :instant))))
573 |
574 | (defun demo-it--shell-buffer-name (&optional name)
575 | "Return the buffer NAME for the shell or eshell window."
576 | (if name
577 | (concat "Shell: " name)
578 | "Shell"))
579 |
580 | (defun demo-it-insert-shell (command &optional speed)
581 | "Inserts some text in the given shell or eshell. The optional
582 | SPEED overrides the custom, `demo-it--insert-text-speed'."
583 | (demo-it-insert command speed)
584 | (if (eq demo-it--shell-or-eshell :eshell)
585 | (eshell-send-input)
586 | (comint-send-input)))
587 |
588 | (defun demo-it-insert (str &optional speed)
589 | "Insert STR into the current buffer as if you were typing it by hand.
590 | The SPEED (if non-nil) overrides the default value settings of the
591 | `demo-it--insert-text-speed' custom variable."
592 | (let ((timings (demo-it--get-insert-text-speed speed)))
593 |
594 | (if (eq timings :instant)
595 | (insert str)
596 |
597 | (let ((entries (if (stringp str)
598 | (string-to-list str)
599 | str))
600 | (bottom-limit (car timings))
601 | (top-limit (cdr timings)))
602 | ;; If we are not inserting instantaneously, then loop over each
603 | ;; character in the string with a random delay based on this range:
604 | (dolist (ch entries)
605 | (insert ch)
606 | (let ((tm (+ (/ bottom-limit 1000.0)
607 | (/ (random top-limit) 1000.0))))
608 | (sit-for tm)))))))
609 |
610 | (defun demo-it-run-in-shell (command &optional name speed)
611 | "Run shell command COMMAND in a previously initialized Eshell.
612 | If NAME is not specified, it defaults to `Shell'."
613 | (pop-to-buffer (demo-it--shell-buffer-name name))
614 | (goto-char (point-max))
615 | (demo-it-insert-shell command speed))
616 |
617 | (define-obsolete-function-alias 'demo-it-run-in-eshell 'demo-it-run-in-shell "2016-Oct")
618 | (define-obsolete-function-alias 'demo-it-type-in-eshell 'demo-it-run-in-shell "2016-Oct")
619 |
620 | (defun demo-it-show-shell (&optional name side width)
621 | "Show the shell buffer of a given NAME whose buffer may have
622 | been buried and not in visible. Optionally specify the
623 | SIDE (either 'below or 'side) of the screen where the shell
624 | should be shown."
625 | (demo-it--make-side-window side width)
626 | (switch-to-buffer (demo-it--shell-buffer-name name)))
627 |
628 | (define-obsolete-function-alias 'demo-it-show-eshell 'demo-it-show-shell "2016-Oct")
629 |
630 |
631 | ;; TITLE DISPLAY
632 | ;;
633 | ;; Create a file to serve as a "title" as it will be displayed with a
634 | ;; larger-than-life font and make Emacs not look like Emacs.
635 |
636 | (defun demo-it-title-screen (file &optional size)
637 | "Display FILE to serve as the demonstration's title, as it will
638 | be displayed with a larger-than-life font without a mode line,
639 | etc. SIZE specifies the text scale, which ignores the
640 | `demo-it--text-scale' customization setting and defaults to 5x."
641 | (fringe-mode '(0 . 0))
642 |
643 | (find-file file)
644 | (show-all)
645 | (demo-it-hide-mode-line)
646 | (setq cursor-type nil)
647 | (if (fboundp 'flyspell-mode)
648 | (flyspell-mode -1))
649 | (variable-pitch-mode 1)
650 | (text-scale-set (or size (demo-it--get-text-scale :huge)))
651 |
652 | ;; Time to brag a wee bit...
653 | (message "† This presentation is running within Emacs."))
654 |
655 |
656 | ;; ----------------------------------------------------------------------
657 | ;; DEALING WITH FRAME
658 | ;;
659 | ;; During a demonstration, it might be nice to toggle between
660 | ;; full screen and "regular window" in a programmatic way:
661 |
662 | (defun demo-it-toggle-fullscreen ()
663 | "Toggle the frame between full screen and normal size. Only
664 | useful for old versions of Emacs, but this code probably won't
665 | work on them anyway."
666 | (declare (obsolete toggle-frame-fullscreen "2016-Oct"))
667 | (interactive)
668 | (set-frame-parameter
669 | nil 'fullscreen
670 | (when (not (frame-parameter nil 'fullscreen)) 'fullboth)))
671 |
672 | ;; We can force the window to be full screen:
673 |
674 | (defun demo-it-frame-fullscreen ()
675 | "Set the frame window to cover the full screen."
676 | (interactive)
677 | (set-frame-parameter nil 'fullscreen 'fullboth))
678 |
679 | ;; Let's make a right-side frame window:
680 |
681 | (defun demo-it-frame-leftside ()
682 | "Set the window frame to be exactly half the physical display
683 | screen, and place it on the left side of the screen. This can be
684 | helpful when showing off some other application."
685 | (declare (obsolete "Really!? You think this is useful?" "2016-Oct"))
686 | (interactive)
687 | (let* ((full-pixels (- (x-display-pixel-width) 16))
688 | (full-width (/ full-pixels (frame-char-width)))
689 | (dest-width (/ full-width 2)))
690 | (set-frame-parameter nil 'fullscreen nil)
691 | (set-frame-parameter nil 'width dest-width)
692 | (set-frame-parameter nil 'left 0)))
693 |
694 | ;; Temporary variables
695 | ;;
696 | ;; Set variables during a demonstration.
697 | ;; They are restored after the demonstration.
698 |
699 | (defvar demo-it--setq-tempvars (make-hash-table))
700 | (defvar demo-it--setq-voidvars nil)
701 | (defvar demo-it--setq-nilvars nil)
702 |
703 | (defun demo-it--setq (l)
704 | (cl-case (length l)
705 | (0)
706 | (1
707 | (error "Argument length is odd"))
708 | (t
709 | (let ((name (car l))
710 | (var (eval (cadr l))))
711 | (cond ((and (boundp name) (symbol-value name))
712 | (puthash name (symbol-value name) demo-it--setq-tempvars))
713 | ((boundp name)
714 | (push name demo-it--setq-nilvars))
715 | (t
716 | (push name demo-it--setq-voidvars)))
717 | (set name var)
718 | (demo-it--setq (nthcdr 2 l))))))
719 |
720 | (defmacro demo-it-setq (&rest list)
721 | "Like `setq', but the values are restored to original after the demo.
722 | Actually restored by `demo-it--setq-restore'."
723 | `(demo-it--setq '(,@list)))
724 |
725 | (defmacro demo-it-setq-save (&rest list)
726 | "Saves the original value of a LIST of variables.
727 |
728 | Call `demo-it--setq-restore' to restore the original values of
729 | the variables."
730 | `(mapcar ,(lambda (v) (puthash v (eval v) demo-it--setq-tempvars))
731 | '(,@list)))
732 |
733 | (defun demo-it--setq-restore ()
734 | "Restore values of setting by `demo-it-setq'."
735 | (cl-loop for name being the hash-keys in demo-it--setq-tempvars using (hash-values value)
736 | do (set name value))
737 | (dolist (name demo-it--setq-nilvars) (set name nil))
738 | (mapc 'makunbound demo-it--setq-voidvars)
739 | (clrhash demo-it--setq-tempvars)
740 | (setq demo-it--setq-nilvars nil
741 | demo-it--setq-voidvars nil))
742 |
743 | (defun demo-it--set-properties (l)
744 | "Sets a series of single property values from list, L."
745 | ;; First, save all the customization properties...
746 | (demo-it-setq-save demo-it--keymap-mode-style
747 | demo-it--shell-or-eshell
748 | demo-it--open-windows
749 | demo-it--text-scale
750 | demo-it--start-fullscreen
751 | demo-it--start-single-window
752 | demo-it--insert-text-speed)
753 | ;; Second, set all the new customization properties:
754 | (mapc 'demo-it--set-property l))
755 | ;; Helper Functions
756 |
757 | (defun demo-it-message-keybinding (key command)
758 | "Display message showing the KEY keybinding and its COMMAND."
759 | (interactive)
760 | (message "Typed: '%s' Command: '%s'" key command))
761 |
762 | ;; ----------------------------------------------------------------------
763 |
764 | (require 'demo-it-present)
765 | (require 'demo-it-extras)
766 |
767 | ;; As a final harrah, we need to let other files know how to include
768 | ;; this bad child.
769 |
770 | (provide 'demo-it)
771 |
772 | ;;; demo-it.el ends here
773 |
--------------------------------------------------------------------------------
/demo-it.org:
--------------------------------------------------------------------------------
1 | #+TITLE: Demo It
2 | #+AUTHOR: Howard Abrams
3 | #+EMAIL: howard.abrams@gmail.com
4 | #+DATE: 2016 Oct 06
5 | #+DESCRIPTION: This file is used as the basis for the Info documentation
6 | #+OPTIONS: ':t toc:t author:t email:t
7 | #+LANGUAGE: en
8 | #+MACRO: version 2.0
9 | #+MACRO: updated last updated 24 October 2016
10 |
11 | #+TEXINFO_FILENAME: demo-it.info
12 | #+TEXINFO_HEADER: @syncodeindex pg cp
13 | #+TEXINFO_HEADER: @syncodeindex vr cp
14 |
15 | * Basics
16 |
17 | At the end of each sprint, each of us demonstrate our accomplishments.
18 | These reviews often incorporate the following trifecta:
19 |
20 | * Presentations explaining the technology and whatnot
21 | * Source code reviews...correctly highlighted and interactive
22 | * Executing the code in a shell
23 |
24 | During my sprint reviews, I noticed I used my org-mode-formatted
25 | files, eshell and source code buffers... In other words, I was
26 | always in Emacs. However, fat-fingering or mentally burping delayed
27 | the gratification for my audience while I laboriously typed. I
28 | originally solved this problem by predefining each "step" as an
29 | Emacs Lisp function, and then had another function execute each
30 | function when I hit an /advance/ key (=F12=).
31 |
32 | After I had amassed a small army of /helper functions/, I packaged it as
33 | =demo-it=, because I lack the imagination to come up with anything more
34 | clever.
35 |
36 | See the following videos as examples of what can be done:
37 |
38 | * [[http://www.youtube.com/watch?v=B6jfrrwR10k][Emacs: An Introduction for the Curious]]
39 | * [[https://www.youtube.com/watch?v=dljNabciEGg][Literate DevOps Programming]]
40 | * [[http://www.youtube.com/watch?v=3T00X_sNg4Q][Learn You Some Lisp for Great Good]]
41 |
42 | ** Simple Example
43 | #+CINDEX: Basic exmaple
44 |
45 | Using this project is a four step process:
46 |
47 | 1. Load the library in your own Elisp source code file
48 | 2. Create zero or more helper functions that "do things", or use the
49 | functions provided by this project.
50 | 3. Order the functions by calling =(demo-it-create)=
51 | 4. Call =demo-it-start= to begin the fun.
52 |
53 | Press the space for each step, or call =demo-it-end= to end early.
54 |
55 | For instance:
56 |
57 | #+BEGIN_SRC elisp
58 | (require 'demo-it)
59 |
60 | (defun my-demo-step/show-code ()
61 | "Helper demo function that displays some source code and
62 | advances the presentation at the same time."
63 | (demo-it-load-file "example/example.py")
64 | (demo-it-presentation-advance))
65 |
66 | ;; Order the functions and forms for this presentation:
67 | (demo-it-create (demo-it-presentation "example/example.org")
68 | my-demo-step/show-code
69 | demo-it-presentation-return ; close file and advance
70 | (demo-it-run-in-eshell "python example/example.py"))
71 |
72 | (demo-it-start)
73 | #+END_SRC
74 |
75 | ** Step Types
76 | #+PINDEX: demo-it-create
77 | #+CINDEX: Parameters for demo-it-create
78 |
79 | The `demo-it-create' is a macro that stores a single demonstration.
80 | Calling it a second time replaces any previously created demonstrations.
81 |
82 | Each "step" given to the =demo-it-create= macro can be one of the
83 | following:
84 |
85 | - Expression typically calling a helper function, for instance:
86 | #+BEGIN_SRC elisp
87 | (demo-it-presentation "example/example.org")
88 | #+END_SRC
89 |
90 | - Name of a function to call that does multiple actions, for instance:
91 | #+BEGIN_SRC elisp
92 | demo-it-presentation-return
93 | #+END_SRC
94 |
95 | - a string referring to a key-binding to run, for instance:
96 | #+BEGIN_SRC elisp
97 | "C-x C-f example.el "
98 | #+END_SRC
99 |
100 | - a property that affects demonstration behavior, see the
101 | [[Demonstration Options]] or [[Customization]]
102 |
103 | Note: Any Emacs function can be called, either by name or as part
104 | of an expression. These functions can be standard functions,
105 | supplied by this =demo-it= package, or even ones you write. ;-)
106 |
107 | ** Demonstration Options
108 | #+CINDEX: Demonstration Behavior options
109 |
110 | The following list of keywords can be passed to =demo-it-create= to
111 | override various [[Customization]] settings:
112 |
113 | - =:simple-mode= uses mode where space advances demonstration.
114 | - =:advance-mode= uses mode where ~F12~ advances demonstration.
115 | - =:use-shell= chooses a standard =shell= command line interface when
116 | running the [[demo-it-start-shell]] command.
117 | - =:use-shell= chooses to use the built-in Emacs shell, which Emacs
118 | uses find more comfortable when subjected to Windows systems.
119 | - =:eshell= is an alias for =:use-eshell.=
120 | - =:shell= is an alias for =:user-shell=.
121 | - =:windows-on-right= defaults to opening auxiliary windows on the
122 | right side of the frame (see [[Showing Files][demo-it-load-file]] and other helper
123 | functions for examples).
124 | - =:windows-on-side= is an alias for =:windows-on-right=.
125 | - =:windows-on-left= like the above, but defaults to the /left/ side of
126 | the frame.
127 | - =:windows-below= opens other windows at the bottom of the current frame.
128 | - =:windows-above= opens other windows at the top of the current frame.
129 | - =:fullscreen= starts the demonstration with the current frame in fullscreen mode.
130 | - =:single-window= deletes other windows when started, and restores
131 | those windows when the demonstration completes.
132 | - =:text-small= starts presentations and other files in a slightly
133 | smaller font that the current default. Yeah, it seems like a nice
134 | idea to offer it, but I wonder if that is really helpful as a
135 | default for a demonstration.
136 | - =:text-normal= starts presentations and other loaded files in the
137 | default font and size.
138 | - =:text-medium= starts presentations and other loaded files in a
139 | slight larger font size (technically scaled at 1).
140 | - =:text-large= scales presentations and other loaded files at 2.
141 | - =:text-x-large= scales loaded files at 3.
142 | - =:text-xx-large= scales loaded files at 4 ... go figure.
143 | - =:text-huge= scales newly loaded files at 5. Got a big monitor or
144 | very few words, I see.
145 | - =:insert-slow= shell commands (and other calls to [[Inserting Text][demo-it-insert]]
146 | function) are inserted character by character as if a hacker who
147 | never took a typing class in middle school was typing the text.
148 | - =:insert-medium= shell commands and other text are inserted as if a
149 | medium-grade nerd with sufficient typing skills entered them.
150 | - =:insert-fast= shell commands are entered like a typist, but to an
151 | audience with the attention span of a gerbil.
152 | - =:insert-quickly= shell commands are instantly entered, and the
153 | audience is spared the gimmickry of yet-another Emacs feature.
154 | - =:show-mode-line= leaves the mode-line alone for presentations and
155 | files loaded by the demonstration package.
156 | - =:hide-mode-line= hides the mode line so neckbeards pay attention
157 | to your demonstration and quit straining to see what minor modes
158 | you prefer. Still using paredit, I see.
159 | - =:hide-org-markers= hides the asterisks, slashes, and other markup
160 | characters that format text, but still shows the text in bold and
161 | italics.
162 | - =:show-org-markers= displays org-mode presentations as you wrote it.
163 | - =:variable-width= uses a variable width font for presentations
164 | because we want to make the vi users cry.
165 | - =:fixed-width= displays org-mode presentations with your default
166 | monospaced font for ultra nerd cred. You may need this feature if
167 | source code in your presentation.
168 | - =:show-block-headers= Should the =#+begin= and =#+end= markers be
169 | shown? If you are trying to talk about /literate devops/ then, the
170 | answer is yes, show them the way you see them.
171 | - =:hide-block-headers= Hides the =#+begin= and =#+end= markers, but
172 | shows the glorious source code inside. Currently, also shows the
173 | surrounding =#+HEADER= entries, so beware.
174 |
175 | ** Running the Demo
176 | #+PINDEX: demo-it-start
177 | #+CINDEX: Starting Demonstration
178 |
179 | Once the demonstration has been created using ~demo-it-create~,
180 | start it by calling =demo-it-start=, as this will invoke the
181 | first step.
182 |
183 | Typically, pressing the =SPACE= or =RETURN= key will advance to the
184 | next step, but this depends on which of the [[Demo Modes]] was chosen.
185 |
186 | A deprecated version of =demo-it-start= allows you to pass in a list
187 | of the steps, but creating this list can be problematic, so you'll
188 | get more mileage from the =demo-it-create= macro.
189 |
190 | ** Demo Modes
191 | #+CINDEX: Minor modes
192 |
193 | Some demonstrations are so complete that pressing the space bar to
194 | advance to each step is sufficient. However, this project can be
195 | used as a /helper/ where each step merely sets up an environment
196 | where some Emacs feature or source code can be elaborated with
197 | personal prestidigitation. In this case, using the space and return
198 | to advance the demonstration would limit what can be demonstrated manually.
199 |
200 | So =demo-it= contains two minor modes, and starting a
201 | demonstration, one of the following minor mode is chosen.
202 |
203 | The choice is either made by setting the global customization
204 | value, , or by passing the following keyword to =demo-it-create=.
205 | - =:simple-mode=
206 | - =:advance-mode=
207 |
208 | *** demo-it-mode
209 | #+PINDEX: demo-it-mode
210 |
211 | The standard minor mode for demonstrations, has the following key
212 | features:
213 | - ~Space~ or ~Return~ advances to the next demonstration step
214 | - ~q~ turns off this mode, allowing you to type normally.
215 | Call =demo-it-mode= to resume this mode
216 | - ~Q~ ends the demonstration
217 |
218 | Note: In this mode, clicking the mouse on the right-side of the
219 | screen will advance the demonstration, while clicking elsewhere,
220 | repositions the cursor.
221 |
222 | *** demo-it-mode-adv
223 | #+PINDEX: demo-it-mode-adv
224 |
225 | The advanced mode is used when the =demo-it= project simply sets
226 | up an environment, where you want most keys available to enter
227 | commands manually. This mode has the following key features:
228 |
229 | - ~F12~ advances to the next step in the demonstration
230 | - ~M-F12~ ends the demonstration
231 |
232 | Why yes, while called /advanced/ is certainly has limited features.
233 |
234 | * Showing Presentations
235 | #+CINDEX: org-mode Presentations
236 |
237 | This project relies on other projects to do most of the heavy
238 | lifting for using ~org-mode~ files as the basis of a presentation,
239 | especially the [[https://github.com/takaxp/org-tree-slide][org-tree-slide]] project, which displays each section
240 | under a header as the sole contents of a buffer.
241 |
242 | The following functions can be added to your demonstration to
243 | control the display of the presentation.
244 |
245 | ** demo-it-presentation
246 | #+PINDEX: demo-it-presentation
247 | #+CINDEX: Presentations
248 |
249 | (file &optional size style section)
250 |
251 | Loads the given ~org-mode~ file as a presentation. This
252 | automatically calls [[https://github.com/takaxp/org-tree-slide][org-tree-slide]] if available.
253 |
254 | This function takes an optional ~size~ parameter to specifies the
255 | text scale. If ~nil~, this defaults to the value set in
256 | [[demo-it--text-scale]] customization variable.
257 |
258 | The optional ~style~ parameter can be set to either :variable for
259 | variable font pitch, :blocks for diminished headers on org-blocks,
260 | or :both to enable both features. This is a deprecated, legacy
261 | feature, since it is easier and clearer to either use the
262 | customization variables:
263 | - [[demo-it--presentation-variable-width]]
264 | - [[demo-it--presentation-hide-org-blocks]]
265 |
266 | The final parameter, ~section~, is a string containing the name of
267 | an ~org-mode~ header to specify as the first section to display.
268 |
269 | ** demo-it-presentation-quit
270 | #+PINDEX: demo-it-presentation-quit
271 |
272 | Undoes the display settings made to the presentation buffer.
273 |
274 | ** demo-it-presentation-return
275 | #+PINDEX: demo-it-presentation-return
276 |
277 | Makes the last running presentation the current buffer, deletes
278 | other windows, and advances to the next ~org-mode~ section.
279 |
280 | ** demo-it-presentation-return-noadvance
281 | #+PINDEX: demo-it-presentation-return-noadvance
282 |
283 | Similar to calling [[demo-it-presentation-return]] in that the latest
284 | specified presentation becomes the current buffer and all other
285 | windows are deleted.
286 |
287 | However, the presentation is not advanced to the next section.
288 |
289 | ** demo-it-presentation-advance
290 | #+PINDEX: demo-it-presentation-advance
291 |
292 | Advances the currently running presentation to the next section,
293 | but doesn't change focus to the window. Any further commands happen
294 | in the current window.
295 |
296 | This function is useful if a presentation discusses multiple
297 | commands, then you can advance through them while other commands
298 | actually perform the action (like executing commands in a shell).
299 |
300 | As an example, the following demonstration will /live-code/ while the
301 | presentation discusses each part:
302 |
303 | #+BEGIN_SRC elisp
304 | (demo-it-create (demo-it-presentation "elisp-cookbook.org")
305 | (demo-it-load-file "elisp-example.el")
306 |
307 | ; Advance to next section that talks about defun:
308 | demo-it-presentation-advance
309 |
310 | ; Start coding an Emacs Lisp function:
311 | (demo-it-insert "def") ; Begin yasnippet template
312 | "TAB" ; Trigger yasnippet
313 | (demo-it-insert "some-func") ; The function name
314 | "TAB" ; Advance to parameters
315 | (demo-it-insert "x y") ; parameters
316 | "TAB" ; Advance to parameters
317 | (demo-it-insert "Example function.")
318 | "TAB" ; Advance to interactive
319 | (demo-it-insert " ") ; No need for this section
320 | "TAB" ; Advance to function body
321 |
322 | ; Advance to next section to talk about if statements
323 | demo-it-presentation-advance
324 |
325 | (demo-it-insert "if") ; Begin next template
326 | "TAB" ; Trigger yasnippet
327 | (demo-it-insert "(eq x y)") ; predicate expression
328 | "TAB" ; Advance to if body
329 |
330 | ) ;; etc.
331 | #+END_SRC
332 |
333 | ** demo-it-presentation-highlight-phrase
334 | #+PINDEX: demo-it-presentation-highlight-phrase
335 |
336 | Given a string parameter, ~phrase~, as a regular expression, this
337 | function highlights a /phrase/ in the presentation buffer without
338 | changing the current buffer. This is
339 | useful to highlight bullet point items while executing appropriate
340 | code.
341 |
342 | The ~color~ parameter is a face from the ~hi-lock~ project,
343 | e.g. :hi-yellow.
344 |
345 | Note: This unhighlights previous highlighted phrases.
346 | Call ~demo-it-presentation-unhighlight-all~ if you just want to
347 | remove the highlighting.
348 |
349 | ** demo-it-single-presentation
350 | #+PINDEX: demo-it-single-presentation
351 | #+CINDEX: Demonstration with Only Presentation
352 |
353 | Demonstration similar to calling [[demo-it-presentation]], in that it
354 | presents an ~org-mode~ file as a full-screen presentation. In this
355 | form, the demonstration doesn't do anything more than advance
356 | through the presentation, and calling either ~demo-it-create~ or
357 | ~demo-it-start~ is not needed.
358 |
359 | This function begins a minor-mode where the space or return key
360 | advances the presentation to the next section. In this mode, the
361 | ~q~ disables this mode, and ~Q~ quits the demonstration and
362 | presentation.
363 |
364 | While the standard customization variables configure the
365 | presentation display style, this function accepts a ~size~
366 | parameter to set the text scaling size.
367 |
368 | The optional ~style~ parameter can be set to either :variable for
369 | variable font pitch, :blocks for diminished headers on org-blocks,
370 | or :both to enable both features.
371 |
372 | * Showing Files
373 | #+CINDEX: Showing Side Files
374 | #+CINDEX: Options for side files
375 |
376 | While a simple call to =find-file= is often sufficient to display a
377 | file in Emacs, the following functions can be helpful for showing
378 | files and source code during a demonstration.
379 |
380 | These functions often take the following optional parameters, and in
381 | the spirit of DRY, we will specify them here:
382 |
383 | The optional ~side~ parameter specifies the side of the frame to
384 | display the new window. Acceptable values can one of the following
385 | keywords:
386 | - =:above=
387 | - =:below=
388 | - =:left=
389 | - =:right=
390 | - =:side= is a synomym for =:right=
391 | - =:none= loads the file in the current buffer.
392 |
393 | If ~nil~, defaults is to use the customized value of
394 | [[demo-it--open-windows]].
395 |
396 | The optional ~size~ parameter takes an integer and specifies the
397 | text scale. If ~nil~, this defaults to the value set in
398 | [[demo-it--text-scale]] customization variable.
399 |
400 | The ~width~ parameter specifies the size of
401 | the new window, which is either the width of a side window, or
402 | the height if the window is =:above= or =:below=.
403 |
404 | ** demo-it-load-file
405 | #+PINDEX: demo-it-load-file
406 | #+CINDEX: Loading side files
407 | Calling this function with a file, first splits the root frame into
408 | a side window and loads the file into that window.
409 |
410 | Keep in mind, that calling it a second time will result in further
411 | splitting of the root window. Call =delete-window= or
412 | [[demo-it-presentation-return-noadvance]], or close the window
413 | while also updating the presentation with [[demo-it-presentation-return]].
414 |
415 | The optional parameters this function takes are [[Showing Files][described above]].
416 |
417 | ** demo-it-load-part-file
418 | #+PINDEX: demo-it-load-part-file
419 | #+CINDEX: Show part of a file
420 |
421 | Splits window and loads a file, but also narrows to particular region.
422 |
423 | If the ~type~ parameter is set to =:line=, then the ~start~ and
424 | ~end~ parameters specify the first and last lines of the region to
425 | narrow. If ~type~ is set to =:char=, then ~start~ and ~end~ refer
426 | to specific character positions.
427 |
428 | The other optional parameters this function takes are [[Showing Files][described above]].
429 |
430 | See [[demo-it-load-fancy-file]] for an alternative version.
431 |
432 | ** demo-it-load-fancy-file
433 | #+CINDEX: demo-it-load-fancy-file
434 | #+PINDEX: Highlighting while showing side file
435 |
436 | Splits the root frame and loads a ~file~ specified by the first
437 | parameter in that window (see [[demo-it-load-file]]), however, this
438 | function can use the
439 | [[https://github.com/Malabarba/fancy-narrow][fancy narrow]] to
440 | highlight part of the buffer (if it has been loaded), otherwise, it
441 | behaves like [[demo-it-load-part-file]] and narrows to the area specified.
442 |
443 | If the second parameter, ~type~ is a string that specifies a
444 | function name (available via ~imenu~), then it highlights
445 | that function.
446 |
447 | If ~type~ is a =:line=, then the next two parameters, ~start~ and ~end~
448 | specifies the beginning or ending lines.
449 |
450 | If ~type~ is =:char=, then ~start~ and ~end~ are exact buffer
451 | positions, which you can determine by evaluating (~M-;~) the
452 | following expression:
453 | #+BEGIN_SRC elisp
454 | (kill-new (int-to-string (point)))
455 | #+END_SRC
456 |
457 | The optional parameters ~side~ and ~size~ are
458 | [[Showing Files][described above]].
459 |
460 | Note: This function simply detects if the ~fancy-narrow~ package
461 | has been loaded. The demonstration will need to issue a ~require~.
462 |
463 | ** demo-it-show-image
464 | #+PINDEX: demo-it-show-image
465 |
466 | Loads a file as an image (or any other special file) in another
467 | window without a mode line or fringe.
468 |
469 | The optional parameters this function takes are [[Showing Files][described above]].
470 |
471 | ** demo-it-compare-files
472 | #+PINDEX: demo-it-compare-files
473 | #+CINDEX: Showing Two Files
474 |
475 | Loads two files in either two windows on top of each other on the
476 | right side of the screen, or two windows below (depending on the
477 | value of the ~side~, which should either be =:below= or =:side=.
478 |
479 | The other optional parameter, ~size~ is [[Showing Files][described above]].
480 |
481 | * Running Commands
482 | #+CINDEX: Shell Commands
483 |
484 | What Emacs-sponsored demonstration would be complete without being
485 | able to run the application you created. While your demonstration
486 | could easily call ~shell-command~, starting a shell, and having
487 | Emacs /type/ the commands makes a demonstration appear more real and
488 | interactive.
489 |
490 | The /typing/ abilities when inserting text are not very realistic,
491 | as it simply picks a random delay between each letter. What is
492 | lacking, however, it clacking should of the switches going off while
493 | the letter appears (PRs are acceptable).
494 |
495 | The following functions can be added to your demonstration to enter
496 | commands in a shell (both your default shell, as well as the Eshell
497 | is supported by setting the [[demo-it--shell-or-eshell]] variable or
498 | giving =demo-it-create= one of the following keyword configurations:
499 |
500 | - =:use-shell=
501 | - =:use-eshell=
502 |
503 | ** demo-it-start-shell
504 | #+PINDEX: demo-it-start-shell
505 |
506 | Starts a shell or eshell instance, in a particular directory and
507 | executes the given command. The command can be entered into the
508 | shell with a slight random delay intended to mimic a person typing.
509 | This speed of this is specified by [[demo-it--insert-text-speed]].
510 |
511 | The optional ~name~ parameter labels the buffer, and defaults to
512 | ~Shell~.
513 |
514 | The other optional parameters this function takes are
515 | [[Showing Files][described above]].
516 |
517 | ** demo-it-run-in-shell
518 | #+PINDEX: demo-it-run-in-shell
519 | #+CINDEX: Typing in Shell
520 |
521 | Run shell command in a shell previously started with
522 | [[demo-it-start-shell]]. If a ~name~ is not specified, it defaults to
523 | name, ~Shell~.
524 |
525 | The optional ~speed~ parameter overrides the customization value
526 | set by [[demo-it--insert-text-speed]], or the text-speed related
527 | keyword given to =demo-it-create=.
528 |
529 | ** demo-it-show-shell
530 | #+PINDEX: demo-it-show-shell
531 |
532 | Call to display the shell buffer if the shell window of a given
533 | ~name~ has been hidden. If ~name~ is not specified, it defaults to
534 | ~Shell~.
535 |
536 | The other optional parameters this function takes are
537 | [[Showing Files][described above]].
538 |
539 | * Inserting Text
540 | #+PINDEX: demo-it-insert
541 | #+CINDEX: Typing Text into Buffer
542 |
543 | Perhaps you want to regale your audience with your programmatic
544 | prowess, but don't dare attempt to do live-coding in front of live
545 | individuals? Yes, even creating a series of yasnippets can result in
546 | some serious embarrassment (and compiler errors) if you fat-finger
547 | any of the fields.
548 |
549 | Have no fear, just create a series of entries that contains calls to
550 | ~demo-it-insert~, as this function inserts a string into the current
551 | buffer as if you were typing it by hand (this is called by
552 | [[demo-it-run-in-shell]]).
553 |
554 | The following =demo-it= example uses this function as well as
555 | the =def= yasnippet for Ruby and particular keystrokes to move from
556 | field to field:
557 |
558 | #+BEGIN_SRC elisp :results silent
559 | (demo-it-create (find-file "foobar.rb")
560 | (demo-it-insert "def")
561 | (yas-expand)
562 | (demo-it-insert "hello")
563 | "TAB TAB"
564 | (demo-it-insert "name")
565 | "TAB"
566 | (demo-it-insert "\"Hello, #{name}\"" :fast))
567 | #+END_SRC
568 |
569 | The optional ~speed~ parameter is [[Showing Files][described above]].
570 |
571 | Note: The previous version of =demo-it= offered specialized
572 | feature for inserting text where each string to entered was put in
573 | a hashmap, ~demo-it-text-entries~, and the entries were inserted
574 | with calls to a dedicated function, ~demo-it-insert-text~. However,
575 | the above seems to work just as well without a special function, so
576 | it has been deprecated and removed.
577 |
578 | * Extra Functions
579 |
580 | The following are useful functions that don't fit in the previous
581 | sections, so consider this the /miscellaeous/ section.
582 |
583 | ** demo-it-end
584 | #+PINDEX: demo-it-end
585 | #+CINDEX: Ending Demonstration
586 |
587 | Calling this command ends the current demonstration by disabling
588 | the mode (see [[Demo Modes]]), resetting the values inflicted on the presentation buffer
589 | as well as restoring the window arrangement to their original glory
590 | before =demo-it-start= was called.
591 |
592 | ** demo-it-step
593 | #+PINDEX: demo-it-step
594 |
595 | This function is typically called by one of the [[Demo Modes]]
596 | to execute the next step in the current demonstration.
597 |
598 | However, this function can be called to jump to a particular STEP
599 | by specifying a step number to the optional parameter, ~step~. This
600 | can also be done with a prefix, e.g. C-6 to run the 6th step.
601 |
602 | Keep in mind that normally step functions expect a particular state
603 | to be established, so calling this function to jump to a particular
604 | step may not work as intended.
605 |
606 | Why yes, we do want to figure out a good mechanism for establishing
607 | a state for each called step, but that be a wee-bit challenging.
608 |
609 | ** demo-it-restep
610 | #+PINDEX: demo-it-restep
611 | #+CINDEX: Redoing Demo Step
612 |
613 | Re-executes the previous step in the current demonstration.
614 |
615 | Note, this doesn't handle the concept of the state of the Emacs
616 | system, so calling this function interactively does not rewind and
617 | re-executes, it just re-executes given the current Emacs state.
618 |
619 | ** demo-it-show-step
620 | #+PINDEX: demo-it-show-step
621 | #+CINDEX: What step am I on?
622 |
623 | Displays a message about the expected function (that is, the
624 | function that /will be run/) during the next step. This can be
625 | useful when you've lost your way, and ask yourself, How did I
626 | get here?
627 |
628 | Of course, you may ask yourself, How do I work this? \\
629 | And you may ask yourself, Where is that large automobile? \\
630 | And you may tell yourself, This is not my beautiful house! \\
631 | And you may tell yourself, This is not my beautiful wife!
632 |
633 | ** demo-it-hide-mode-line
634 | #+PINDEX: demo-it-hide-mode-line
635 |
636 | Hides the mode line for a current buffer. This is done by setting
637 | the ~mode-line-format~ to ~nil~, but also saves off the value so
638 | that it can be restored by calling [[demo-it-show-mode-line]].
639 |
640 | ** demo-it-show-mode-line
641 | #+PINDEX: demo-it-how-mode-line
642 |
643 | Shows the mode line of the current buffer, if it was previously
644 | hidden with a call to [[demo-it-hide-mode-line]].
645 |
646 | ** demo-it-title-screen
647 | #+PINDEX: demo-it-title-screen
648 | #+CINDEX: Demonstration Begins
649 |
650 | Displays a file as the demonstration's title, e.g.
651 | displayed with a larger-than-life font without a mode line,
652 | etc. Typically, a specially-formatted org-mode file would do the
653 | job, but any file, including an image will work.
654 |
655 | The ~size~ parameter specifies the text scale, which ignores the
656 | [[demo-it--text-scale]] customization setting and defaults to :huge
657 | (or 5x your normal text font size).
658 |
659 | ** demo-it-message-keybinding
660 | #+PINDEX: demo-it-message-keybinding
661 | #+CINDEX: Showing what you type
662 |
663 | When demonstrating Emacs features, you may want to display the
664 | keystroke you type. Yes, you could (and probably should) use a
665 | package like [[http://www.foldr.org/~michaelw/emacs/mwe-log-commands.el][mwe-log-commands]] by Michael Weber, but you can't
666 | really use that sort of feature with =demo-it=, as you'd just log a
667 | bunch of spacebars bound to [[demo-it-step]].
668 |
669 | What you really want is to display the key you /wanted/ to type.
670 | For that, you'll want to end your /step function/ with a call to
671 | ~demo-it-message-keybinding~, as it will take two strings, where
672 | the first one is the "key" and the other is a function or command
673 | that it normally calls.
674 |
675 | For instance:
676 | #+BEGIN_SRC elisp
677 | (defun my-demo/dired-a-directory ()
678 | "Opens a `dired' buffer on a particular directory.
679 | This is a step function that I add to demo-it-create."
680 | (dired (expand-file-name "~/work"))
681 | (demo-it-message-keybinding "C-x d" "dired"))
682 | #+END_SRC
683 |
684 | This sort of /step function/ would be added to =demo-it-create= as
685 | a simple symbol, like:
686 | #+BEGIN_SRC elisp
687 | (demo-it-create ;; :keybindings
688 | ;; other functions and expressions
689 | my-demo/dired-a-directory
690 | ;; other functions and expressions
691 | )
692 | #+END_SRC
693 |
694 | ** demo-it-highlight-dwim
695 | #+CINDEX: demo-it-highlight-dwim
696 | #+PINDEX: Text highlighting
697 |
698 | Can use the [[https://github.com/Malabarba/fancy-narrow][fancy-narrow]] package to highlight a particular
699 | /section/. If the package is not available, it simply /narrows/ to that
700 | area. If called interactively, this highlights the region (if
701 | active) or the current function.
702 |
703 | If the first parameter, ~type-or-fn~ is a string, this specifies
704 | the name of a function to highlight.
705 |
706 | If it is a =:line=, then the next two parameters, ~start~ and ~end~
707 | specifies the beginning or ending lines.
708 |
709 | If it is =:char=, then ~start~ and ~end~ are exact buffer
710 | positions, which you can determine by evaluating (~M-;~) the
711 | following expression:
712 | #+BEGIN_SRC elisp
713 | (kill-new (int-to-string (point)))
714 | #+END_SRC
715 |
716 | If ~type-or-fn~ is ~nil~ and the region is active, highlight the
717 | region.
718 |
719 | If none of the following match, simply select the function the
720 | point is currently in.
721 |
722 | Note: While this function checks to see if the package is
723 | available and loaded, it does not actually do the loading (or the
724 | installing of the package), for that, you will need to do something
725 | like:
726 |
727 | #+BEGIN_SRC elisp
728 | (require 'fancy-narrow)
729 | #+END_SRC
730 |
731 | * Customization
732 | :PROPERTIES:
733 | :APPENDIX: t
734 | :END:
735 | #+CINDEX: Demonstration Customizations
736 |
737 | The following is a list of custom variables that can be set through
738 | the standard Emacs customization feature (under the =demo-it= group).
739 | Note, each custom value may be overridden with a magic symbol to the
740 | [[Step Types][demo-it-create]] macro or with a parameter to many functions.
741 |
742 | ** demo-it--keymap-mode-style
743 | #+PINDEX: demo-it--keymap-mode-style
744 | #+CINDEX: Defaults for advancing demo
745 |
746 | The keymap-specific minor mode to use when a demonstration
747 | starts. Should either be set to the symbol, =:simple-mode= for using
748 | the space to advance to next step and ~q~ to exit the demonstration,
749 | or =:advanced-mode=, where ~F12~ advances.
750 |
751 | Defaults to =:simple-mode=
752 |
753 | This setting can be overridden by a keyword to =demo-it-create=:
754 | - =:simple-mode=
755 | - =:advanced-mode=
756 |
757 | ** demo-it--shell-or-eshell
758 | #+PINDEX: demo-it--shell-or-eshell
759 |
760 | When opening up a shell, this customization value specifies whether
761 | it should run the =shell= or =eshell= command.
762 |
763 | Should be set to one of the following keywords:
764 | - =:shell=
765 | - =:eshell=
766 |
767 | Defaults to =:eshell=
768 |
769 | This setting can be overridden by the following keywords to
770 | =demo-it-create= macro:
771 | - =:use-eshell=
772 | - =:use-shell=
773 |
774 | ** demo-it--open-windows
775 | #+PINDEX: demo-it--open-windows
776 | #+CINDEX: Side Windows
777 |
778 | When opening side windows, split the frame on a particular side.
779 | Should be set to one of the following keywords:
780 |
781 | - =:above=
782 | - =:below=
783 | - =:left=
784 | - =:right=
785 |
786 | The keyword, =:side= is a synonym for =:right=.
787 |
788 | Defaults to =:right=
789 |
790 | This setting can be overridden by one of the following keywords
791 | passed to =demo-it-create=:
792 | - =:windows-on-side=
793 | - =:windows-on-right=
794 | - =:windows-on-left=
795 | - =:windows-below=
796 | - =:windows-above=
797 |
798 | ** demo-it--open-windows-size
799 | #+PINDEX: demo-it--open-windows-size
800 | #+CINDEX: Side Windows Size
801 |
802 | The size of side windows to open. This is the width if the window
803 | is opened on one of the sides (=:left= or =:right=), or the height
804 | if the window is opened =:above= or =:below=.
805 |
806 | Defaults to =80=
807 |
808 | ** demo-it--text-scale
809 | #+PINDEX: demo-it--text-scale
810 | #+CINDEX: Side Windows Font Size
811 |
812 | Sets the default text scale when opening files in side windows (see
813 | [[demo-it--open-windows]]). While this can be set to an integer, it
814 | can also be set to one of the following keywords:
815 | - =:small=, set to a text scale of -1
816 | - =:normal=, set to a text scale of 0
817 | - =:medium=, set to a text scale of 1
818 | - =:large=, set to a text scale of 2
819 | - =:x-large=, set to a text scale of 3
820 | - =:xx-large=, set to a text scale of 4
821 | - =:huge=, set to a text scale of 5
822 |
823 | It defaults to =:large= (a =text-scale-set= value of =2=).
824 |
825 | This customization value can be overridden with one of the
826 | following keywords passed to =demo-it-create=:
827 | - =:text-small=
828 | - =:text-normal=
829 | - =:text-medium=
830 | - =:text-large=
831 | - =:text-x-large=
832 | - =:text-xx-large=
833 | - =:text-huge=
834 |
835 | ** demo-it--start-fullscreen
836 | #+PINDEX: demo-it--start-fullscreen
837 |
838 | A boolean setting that if set to a non-nil value, demonstrations
839 | start with the current frame in fullscreen mode. Defaults to
840 | =false=.
841 |
842 | This customization value can be overridden with =:fullscreen=
843 | keyword passed to =demo-it-create=.
844 |
845 | ** demo-it--start-single-window
846 | #+PINDEX: demo-it--start-single-window
847 |
848 | A boolean setting that if non-nil, deletes other windows to start
849 | the demonstration with a current buffer window being the only
850 | displayed window. Defaults to =t=.
851 |
852 | This customization value can be overridden with =:single-window=
853 | keyword passed to =demo-it-create=.
854 |
855 | ** demo-it--presentation-hide-mode-line
856 | #+PINDEX: demo-it--presentation-hide-mode-line
857 |
858 | If set to a nil value (/false/), the mode-line is hidden for any
859 | presentation files (this doesn't affect other files opened with the
860 | [[demo-it-load-file]]). Defaults to =t=.
861 |
862 | This customization value can be overridden with either of the
863 | following keywords passed to =demo-it-create=:
864 | - =:show-mode-line=
865 | - =:hide-mode-line=
866 |
867 | ** demo-it--presentation-hide-org-markers
868 | #+PINDEX: demo-it--presentation-hide-org-markers
869 |
870 | If set to a non-nil value, surrounding asterisks, underlines and
871 | slashes that define an ~org-mode~ textual formats in a presentation
872 | are displayed. Otherwise those characters hidden, even though the
873 | effects of bolding and italics are still shown. Defaults to =t=.
874 |
875 | This customization value can be overridden with either of the
876 | following keywords passed to =demo-it-create=:
877 | - =:show-org-markers=
878 | - =:hide-org-markers=
879 |
880 | ** demo-it--presentation-variable-width
881 | #+PINDEX: demo-it--presentation-variable-width
882 |
883 | If set to a non-nil value, a /variable-width/ font is used when
884 | displaying ~org-mode~ presentation files, otherwise the standard
885 | fixed-width font is used. Defaults to =nil=.
886 |
887 | This customization value can be overridden with either of the
888 | following keywords passed to =demo-it-create=:
889 | - =:variable-width=
890 | - =:fixed-width=
891 |
892 | ** demo-it--presentation-hide-org-blocks
893 | #+PINDEX: demo-it--presentation-hide-org-blocks
894 |
895 | If set to a non-nil value, the start and ending lines of ~org-mode~
896 | blocks are shown during a presentation, otherwise these lines are
897 | hidden, but the contents within the blocks are still shown.
898 |
899 | This currently only hides these lines:
900 | #+BEGIN_EXAMPLE
901 | ,#+BEGIN_SRC
902 | ...
903 | ,#+END_SRC
904 | #+END_EXAMPLE
905 |
906 | Other surrounding header values, like =#+HEADERS:= may still be seen.
907 |
908 | This defaults to =t=, however, this customization value can be
909 | overridden with either of the following keywords passed to
910 | =demo-it-create=:
911 | - =:show-block-headers=
912 | - =:hide-block-headers=
913 |
914 | ** demo-it--insert-text-speed
915 | #+PINDEX: demo-it--insert-text-speed
916 |
917 | The functions, [[demo-it-run-in-shell]], [[demo-it-start-shell]],
918 | and [[Inserting Text][demo-it-insert]], enters the text into the shell as if a human
919 | were typing it. This value specifies the speed at which that text
920 | is inserted into the shell.
921 |
922 | This can set to one of the following keywords:
923 | - =:instant= to insert text with no delay
924 | - =:slow=
925 | - =:medium=
926 | - =:fast=
927 |
928 | Defaults to =:medium=.
929 |
930 | This can also specify a tuple of two integer values for the random
931 | number of milliseconds between those two values to delay before
932 | inserting each character, for instance, the =:medium= delay has a
933 | lower value of 30 milliseconds, and an upper delay of 500.
934 |
935 | * Copying
936 | :PROPERTIES:
937 | :COPYING: t
938 | :END:
939 | #+CINDEX: Open Source License
940 |
941 | This manual is for =demo-it= (version {{{version}}},
942 | {{{updated}}}), a project for running demonstrations within Emacs.
943 |
944 | Copyright @@texinfo:@copyright{}@@ 2016, Howard Abrams
945 |
946 | #+BEGIN_QUOTE
947 | Permission is granted to copy, distribute and/or modify this
948 | document under the terms of the GNU Free Documentation License,
949 | Version 1.3 or any later version published by the Free Software
950 | Foundation; with no Invariant Sections, with no Front-Cover Texts,
951 | and with no Back-Cover Texts. A copy of the license is included in
952 | the section entitled "GNU Free Documentation License".
953 | #+END_QUOTE
954 |
955 | #+TEXINFO_DIR_CATEGORY: Emacs
956 | #+TEXINFO_DIR_TITLE: Demo It: (demo-it)
957 | #+TEXINFO_DIR_DESC: Demonstrations made and shown in Emacs
958 |
959 | * Index
960 | :PROPERTIES:
961 | :INDEX: cp
962 | :END:
963 |
964 | For those of you trying to read this online, this index is generated
965 | and only available within Emacs. If you are reading this from within
966 | Emacs, well-done.
967 |
--------------------------------------------------------------------------------
/demo-it.texi:
--------------------------------------------------------------------------------
1 | \input texinfo @c -*- texinfo -*-
2 | @c %**start of header
3 | @setfilename demo-it.info
4 | @settitle Demo It
5 | @documentencoding UTF-8
6 | @documentlanguage en
7 | @syncodeindex pg cp
8 | @syncodeindex vr cp
9 | @c %**end of header
10 |
11 | @copying
12 | @cindex Open Source License
13 |
14 | This manual is for @verb{~demo-it~} (version 2.0,
15 | last updated 24 October 2016), a project for running demonstrations within Emacs.
16 |
17 | Copyright @copyright{} 2016, Howard Abrams
18 |
19 | @quotation
20 | Permission is granted to copy, distribute and/or modify this
21 | document under the terms of the GNU Free Documentation License,
22 | Version 1.3 or any later version published by the Free Software
23 | Foundation; with no Invariant Sections, with no Front-Cover Texts,
24 | and with no Back-Cover Texts. A copy of the license is included in
25 | the section entitled ``GNU Free Documentation License''.
26 | @end quotation
27 | @end copying
28 |
29 | @dircategory Emacs
30 | @direntry
31 | * Demo It: (demo-it). Demonstrations made and shown in Emacs.
32 | @end direntry
33 |
34 | @finalout
35 | @titlepage
36 | @title Demo It
37 | @author Howard Abrams (@email{howard.abrams@@gmail.com})
38 | @page
39 | @vskip 0pt plus 1filll
40 | @insertcopying
41 | @end titlepage
42 |
43 | @contents
44 |
45 | @ifnottex
46 | @node Top
47 | @top Demo It
48 | @insertcopying
49 | @end ifnottex
50 |
51 | @menu
52 | * Basics::
53 | * Showing Presentations::
54 | * Showing Files::
55 | * Running Commands::
56 | * Inserting Text::
57 | * Extra Functions::
58 | * Customization::
59 | * Index::
60 |
61 | @detailmenu
62 | --- The Detailed Node Listing ---
63 |
64 | Basics
65 |
66 | * Simple Example::
67 | * Step Types::
68 | * Demonstration Options::
69 | * Running the Demo::
70 | * Demo Modes::
71 |
72 |
73 |
74 |
75 |
76 | Demo Modes
77 |
78 | * demo-it-mode::
79 | * demo-it-mode-adv::
80 |
81 | Showing Presentations
82 |
83 | * demo-it-presentation::
84 | * demo-it-presentation-quit::
85 | * demo-it-presentation-return::
86 | * demo-it-presentation-return-noadvance::
87 | * demo-it-presentation-advance::
88 | * demo-it-presentation-highlight-phrase::
89 | * demo-it-single-presentation::
90 |
91 |
92 |
93 | Showing Files
94 |
95 | * demo-it-load-file::
96 | * demo-it-load-part-file::
97 | * demo-it-load-fancy-file::
98 | * demo-it-show-image::
99 | * demo-it-compare-files::
100 |
101 |
102 |
103 | Running Commands
104 |
105 | * demo-it-start-shell::
106 | * demo-it-run-in-shell::
107 | * demo-it-show-shell::
108 |
109 |
110 |
111 |
112 | Extra Functions
113 |
114 | * demo-it-end::
115 | * demo-it-step::
116 | * demo-it-restep::
117 | * demo-it-show-step::
118 | * demo-it-hide-mode-line::
119 | * demo-it-show-mode-line::
120 | * demo-it-title-screen::
121 | * demo-it-message-keybinding::
122 | * demo-it-highlight-dwim::
123 |
124 |
125 |
126 | Customization
127 |
128 | * demo-it--keymap-mode-style::
129 | * demo-it--shell-or-eshell::
130 | * demo-it--open-windows::
131 | * demo-it--open-windows-size::
132 | * demo-it--text-scale::
133 | * demo-it--start-fullscreen::
134 | * demo-it--start-single-window::
135 | * demo-it--presentation-hide-mode-line::
136 | * demo-it--presentation-hide-org-markers::
137 | * demo-it--presentation-variable-width::
138 | * demo-it--presentation-hide-org-blocks::
139 | * demo-it--insert-text-speed::
140 | @end detailmenu
141 | @end menu
142 |
143 |
144 |
145 | @node Basics
146 | @unnumbered Basics
147 |
148 | At the end of each sprint, each of us demonstrate our accomplishments.
149 | These reviews often incorporate the following trifecta:
150 |
151 | @itemize
152 | @item
153 | Presentations explaining the technology and whatnot
154 | @item
155 | Source code reviews@dots{}correctly highlighted and interactive
156 | @item
157 | Executing the code in a shell
158 | @end itemize
159 |
160 | During my sprint reviews, I noticed I used my org-mode-formatted
161 | files, eshell and source code buffers@dots{} In other words, I was
162 | always in Emacs. However, fat-fingering or mentally burping delayed
163 | the gratification for my audience while I laboriously typed. I
164 | originally solved this problem by predefining each ``step'' as an
165 | Emacs Lisp function, and then had another function execute each
166 | function when I hit an @emph{advance} key (@verb{~F12~}).
167 |
168 | After I had amassed a small army of @emph{helper functions}, I packaged it as
169 | @verb{~demo-it~}, because I lack the imagination to come up with anything more
170 | clever.
171 |
172 | See the following videos as examples of what can be done:
173 |
174 | @itemize
175 | @item
176 | @uref{http://www.youtube.com/watch?v=B6jfrrwR10k,Emacs: An Introduction for the Curious}
177 | @item
178 | @uref{https://www.youtube.com/watch?v=dljNabciEGg,Literate DevOps Programming}
179 | @item
180 | @uref{http://www.youtube.com/watch?v=3T00X_sNg4Q,Learn You Some Lisp for Great Good}
181 | @end itemize
182 |
183 | @menu
184 | * Simple Example::
185 | * Step Types::
186 | * Demonstration Options::
187 | * Running the Demo::
188 | * Demo Modes::
189 | @end menu
190 |
191 | @node Simple Example
192 | @unnumberedsec Simple Example
193 |
194 | @cindex Basic exmaple
195 |
196 | Using this project is a four step process:
197 |
198 | @enumerate
199 | @item
200 | Load the library in your own Elisp source code file
201 | @item
202 | Create zero or more helper functions that ``do things'', or use the
203 | functions provided by this project.
204 | @item
205 | Order the functions by calling @verb{~(demo-it-create)~}
206 | @item
207 | Call @verb{~demo-it-start~} to begin the fun.
208 | @end enumerate
209 |
210 | Press the space for each step, or call @verb{~demo-it-end~} to end early.
211 |
212 | For instance:
213 |
214 | @lisp
215 | (require 'demo-it)
216 |
217 | (defun my-demo-step/show-code ()
218 | "Helper demo function that displays some source code and
219 | advances the presentation at the same time."
220 | (demo-it-load-side-window "example/example.py")
221 | (demo-it-presentation-advance))
222 |
223 | ;; Order the functions and forms for this presentation:
224 | (demo-it-create (demo-it-presentation "example/example.org")
225 | my-demo-step/show-code
226 | demo-it-presentation-return ; close file and advance
227 | (demo-it-run-in-eshell "python example/example.py"))
228 |
229 | (demo-it-start)
230 | @end lisp
231 |
232 | @node Step Types
233 | @unnumberedsec Step Types
234 |
235 | @pindex demo-it-create
236 | @cindex Parameters for demo-it-create
237 |
238 | The `demo-it-create' is a macro that stores a single demonstration.
239 | Calling it a second time replaces any previously created demonstrations.
240 |
241 | Each ``step'' given to the @verb{~demo-it-create~} macro can be one of the
242 | following:
243 |
244 | @itemize
245 | @item
246 | Expression typically calling a helper function, for instance:
247 | @lisp
248 | (demo-it-presentation "example/example.org")
249 | @end lisp
250 |
251 | @item
252 | Name of a function to call that does multiple actions, for instance:
253 | @lisp
254 | demo-it-presentation-return
255 | @end lisp
256 |
257 | @item
258 | a string referring to a key-binding to run, for instance:
259 | @lisp
260 | "C-x C-f example.el "
261 | @end lisp
262 |
263 | @item
264 | a property that affects demonstration behavior, see the
265 | @ref{Demonstration Options,Demonstration Options} or @ref{Customization,Customization}
266 | @end itemize
267 |
268 | Note: Any Emacs function can be called, either by name or as part
269 | of an expression. These functions can be standard functions,
270 | supplied by this @verb{~demo-it~} package, or even ones you write. ;-)
271 |
272 | @node Demonstration Options
273 | @unnumberedsec Demonstration Options
274 |
275 | @cindex Demonstration Behavior options
276 |
277 | The following list of keywords can be passed to @verb{~demo-it-create~} to
278 | override various @ref{Customization,Customization} settings:
279 |
280 | @itemize
281 | @item
282 | @verb{~:simple-mode~} uses mode where space advances demonstration.
283 | @item
284 | @verb{~:advance-mode~} uses mode where @code{F12} advances demonstration.
285 | @item
286 | @verb{~:use-shell~} chooses a standard @verb{~shell~} command line interface when
287 | running the @ref{demo-it-start-shell,demo-it-start-shell} command.
288 | @item
289 | @verb{~:use-shell~} chooses to use the built-in Emacs shell, which Emacs
290 | uses find more comfortable when subjected to Windows systems.
291 | @item
292 | @verb{~:eshell~} is an alias for @verb{~:use-eshell.~}
293 | @item
294 | @verb{~:shell~} is an alias for @verb{~:user-shell~}.
295 | @item
296 | @verb{~:windows-on-right~} defaults to opening auxiliary windows on the
297 | right side of the frame (see @ref{Showing Files,demo-it-load-file} and other helper
298 | functions for examples).
299 | @item
300 | @verb{~:windows-on-side~} is an alias for @verb{~:windows-on-right~}.
301 | @item
302 | @verb{~:windows-on-left~} like the above, but defaults to the @emph{left} side of
303 | the frame.
304 | @item
305 | @verb{~:windows-below~} opens other windows at the bottom of the current frame.
306 | @item
307 | @verb{~:windows-above~} opens other windows at the top of the current frame.
308 | @item
309 | @verb{~:fullscreen~} starts the demonstration with the current frame in fullscreen mode.
310 | @item
311 | @verb{~:single-window~} deletes other windows when started, and restores
312 | those windows when the demonstration completes.
313 | @item
314 | @verb{~:text-small~} starts presentations and other files in a slightly
315 | smaller font that the current default. Yeah, it seems like a nice
316 | idea to offer it, but I wonder if that is really helpful as a
317 | default for a demonstration.
318 | @item
319 | @verb{~:text-normal~} starts presentations and other loaded files in the
320 | default font and size.
321 | @item
322 | @verb{~:text-medium~} starts presentations and other loaded files in a
323 | slight larger font size (technically scaled at 1).
324 | @item
325 | @verb{~:text-large~} scales presentations and other loaded files at 2.
326 | @item
327 | @verb{~:text-x-large~} scales loaded files at 3.
328 | @item
329 | @verb{~:text-xx-large~} scales loaded files at 4 @dots{} go figure.
330 | @item
331 | @verb{~:text-huge~} scales newly loaded files at 5. Got a big monitor or
332 | very few words, I see.
333 | @item
334 | @verb{~:insert-slow~} shell commands (and other calls to @ref{Inserting Text,demo-it-insert}
335 | function) are inserted character by character as if a hacker who
336 | never took a typing class in middle school was typing the text.
337 | @item
338 | @verb{~:insert-medium~} shell commands and other text are inserted as if a
339 | medium-grade nerd with sufficient typing skills entered them.
340 | @item
341 | @verb{~:insert-fast~} shell commands are entered like a typist, but to an
342 | audience with the attention span of a gerbil.
343 | @item
344 | @verb{~:insert-quickly~} shell commands are instantly entered, and the
345 | audience is spared the gimmickry of yet-another Emacs feature.
346 | @item
347 | @verb{~:show-mode-line~} leaves the mode-line alone for presentations and
348 | files loaded by the demonstration package.
349 | @item
350 | @verb{~:hide-mode-line~} hides the mode line so neckbeards pay attention
351 | to your demonstration and quit straining to see what minor modes
352 | you prefer. Still using paredit, I see.
353 | @item
354 | @verb{~:hide-org-markers~} hides the asterisks, slashes, and other markup
355 | characters that format text, but still shows the text in bold and
356 | italics.
357 | @item
358 | @verb{~:show-org-markers~} displays org-mode presentations as you wrote it.
359 | @item
360 | @verb{~:variable-width~} uses a variable width font for presentations
361 | because we want to make the vi users cry.
362 | @item
363 | @verb{~:fixed-width~} displays org-mode presentations with your default
364 | monospaced font for ultra nerd cred. You may need this feature if
365 | source code in your presentation.
366 | @item
367 | @verb{~:show-block-headers~} Should the @verb{~#+begin~} and @verb{~#+end~} markers be
368 | shown? If you are trying to talk about @emph{literate devops} then, the
369 | answer is yes, show them the way you see them.
370 | @item
371 | @verb{~:hide-block-headers~} Hides the @verb{~#+begin~} and @verb{~#+end~} markers, but
372 | shows the glorious source code inside. Currently, also shows the
373 | surrounding @verb{~#+HEADER~} entries, so beware.
374 | @end itemize
375 |
376 | @node Running the Demo
377 | @unnumberedsec Running the Demo
378 |
379 | @pindex demo-it-start
380 | @cindex Starting Demonstration
381 |
382 | Once the demonstration has been created using @code{demo-it-create},
383 | start it by calling @verb{~demo-it-start~}, as this will invoke the
384 | first step.
385 |
386 | Typically, pressing the @verb{~SPACE~} or @verb{~RETURN~} key will advance to the
387 | next step, but this depends on which of the @ref{Demo Modes,Demo Modes} was chosen.
388 |
389 | A deprecated version of @verb{~demo-it-start~} allows you to pass in a list
390 | of the steps, but creating this list can be problematic, so you'll
391 | get more mileage from the @verb{~demo-it-create~} macro.
392 |
393 | @node Demo Modes
394 | @unnumberedsec Demo Modes
395 |
396 | @cindex Minor modes
397 |
398 | Some demonstrations are so complete that pressing the space bar to
399 | advance to each step is sufficient. However, this project can be
400 | used as a @emph{helper} where each step merely sets up an environment
401 | where some Emacs feature or source code can be elaborated with
402 | personal prestidigitation. In this case, using the space and return
403 | to advance the demonstration would limit what can be demonstrated manually.
404 |
405 | So @verb{~demo-it~} contains two minor modes, and starting a
406 | demonstration, one of the following minor mode is chosen.
407 |
408 | The choice is either made by setting the global customization
409 | value, , or by passing the following keyword to @verb{~demo-it-create~}.
410 | @itemize
411 | @item
412 | @verb{~:simple-mode~}
413 | @item
414 | @verb{~:advance-mode~}
415 | @end itemize
416 |
417 | @menu
418 | * demo-it-mode::
419 | * demo-it-mode-adv::
420 | @end menu
421 |
422 | @node demo-it-mode
423 | @unnumberedsubsec demo-it-mode
424 |
425 | @pindex demo-it-mode
426 |
427 | The standard minor mode for demonstrations, has the following key
428 | features:
429 | @itemize
430 | @item
431 | @code{Space} or @code{Return} advances to the next demonstration step
432 | @item
433 | @code{q} turns off this mode, allowing you to type normally.
434 | Call @verb{~demo-it-mode~} to resume this mode
435 | @item
436 | @code{Q} ends the demonstration
437 | @end itemize
438 |
439 | Note: In this mode, clicking the mouse on the right-side of the
440 | screen will advance the demonstration, while clicking elsewhere,
441 | repositions the cursor.
442 |
443 | @node demo-it-mode-adv
444 | @unnumberedsubsec demo-it-mode-adv
445 |
446 | @pindex demo-it-mode-adv
447 |
448 | The advanced mode is used when the @verb{~demo-it~} project simply sets
449 | up an environment, where you want most keys available to enter
450 | commands manually. This mode has the following key features:
451 |
452 | @itemize
453 | @item
454 | @code{F12} advances to the next step in the demonstration
455 | @item
456 | @code{M-F12} ends the demonstration
457 | @end itemize
458 |
459 | Why yes, while called @emph{advanced} is certainly has limited features.
460 |
461 | @node Showing Presentations
462 | @unnumbered Showing Presentations
463 |
464 | @cindex org-mode Presentations
465 |
466 | This project relies on other projects to do most of the heavy
467 | lifting for using @code{org-mode} files as the basis of a presentation,
468 | especially the @uref{https://github.com/takaxp/org-tree-slide,org-tree-slide} project, which displays each section
469 | under a header as the sole contents of a buffer.
470 |
471 | The following functions can be added to your demonstration to
472 | control the display of the presentation.
473 |
474 | @menu
475 | * demo-it-presentation::
476 | * demo-it-presentation-quit::
477 | * demo-it-presentation-return::
478 | * demo-it-presentation-return-noadvance::
479 | * demo-it-presentation-advance::
480 | * demo-it-presentation-highlight-phrase::
481 | * demo-it-single-presentation::
482 | @end menu
483 |
484 | @node demo-it-presentation
485 | @unnumberedsec demo-it-presentation
486 |
487 | @pindex demo-it-presentation
488 | @cindex Presentations
489 |
490 | (file &optional size style section)
491 |
492 | Loads the given @code{org-mode} file as a presentation. This
493 | automatically calls @uref{https://github.com/takaxp/org-tree-slide,org-tree-slide} if available.
494 |
495 | This function takes an optional @code{size} parameter to specifies the
496 | text scale. If @code{nil}, this defaults to the value set in
497 | @ref{demo-it--text-scale,demo-it--text-scale} customization variable.
498 |
499 | The optional @code{style} parameter can be set to either :variable for
500 | variable font pitch, :blocks for diminished headers on org-blocks,
501 | or :both to enable both features. This is a deprecated, legacy
502 | feature, since it is easier and clearer to either use the
503 | customization variables:
504 | @itemize
505 | @item
506 | @ref{demo-it--presentation-variable-width,demo-it--presentation-variable-width}
507 | @item
508 | @ref{demo-it--presentation-hide-org-blocks,demo-it--presentation-hide-org-blocks}
509 | @end itemize
510 |
511 | The final parameter, @code{section}, is a string containing the name of
512 | an @code{org-mode} header to specify as the first section to display.
513 |
514 | @node demo-it-presentation-quit
515 | @unnumberedsec demo-it-presentation-quit
516 |
517 | @pindex demo-it-presentation-quit
518 |
519 | Undoes the display settings made to the presentation buffer.
520 |
521 | @node demo-it-presentation-return
522 | @unnumberedsec demo-it-presentation-return
523 |
524 | @pindex demo-it-presentation-return
525 |
526 | Makes the last running presentation the current buffer, deletes
527 | other windows, and advances to the next @code{org-mode} section.
528 |
529 | @node demo-it-presentation-return-noadvance
530 | @unnumberedsec demo-it-presentation-return-noadvance
531 |
532 | @pindex demo-it-presentation-return-noadvance
533 |
534 | Similar to calling @ref{demo-it-presentation-return,demo-it-presentation-return} in that the latest
535 | specified presentation becomes the current buffer and all other
536 | windows are deleted.
537 |
538 | However, the presentation is not advanced to the next section.
539 |
540 | @node demo-it-presentation-advance
541 | @unnumberedsec demo-it-presentation-advance
542 |
543 | @pindex demo-it-presentation-advance
544 |
545 | Advances the currently running presentation to the next section,
546 | but doesn't change focus to the window. Any further commands happen
547 | in the current window.
548 |
549 | This function is useful if a presentation discusses multiple
550 | commands, then you can advance through them while other commands
551 | actually perform the action (like executing commands in a shell).
552 |
553 | As an example, the following demonstration will @emph{live-code} while the
554 | presentation discusses each part:
555 |
556 | @lisp
557 | (demo-it-create (demo-it-presentation "elisp-cookbook.org")
558 | (demo-it-load-file "elisp-example.el")
559 |
560 | ; Advance to next section that talks about defun:
561 | demo-it-presentation-advance
562 |
563 | ; Start coding an Emacs Lisp function:
564 | (demo-it-insert "def") ; Begin yasnippet template
565 | "TAB" ; Trigger yasnippet
566 | (demo-it-insert "some-func") ; The function name
567 | "TAB" ; Advance to parameters
568 | (demo-it-insert "x y") ; parameters
569 | "TAB" ; Advance to parameters
570 | (demo-it-insert "Example function.")
571 | "TAB" ; Advance to interactive
572 | (demo-it-insert " ") ; No need for this section
573 | "TAB" ; Advance to function body
574 |
575 | ; Advance to next section to talk about if statements
576 | demo-it-presentation-advance
577 |
578 | (demo-it-insert "if") ; Begin next template
579 | "TAB" ; Trigger yasnippet
580 | (demo-it-insert "(eq x y)") ; predicate expression
581 | "TAB" ; Advance to if body
582 |
583 | ) ;; etc.
584 | @end lisp
585 |
586 | @node demo-it-presentation-highlight-phrase
587 | @unnumberedsec demo-it-presentation-highlight-phrase
588 |
589 | @pindex demo-it-presentation-highlight-phrase
590 |
591 | Given a string parameter, @code{phrase}, as a regular expression, this
592 | function highlights a @emph{phrase} in the presentation buffer without
593 | changing the current buffer. This is
594 | useful to highlight bullet point items while executing appropriate
595 | code.
596 |
597 | The @code{color} parameter is a face from the @code{hi-lock} project,
598 | e.g. :hi-yellow.
599 |
600 | Note: This unhighlights previous highlighted phrases.
601 | Call @code{demo-it-presentation-unhighlight-all} if you just want to
602 | remove the highlighting.
603 |
604 | @node demo-it-single-presentation
605 | @unnumberedsec demo-it-single-presentation
606 |
607 | @pindex demo-it-single-presentation
608 | @cindex Demonstration with Only Presentation
609 |
610 | Demonstration similar to calling @ref{demo-it-presentation,demo-it-presentation}, in that it
611 | presents an @code{org-mode} file as a full-screen presentation. In this
612 | form, the demonstration doesn't do anything more than advance
613 | through the presentation, and calling either @code{demo-it-create} or
614 | @code{demo-it-start} is not needed.
615 |
616 | This function begins a minor-mode where the space or return key
617 | advances the presentation to the next section. In this mode, the
618 | @code{q} disables this mode, and @code{Q} quits the demonstration and
619 | presentation.
620 |
621 | While the standard customization variables configure the
622 | presentation display style, this function accepts a @code{size}
623 | parameter to set the text scaling size.
624 |
625 | The optional @code{style} parameter can be set to either :variable for
626 | variable font pitch, :blocks for diminished headers on org-blocks,
627 | or :both to enable both features.
628 |
629 | @node Showing Files
630 | @unnumbered Showing Files
631 |
632 | @cindex Showing Side Files
633 | @cindex Options for side files
634 |
635 | While a simple call to @verb{~find-file~} is often sufficient to display a
636 | file in Emacs, the following functions can be helpful for showing
637 | files and source code during a demonstration.
638 |
639 | These functions often take the following optional parameters, and in
640 | the spirit of DRY, we will specify them here:
641 |
642 | The optional @code{side} parameter specifies the side of the frame to
643 | display the new window. Acceptable values can one of the following
644 | keywords:
645 | @itemize
646 | @item
647 | @verb{~:above~}
648 | @item
649 | @verb{~:below~}
650 | @item
651 | @verb{~:left~}
652 | @item
653 | @verb{~:right~}
654 | @item
655 | @verb{~:side~} is a synomym for @verb{~:right~}
656 | @item
657 | @verb{~:none~} loads the file in the current buffer.
658 | @end itemize
659 |
660 | If @code{nil}, defaults is to use the customized value of
661 | @ref{demo-it--open-windows,demo-it--open-windows}.
662 |
663 | The optional @code{size} parameter takes an integer and specifies the
664 | text scale. If @code{nil}, this defaults to the value set in
665 | @ref{demo-it--text-scale,demo-it--text-scale} customization variable.
666 |
667 | The @code{width} parameter specifies the size of
668 | the new window, which is either the width of a side window, or
669 | the height if the window is @verb{~:above~} or @verb{~:below~}.
670 |
671 | @menu
672 | * demo-it-load-file::
673 | * demo-it-load-part-file::
674 | * demo-it-load-fancy-file::
675 | * demo-it-show-image::
676 | * demo-it-compare-files::
677 | @end menu
678 |
679 | @node demo-it-load-file
680 | @unnumberedsec demo-it-load-file
681 |
682 | @pindex demo-it-load-file
683 | @cindex Loading side files
684 | Calling this function with a file, first splits the root frame into
685 | a side window and loads the file into that window.
686 |
687 | Keep in mind, that calling it a second time will result in further
688 | splitting of the root window. Call @verb{~delete-window~} or
689 | @ref{demo-it-presentation-return-noadvance,demo-it-presentation-return-noadvance}, or close the window
690 | while also updating the presentation with @ref{demo-it-presentation-return,demo-it-presentation-return}.
691 |
692 | The optional parameters this function takes are @ref{Showing Files,described above}.
693 |
694 | @node demo-it-load-part-file
695 | @unnumberedsec demo-it-load-part-file
696 |
697 | @pindex demo-it-load-part-file
698 | @cindex Show part of a file
699 |
700 | Splits window and loads a file, but also narrows to particular region.
701 |
702 | If the @code{type} parameter is set to @verb{~:line~}, then the @code{start} and
703 | @code{end} parameters specify the first and last lines of the region to
704 | narrow. If @code{type} is set to @verb{~:char~}, then @code{start} and @code{end} refer
705 | to specific character positions.
706 |
707 | The other optional parameters this function takes are @ref{Showing Files,described above}.
708 |
709 | See @ref{demo-it-load-fancy-file,demo-it-load-fancy-file} for an alternative version.
710 |
711 | @node demo-it-load-fancy-file
712 | @unnumberedsec demo-it-load-fancy-file
713 |
714 | @cindex demo-it-load-fancy-file
715 | @pindex Highlighting while showing side file
716 |
717 | Splits the root frame and loads a @code{file} specified by the first
718 | parameter in that window (see @ref{demo-it-load-file,demo-it-load-file}), however, this
719 | function can use the
720 | @uref{https://github.com/Malabarba/fancy-narrow,fancy narrow} to
721 | highlight part of the buffer (if it has been loaded), otherwise, it
722 | behaves like @ref{demo-it-load-part-file,demo-it-load-part-file} and narrows to the area specified.
723 |
724 | If the second parameter, @code{type} is a string that specifies a
725 | function name (available via @code{imenu}), then it highlights
726 | that function.
727 |
728 | If @code{type} is a @verb{~:line~}, then the next two parameters, @code{start} and @code{end}
729 | specifies the beginning or ending lines.
730 |
731 | If @code{type} is @verb{~:char~}, then @code{start} and @code{end} are exact buffer
732 | positions, which you can determine by evaluating (@code{M-;}) the
733 | following expression:
734 | @lisp
735 | (kill-new (int-to-string (point)))
736 | @end lisp
737 |
738 | The optional parameters @code{side} and @code{size} are
739 | @ref{Showing Files,described above}.
740 |
741 | Note: This function simply detects if the @code{fancy-narrow} package
742 | has been loaded. The demonstration will need to issue a @code{require}.
743 |
744 | @node demo-it-show-image
745 | @unnumberedsec demo-it-show-image
746 |
747 | @pindex demo-it-show-image
748 |
749 | Loads a file as an image (or any other special file) in another
750 | window without a mode line or fringe.
751 |
752 | The optional parameters this function takes are @ref{Showing Files,described above}.
753 |
754 | @node demo-it-compare-files
755 | @unnumberedsec demo-it-compare-files
756 |
757 | @pindex demo-it-compare-files
758 | @cindex Showing Two Files
759 |
760 | Loads two files in either two windows on top of each other on the
761 | right side of the screen, or two windows below (depending on the
762 | value of the @code{side}, which should either be @verb{~:below~} or @verb{~:side~}.
763 |
764 | The other optional parameter, @code{size} is @ref{Showing Files,described above}.
765 |
766 | @node Running Commands
767 | @unnumbered Running Commands
768 |
769 | @cindex Shell Commands
770 |
771 | What Emacs-sponsored demonstration would be complete without being
772 | able to run the application you created. While your demonstration
773 | could easily call @code{shell-command}, starting a shell, and having
774 | Emacs @emph{type} the commands makes a demonstration appear more real and
775 | interactive.
776 |
777 | The @emph{typing} abilities when inserting text are not very realistic,
778 | as it simply picks a random delay between each letter. What is
779 | lacking, however, it clacking should of the switches going off while
780 | the letter appears (PRs are acceptable).
781 |
782 | The following functions can be added to your demonstration to enter
783 | commands in a shell (both your default shell, as well as the Eshell
784 | is supported by setting the @ref{demo-it--shell-or-eshell,demo-it--shell-or-eshell} variable or
785 | giving @verb{~demo-it-create~} one of the following keyword configurations:
786 |
787 | @itemize
788 | @item
789 | @verb{~:use-shell~}
790 | @item
791 | @verb{~:use-eshell~}
792 | @end itemize
793 |
794 | @menu
795 | * demo-it-start-shell::
796 | * demo-it-run-in-shell::
797 | * demo-it-show-shell::
798 | @end menu
799 |
800 | @node demo-it-start-shell
801 | @unnumberedsec demo-it-start-shell
802 |
803 | @pindex demo-it-start-shell
804 |
805 | Starts a shell or eshell instance, in a particular directory and
806 | executes the given command. The command can be entered into the
807 | shell with a slight random delay intended to mimic a person typing.
808 | This speed of this is specified by @ref{demo-it--insert-text-speed,demo-it--insert-text-speed}.
809 |
810 | The optional @code{name} parameter labels the buffer, and defaults to
811 | @code{Shell}.
812 |
813 | The other optional parameters this function takes are
814 | @ref{Showing Files,described above}.
815 |
816 | @node demo-it-run-in-shell
817 | @unnumberedsec demo-it-run-in-shell
818 |
819 | @pindex demo-it-run-in-shell
820 | @cindex Typing in Shell
821 |
822 | Run shell command in a shell previously started with
823 | @ref{demo-it-start-shell,demo-it-start-shell}. If a @code{name} is not specified, it defaults to
824 | name, @code{Shell}.
825 |
826 | The optional @code{speed} parameter overrides the customization value
827 | set by @ref{demo-it--insert-text-speed,demo-it--insert-text-speed}, or the text-speed related
828 | keyword given to @verb{~demo-it-create~}.
829 |
830 | @node demo-it-show-shell
831 | @unnumberedsec demo-it-show-shell
832 |
833 | @pindex demo-it-show-shell
834 |
835 | Call to display the shell buffer if the shell window of a given
836 | @code{name} has been hidden. If @code{name} is not specified, it defaults to
837 | @code{Shell}.
838 |
839 | The other optional parameters this function takes are
840 | @ref{Showing Files,described above}.
841 |
842 | @node Inserting Text
843 | @unnumbered Inserting Text
844 |
845 | @pindex demo-it-insert
846 | @cindex Typing Text into Buffer
847 |
848 | Perhaps you want to regale your audience with your programmatic
849 | prowess, but don't dare attempt to do live-coding in front of live
850 | individuals? Yes, even creating a series of yasnippets can result in
851 | some serious embarrassment (and compiler errors) if you fat-finger
852 | any of the fields.
853 |
854 | Have no fear, just create a series of entries that contains calls to
855 | @code{demo-it-insert}, as this function inserts a string into the current
856 | buffer as if you were typing it by hand (this is called by
857 | @ref{demo-it-run-in-shell,demo-it-run-in-shell}).
858 |
859 | The following @verb{~demo-it~} example uses this function as well as
860 | the @verb{~def~} yasnippet for Ruby and particular keystrokes to move from
861 | field to field:
862 |
863 | @lisp
864 | (demo-it-create (find-file "foobar.rb")
865 | (demo-it-insert "def")
866 | (yas-expand)
867 | (demo-it-insert "hello")
868 | "TAB TAB"
869 | (demo-it-insert "name")
870 | "TAB"
871 | (demo-it-insert "\"Hello, #@{name@}\"" :fast))
872 | @end lisp
873 |
874 | The optional @code{speed} parameter is @ref{Showing Files,described above}.
875 |
876 | Note: The previous version of @verb{~demo-it~} offered specialized
877 | feature for inserting text where each string to entered was put in
878 | a hashmap, @code{demo-it-text-entries}, and the entries were inserted
879 | with calls to a dedicated function, @code{demo-it-insert-text}. However,
880 | the above seems to work just as well without a special function, so
881 | it has been deprecated and removed.
882 |
883 | @node Extra Functions
884 | @unnumbered Extra Functions
885 |
886 | The following are useful functions that don't fit in the previous
887 | sections, so consider this the @emph{miscellaeous} section.
888 |
889 | @menu
890 | * demo-it-end::
891 | * demo-it-step::
892 | * demo-it-restep::
893 | * demo-it-show-step::
894 | * demo-it-hide-mode-line::
895 | * demo-it-show-mode-line::
896 | * demo-it-title-screen::
897 | * demo-it-message-keybinding::
898 | * demo-it-highlight-dwim::
899 | @end menu
900 |
901 | @node demo-it-end
902 | @unnumberedsec demo-it-end
903 |
904 | @pindex demo-it-end
905 | @cindex Ending Demonstration
906 |
907 | Calling this command ends the current demonstration by disabling
908 | the mode (see @ref{Demo Modes,Demo Modes}), resetting the values inflicted on the presentation buffer
909 | as well as restoring the window arrangement to their original glory
910 | before @verb{~demo-it-start~} was called.
911 |
912 | @node demo-it-step
913 | @unnumberedsec demo-it-step
914 |
915 | @pindex demo-it-step
916 |
917 | This function is typically called by one of the @ref{Demo Modes,Demo Modes}
918 | to execute the next step in the current demonstration.
919 |
920 | However, this function can be called to jump to a particular STEP
921 | by specifying a step number to the optional parameter, @code{step}. This
922 | can also be done with a prefix, e.g. C-6 to run the 6th step.
923 |
924 | Keep in mind that normally step functions expect a particular state
925 | to be established, so calling this function to jump to a particular
926 | step may not work as intended.
927 |
928 | Why yes, we do want to figure out a good mechanism for establishing
929 | a state for each called step, but that be a wee-bit challenging.
930 |
931 | @node demo-it-restep
932 | @unnumberedsec demo-it-restep
933 |
934 | @pindex demo-it-restep
935 | @cindex Redoing Demo Step
936 |
937 | Re-executes the previous step in the current demonstration.
938 |
939 | Note, this doesn't handle the concept of the state of the Emacs
940 | system, so calling this function interactively does not rewind and
941 | re-executes, it just re-executes given the current Emacs state.
942 |
943 | @node demo-it-show-step
944 | @unnumberedsec demo-it-show-step
945 |
946 | @pindex demo-it-show-step
947 | @cindex What step am I on?
948 |
949 | Displays a message about the expected function (that is, the
950 | function that @emph{will be run}) during the next step. This can be
951 | useful when you've lost your way, and ask yourself, How did I
952 | get here?
953 |
954 | Of course, you may ask yourself, How do I work this? @*
955 | And you may ask yourself, Where is that large automobile? @*
956 | And you may tell yourself, This is not my beautiful house! @*
957 | And you may tell yourself, This is not my beautiful wife!
958 |
959 | @node demo-it-hide-mode-line
960 | @unnumberedsec demo-it-hide-mode-line
961 |
962 | @pindex demo-it-hide-mode-line
963 |
964 | Hides the mode line for a current buffer. This is done by setting
965 | the @code{mode-line-format} to @code{nil}, but also saves off the value so
966 | that it can be restored by calling @ref{demo-it-show-mode-line,demo-it-show-mode-line}.
967 |
968 | @node demo-it-show-mode-line
969 | @unnumberedsec demo-it-show-mode-line
970 |
971 | @pindex demo-it-how-mode-line
972 |
973 | Shows the mode line of the current buffer, if it was previously
974 | hidden with a call to @ref{demo-it-hide-mode-line,demo-it-hide-mode-line}.
975 |
976 | @node demo-it-title-screen
977 | @unnumberedsec demo-it-title-screen
978 |
979 | @pindex demo-it-title-screen
980 | @cindex Demonstration Begins
981 |
982 | Displays a file as the demonstration's title, e.g.
983 | displayed with a larger-than-life font without a mode line,
984 | etc. Typically, a specially-formatted org-mode file would do the
985 | job, but any file, including an image will work.
986 |
987 | The @code{size} parameter specifies the text scale, which ignores the
988 | @ref{demo-it--text-scale,demo-it--text-scale} customization setting and defaults to :huge
989 | (or 5x your normal text font size).
990 |
991 | @node demo-it-message-keybinding
992 | @unnumberedsec demo-it-message-keybinding
993 |
994 | @pindex demo-it-message-keybinding
995 | @cindex Showing what you type
996 |
997 | When demonstrating Emacs features, you may want to display the
998 | keystroke you type. Yes, you could (and probably should) use a
999 | package like @uref{http://www.foldr.org/~michaelw/emacs/mwe-log-commands.el,mwe-log-commands} by Michael Weber, but you can't
1000 | really use that sort of feature with @verb{~demo-it~}, as you'd just log a
1001 | bunch of spacebars bound to @ref{demo-it-step,demo-it-step}.
1002 |
1003 | What you really want is to display the key you @emph{wanted} to type.
1004 | For that, you'll want to end your @emph{step function} with a call to
1005 | @code{demo-it-message-keybinding}, as it will take two strings, where
1006 | the first one is the ``key'' and the other is a function or command
1007 | that it normally calls.
1008 |
1009 | For instance:
1010 | @lisp
1011 | (defun my-demo/dired-a-directory ()
1012 | "Opens a `dired' buffer on a particular directory.
1013 | This is a step function that I add to demo-it-create."
1014 | (dired (expand-file-name "~/work"))
1015 | (demo-it-message-keybinding "C-x d" "dired"))
1016 | @end lisp
1017 |
1018 | This sort of @emph{step function} would be added to @verb{~demo-it-create~} as
1019 | a simple symbol, like:
1020 | @lisp
1021 | (demo-it-create ;; :keybindings
1022 | ;; other functions and expressions
1023 | my-demo/dired-a-directory
1024 | ;; other functions and expressions
1025 | )
1026 | @end lisp
1027 |
1028 | @node demo-it-highlight-dwim
1029 | @unnumberedsec demo-it-highlight-dwim
1030 |
1031 | @cindex demo-it-highlight-dwim
1032 | @pindex Text highlighting
1033 |
1034 | Can use the @uref{https://github.com/Malabarba/fancy-narrow,fancy-narrow} package to highlight a particular
1035 | @emph{section}. If the package is not available, it simply @emph{narrows} to that
1036 | area. If called interactively, this highlights the region (if
1037 | active) or the current function.
1038 |
1039 | If the first parameter, @code{type-or-fn} is a string, this specifies
1040 | the name of a function to highlight.
1041 |
1042 | If it is a @verb{~:line~}, then the next two parameters, @code{start} and @code{end}
1043 | specifies the beginning or ending lines.
1044 |
1045 | If it is @verb{~:char~}, then @code{start} and @code{end} are exact buffer
1046 | positions, which you can determine by evaluating (@code{M-;}) the
1047 | following expression:
1048 | @lisp
1049 | (kill-new (int-to-string (point)))
1050 | @end lisp
1051 |
1052 | If @code{type-or-fn} is @code{nil} and the region is active, highlight the
1053 | region.
1054 |
1055 | If none of the following match, simply select the function the
1056 | point is currently in.
1057 |
1058 | Note: While this function checks to see if the package is
1059 | available and loaded, it does not actually do the loading (or the
1060 | installing of the package), for that, you will need to do something
1061 | like:
1062 |
1063 | @lisp
1064 | (require 'fancy-narrow)
1065 | @end lisp
1066 |
1067 | @node Customization
1068 | @appendix Customization
1069 |
1070 | @cindex Demonstration Customizations
1071 |
1072 | The following is a list of custom variables that can be set through
1073 | the standard Emacs customization feature (under the @verb{~demo-it~} group).
1074 | Note, each custom value may be overridden with a magic symbol to the
1075 | @ref{Step Types,demo-it-create} macro or with a parameter to many functions.
1076 |
1077 | @menu
1078 | * demo-it--keymap-mode-style::
1079 | * demo-it--shell-or-eshell::
1080 | * demo-it--open-windows::
1081 | * demo-it--open-windows-size::
1082 | * demo-it--text-scale::
1083 | * demo-it--start-fullscreen::
1084 | * demo-it--start-single-window::
1085 | * demo-it--presentation-hide-mode-line::
1086 | * demo-it--presentation-hide-org-markers::
1087 | * demo-it--presentation-variable-width::
1088 | * demo-it--presentation-hide-org-blocks::
1089 | * demo-it--insert-text-speed::
1090 | @end menu
1091 |
1092 | @node demo-it--keymap-mode-style
1093 | @unnumberedsec demo-it--keymap-mode-style
1094 |
1095 | @pindex demo-it--keymap-mode-style
1096 | @cindex Defaults for advancing demo
1097 |
1098 | The keymap-specific minor mode to use when a demonstration
1099 | starts. Should either be set to the symbol, @verb{~:simple-mode~} for using
1100 | the space to advance to next step and @code{q} to exit the demonstration,
1101 | or @verb{~:advanced-mode~}, where @code{F12} advances.
1102 |
1103 | Defaults to @verb{~:simple-mode~}
1104 |
1105 | This setting can be overridden by a keyword to @verb{~demo-it-create~}:
1106 | @itemize
1107 | @item
1108 | @verb{~:simple-mode~}
1109 | @item
1110 | @verb{~:advanced-mode~}
1111 | @end itemize
1112 |
1113 | @node demo-it--shell-or-eshell
1114 | @unnumberedsec demo-it--shell-or-eshell
1115 |
1116 | @pindex demo-it--shell-or-eshell
1117 |
1118 | When opening up a shell, this customization value specifies whether
1119 | it should run the @verb{~shell~} or @verb{~eshell~} command.
1120 |
1121 | Should be set to one of the following keywords:
1122 | @itemize
1123 | @item
1124 | @verb{~:shell~}
1125 | @item
1126 | @verb{~:eshell~}
1127 | @end itemize
1128 |
1129 | Defaults to @verb{~:eshell~}
1130 |
1131 | This setting can be overridden by the following keywords to
1132 | @verb{~demo-it-create~} macro:
1133 | @itemize
1134 | @item
1135 | @verb{~:use-eshell~}
1136 | @item
1137 | @verb{~:use-shell~}
1138 | @end itemize
1139 |
1140 | @node demo-it--open-windows
1141 | @unnumberedsec demo-it--open-windows
1142 |
1143 | @pindex demo-it--open-windows
1144 | @cindex Side Windows
1145 |
1146 | When opening side windows, split the frame on a particular side.
1147 | Should be set to one of the following keywords:
1148 |
1149 | @itemize
1150 | @item
1151 | @verb{~:above~}
1152 | @item
1153 | @verb{~:below~}
1154 | @item
1155 | @verb{~:left~}
1156 | @item
1157 | @verb{~:right~}
1158 | @end itemize
1159 |
1160 | The keyword, @verb{~:side~} is a synonym for @verb{~:right~}.
1161 |
1162 | Defaults to @verb{~:right~}
1163 |
1164 | This setting can be overridden by one of the following keywords
1165 | passed to @verb{~demo-it-create~}:
1166 | @itemize
1167 | @item
1168 | @verb{~:windows-on-side~}
1169 | @item
1170 | @verb{~:windows-on-right~}
1171 | @item
1172 | @verb{~:windows-on-left~}
1173 | @item
1174 | @verb{~:windows-below~}
1175 | @item
1176 | @verb{~:windows-above~}
1177 | @end itemize
1178 |
1179 | @node demo-it--open-windows-size
1180 | @unnumberedsec demo-it--open-windows-size
1181 |
1182 | @pindex demo-it--open-windows-size
1183 | @cindex Side Windows Size
1184 |
1185 | The size of side windows to open. This is the width if the window
1186 | is opened on one of the sides (@verb{~:left~} or @verb{~:right~}), or the height
1187 | if the window is opened @verb{~:above~} or @verb{~:below~}.
1188 |
1189 | Defaults to @verb{~80~}
1190 |
1191 | @node demo-it--text-scale
1192 | @unnumberedsec demo-it--text-scale
1193 |
1194 | @pindex demo-it--text-scale
1195 | @cindex Side Windows Font Size
1196 |
1197 | Sets the default text scale when opening files in side windows (see
1198 | @ref{demo-it--open-windows,demo-it--open-windows}). While this can be set to an integer, it
1199 | can also be set to one of the following keywords:
1200 | @itemize
1201 | @item
1202 | @verb{~:small~}, set to a text scale of -1
1203 | @item
1204 | @verb{~:normal~}, set to a text scale of 0
1205 | @item
1206 | @verb{~:medium~}, set to a text scale of 1
1207 | @item
1208 | @verb{~:large~}, set to a text scale of 2
1209 | @item
1210 | @verb{~:x-large~}, set to a text scale of 3
1211 | @item
1212 | @verb{~:xx-large~}, set to a text scale of 4
1213 | @item
1214 | @verb{~:huge~}, set to a text scale of 5
1215 | @end itemize
1216 |
1217 | It defaults to @verb{~:large~} (a @verb{~text-scale-set~} value of @verb{~2~}).
1218 |
1219 | This customization value can be overridden with one of the
1220 | following keywords passed to @verb{~demo-it-create~}:
1221 | @itemize
1222 | @item
1223 | @verb{~:text-small~}
1224 | @item
1225 | @verb{~:text-normal~}
1226 | @item
1227 | @verb{~:text-medium~}
1228 | @item
1229 | @verb{~:text-large~}
1230 | @item
1231 | @verb{~:text-x-large~}
1232 | @item
1233 | @verb{~:text-xx-large~}
1234 | @item
1235 | @verb{~:text-huge~}
1236 | @end itemize
1237 |
1238 | @node demo-it--start-fullscreen
1239 | @unnumberedsec demo-it--start-fullscreen
1240 |
1241 | @pindex demo-it--start-fullscreen
1242 |
1243 | A boolean setting that if set to a non-nil value, demonstrations
1244 | start with the current frame in fullscreen mode. Defaults to
1245 | @verb{~false~}.
1246 |
1247 | This customization value can be overridden with @verb{~:fullscreen~}
1248 | keyword passed to @verb{~demo-it-create~}.
1249 |
1250 | @node demo-it--start-single-window
1251 | @unnumberedsec demo-it--start-single-window
1252 |
1253 | @pindex demo-it--start-single-window
1254 |
1255 | A boolean setting that if non-nil, deletes other windows to start
1256 | the demonstration with a current buffer window being the only
1257 | displayed window. Defaults to @verb{~t~}.
1258 |
1259 | This customization value can be overridden with @verb{~:single-window~}
1260 | keyword passed to @verb{~demo-it-create~}.
1261 |
1262 | @node demo-it--presentation-hide-mode-line
1263 | @unnumberedsec demo-it--presentation-hide-mode-line
1264 |
1265 | @pindex demo-it--presentation-hide-mode-line
1266 |
1267 | If set to a nil value (@emph{false}), the mode-line is hidden for any
1268 | presentation files (this doesn't affect other files opened with the
1269 | @ref{demo-it-load-file,demo-it-load-file}). Defaults to @verb{~t~}.
1270 |
1271 | This customization value can be overridden with either of the
1272 | following keywords passed to @verb{~demo-it-create~}:
1273 | @itemize
1274 | @item
1275 | @verb{~:show-mode-line~}
1276 | @item
1277 | @verb{~:hide-mode-line~}
1278 | @end itemize
1279 |
1280 | @node demo-it--presentation-hide-org-markers
1281 | @unnumberedsec demo-it--presentation-hide-org-markers
1282 |
1283 | @pindex demo-it--presentation-hide-org-markers
1284 |
1285 | If set to a non-nil value, surrounding asterisks, underlines and
1286 | slashes that define an @code{org-mode} textual formats in a presentation
1287 | are displayed. Otherwise those characters hidden, even though the
1288 | effects of bolding and italics are still shown. Defaults to @verb{~t~}.
1289 |
1290 | This customization value can be overridden with either of the
1291 | following keywords passed to @verb{~demo-it-create~}:
1292 | @itemize
1293 | @item
1294 | @verb{~:show-org-markers~}
1295 | @item
1296 | @verb{~:hide-org-markers~}
1297 | @end itemize
1298 |
1299 | @node demo-it--presentation-variable-width
1300 | @unnumberedsec demo-it--presentation-variable-width
1301 |
1302 | @pindex demo-it--presentation-variable-width
1303 |
1304 | If set to a non-nil value, a @emph{variable-width} font is used when
1305 | displaying @code{org-mode} presentation files, otherwise the standard
1306 | fixed-width font is used. Defaults to @verb{~nil~}.
1307 |
1308 | This customization value can be overridden with either of the
1309 | following keywords passed to @verb{~demo-it-create~}:
1310 | @itemize
1311 | @item
1312 | @verb{~:variable-width~}
1313 | @item
1314 | @verb{~:fixed-width~}
1315 | @end itemize
1316 |
1317 | @node demo-it--presentation-hide-org-blocks
1318 | @unnumberedsec demo-it--presentation-hide-org-blocks
1319 |
1320 | @pindex demo-it--presentation-hide-org-blocks
1321 |
1322 | If set to a non-nil value, the start and ending lines of @code{org-mode}
1323 | blocks are shown during a presentation, otherwise these lines are
1324 | hidden, but the contents within the blocks are still shown.
1325 |
1326 | This currently only hides these lines:
1327 | @verbatim
1328 | #+BEGIN_SRC
1329 | ...
1330 | #+END_SRC
1331 | @end verbatim
1332 |
1333 | Other surrounding header values, like @verb{~#+HEADERS:~} may still be seen.
1334 |
1335 | This defaults to @verb{~t~}, however, this customization value can be
1336 | overridden with either of the following keywords passed to
1337 | @verb{~demo-it-create~}:
1338 | @itemize
1339 | @item
1340 | @verb{~:show-block-headers~}
1341 | @item
1342 | @verb{~:hide-block-headers~}
1343 | @end itemize
1344 |
1345 | @node demo-it--insert-text-speed
1346 | @unnumberedsec demo-it--insert-text-speed
1347 |
1348 | @pindex demo-it--insert-text-speed
1349 |
1350 | The functions, @ref{demo-it-run-in-shell,demo-it-run-in-shell}, @ref{demo-it-start-shell,demo-it-start-shell},
1351 | and @ref{Inserting Text,demo-it-insert}, enters the text into the shell as if a human
1352 | were typing it. This value specifies the speed at which that text
1353 | is inserted into the shell.
1354 |
1355 | This can set to one of the following keywords:
1356 | @itemize
1357 | @item
1358 | @verb{~:instant~} to insert text with no delay
1359 | @item
1360 | @verb{~:slow~}
1361 | @item
1362 | @verb{~:medium~}
1363 | @item
1364 | @verb{~:fast~}
1365 | @end itemize
1366 |
1367 | Defaults to @verb{~:medium~}.
1368 |
1369 | This can also specify a tuple of two integer values for the random
1370 | number of milliseconds between those two values to delay before
1371 | inserting each character, for instance, the @verb{~:medium~} delay has a
1372 | lower value of 30 milliseconds, and an upper delay of 500.
1373 |
1374 | @node Index
1375 | @unnumbered Index
1376 |
1377 | For those of you trying to read this online, this index is generated
1378 | and only available within Emacs. If you are reading this from within
1379 | Emacs, well-done.
1380 |
1381 | @printindex cp
1382 |
1383 | @bye
--------------------------------------------------------------------------------
/demonstration/a-demo.el:
--------------------------------------------------------------------------------
1 | ;;; A-DEMO --- Demonstration of demo-it
2 | ;;
3 | ;; Author: Howard Abrams
4 | ;; Copyright © 2016, Howard Abrams, all rights reserved.
5 | ;; Created: 27 October 2016
6 | ;;
7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 | ;;
9 | ;;; Commentary:
10 | ;;
11 | ;; A demonstration and a bit of a live tutorial of the demo-it
12 | ;; project... yeah, seriously meta.
13 | ;;
14 | ;; Keep in mind, this is a bit of an 'advanced demonstration' where
15 | ;; many of the steps are actually functions that perform multiple
16 | ;; actions. Tis also a little more fun to craft.
17 | ;;
18 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19 | ;;
20 | ;;; Code:
21 |
22 | (require 'demo-it)
23 |
24 | ;; Let's pretend our demonstration is really code, and define a few
25 | ;; variables that we'll use when referring to the source code files in
26 | ;; the 'examples' directory:
27 |
28 | (setq a-demo/example-dir (expand-file-name "../example"))
29 | (setq a-demo/python-buffer "example.py")
30 | (setq a-demo/python-source
31 | (format "%s/%s" a-demo/example-dir a-demo/python-buffer))
32 | (setq a-demo/ruby-buffer "example.rb")
33 | (setq a-demo/ruby-source
34 | (format "%s/%s" a-demo/example-dir a-demo/ruby-buffer))
35 |
36 |
37 | ;; The following is the steps to this demonstration, keep in mind that
38 | ;; many of the 'steps' are calls to functions defined below.
39 | ;;
40 | ;; Note: The keywords may override some of your default settings of
41 | ;; our customized variables.
42 |
43 | (demo-it-create :fullscreen :single-window :advanced-mode
44 | :use-shell :variable-width
45 |
46 | (demo-it-presentation "a-demo.org")
47 | demo-it-presentation-advance
48 | demo-it-presentation-advance
49 |
50 | ;; Mini demonstration ...
51 | (find-file a-demo/ruby-source)
52 | (demo-it-start-shell a-demo/example-dir)
53 | (demo-it-run-in-shell "ruby ./example.rb")
54 | "M-p"
55 | (demo-it-run-in-shell " Everyone")
56 |
57 | ;; And the rest of the demonstration
58 | demo-it-presentation-return ; Demo It Functions
59 | demo-it-presentation-advance
60 | a-demo/show-file
61 | a-demo/show-part-file
62 | a-demo/show-fancy-file
63 | a-demo/show-compare-files
64 | demo-it-presentation-return ; Running Code
65 | demo-it-presentation-advance ; Presenting
66 |
67 | demo-it-presentation-advance ; Misc
68 | (demo-it-show-image
69 | (format "%s/pdx-emacs.png" a-demo/example-dir)
70 | :below 0 18)
71 | demo-it-presentation-return-noadvance
72 |
73 | demo-it-presentation-advance ; Getting Started
74 | a-demo/show-customizations
75 | a-demo/show-info-mode
76 | demo-it-presentation-return-noadvance)
77 |
78 | ;; The following functions are a collection of multi-action steps
79 |
80 | (defun a-demo/show-file ()
81 | "An example of a multi-function 'step' where we write a number
82 | of sommands that will be executed with a single action. In this
83 | case, we first highlight a presentation phrase and then display
84 | the source code.
85 |
86 | We also make sure we have killed the source code to display, so
87 | that any settings we may have added to it go away."
88 | (demo-it-presentation-highlight-phrase "demo-it-load-file")
89 | (ignore-errors ; Make sure we load a fresh copy
90 | (kill-buffer a-demo/python-buffer))
91 | (demo-it-load-file a-demo/python-source))
92 |
93 | (defun a-demo/show-part-file ()
94 | (demo-it-presentation-return-noadvance)
95 | (ignore-errors ; File shouldn't be loaded, but just in case:
96 | (kill-buffer a-demo/python-buffer))
97 | (demo-it-presentation-highlight-phrase "demo-it-load-part-file")
98 | (demo-it-load-part-file a-demo/python-source :line 5 12))
99 |
100 | (defun a-demo/show-fancy-file ()
101 | (demo-it-presentation-return-noadvance) ; (kill-buffer-and-window)
102 | (kill-buffer a-demo/python-buffer)
103 | (demo-it-presentation-highlight-phrase "demo-it-load-fancy-file")
104 | (demo-it-load-fancy-file a-demo/python-source :line 5 12))
105 |
106 | (defun a-demo/show-compare-files ()
107 | (demo-it-presentation-return-noadvance) ; (kill-buffer-and-window)
108 | (kill-buffer a-demo/python-buffer)
109 | (demo-it-presentation-highlight-phrase "demo-it-compare-files")
110 | (demo-it-compare-files a-demo/python-source a-demo/ruby-source))
111 |
112 | (defun a-demo/show-customizations ()
113 | "Simply opens up the customize-group in side window"
114 | (demo-it-presentation-highlight-phrase "Customize the package")
115 | (split-window-horizontally)
116 | (customize-group-other-window "demo-it"))
117 |
118 | (defun a-demo/show-info-mode ()
119 | "Opens side window with the Info to demo-it"
120 | (demo-it-presentation-highlight-phrase "Read the.*$")
121 | (info "demo-it"))
122 |
123 | (defun a-demo/clean-up ()
124 | "Cleans up the files it has loaded, et. al."
125 | (interactive)
126 | (ignore-errors
127 | (kill-bufer "Shell"))
128 | (ignore-errors
129 | (kill-buffer a-demo/python-buffer))
130 | (ignore-errors
131 | (kill-buffer a-demo/ruby-buffer)))
132 |
133 | (a-demo/clean-up)
134 |
135 | (demo-it-start)
136 |
137 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
138 | ;;; a-demo.el ends here
139 |
--------------------------------------------------------------------------------
/demonstration/a-demo.org:
--------------------------------------------------------------------------------
1 | #+TITLE: Demo-It
2 | #+AUTHOR: Howard Abrams
3 | #+EMAIL: howard.abrams@gmail.com
4 | #+DATE: 2016 Oct 26
5 | #+TAGS: presentation demo-it
6 |
7 | * What and Why?
8 |
9 | We all communicate in a /demonstrable way/.
10 |
11 | End of Sprint demonstration/retrospectives often involve
12 | /showing/ what you did...
13 |
14 | - Source code viewing
15 | - Source code running
16 | - High-level explanations...
17 |
18 | * Once upon a time...
19 |
20 | A demonstration is just a /number of steps/
21 |
22 | I do everything in Emacs, so...
23 |
24 | I created some helper functions: [[http://github.com/howardabrams/demo-it][demo-it]]
25 |
26 | I now /program/ my demonstrations
27 |
28 | * Example of a Demo
29 |
30 | Each /step/ in the demo can be:
31 | 1. a function to call
32 | 2. an expression to evaluate
33 | 3. a key to press
34 |
35 | #+BEGIN_EXAMPLE
36 | (demo-it-create (find-file "example.rb") ; expression
37 | demo-it-start-shell ; function
38 | (demo-it-run-in-shell "ruby example.rb")
39 | "M-p" ; keystroke
40 | (demo-it-insert " Everyone")
41 | "RET")
42 | #+END_EXAMPLE
43 |
44 | Start with =M-x demo-it-start=
45 |
46 | * Demo It Functions
47 |
48 | Creating Emacs demonstrations is that simple.
49 |
50 | Demo-It also provides many /helper functions/:
51 |
52 | ** Showing Code
53 |
54 | Usually want to show files /next/ to the presentation:
55 |
56 | - =demo-it-load-file= :: Shows code in side window
57 |
58 | - =demo-it-load-part-file= :: Narrows to a section
59 |
60 | - =demo-it-load-fancy-file= :: Highlights part
61 |
62 | - =demo-it-compare-files= :: Shows two files
63 |
64 | ** Running Code
65 |
66 | Begin a shell (or eshell) to /psuedo-interactive/ enter commands.
67 |
68 | - =demo-it-start-shell= :: Begin a shell, optional parameters:
69 | - =directory=
70 | - =command= to run
71 | - =name= (defaults to "Shell")
72 | - =side= can be =:right= or =:below=, etc.
73 | - =size= is the font size
74 | - =width= is the size of window either, /width/ or /length/
75 |
76 | - =demo-it-run-in-shell= :: Run a command
77 |
78 | - =demo-it-show-shell= :: Switches to shell buffer
79 |
80 | ** Presenting
81 |
82 | Uses =org-tree-slide= to display an =org-mode= as a /presentation/.
83 | (Each /section/ is a /screen/)
84 |
85 | - =demo-it-presentation= :: loads a presentation and optionally goes
86 | to a particular section
87 |
88 | - =demo-it-presentation-quit= :: stops presentation but not demo
89 |
90 | - =demo-it-presentation-return= :: closes other windows and advances
91 | to next section
92 |
93 | - =demo-it-presentation-return-noadvance= :: closes other windows,
94 | but /does not/ advance to the next section
95 |
96 | - =demo-it-presentation-advance= :: goes to next section
97 |
98 | - =demo-it-presentation-highlight-phrase= :: regular expression
99 | highlights some part of the presentation
100 |
101 | ** Misc Functions
102 |
103 | - =demo-it-insert= :: /types/ into a buffer
104 |
105 | - =demo-it-highlight-dwim= :: highlights region or function
106 | (actually can be interactive)
107 |
108 | - =demo-it-show-image= :: loads file without mode-line
109 |
110 | - =demo-it-single-presentation= :: complete demo of only
111 | a presentation
112 |
113 | * Getting Started
114 |
115 | Use =package-install= from MELPA: =demo-it=
116 |
117 | - Customize the package
118 |
119 | - Read the [[info:demo-it][Info File]]
120 |
121 | - Use a [[file:~/Work/demo-it/snippets/demo-it][yasnippet template]]
122 |
123 | - Keep it simple
124 |
125 | ** Questions?
126 |
--------------------------------------------------------------------------------
/dir:
--------------------------------------------------------------------------------
1 | This is the file .../info/dir, which contains the
2 | topmost node of the Info hierarchy, called (dir)Top.
3 | The first time you invoke Info you start off looking at this node.
4 |
5 | File: dir, Node: Top This is the top of the INFO tree
6 |
7 | This (the Directory node) gives a menu of major topics.
8 | Typing "q" exits, "?" lists all Info commands, "d" returns here,
9 | "h" gives a primer for first-timers,
10 | "mEmacs" visits the Emacs manual, etc.
11 |
12 | In Emacs, you can click mouse button 2 on a menu item or cross reference
13 | to select it.
14 |
15 | * Menu:
16 |
17 | Emacs
18 | * Demo It: (demo-it). Demonstrations made and shown in Emacs.
19 |
--------------------------------------------------------------------------------
/example/error-example.el:
--------------------------------------------------------------------------------
1 | ;;; error-example.el --- Demo error example -*- lexical-binding: t; -*-
2 |
3 | ;;; Commentary:
4 |
5 | ;; This is a simple demonstration that shows off an error handling of
6 | ;; the demo-it system. Evaluating this buffer starts off the
7 | ;; presentation, and hitting SPC steps through the demonstration.
8 |
9 | ;;; Code:
10 |
11 | (setq a 0)
12 | (demo-it-start
13 | '((lambda ()
14 | (demo-it-setq a 2))
15 | (lambda ()
16 | (run-with-timer 3 nil (lambda () (message "a=%s (after the error demo)" a)))
17 | (message "a=%s" a))
18 | (lambda ()
19 | (error "an error"))
20 | (lambda ()
21 | (message "not reached"))))
22 |
23 | (provide 'error-example)
24 | ;;; error-example.el ends here
25 |
--------------------------------------------------------------------------------
/example/example-code.el:
--------------------------------------------------------------------------------
1 | ;;; difference-of-squares.el --- Difference of Squares (exercism)
2 |
3 | ;;; Commentary:
4 |
5 | ;; Interesting exercise that is quite simple to solve if you can
6 | ;; use standard mapcar with a generated list of numbers. Obviously,
7 | ;; the `number-sequence' call won't work with extremely large
8 | ;; numbers.
9 | ;;
10 | ;; But my goal, I think, was to make something parallel and
11 | ;; readable.
12 |
13 | ;;; Code:
14 |
15 | (defun square (n)
16 | "Returns the square of a number."
17 | (* n n))
18 |
19 | (defun sum (list-of-nums)
20 | "Like the + function, but takes a list."
21 | (apply '+ list-of-nums))
22 |
23 | (defun squares (list-of-nums)
24 | "Returns LIST-OF-NUMS where each element is squared."
25 | (mapcar 'square list-of-nums))
26 |
27 | (defun square-of-sums (n)
28 | "Returns the square of all sums of n with all natural numbers
29 | lower than n."
30 | (square (sum (number-sequence 1 n))))
31 |
32 | (defun sum-of-squares (n)
33 | "Sums the square of n with the square of all natural number
34 | lower than n."
35 | (sum (squares (number-sequence 1 n))))
36 |
37 | (defun difference (n)
38 | "Difference between the square of sums and the sums of squares."
39 | (- (square-of-sums n) (sum-of-squares n)))
40 | (provide 'difference-of-squares)
41 | ;;; difference-of-squares.el ends here
42 |
--------------------------------------------------------------------------------
/example/example-code.py:
--------------------------------------------------------------------------------
1 | def even_cubes(values):
2 | """Given a list of integer values, this
3 | returns the cube (power of 3) for each even
4 | number in the list of values."""
5 | return [x*x*x for x in values if x % 2 == 0]
6 |
--------------------------------------------------------------------------------
/example/example-code.rb:
--------------------------------------------------------------------------------
1 | # Given a list of integer values, this
2 | # returns the cube (power of 3) for each even
3 | # number in the list of values.
4 |
5 | def cube(x)
6 | x * x * x
7 | end
8 |
9 | def even_cubes(values)
10 | values.select(&:even?).map(&:cube)
11 | end
12 |
--------------------------------------------------------------------------------
/example/example-files.el:
--------------------------------------------------------------------------------
1 | ;;; EXAMPLE-FILES --- Demo of `demo-it' showing files
2 | ;;
3 | ;; Author: Howard Abrams
4 | ;; Copyright © 2016, Howard Abrams, all rights reserved.
5 | ;; Created: 3 October 2016
6 | ;;
7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 | ;;
9 | ;;; Commentary:
10 | ;;
11 | ;; This demonstration shows some of the ways we can load and show
12 | ;; files, like images and source code.
13 | ;;
14 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15 | ;;
16 | ;; This program is free software; you can redistribute it and/or
17 | ;; modify it under the terms of the GNU General Public License as
18 | ;; published by the Free Software Foundation; either version 3, or
19 | ;; (at your option) any later version.
20 | ;;
21 | ;; This program is distributed in the hope that it will be useful,
22 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 | ;; General Public License for more details.
25 | ;;
26 | ;; You should have received a copy of the GNU General Public License
27 | ;; along with this program; see the file COPYING. If not, write to
28 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
29 | ;; Floor, Boston, MA 02110-1301, USA.
30 | ;;
31 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
32 | ;;
33 | ;;; Code:
34 |
35 | (require 'demo-it)
36 |
37 | (ignore-errors
38 | (kill-buffer "example.py"))
39 |
40 | (defun dit-switch-and-load-two ()
41 | (demo-it-presentation-return)
42 | (demo-it-compare-files "example-code.py" "example-code.rb"))
43 |
44 | (demo-it-create :full-screen :single-window :hide-block-headers
45 | (demo-it-presentation "example-files.org")
46 | demo-it-presentation-return
47 | (demo-it-load-fancy-file "example-code.el" :line 27 36)
48 | dit-switch-and-load-two
49 | demo-it-presentation-return
50 | (demo-it-show-image "pdx-emacs.png" :below nil 16)
51 | demo-it-presentation-return)
52 |
53 | (demo-it-start)
54 |
55 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
56 | ;;; example-files.el ends here
57 |
--------------------------------------------------------------------------------
/example/example-files.org:
--------------------------------------------------------------------------------
1 | #+TITLE: Example Demonstration of Showing Files
2 | #+AUTHOR: Howard Abrams
3 | #+EMAIL: howard.abrams@gmail.com
4 | #+DATE: 2016 Oct 03
5 |
6 | * Display Source Code Inline
7 |
8 | In this demonstration, we show how to display files.
9 |
10 | You can display in-line with =org-mode= code blocks:
11 |
12 | #+BEGIN_SRC emacs-lisp
13 | (defun response-for (msg)
14 | "Return message based on the input string, MSG.
15 | The responses are based on `Bob' Exercism project."
16 | (let ((case-fold-search nil) ;; Case matters!
17 | ;; Let's operate on a simpler string:
18 | (ops-msg (string-trim (replace-regexp-in-string
19 | "[0-9,.%^@#$*()]" "" msg))))
20 | (cond
21 | ((string-match "^$" msg) "Fine. Be that way!")
22 | ((string-match "^[A-Z][A-Z' ?!]+$" ops-msg) "Whoa, chill out!")
23 | ((string-match "\\?$" ops-msg) "Sure.")
24 | (t "Whatever."))))
25 | #+END_SRC
26 |
27 | * Display Source in Separate Window
28 |
29 | You can display source in its own buffer window.
30 |
31 | This shows the complete source code file,
32 | but with a sub-section highlighted.
33 |
34 | If you have [[https://github.com/Malabarba/fancy-narrow][fancy-narrow]] package installed,
35 | the highlighted code is colored, and the
36 | rest of the file is gray.
37 |
38 | If not, we simply narrow to the region.
39 |
40 | * Showing Code Comparisons
41 |
42 | To demonstrate the difference between two files,
43 | use =demo-it-compare-files= where each file
44 | is placed next to each other.
45 |
46 | This function allows the code to be show on
47 | the =:side= or =:below=.
48 |
49 | * Loading Images
50 |
51 | Since presentations like this one remove
52 | Emacs decorations, images can be displayed
53 | the same way.
54 |
55 | * Better Control
56 |
57 | When creating a demonstration where you
58 | plan to show code, choose =:advanced-mode=
59 |
60 | While this means you use =F12= to advance,
61 | you can use any other keys to show off
62 | your source code.
63 |
--------------------------------------------------------------------------------
/example/example-shell.el:
--------------------------------------------------------------------------------
1 | ;;; EXAMPLE-SHELL --- Demonstrates Shell Features
2 | ;;
3 | ;; Author: Howard Abrams
4 | ;; Copyright © 2016, Howard Abrams, all rights reserved.
5 | ;; Created: 1 October 2016
6 | ;;
7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 | ;;
9 | ;;; Commentary:
10 | ;;
11 | ;; Demonstrates the features of running commands in a shell.
12 | ;;
13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14 | ;;
15 | ;; This program is free software; you can redistribute it and/or
16 | ;; modify it under the terms of the GNU General Public License as
17 | ;; published by the Free Software Foundation; either version 3, or
18 | ;; (at your option) any later version.
19 | ;;
20 | ;; This program is distributed in the hope that it will be useful,
21 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 | ;; General Public License for more details.
24 | ;;
25 | ;; You should have received a copy of the GNU General Public License
26 | ;; along with this program; see the file COPYING. If not, write to
27 | ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
28 | ;; Floor, Boston, MA 02110-1301, USA.
29 | ;;
30 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
31 | ;;
32 | ;;; Code:
33 |
34 | (require 'demo-it)
35 |
36 | (demo-it-create :use-eshell ;; Change this to :use-shell
37 | :single-window
38 | :windows-on-right
39 | :insert-fast
40 | :text-large
41 |
42 | (demo-it-presentation "example-shell.org")
43 |
44 | ;; This step opens up a shell window:
45 | (demo-it-start-shell)
46 |
47 | ;; Press 'Space' to run each of these commands:
48 | (demo-it-run-in-shell "pwd")
49 | (demo-it-run-in-shell "hostname" nil :slow)
50 |
51 | ;; Closes the window and goes to next presentation section
52 | (demo-it-presentation-return)
53 |
54 | ;; Passing nil for first parameter uses current dir
55 | ;; Connect to default shell if third param is nil
56 | (demo-it-start-shell nil "ls" nil :below :large 10))
57 |
58 | (demo-it-start)
59 |
60 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
61 | ;;; example-shell.el ends here
62 |
--------------------------------------------------------------------------------
/example/example-shell.org:
--------------------------------------------------------------------------------
1 | #+TITLE: Shell Demonstration Example
2 | #+AUTHOR: Howard Abrams
3 | #+EMAIL: howard.abrams@gmail.com
4 | #+DATE: 2016 Oct 01
5 |
6 | * Shell Demonstration Example
7 |
8 | Opening up a shell window (or =eshell=) and running commands is easy:
9 |
10 | #+BEGIN_SRC elisp
11 | (demo-it-start-shell)
12 | #+END_SRC
13 |
14 | Press the ~Space~ to advance to each step which runs various commands
15 | at different /speeds/ specified to =demo-it-create=:
16 |
17 | - :insert-quickly
18 | - :insert-fast
19 | - :insert-medium
20 | - :insert-slow
21 |
22 | All demonstrations can behave the same with customization.
23 |
24 | * Window Positions
25 |
26 | Depending on your monitor, you can start your shell in other
27 | configurations... like :below
28 |
--------------------------------------------------------------------------------
/example/example-title.org:
--------------------------------------------------------------------------------
1 |
2 |
3 | * Demo-It
4 |
5 | A simple demonstration of making demonstrations
6 | ...within Emacs
7 |
--------------------------------------------------------------------------------
/example/example.el:
--------------------------------------------------------------------------------
1 | ;;; EXAMPLE --- Demonstrate a demo-it demonstration
2 |
3 | ;;; Commentary:
4 |
5 | ;; This is a simple demonstration that shows off a few of the
6 | ;; functions and options of the demo-it system. Evaluating this
7 | ;; buffer starts off the presentation, and hitting SPC steps through
8 | ;; the demonstration.
9 |
10 | ;;; Code:
11 |
12 | (require 'demo-it)
13 |
14 | ;; ----------------------------------------------------------------------
15 | ;; Create some demonstration helper functions...
16 |
17 | (defun dit-load-source-code ()
18 | "Load some source code in a side window."
19 | (demo-it-presentation-advance)
20 | (demo-it-load-fancy-file "example.py" :line 5 12 :side))
21 |
22 | (defun dit-run-code ()
23 | "Execute our source code in an Eshell buffer."
24 | ;; Close other windows and advance the presentation:
25 | (demo-it-presentation-return)
26 | (demo-it-start-shell)
27 | (demo-it-run-in-shell "python example.py Snoopy"))
28 |
29 | ;; ----------------------------------------------------------------------
30 | ;; Demonstration creation and the ordering of steps...
31 |
32 | (demo-it-create :single-window :insert-fast
33 | (demo-it-title-screen "example-title.org")
34 | (demo-it-presentation "example.org")
35 | dit-load-source-code ;; Step 3
36 | dit-run-code) ;; Step 4
37 |
38 | ;; ----------------------------------------------------------------------
39 | ;; Start the presentation whenever this script is evaluated. Good idea?
40 |
41 | (demo-it-start)
42 |
43 | ;;; example.el ends here
44 |
--------------------------------------------------------------------------------
/example/example.org:
--------------------------------------------------------------------------------
1 | #+TITLE: An Example of Demo-It
2 | #+AUTHOR: Howard Abrams
3 | #+DATE: 2014 Jul 29
4 |
5 | This document is a simple presentation that can show off the
6 | many...well, the few features of the =demo-it= project.
7 |
8 | * Introduction
9 |
10 | Demo-It is a very simple project that allows you to execute
11 | pre-defined steps within Emacs.
12 |
13 | I use it along with org-tree-slide in order to begin with a
14 | nifty-swell presentation explaining the source code I've written.
15 |
16 | * Source Code Highlighting
17 |
18 | We can show source code using Emacs'
19 | built in capabilities, including connecting
20 | to a REPL.
21 |
22 | Of course, this depends on what source
23 | code and how well you have integrated
24 | that language with Emacs. ;-)
25 |
26 | * Code Demonstration
27 |
28 | At this point, we can assume that we
29 | have some sort of script that would be
30 | great to actually run in a shell...
31 |
--------------------------------------------------------------------------------
/example/example.py:
--------------------------------------------------------------------------------
1 | # This Python program is a simple example.
2 | import sys
3 |
4 |
5 | def greeting(name):
6 | """Prints a greeting when given the
7 | optional name variable."""
8 | if name:
9 | print "Hello, %s" % name
10 | else:
11 | print "Hello World"
12 |
13 |
14 | if __name__ == "__main__":
15 | if len(sys.argv) > 0:
16 | name = sys.argv[1]
17 | else:
18 | name = None
19 |
20 | greeting(name)
21 |
--------------------------------------------------------------------------------
/example/example.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | # Simplistic example of a Ruby function demonstrating that
4 | # quintessential program, the hello world:
5 |
6 | def greeting(name)
7 | if name
8 | print "Hello, #{name}!\n"
9 | else
10 | print "Hello World.\n"
11 | end
12 | end
13 |
14 | greeting(ARGV.first)
15 |
--------------------------------------------------------------------------------
/example/kbd-example.el:
--------------------------------------------------------------------------------
1 | ;;; kbd-example.el --- Demonstration of step by keyboard macro -*- lexical-binding: t; -*-
2 |
3 | ;;; Commentary:
4 |
5 | ;; This is a simple demonstration that shows off keyboard macro
6 | ;; of the demo-it system. Evaluating this buffer starts off the
7 | ;; presentation, and hitting SPC steps through the demonstration.
8 |
9 | ;;; Code:
10 |
11 | (demo-it-start
12 | '((lambda () (message "Show example.el"))
13 | "C-x C-f example.el "
14 | "M-<"
15 | "M->"))
16 |
17 | (provide 'kbd-example)
18 | ;;; kbd-example.el ends here
19 |
--------------------------------------------------------------------------------
/example/pdx-emacs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/howardabrams/demo-it/e399fd7ceb73caeae7cb50b247359bafcaee2a3f/example/pdx-emacs.png
--------------------------------------------------------------------------------
/example/setq-example.el:
--------------------------------------------------------------------------------
1 | ;;; setq-example.el --- Demonstration of demo-it-setq -*- lexical-binding: t; -*-
2 |
3 | ;;; Commentary:
4 |
5 | ;; This is a simple demonstration that shows off temporary variables
6 | ;; of the demo-it system. Evaluating this buffer starts off the
7 | ;; presentation, and hitting SPC steps through the demonstration.
8 |
9 | ;;; Code:
10 |
11 | (demo-it-start
12 | '((lambda ()
13 | (setq a 1)
14 | (makunbound 'v)
15 | (message "a=%d v=%s boundp=%s" a (bound-and-true-p v) (boundp 'v)))
16 | (lambda ()
17 | (demo-it-setq a 10 v 0)
18 | (message "a=%d v=%s boundp=%s" a (bound-and-true-p v) (boundp 'v))
19 | (run-at-time 2 nil (lambda () (message "After demo: a=%d v=%s boundp=%s" a (bound-and-true-p v) (boundp 'v)))))))
20 |
21 | (provide 'setq-example)
22 | ;;; setq-example.el ends here
23 |
--------------------------------------------------------------------------------
/snippets/demo-it:
--------------------------------------------------------------------------------
1 | # -*- mode: snippet; require-final-newline: nil -*-
2 | # key: Sample Functions for demo-it
3 | # name: demoit
4 | # contributor: Howard Abrams
5 | # --
6 | ;;; ${1:`(file-name-sans-extension (file-name-base (buffer-file-name)))`} --- ${2:Simple Summary}
7 |
8 | ;;; Commentary:
9 |
10 | ;; $3
11 |
12 | ;;; Code:
13 |
14 | (load-library "demo-it")
15 |
16 | ;; ----------------------------------------------------------------------
17 | ;; Create functions for complicated, but individual steps
18 |
19 | (defun ${4:my-demo}-step-function ()
20 | "Display $1.org (an 'org-mode' file) as a presentation."
21 | (demo-it-presentation "$1.org")
22 | (demo-it-presentation-highlight-phrase "Step 1"))
23 |
24 | ;; ----------------------------------------------------------------------
25 | ;; Demonstration Order and configuration
26 |
27 | (demo-it-create :fullscreen :single-window
28 | $0
29 | (demo-it-title-screen "$1-title.org")
30 | $4-step-function)
31 |
32 | ;; ----------------------------------------------------------------------
33 | ;; Start the presentation whenever this script is evaluated. Good idea?
34 |
35 | (demo-it-start)
36 |
37 | ;;; $1.el ends here
38 |
--------------------------------------------------------------------------------