Add executable code examples to you reveal.js presentation.
Tabbing between Keynote and a terminal looks terrible and it is impossible to type with people watching anyway.
Looks like this:
IMPORTANT NOTE: This, um, exposes a URL that can be used to execute user-provided commands on your machine. There are a few measures taken to restrict this to its intended use, but it's almost certainly still exploitable somehow. Be careful!
The plugin requires that your presentation be served by Express. A minimal version looks like this:
const express = require('express');
const revealRunInTerminal = require('reveal-run-in-terminal');
let app = express();
app.use(revealRunInTerminal());
app.use(express.static('node_modules/reveal.js'));
app.listen(5000);
Options for revealRunInTerminal
:
publicPath
(default:'.'
): Directory to serve files and load executed code from.commandRegex
(default:/\S*/
): Regex that executable must match. This is a safety measure to make sure you don't run anything you didn't intend to.allowRemote
(default:false
): Allow command-execution requests from non-localhost sources. Probably don't ever do this.log
(default:false
): Whether to log executed commands (along with PID and exit code) to the server console.
The server handles exposing the plugin's client-side JS and CSS dependencies. It's up to you make sure reveal.js files are exposed (the above is a good approach). You can keep your own source files (including reveal.js ones if you're vendoring them) in the public path reveal-run-in-terminal uses, but you do not have to.
<link rel="stylesheet" href="plugin/reveal-run-in-terminal.css" />
You should use reveal.js's plugin system, like this:
Reveal.initialize({
// some options
dependencies: [
{
src: 'plugin/reveal-run-in-terminal.js',
callback: function() {
RunInTerminal.init();
},
async: true,
},
// more plugins
],
});
Nothing will happen until RunInTerminal#init
is called. You should also include the highlight plugin if you want code to be syntax highlighted.
RunInTerminal#init
options:
defaultBin
: Default value for thedata-run-in-terminal-bin
attribute of individual slides (the executable used to run each code example).
`
<section
data-run-in-terminal="code/some-great-example.js"
data-run-in-terminal-bin="node"
>
<h2>Here Is A Great Example</h2>
</section>
The section
elements for reveal-run-in-terminal slides use these attributes:
data-run-in-terminal
(required): Path to the code to display and run.data-run-in-terminal-bin
(required unlessdefaultBin
was passed toTerminalSlides#init
): The executable used to run the code example.data-run-in-terminal-args
: Additional space-separated arguments to pass to the command to be run. Use single quotes for values including spaces.
The slide above will initially display code from {publicPath}/code/some-great-example.js
and an empty simulated terminal prompt. Two fragments are added by the plugin:
- The first displays the command that will be run (
node code/some-great-example.js
in this case). - The second adds the
stdout
andstderr
from that command as executed by the server.
So, the process goes:
- Advance to slide (empty prompt)
- Advance to command fragment (prompt with command)
- Advance to command execution (output incrementally added after command)
- Advance to next silde
npm start
runs it on port 5000.
npm run build
browserifies it.
/reveal-run-in-terminal
is implemented as aGET
request in order to use theEventSource
API on the client to stream process output. Yes, socket.io something something but this avoids additional dependencies and is pretty simple.- It would be cool to do this for Node specifically using the
vm
module instead of spawning a process but I couldn't figure out how to capturestderr
/stdout
/process termination in a way that reliably mimicked what running a script would do. - Maybe it would be better to use
#!
syntax at the top of files to specify how to run them instead of requiring that option per-slide? I didn't want to require the code files to be executable or have to manipulate them before putting them on the page.
- Record command output so that live presentations can be given with static assets.
- Colorize
stdout
vsstderr
. - Display process exit code somehow.
- Better integration with other plugins (is it possible to use this and server notes? multiplexing?).
- Source highlighting.
- Source diffing.