IMPORTANT NOTE: After discussion with Stanley Nguyen, it appears it maintains a more davanced/usable fork of reveal-run-in-terminal. As a consequence, instead of maintaining two forks of that very interesting plugin, it is way better to let the best implementor become the maintainer. In other words, this repository is archived and the official version of reveal-run-in-terminal is available at https://github.com/stanleynguyen/reveal-run-in-terminal
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!
We provide servers for "some" languages (the ones for which the plugin developers have some experience with). If your server-side language of choice isn't listed here ... see "Implementing a server".
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.
You can also see an example usage in demo/app.js
<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.
A server for revealjs-run-in-terminal should implement a classical http file server and the following endpoint
GET reveal-run-in-terminal?bin={binary}&src={src-path}&args={args}
Where
binary
is a name of a binary available on$PATH
src
is an executable script forbinary
args
are a list of space-separated arguments
The demo
folder contains a few examples that can be used to validate your implementation.
The requests used are
GET /reveal-run-in-terminal?bin=node&src=code%2Fnode-example.js
GET /reveal-run-in-terminal?bin=node&src=code%2Fnode-error-example.js
GET /reveal-run-in-terminal?bin=ruby&src=code%2Fruby-argv-example.rb&args=the%20quick%20%27brown%20fox%27
npm run build
browserifies it.
Just run [smooth-release](https://github.com/buildo/smooth-release)
which performs "clean" release in a way compatible with my maven habitus.
/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.