Typstage: animated HTML presentations from a single Typst file

Thanks! I gave it a proper try across a couple of themes and it worked great everywhere.

One thing I couldn’t get working: generating transition slides via the navigator package. It relies on Typst’s query()/location() to find headings and figure out which section is “active”, but it seems typstage parses headings into its own data before layout, so there’s no real heading left for query() to find. If I’m right, It’s really just navigator’s introspection model that doesn’t fit the HTML export path, not a typstage issue as such.

Thank you so much for all your work!

1 Like

Hi, I think I found a problem in one of the new example decks. On Linux I see this, both in firefox and chrome:

By the way, I also saw the new decks based on mosaic, thank you I will have a look at how you made them when I have time.

1 Like

Now submitted to Universe typst/packages#5713.

Four days and rather a lot of commits, so a list rather than prose:

  • GeoGebra is no longer a companion package. @maucejo, I sent you off to fetch typstage-geogebra separately; that is out of date. geogebra and the ggb-* calls ship with typstage itself, and a deck that never calls them carries none of it.
  • scene @Marti, that is the manim connection, turned around. There a number moves while the film runs and the picture follows it; here a deck writes a function from a value to a picture and says at which values the talk stops. Typst renders every stop and the frames between, and a keypress pulls the picture from one to the next. Alongside it: camera to pan and zoom within a slide, enter: "draw" for a stroked path that draws itself, build for a drawing that grows in stages, plus flipbook and video.
  • morph now flies inside a slide, not only between two, so an equation can rewrite itself line by line with | -2 style annotations riding along. stagger and alternatives can morph as well.
  • The speaker view became a desk of tiles, with two clocks: the one that knows your planned duration, and class-clock(), a full-screen clock the room can read.
  • Seventeen example decks, three of them adaptations of Mosaic decks. @LucaD, that is the nearest thing to an answer I have for you: tiles and the five layouts are the spatial part, and the three Mosaic adaptations are there so the comparison is on the screen rather than in my prose.
  • Both manuals are complete in both languages English · Deutsch plus a tutorial that builds one deck from an empty file to a handout.
  • Smaller: prefers-reduced-motion is honoured, the progress bar grows instead of cross-fading, there is a logo, and an overflow check now measures every example deck, it found three slides of my own tour running off the bottom edge, which the browser had been quietly cropping.
  • @Mc-Zen, the comparison you asked for is written: in the README and in both manuals. Not only against the PDF packages but against the nearest neighbours, touying-exporter (one SVG per slide, packaged with impress.js) and slipst (slipshow’s scrolling slips instead of fixed-size slides), which is the half I had been missing. One claim in it is deliberately weak: I found no other Typst package that morphs glyph by glyph, but “I know of none” is not “there is none” correct me if it is wrong.
5 Likes

Hello! I’m using the Tinymist extension for VSCode to compile Typst in my machine, but the sample deck doesn’t seem to work as of the moment. The error message said “package not found”. It seems like it cannot find the Typstage library. How should I run it? Did I miss something? Thanks in advance!

Hi! The package is not published yet, so not live on the universe.

If you haven’t any experience with manually installing local packages you should just wait for the official release (when the Typst team accepts the package).

Otherwise you could read here, how to install the package locally:

1 Like

Hi. Thank you! I’ll wait for the official release then. So excited to try it! Great work!

1 Like

It’s live so you can test it right now! :grin: :partying_face:

Please share your experiences and results. :pray:

8 Likes

Thank you for making something so awesome :fire:

Just wondering, how difficult would it be to try and implement rtl as well for some languages.


It’s very interesting how the layout responds to dir: rtl on the text set rule but the actual text is still aligned to the left side.
The only option I found that worked (kind of) was to place the entire text inside align like the following (plus sometimes having to put a block of width 100% around it):

#set text(
  font: "B Yas",
  dir: rtl,
  lang: "fa"
)
...

== چهار مثلث در یک مربع

