[ANN] Slipshow!

Dear reader,

I am absolutely thrilled to announce the release of slipshow 0.1.1 on this forum! As you have all noticed, that is a huge leap from the previous version, 0.0.34. (What can have motivated this?)

Recall that Slipshow is a tool to prepare presentation support, that is based on scripted scrolling and zooming (instead of slides).

I’ll use this single thread to announce all future versions of slipshow, to avoid polluting the global namespace, as it makes sense to keep this forum centered around OCaml, and this tool has nothing to do with OCaml …

… well, almost nothing to do with OCaml, since in this version the engine has been fully rewritten in OCaml (hence the bold new version) and works much better! Making it a full OCaml project. Thanks, OCaml developers of open source libraries and language!

To upgrade it, you can do:

$ opam update
$ opam upgrade slipshow

What? Some people don’t have it installed already? For those, it will be:

$ opam update
$ opam install slipshow

Now comes the moment you are all waiting for: the list of new features!

TLDR:

  • Engine rewritten in OCaml
    • Fewer bugs when navigating back
    • Stronger foundation (eg, for subslips)
    • Custom scripts requires minor adjustments
    • Breaking change in subslip HTML
  • Drawing now in SVG
    • No more zoom issues
    • Erasing works “per-stroke”
  • Revamped table of content
    • Now based on title structure rather than subslips
  • New --markdown-output flag for converting to GFM
  • Parser bugfixes
  • License change: Now GPLv3 (previously MIT)
  • npm distribution discontinued.
  • Special thanks to NLNet for their sponsorship!

Dear readers,

I am thrilled to announce the 0.1 release of Slipshow, the slip-based presentation tool!

This is a major minor release. While versions 0.0.1 to 0.0.33 have served well to experiment, this release marks a fresh start, aimed at being a solid foundation for a project with a clear direction. A huge thank you to NLNet for sponsoring this milestone!

So, what is new? Quite a lot, the main change being that the engine has been fully rewritten.

The engine

Started as a single file javascript project, the old engine evolved presentation by presentation – leading to numerous bugs, maintenance challenge or extensibility issue. (In other word, I did all I could not to touch it despite all the bugs)

This release introduces a complete rewrite of the engine in OCaml, with new design choices that improve reliability and expandability. Let’s go over the key benefits and breaking changes.

Navigating Forward… and Backward

One of the greatest weakness of the old engine was handling backward navigation. Since it started as a simple “script scheduler”, going back wasn’t straightforward. The workaround involved taking a snapshot of… everything (the DOM, the state, …), to be able to go back in time.

This had many bugs, in animations (such as the “focus” action), and in its iteraction with other features (such as drawing).

So, what is new in this engine? The engine now records an undo function for each step of the presentation. While this may not sound much, it is a ton better in terms of development. It’s a much stronger foundation to build new features from. It’s also much more
efficient for long presentations.

In most cases, your old presentations will work without modification in the new engine. However, there is one case where it needs modification: when you include the execution of a custom script in your presentation. In this case, you need to return the function undo to undo the executed step: see the documentation! (This is not ideal and better solutions are being experimented)

Writing

Previously, live annotations used the excellent atrament library. While great in many cases, its bitmap-based approach caused blurriness when zooming.

This release introduces a custom SVG-based annotation system, which eliminates zoom issues. Another change: erasing now works stroke-by-stroke instead of pixel-by-pixel.

Table of content

The old table of contents was based on the slip structure, which didn’t work well for presentations that primarily used a single slip (as is often the case with compiled presentations).

The new sidebar-style table of contents is now generated from headers, making it more intuitive and aligned with the presentation’s structure—resulting in a much smoother navigation experience!

Breaking change: Subslips

The HTML structure for subslips has evolved, in particuler to avoid having to provide the scale of your subslips.

Support for subslip in the new engine is not mature and will be announced in the next release, but bear in mind that if your presentation relies on them, you might want to wait a bit before migrating to the new engine!

