Skip to content

schochastics/vhsR

Repository files navigation

vhsR vhsR website

Animated GIF demos of R code, generated by an R one-liner. Wraps charmbracelet/vhs.

Installation

# install.packages("pak")
pak::pak("schochastics/vhsR")

vhs itself plus its runtime dependencies (ttyd, ffmpeg) are downloaded into a per-user cache on first use:

library(vhsR)
vhsr_install()   # one-time setup
vhsr_doctor()    # confirms everything is in place

On macOS, vhsr_install() will print a brew install line for ttyd and ffmpeg (those have no usable upstream binaries for macOS); on Linux and Windows everything is downloaded automatically.

Usage

record_demo({
  x <- 1:5
  mean(x)
  head(cars, 3)
}, output = "demo.gif")

That writes demo.gif next to your working directory. The GIF shows the code being typed at a real R prompt, with output appearing as it would in an interactive session.

Styling

record_demo(
  {
    fit <- lm(mpg ~ wt, data = mtcars)
    summary(fit)$coefficients
  },
  output         = "fit.gif",
  width          = 1000,
  height         = 500,
  font_size      = 20,
  theme          = "Dracula",
  typing_speed   = "100ms",
  playback_speed = 1.25
)

Pacing

Four extra timing args control how the recording feels:

  • start_pause — sleep between R startup and the first typed line (default "800ms").
  • end_pause — sleep before the (hidden) q() exit (default "500ms").
  • paragraph_pause — when set, blank lines in expr become a sleep of this duration instead of being typed.
  • typing_speed_jitter — numeric in [0, 1]; per-line typing speed is sampled within ±jitter of typing_speed so the recording feels less mechanical. Call set.seed() first for reproducibility.
record_demo(
  {
    x <- 1:5
    mean(x)

    head(cars, 3)
  },
  output              = "paced.gif",
  paragraph_pause     = "1s",
  typing_speed_jitter = 0.3
)

Recording from a script file

If the demo lives in a .R file, point at it directly:

record_demo_file("examples/demo.R", output = "demo.gif")

Equivalent to inlining the file’s contents in record_demo(). Syntax errors are caught up-front with a pointer to the file path.

Single-frame screenshot

For static documentation — prompt, code, and output in a PNG instead of a GIF:

record_demo_screenshot(
  {
    fit <- lm(mpg ~ wt, data = mtcars)
    summary(fit)$coefficients
  },
  output = "fit.png"
)

By default the screenshot is taken after the last typed line. Pass at = "after:N" (1-indexed) to capture after a specific line.

Knitr / Rmd chunks

vhsR registers a vhsr knitr engine on package load, so you can drop a chunk into a vignette, README.Rmd, or pkgdown article:

``` vhsr
x <- 1:5
mean(x)
head(cars, 3)
#> ![](man/figures/demo.gif)
```

The chunk records a GIF at output= and inserts the corresponding markdown image-include in the rendered document. Forwarded chunk options: output, width, height, font_size, theme, typing_speed, playback_speed, line_pause, backend.

Embedding in HTML

For Rmarkdown documents or Shiny apps that want playback controls:

vhsr_widget("demo.mp4")

Returns an htmltools::tagList. .gif becomes a styled <img>; .mp4 / .webm become a <video controls loop muted playsinline> with the appropriate MIME source. width / height accept either numerics (treated as pixels) or strings ("100%", "50vw", …).

Escape hatch

For full control over the recording, write a .tape script directly and hand it to vhsr_run_tape() — or pass the tape = argument to record_demo():

vhsr_run_tape('
Output hello.gif
Set FontSize 22
Type "echo hi from vhs"
Enter
Sleep 1s
')

About

Resources

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE
MIT
LICENSE.md

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages