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
- 1In fact, this is an even further upstream issue in the renderers used by
agg
.