@stdlib/repl-presentation

0.2.1 • Public • Published
About stdlib...

We believe in a future in which the web is a preferred environment for numerical computation. To help realize this future, we've built stdlib. stdlib is a standard library, with an emphasis on numerical and scientific computation, written in JavaScript (and C) for execution in browsers and in Node.js.

The library is fully decomposable, being architected in such a way that you can swap out and mix and match APIs and functionality to cater to your exact preferences and use cases.

When you use stdlib, you can be absolutely certain that you are using the most thorough, rigorous, well-written, studied, documented, tested, measured, and high-quality code out there.

To join us in bringing numerical computing to the web, get started by checking us out on GitHub, and please consider financially supporting stdlib. We greatly appreciate your continued support!

REPL Presentation

NPM version

Run a REPL presentation.

This package allows building presentations using only a REPL environment.

Features

  • Easy to write and minimal slide markup.
  • Built-in navigation commands to move and jump between slides.
  • Slide fragments (i.e., incremental slides).
  • Progress display.
  • Text alignment (left, right, centered, flush) and horizontal rules.
  • ANSI colors and styling.
  • Emoji support.
  • Executable slide code.
  • Programmatic interface.
  • Command-line interface (CLI).
  • Watch mode with automatic reload (aka, "hot reloading").

Authoring

A REPL presentation source file is a text file which includes minimal markup for delineating slides, slide fragments, speaker notes, code, text alignment, and styling.

Slides

To delineate a new slide, use three dashes ---.


This is the first slide.

---

This is the second slide.

Leading and trailing whitespace between slides is removed.

Slide Fragments

To delineate a slide fragment (i.e., incremental slide), use two dashes --.


This is an incremental slide.

--

...which includes some more text

--

...and even more text

--

...and even more text

Leading and trailing whitespace between slide fragments is removed. To manually space slide fragments, use the ANSI escape cope \s.


List items are separated by blank lines...
\s

--

• Item 1.
\s

--

• Item 2.
\s

--

• Item 3.

--

\s
...by using the ANSI escape code to reset styling.

Code Blocks

To delineate slide code, use three backticks.


This is a slide with code.

```
var x = 3.14;
```

By default, code blocks are assumed to be JavaScript. To explicitly specify the code block language, include the language identifier after the first set of backticks.


This is a slide with code.

```javascript
var x = 3.14;
```

Only JavaScript code blocks are runnable. To run JavaScript code on the current slide, invoke the presentation command runSlide() at the REPL prompt.

Speaker Notes

To delineate speaker notes, use three tildes ~~~ after a slide's content and before delineating the next slide.


This is a slide

~~~

...with speaker notes.

Text Alignment

To align text, use the following markup at the start of a content line to align

Character Sequence Description
| Centered
< Left-aligned
<< Left-flushed
> Right-aligned
>> Right-flushed

For example,


| This text is center-aligned.

---

< This text is left-aligned.

---

<< This text is left-flushed.

---

> This text is right-aligned.

---

>> This text is right-flushed.

The space separating the alignment character sequence from the text is required.

ANSI Colors and Styling

To apply ANSI colors and styling, use the following markup

Escape Code Description
\x Foreground color
\X Background color
\* Bold
\_ Underlined
\! Reverse colors
\s Reset to normal

For example,


\rThis text is colored red.\s

---

\gThis text is colored green.\s

---

\YThe text background is yellow.\s

---

\bThis text is bold.\s

---

\_This text is underlined.\s

---

\!This text has inverted colors.\s

---

\_\*This text is both underlined and bold.\s\s

Emoji

To include an emoji, insert the relevant emoji code. For example,


:books: :grinning: :+1: :man: :woman:

Note, however, that emoji support is limited to emoji which are two columns wide. Accordingly, not all emoji are supported.

Horizontal Rules

To insert horizontal rules, use the following markup at the start of a line

Character Sequence Description
/ Content width
// Full screen

For example, to insert a horizontal rule spanning the content width


Rule length matches the length of this sentence.

/

More content below.

To insert a horizontal rule spanning the slide width


Rule spans the slide width.

//

More content below.

The default rule character is -. To specify an alternative rule character sequence, provide a pattern. For example,


/=+

