Limitations

The approach used in Asciicast.jl has some limitations, and for some use cases it may be better to use the command-line tool asciinema directly.

Cannot use keyboard input

Since Asciicast.jl works by running short Julia scripts and capturing the inputs and outputs, one cannot use keyboard input to direct what runs. This makes it hard to capture things like terminal menus and other UI which requires input via Asciicast.jl.

Cannot rely on stdout (or stderr) in one line being still open in the next

This is an Documenter limitation which also affects Asciicast, both in @cast blocks in Documenter, as well as in the @cast_str and gifs generated via cast_document. For example, in the code

using ProgressMeter
prog = ProgressThresh(1e-5; desc="Minimizing:")
for val in exp10.(range(2, stop=-6, length=20))
    update!(prog, val)
    sleep(0.1)
end

prog implicitly captures stdout inside the ProgressThresh object. However, the way this code is processed is basically one "block" at a time (the same as the REPL works). But each block is given a different stdout object (in order to capture it's outputs individually) which is closed at the end of the execution that block. That is, prog = ProgressThresh(1e-5; desc="Minimizing:") gets a stdout, which is then closed before the for-loop runs. Then update! in the for-loop tries to write to this stdout, which has already been closed.

One workaround here is to use a begin or let block, to group lines that need to share access to the stdout object:

julia> using ProgressMeter
julia> begin prog = ProgressThresh(1e-5; desc="Minimizing:") for val in exp10.(range(2, stop=-6, length=20)) update!(prog, val) sleep(0.1) end end

Limited emoji support in gifs

This is an agg limitation[1]. Currently, emojis are only supported if you install the font Noto Emoji, and they are monochrome only (not color).

cast_document effectively reformats the document

pandoc is not a source-precise markdown parser, and ignores "syntax trivia" like whitespace and so forth in its internal representation of the document. This means when it writes out the document after processing, it changes the whitespace, some newlines, and things like that. The rendered output should generally not change, but the file itself can change quite a bit.

cast"" blocks require everything to be defined within the block

Unlike Documenter @cast blocks, or markdown julia {cast="true"} blocks, which support defining items in one block and reusing those definitions in the next, @cast_str requires everything to be defined within the block. That is because we do not have an easy way to pass around the module with which the code is executed within. We could just execute the code in whatever module the @cast_str macro is being evaluated in (often Main), but then that module's state would be updated by the contents of the block (including globals, function definitions, etc), which may be unexpected. Instead we require these blocks to be self-contained. They do support using and include however, facilitating code-reuse.

Non-limitations

ANSI escape codes work properly

Tools like ProgressMeter.jl use escape codes so modify the terminal state so that the progress meter overwrites itself. This isn't compatible with standard @repl blocks:

julia> using ProgressMeter
julia> @showprogress dt=0.1 desc="Computing..." for i in 1:10 sleep(0.1) end Computing... 20%|███████▊ | ETA: 0:00:03 Computing... 60%|███████████████████████▍ | ETA: 0:00:01 Computing... 70%|███████████████████████████▎ | ETA: 0:00:01 Computing... 80%|███████████████████████████████▎ | ETA: 0:00:00 Computing... 90%|███████████████████████████████████▏ | ETA: 0:00:00 Computing... 100%|███████████████████████████████████████| Time: 0:00:01

But it does tend to work with @cast blocks and other Asciicast constructs:

julia> using ProgressMeter
julia> @showprogress dt=0.1 desc="Computing..." for i in 1:10 sleep(0.1) end