#side-by-side(
  card(title: [درود])[
    #align(right)[
      متن تستی و آزمایشی صرفا جهت بررسی چینش متن های راست به چپ 
    ]
  ],
  stagger[
    #align(right)[
      - چقدر دشوار می تونه باشه؟
      - احتمالا خیلی خیلی زیاد... بوی دردسر میاد... $a^2 + b^2 = c^2$ ای بابا... 
    ]
  ],
)

#v(1fr)

#callout(title: align(right, box(width: 100%)[به یاد داشته باشید]))[
  #align(right)[
    #box(width: 100%)[
      مساحت باقی مانده تغییر نمی کند، فقط شکل آن تغییر می کند.
    ]
  ]
]

Give’s the following:

I have no idea how to fix the top headers either :_) or move the red bar to the right… and so on.
An dir option like this or support for the “bidi-flow” package would be greatly appreciated. I’d love to help If I’m able to ^^

Thanks for the report, and for the pictures!
They made the cause easy to find.

It is fixed now, and the fix is smaller than it looks. Typst turns a paragraph around by itself as soon as text.dir is rtl, because a paragraph’s default alignment is start and start follows the direction. typstage was placing the slide body with place(top + left, …), and place hands its alignment down into the content as a style. That fixed left beat the start every paragraph would have resolved for itself. So the grid mirrored, the list mirrored, and every line inside them still began on the left. Exactly what your first screenshot shows.

Everything the package places by hand now anchors at start instead of left. From your example, this is all it takes:

#set text(font: "B Yas", dir: rtl, lang: "fa")

#show: presentation.with(...)

lang: alone is enough. The package uses Typst’s own list of languages that read from the right, so lang: "fa" implies the direction, same as everywhere else in Typst.

Three things to know:

  • The set rule has to stand before #show: presentation. Written after it, the slide bodies still turn around, but the title slide, the section slides and the footer do not: they are drawn outside that scope.
  • Slide transitions do not mirror. transition("slide") still comes from the right unless you say from: "left".
  • The footer’s 1 / 3 renders as 3 / 1. That is bidi doing its job, not the package losing count.

It is on main now and will go out with the next release. If you can give it
a try on your own deck I would be glad to hear whether anything is still
sitting on the wrong side.

3 Likes

Appreciate it! :sparkles: I messed around with a lot of things and examples and it seems to be working flawlessly. I’ll share if I happen to come across any. Thanks a ton once more :pray:

1 Like

This is just what I needed! Thank you very much!

One observation:

I just tried #footnote and it doesn’t behave as it should. I get the footnote somewhat squeezed into the bottom and my content is moved to a new slide.

Thank’s for your observation!

I will try to add a fix to the 0.1.1 release.

EDIT:
Fixed, and thank you. That was a real one.

Typst puts footnote entries at the foot of the text area. A typstage slide is
a block of exactly page height, so there is nothing left down there: the note was pushed onto a page of its own, in front of the slide that names it, and your content moved on. In the browser it did not appear on any slide at all.

The deck sets the note itself now. It stands at the foot of its slide, under a short rule, numbered from one on every slide, and it reaches all three outputs.

One thing on top: if the footnote sits inside a reveal chain, the note appears in the browser on the same step as its marker, so the foot of the slide gives nothing away that you have not shown yet. Its place is held from the start, so nothing jumps when it arrives.

One limits worth knowing. A footnote in a slide title stops the compilation and says why: the title is repeated as a running head and in the contents, and every repetition set the footnote again.

It is on main, and it is part of the 0.1.1 submission.

2 Likes

typstage 0.1.1 is on Universe.

The headline is footnotes: #footnote now works on a slide. The note stands at the foot of its own slide, numbered from one on every slide, in the browser, the PDF and the handout and a footnote inside a reveal chain appears with its marker, so the foot of the slide gives nothing away. Thanks to whoever reported that it did not.

Also new: contents(): a table of contents that jumps, and can show where the talk stands; decks that read from the right (#set text(lang: “fa”) is enough); pages: “step” for a PDF that unfolds one page per step; and build(at: …).

Full list in the changelog.

Happy typsting!