//=+

Custom patterns can include Unicode and ANSI colors. For example,


/\r=\s\**\s\r=\b=\s\**\s\b=

//\r=\s\**\s\r=\b=\s\**\s\b=

And lastly, custom patterns can include emoji. For example,


/ :grinning: :+1:

// :grinning: :+1:


Installation

npm install @stdlib/repl-presentation

Usage

var Presentation = require( '@stdlib/repl-presentation' );

Presentation( [text,] repl[, options] )

Returns a REPL presentation instance for running a presentation in a provided repl.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Close the REPL:
repl.close();

The function accepts the following options:

  • borderTop: top border character sequence. Default: '*'.
  • borderBottom: bottom border character sequence. Default: '*'.
  • borderLeft: left border character sequence. Default: '* '.
  • borderRight: right border character sequence. Default: ' *'.
  • counter: slide counter. Can either be true, false, or 'progress'. Default: false.
  • width: presentation width. If null, the presentation width is either computed based on the screen size (if a REPL output stream is TTY) or set to 80 characters. Default: null.
  • height: presentation height. If null, the presentation height is either computed based on the screen size (if a REPL output stream is TTY) or set to 25 rows. Default: null.
  • workspace: REPL workspace name. A presentation instance adds presentation commands to the specified workspace, thus allowing presentation navigation and interaction. Default: 'presentation'.
  • load: file path specifying a presentation file to load. If a presentation text is provided, this option is ignored.
  • autoClear: boolean indicating whether to automatically clear the screen before writing a rendered slide to the REPL. Default: true.
  • loop: boolean indicating whether to "loop" a presentation (i.e., proceed to the first slide after the last slide and have the last slide precede the first slide). Default: false.

To initialize a presentation upon instantiating a Presentation instance, either provide a string as the first argument containing the presentation text to render or set the load option to specify a presentation file to load.

Presentation.prototype.currentSlide

Returns the current presentation slide index.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Return the current presentation slide index:
var idx = pres.currentSlide;

// ...

// Close the REPL:
repl.close();

Note: the returned index is the nominal (i.e., one-based) slide index.

Presentation.prototype.end()

Jumps to the last fragment of the last slide.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Jump to the last fragment of the last slide:
pres.end();

// ...

// Close the REPL:
repl.close();

Presentation.prototype.first()

Jumps to the first slide.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Jump to the first slide:
pres.first();

// ...

// Close the REPL:
repl.close();

Presentation.prototype.firstFragment()

Jumps to the first fragment of the current slide.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Jump to the first fragment of the current slide:
pres.firstFragment();

// ...

// Close the REPL:
repl.close();

Presentation.prototype.height

Returns the presentation height.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// Return the presentation height:
var height = pres.height;

// Close the REPL:
repl.close();

Presentation.prototype.jump( n )

Jumps a specified number of slides.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Jump to the third previous slide:
pres.jump( -3 );

// ...

// Jump to the slide after the next:
pres.jump( 2 );

// ...

// Close the REPL:
repl.close();

Presentation.prototype.jumpTo( n )

Jumps to a specified slide, where n is the nominal (i.e., one-based) slide number.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Jump to the fourth slide:
pres.jumpTo( 4 );

// ...

// Close the REPL:
repl.close();

Presentation.prototype.last()

Jumps to the last slide.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Jump to the last slide:
pres.last();

// ...

// Close the REPL:
repl.close();

Presentation.prototype.lastFragment()

Jumps to the last fragment of the current slide.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Jump to the last fragment of the current slide:
pres.lastFragment();

// ...

// Close the REPL:
repl.close();

Presentation.prototype.length

Returns the presentation length (i.e., number of slides).

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Return the presentation length:
var len = pres.length;

// ...

// Close the REPL:
repl.close();

Presentation.prototype.load( file )

Loads a presentation from a file.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Load a presentation from a file:
try {
    pres.load( './path/to/presentation.txt' );
} catch ( error ) {
    console.error( error.message );
}

// ...

// Close the REPL:
repl.close();

Note: relative file paths are resolved relative to the current working directory.

Presentation.prototype.next()

Moves the presentation to the next slide or slide fragment.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Move to the next slide or slide fragment:
pres.next();