Compiler

While this release focuses on the engine, the compiler has also seen improvements, including bug fixes (particularly in the parser) and a new feature:

--markdown-output for markdown exports

If you want to print your presentation or host it as a static webpage, the default format can be cluttered with annotations. The new --markdown-output flag lets you generate a clean, GitHub Flavored Markdown (GFM) file without annotations.

Other

A small but maybe important note: the license has changed, the project has transitioned from MIT to GPLv3, aligning better with its values.

Conclusion

Looking forward to your bug reports!

38 Likes

Could you link to a demo presentation done with this tool?

1 Like

Sure!

Here is a presentation of the tool itself, in French. The source file for it is here.

Here is a math presentation using more features (made using a previous version of the engine, which had more features and more bugs).

Here is the historical first presentation made in Slipshow (made with the worst version of the engine).

(I include presentations made with old versions of the engine to give an idea of what you can do, as the new engine is very new I don’t have many examples using it, and it has some breaking changes which makes porting old presentations using too many features hard to port!)

6 Likes

Here is a non-dogfooded one.

5 Likes

Wow, this is beautiful and convenient.
Well cooked, chef panglesd.

Well cooked.
Cheers.

3 Likes

Both the doggy version, and the other one look completely empty in the chrome web-browser.

Oh! Thanks for reporting.

Could you check if it works in “Private navigation mode”? And does this one works (refreshing cache)?

Some (older) version of Slipshow breaks when some Chrome/Firefox extensions send messages to the page…

(Do not hesitate to continue this conversation in a slipshow issue!)

Let’s continue with a new release in this Slipshow thread. It’s my ginormous pleasure to announce the opam release of:

Slipshow v0.3.0: The return of the subslips

As you can see, a crucial improvement is that releases are now named. Semver is boring, let’s add a bit of fun in a serious world.

The release name subtly suggests that subslips are back. Yes, subslips are back! Slipshow allows your presentation to be visually organized. Subslips are slips that are inside a slip. You can then “enter” it, go through it, and exit it to go back to the original slip.

But a gif is worth a ginormous word, so here it is:

A demo of slipshow entering subslips

To obtain a similar effect, using the new release, you can simply do:

We will discuss three topics:

{style="display:flex" children:slip}
----
# Topic 1

Content of the first topic

---
# Topic 2

Content of the second topic

---
# Topic 3

Content of the third topic

If you want to separate the source in multiple file, it’s easy: {include src="file/to/include.md"}. And did you notice that --- now act as group separators? At this point, let me just output the changelog (highligting some of them):