// ...

// Close the REPL:
repl.close();

Presentation.prototype.nextSlide()

Moves the presentation to the next slide.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Move to the next slide:
pres.nextSlide();

// ...

// Close the REPL:
repl.close();

Presentation.prototype.prev()

Moves the presentation to the previous slide or slide fragment.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Move to the previous slide or slide fragment:
pres.prev();

// ...

// Close the REPL:
repl.close();

Presentation.prototype.prevSlide()

Moves the presentation to the previous slide.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Move to the previous slide:
pres.prevSlide();

// ...

// Close the REPL:
repl.close();

Presentation.prototype.reload()

Reloads a presentation.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Reload a presentation:
try {
    pres.reload();
} catch ( error ) {
    console.error( error.message );
}

// ...

// Close the REPL:
repl.close();

Presentation.prototype.render()

Renders the current presentation slide.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Render the current presentation slide:
var slide = pres.render();
if ( slide === null ) {
    console.log( 'Unable to render slide.' );
}

// ...

// Close the REPL:
repl.close();

Presentation.prototype.run( done )

Runs any code on the current presentation slide.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Run any code on the current slide:
pres.run( done );

function done() {
    // Close the REPL:
    repl.close();
}

Presentation.prototype.show()

Shows a presentation slide (i.e., writes a rendered slide to the presentation REPL)

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Show the current presentation slide:
pres.show();

// ...

// Close the REPL:
repl.close();

Presentation.prototype.slideHeight

Returns the presentation content height.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// Return the presentation slide content height:
var h = pres.slideHeight;

// Close the REPL:
repl.close();

Presentation.prototype.slideWidth

Returns the presentation content width.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// Return the presentation slide content width:
var h = pres.slideWidth;

// Close the REPL:
repl.close();

Presentation.prototype.unwatch( [error] )

Stops watching a presentation file for changes.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Watch a presentation source file:
try {
    pres.watch();
} catch ( error ) {
    console.error( error.message );
}

// ...

// Stop watching a presentation source file:
pres.unwatch();

// ...

// Close the REPL:
repl.close();

Presentation.prototype.watch()

Watches a presentation source file for changes.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// ...

// Watch a presentation source file:
try {
    pres.watch();
} catch ( error ) {
    console.error( error.message );
}

// ...

// Close the REPL:
repl.close();

Note: the method does not track source file "renames". If the source presentation file is renamed, watching stops.

Presentation.prototype.width

Returns the presentation width.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );

// Return the presentation width:
var width = pres.width;

// Close the REPL:
repl.close();

Commands

REPL instances running a REPL presentation support the following commands within the presentation workspace...

blank()

Renders a blank screen.

In [1]: blank();

currentSlide

Returns the nominal current presentation slide index (one-based).

In [1]: var idx = currentSlide;

end()

Jumps to the last fragment of the last presentation slide.

In [1]: end();

first()

Jumps to the first presentation slide.

In [1]: first();

firstFragment()

Jumps to the first fragment of the current presentation slide.

In [1]: firstFragment();

jump( n )

Jumps a specified number of slides.

In [1]: jump( 2 ); // jump two slides forward

In [2]: jump( -2 ); // jump two slide backward

jumpTo( n )

Jumps to a specified presentation slide, where n is the nominal presentation slide index (one-based).

In [1]: jumpTo( 2 ); // jump to the second slide

last()

Jumps to the first fragment of the last presentation slide.

In [1]: last();

lastFragment()

Jumps to the last fragment of the current presentation slide.

In [1]: lastFragment();

loadPresentation( file )

Loads a presentation from a file.

In [1]: loadPresentation( './path/to/presentation.txt' );

Note: relative file paths are resolved relative to the current working directory.

next()

Moves to the next presentation slide or slide fragment.

In [1]: next();

nextSlide()

Moves to the next presentation slide.

In [1]: nextSlide();

numSlides

Returns the number of presentation slides.

In [1]: var len = numSlides;

pres()

Prints presentation help text and shortcuts.

In [1]: pres();

prev()

Moves to the previous presentation slide or slide fragment.

In [1]: prev();

prevSlide()

Moves to the previous presentation slide.

In [1]: prevSlide();