Compiler

  • Fix file watching issues by vendoring a (modified) irmin-watcher, and watching
    all files the presentation depends on (images, themes, …) (#113)
  • Adds a favicon to the presentation file (Slipshow now has a logo!) (#115)
  • Fix missing attributes on images (#117)
  • Fix missing mime type on images that made svg undisplayable (#120)
  • Fix detection of math inside inline attributes (#124)
  • Add --dimension to specify the dimension of the presentation (#131)
  • Add less boring name for versions (#132)

Language

  • Add {include src="path/to/file.md"} to include a file in another (#114)
  • Allow pause to have a target (#118)
  • Remove the need for step to execute actions (#118)
  • Added support for subslips and slides (#118)
  • Added pause blocks (#127)
  • Use horizontal lines (---) to group blocks (#129)
  • Pass attributes to children with children: (#130)
  • Consistently remove the need for -at-unpause (#133)

Engine

  • Simplify table of content by removing preview (#118)
  • Fix wrong computation of location (#118, #119)
  • Improve zooming behaviour (everywhere) and performance (on chrome-based browsers…) (#121)
    • If someone has some expertise on how to improve performance on firefox, I’m interested!
  • Add PageUp and PageDown as navigation keys, adding support for pointers (#126)
  • Do not act when control is pressed (#126)
  • Fix wrong positioning on scaled slips (#128)

Credits

Thanks to the NLNet foundation for supporting this project!

14 Likes

It is with some bitter joy that I’m announcing the 0.4.1 version of Slipshow on opam:

The slides strike back

The main improvements of this version are the introduction of arguments to actions, a frontmatter, and improvements to slides.

All together, they allow to easily design presentations the slides way:

ezgif-208995c3ed578f

---
toplevel-attributes: {children:slide children:enter="~duration:0"}
---

# Slide 1

Content

---

# Slide 2

Content

---

# Slide 3

You get it

So, why “bitter joy”?

I was reluctant to add good support for traditional slide-based presentation. There are already very good and mature solutions for this, including some with similar technical foundations as Slipshow. I was more interested in developping the new things: Slips!

However, Slipshow starts to have useful features that competitor don’t always have (for instance: a self-contained html output! But more, and more to come). Also, for people who already have slide-based presentations, it makes it easier to migrate them, and use a single tool for old and new presentations!

Finally, I wanted to make Slipshow a bit more versatile and added attributes, frontmatter, and a new options: toplevel-attributes. The proper slide support is actually just a nice consequence of this versatility! :partying_face:

Here is the full changelog:

  • Fix children: not working sometimes

  • Add --toplevel-attributes to control the attributes on the toplevel
    container

  • Render slide titles as slide titles

  • Add arguments to actions

  • Add frontmatter

    You can now do

    ---
    theme: vanier
    dimension: 16:9
    css: my_pres.css
    ---
    
    The content here.
    

OCaml-specific notes on action arguments

In this release, I add the ability to give arguments to actions. For instance, an action can be to focus on a specific element:

{#my_element}
Some content

{focus="my_element"}

The “positional” arguments is the list of IDs that must be focused. To add other kind of arguments , they need to be named:

{#my_element}
Some content

{focus="~duration:2 ~margin:5 my_element"}

It was fun to integrate OCaml syntax in slipshow :wink: This way, people coming to OCaml after learning slipshow will feel familiar with the syntax!

12 Likes

The Slipshow development intensifies… It is with external pleasure that I announce the 0.5.0 release of slipshow on opam.


Warning: External files have invaded our world! They raise dead formats like PDF into the liveliness of Slipshow presentations!

Slipshow 0.5.0: Plan 9 from External Files

As subtly hinted by the title, this slipshow release focuses on the integration of external files in a presentation. Rest assured, a compiled Slipshow presentation stays a standalone HTML file!

In effect, you can now include PDFs, videos and audios files in your presentations! Here is a demo:

plan9_demo-ezgif com-video-to-gif-converter

With the simple source:

{#title}
# Plan 9 from External Files

{pause play-media=mp4}
## Video demo

![](plan9.mp4){#mp4 style="width:100%"}

{pause up}
## PDF demo

![](plan9.pdf){#pdf}

{focus=pdf}

{change-page="~n:all pdf"}

{unfocus up=title}

Here is the full changelog:

Compiler

  • Add support for pdfs
  • Add support for audios and videos
  • Fix enter action being added to blockquotes

Language

  • Add a carousel type and a change-page action
  • Add a play-media action

Engine

  • Fix compatibility of slipshow and editable content
  • Fix scroll bar appearing in drawing toolbox
4 Likes

(I hope it’s still OK to announce my releases here, despite their current frequencies and the fact that it’s not an OCaml library.)

I am speechless to announce the new opam release of Slipshow!

Version 0.6.0: The King’s Slipshow

This release focuses on one specific feature: the speaker view.

Peek2025-08-1816-01-ezgif com-video-to-gif-converter

(Disclaimer: AI generated text [1])

The speaker view includes a timer, speaker notes, and a presentation synced with the main one. Note that a compiled presentation is still a standalone html file that you can just double click on.

To open the speaker view, press s. To send some text to the speaker notes, use the speaker-note action, as in the code below:

# The King's Slipshow

{pause speaker-note}
Say it like this: "perhaaaaaaaaps"...

In this grave hour, perhaps the most fateful in our history, I send to every household of my peoples, both at home and overseas, this message, spoken with the same depth of feeling for each one of you as if I were able to cross your threshold and speak to you myself.

{pause speaker-note}
Make a little pause and show a tear, it'll make it more dramatic.

As always, the world finds itself standing on the edge of war.

{pause center=time speaker-note}
Emphasize roar but avoid making everyone uncomfortable.

{#time}
Time after time, we have sought peaceful ways to resolve our differences. Yet too often, dialogue has been drowned out by the roar of weapons.

{pause speaker-note}
Pretend you know what you are speaking about: as a King, you can do that.

We are told that violence is unavoidable, that to be safe we must fight. But this is the old and dangerous lie that “might is right.” If we accept it, we accept the slow destruction of all that makes life worth living.

{pause down=end speaker-note}
DRAMATICALLY POINT FINGERS AT THE AUDIENCE!!!

For the sake of all we cherish, we must find another path. The real challenge before us is not to fight harder, but to imagine peace when anger blinds us, and to choose cooperation when conflict seems easier.

I call on all people, across every border, to remain calm, firm, and united in the higher cause of preserving life. To resist the call of hatred. To remember that in every city, in every nation, there are children who deserve a future unscarred by war.

The road will be hard. There may be days when peace feels impossible. But war spreads beyond the battlefield — it steals homes, divides families, and poisons the generations to come.

{#end}
If we remain steadfast in our refusal to give in to violence, then, with courage and compassion, we will prevail — not by destroying, but by preserving.

Full changelog below:

Engine

  • Add a speaker view, opened with s. (#147)
  • Fix Z and X not working (#147)
  • On step change, move back to the position we left (#148)

Language

  • Add a speaker-note action. (#147)

  1. The text in the left of the gif above was mostly generated by an LLM, mimicking “The King’s speech” declaration of war, but turned to praise peace, which we need a lot in this world ↩︎

6 Likes

I’ve been working on a presentation in Slipshow and overall am enjoying the process! (Can send it along once I finish polishing it up). Wanted to share a couple of thoughts:

  • The style attribute is pretty useful but not really documented anywhere?
  • I wish layout-related stuff was easier; I know I can shell out to HTML/CSS, but it feels a bit hacky.
    • Adding vertical space; I ended up using <br />.
    • Centering stuff horizontally; I used {style="text-align:center"}.
    • Putting stuff side-by-side; I used {style="float:right"} and {style="float:none"}.
  • Wish I could “automate” a step; I want to {center} my presentation’s title from the start, but I need to manually do a step before the {center} is processed.
  • {up}{pause} behaves differently than {pause}{up}. This is probably good, but I don’t think it’s documented?
  • I like {static} and {unstatic}, but would be nice if elements smoothly repositioned to compensate rather than jumping instantly.
  • I think the default table styling would benefit from some more space; I ended up using a bunch of &nbsp;s to compensate.

That’s about it! Let me know if I should clarify anything. No demands to do any of this, ideas are easy and implementation is hard, but wanted to these thoughts along in case they might be useful.

Thank you for your work with Slipshow!

3 Likes

Thanks a lot for the ideas and report! I"m glad you’re overall enjoying the process, that’s nice to hear :slight_smile:

I’d like to make, or integrate, a css framework (like tachyon) to make it easier to do the layout that are used often in a presentation (columns, centering, …). But there will always be a possibility to use CSS directly, as it’s hard to offer all possibilities!
For instance, for vertical space, I define an empty element with some height: {style="height:...px} attached to nothing.

You can[1]! You can define the toplevel attribute of your presentation, which is the step which will be executed on loading of the presentation. Usually it’s slip enter="~duration:0" but you can change it eg to:

---
toplevel-attributes: enter="~duration:0" slip down="~duration:0 my-title"
---

{#my-title}
# Hello

the first one is [[]{up}]{pause} and since the order of execution of actions is DFS, pause is executed first, then up. If you want to have them executed at the same time, {pause up} is the way to go!

I agree! They were defined when it was harder to do that, now I should add this option.


  1. Caveat there is a bug, the center action is executed after the enter one, making it go back to the top… That’s why I’m using down in the example below. But I’ll fix that in the next version ↩︎

2 Likes

Sounds good, thank you for the tips! Incorporated into the presentation.

Sharing the links if there’s interest, here’s the live version: https://www.dmitrivolkov.com/projects/2025-semiringkanren-presentation.html

And here’s the code: GitHub - sporkl/2025-semiringkanren-presentation

(I’ll be presenting this at ICFP next Friday!)

3 Likes

Thanks for the links, the presentation looks great! I hope it’ll go well!

I’m back!

Slipshow 0.7.0: The Slipshow of Dorian Gray

It’s with guilty pleasure that I announce the new release of Slipshow 0.7.0: The Slipshow of Dorian Gray, on opam.

$ opam update
$ opam upgrade slipshow

This release contains a handful of bugfixes. But the highlight of the changelog is an experimental support for recording and replaying annotations!

Peek 2025-11-26 13-25

The gif above was made using the new feature. You can also view it live. If you want an example of a more interesting use of the feature than a picture of me grow old, you can also see this presentation. You can also find the doc here.

The exclusive feature, that might not be obvious above, is that once you’ve recorded a series of strokes, you can edit it. For instance, here is the timeline for this presentation:


You can see it live and edit it by pressing Shift + R in the presentation, and selecting one of the recording in the dropdown on the bottom left.

However experimental this is, I can’t wait to see what kind of good and bad uses it can have for your presentations. Please post them here!

Thanks a lot to NLNet for their invaluable support.

And before the changelog, an exclusive information relevant to OCaml users! The drawing edition UI, and actually the whole drawing mechanism, is made using Functional Reactive Programming, in particular with @let-def’s brr-lwd library! As always, I’d like to say thank you to the developers of open source libraries, you are so great.

Here are the release notes:

BREAKING CHANGES!

  • I removed support for the “setext” headings: Underlining a title with dashes will no longer make a title. Sorry for breaking a standard, but that messes too much with the --- separator. Replace it with atx headings: # This is a title.
  • A bug in the carousel was fixed, breaking the workaround. If you used +2 to go to the next meaningful page, you can now change that, either to +1 or to all.
  • The semantics of focus and unfocus was changed. Before, you had to unfocus as many times as you focused. Now, you have to unfocus only once.
  • If you find any migration problem, please open an issue and I’ll help for the migration!

Compiler

  • Embed Liberation Sans fonts (and use them) (#150)
  • Fix missing favicon (which was missing since speaker view) (#150)
  • Fix changing step number from speaker note does not update serve mode state
    (#154)
  • Fix blank lines considered as elements in carousel (#170)
  • Allow to specify port in slipshow serve with -p or --port (#176)
  • Fix link with no content in block raising a syntax error (#180)
  • Remove support for Setext headings (#178)

Engine

  • Allow to record and replay strokes (#187)
  • Fix speaker note scrolling (#150)
  • Fix script undos recovery when script execution fails (#150)
  • Hide paused/unrevealed elems also for mouse (#150)
  • Don’t execute scripts when computing toc (#150)
  • Mute medias in speaker view (#152)
  • Use the perfect-freehand
    library to generate strokes. (#151)
  • Fix order of execution of actions (center after enter) (#171)
  • Fix pauses not being scoped in slides (#179)
  • Fix exiting not where it should (#179)
  • Fix unfocus behavior to match the docs (#179)
  • Fix wrong position bug on custom dimensions (#182)
  • Fix infinitely jiggling autoresizing (#187)
  • Fix not being able to draw outside of inner presentation (#187)
  • Fix permanent fast-moving bug (#187)
13 Likes