redraw()

Redraws the current presentation slide.

In [1]: redraw();

reloadPresentation()

Reloads a presentation.

In [1]: reloadPresentation();

renderSlide()

Renders the current presentation slide.

In [1]: var str = renderSlide();

runSlide()

Runs slide code.

In [1]: runSlide();

unwatch( [error] )

Stops watching a source presentation file for changes.

In [1]: unwatch();

watch()

Watches a source presentation file for changes.

In [1]: watch();

Note: "Renaming" a source file is not tracked. If a source presentation file is renamed, watching stops.


Shortcuts

Command Shortcut Description
blank b Render a blank screen.
end L Jump to the last fragment of the last slide.
first f Jump to the first slide.
firstFragment ff Jump to the first slide fragment.
jump g Jump a specified number of slides.
jumpTo j Jump to a specified slide.
last l Jump to the first fragment of the last slide.
lastFragment lf Jump to the last slide fragment.
loadPresentation lp Load a presentation.
next n Move to the next slide or slide fragment.
nextSlide N Move to the next slide.
pres h Print presentation help text.
prev p Move to the previous slide or slide fragment.
prevSlide P Move to the previous slide.
redraw rd Redraw the current slide.
reloadPresentation rlp Reload the current presentation.
runSlide r Run slide code.
unwatch uw Stop watching a source file for changes.
watch w Watch a source file for changes.

Events

A REPL presentation emits the following events...

'watch'

This event is emitted upon watching a source presentation file.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

function onWatch() {
    console.log( 'Watching a source file.' );
}

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );
pres.on( 'watch', onWatch );

// ...

// Close the REPL:
repl.close();

'change'

When watching a source presentation file, this event is emitted whenever a source presentation file changes.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

function onChange() {
    console.log( 'Source file changed.' );
}

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );
pres.on( 'change', onChange );

// ...

// Close the REPL:
repl.close();

'unwatch'

This event is emitted upon no longer watching a source presentation file.

var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );

function onUnwatch( error ) {
    console.log( 'No longer watching a source file.' );
    if ( error ) {
        console.error( error.message );
    }
    // Include logic to, e.g., restart watching a source presentation file...
}

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});

// Create a new REPL presentation:
var pres = new Presentation( repl );
pres.on( 'unwatch', onUnwatch );

// ...

// Close the REPL:
repl.close();

Notes

  • Multiple presentations can be run simultaneously within the same REPL environment. To do so, assign each presentation instance to a unique workspace.

Examples

var join = require( 'path' ).join;
var debug = require( '@stdlib/streams-node-debug-sink' );
var REPL = require( '@stdlib/repl' );
var Presentation = require( '@stdlib/repl-presentation' );

function onExit() {
    console.log( '' );
    console.log( 'REPL closed.' );
}

// Create a new REPL:
var repl = new REPL({
    'output': debug()
});
repl.on( 'exit', onExit );

// Create a new REPL presentation:
var pres = new Presentation( repl, {
    'counter': 'progress'
});

// Load a presentation file:
pres.load( join( __dirname, 'examples', 'presentation.txt' ) );

// Get the number of slides:
var len = pres.length;

// Render the first slide:
pres.show();

// Automate the slide show:
setTimeout( next, 100 );

function next() {
    // If we are finished with the slide show, close the REPL...
    if ( pres.currentSlide === len ) {
        return repl.close();
    }
    pres.next().show();
    setTimeout( next, 100 );
}

See Also


Notice

This package is part of stdlib, a standard library for JavaScript and Node.js, with an emphasis on numerical and scientific computing. The library provides a collection of robust, high performance libraries for mathematics, statistics, streams, utilities, and more.

For more information on the project, filing bug reports and feature requests, and guidance on how to develop stdlib, see the main project repository.

Community

Chat


License

See LICENSE.

Copyright

Copyright © 2016-2024. The Stdlib Authors.

Package Sidebar

Install

npm i @stdlib/repl-presentation

Homepage

stdlib.io

Weekly Downloads

5

Version

0.2.1

License

Apache-2.0

Unpacked Size

381 kB

Total Files

84

Last publish

Collaborators

  • stdlib-bot
  • kgryte
  • planeshifter
  • rreusser