Skip to content

support unsized terminals#886

Open
a-h wants to merge 2 commits into
mfontanini:masterfrom
a-h:support_unsized_terminals
Open

support unsized terminals#886
a-h wants to merge 2 commits into
mfontanini:masterfrom
a-h:support_unsized_terminals

Conversation

@a-h

@a-h a-h commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

In CI environments or container builds, there's not always a full terminal. I use presenterm to build HTML / PDF files as part of a CI process.

However, by default, it fails! Running presenterm -E inside a nix or Docker build produces:

Gf=32,a=q,t=f,i=2665712073,s=1,v=1;L25peC9...AAAAAA==
exporting using rows=0, columns=0, width=0, height=0
^[[1A^[[2K^[[1Gwaiting for images to be generated...^[[1E
^[[1A^[[2K^[[1Gprocessing slide 1...^[[1E
^[[38;5;9mrender: screen is too small^[[39m

Note: render: screen is too small.

This is because:

  1. termbg::theme() writes a terminal probe to stdout, producing the Gf=32,... output
  2. WindowSize::current() returns 0x0 without a real terminal - that causes "render: screen is too small"
  3. Crossterm cursor movement (MoveUp, Clear) emits raw ANSI escapes into build logs

I worked around the issue by building slides inside tmux:

mkSlides = pkgs: pkgs.runCommand "slides"
  {
    nativeBuildInputs = [ pkgs.presenterm pkgs.tmux pkgs.d2 pkgs.typst ];
  } ''
  cp -r ${./images} images
  cp ${./slides.md} slides.md
  cp ${./presenterm-export.yaml} presenterm-export.yaml
  mkdir -p $out/slides
  export HOME=$(mktemp -d)
  export TERM=xterm-256color
  tmux new-session -d -s export -x 200 -y 50 "PATH=$PATH HOME=$HOME TERM=$TERM presenterm --image-protocol ascii-blocks -E slides.md -o $out/slides/index.html; tmux wait-for -S done"
  tmux wait-for done
  cp -r images $out/slides/images
'';

But it's quite complex and requires the extra tmux dependency in the build.

This PR adds a function (terminal::has_sized_terminal()) which checks both is_terminal() and that terminal dimensions are non-zero.

If the terminal is not sized:

  • Fall back to 200x50 default export dimensions
  • Skip termbg::theme() and use the dark variant
  • Use plain println! instead of crossterm cursor movement in export logging
  • Use eprintln! for error output

@mfontanini

Copy link
Copy Markdown
Owner

This what the configurable export siz is for. Does that not work for you?

@a-h

a-h commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

The size config works, but needing it is confusing on first use.

You run an export locally, and it works fine, but the same code fails in CI with "render: screen is too small" because you don't have a size.

And you think, what screen, I'm doing an export. Then you have to hunt in the docs.

I think it makes sense to have a default for exports in headless environments.

In the spirit of "batteries included, but replaceable".

@mfontanini

Copy link
Copy Markdown
Owner

Sounds like the problem is the error message should say something like "no TTY detected, use export.dimensions to set the export dimensions" rather than "screen is too small". Falling back to a 200x50 (or any other) size will cause confusion as well: people will see their exported PDF looks like crap and wonder why that's the case.

@a-h

a-h commented Apr 28, 2026

Copy link
Copy Markdown
Contributor Author

I think that makes sense.

If the terminal junk wasn't visible, and you got the clear message:

No TTY detected, set export.dimensions in the config file:

  export:
    dimensions:
      columns: 80
      rows: 30

Config files are automatically loaded from the `--config-file` parameter, the $PRESENTERM_CONFIG_FILE env var, or $XDG_CONFIG_HOME/presenterm/ if $XDG_CONFIG_HOME environment variable is defined, otherwise:

  ~/.config/presenterm/ in Linux.
  ~/Library/Application Support/presenterm/ in macOS.
  ~/AppData/Roaming/presenterm/config/ in Windows.

That would point me in the right direction. But then the next question I'd have is... What should the export dimensions be?

  • For HTML, I'd want something 16:9, since that would be OK for most people, even though it's not ideal for Macbooks.
  • For PDF I intend to view on screen, I'd want 16:9 by default to copy the HTML. I don't care about the file size, that could be reduced by other tools.
  • For PDF that I want to print, maybe A4 landscape would be good, but again, I'd probably just want the 16:9.

How should a user work it out?

@mfontanini

Copy link
Copy Markdown
Owner

That is fair but I think that's:

  • An unrelated problem to the original one you posted. You can already get presentation exports of any size even outside of TTYs. I still think a better error message makes sense (will likely add that in a bit).
  • A problem I'm not so sure how to solve. We could have a predefined set of sizes so you could go and set "16:9" or "a4" or whatever in your config file but I don't know how much that'd solve. e.g. this wouldn't be too different from setting export.dimensions to (160, 90) or something like that. This is IMO a problem specific to each presentation writer, where they need to check what export size fits their presentation best. Even if you were offered alternatives, you'd still need to figure out which one's best for you. It would be nice to be able to use some heuristic to detect the best dimensions to use, though I'm not sure how much effort and how accurate this will be. I guess this could try to find the minimum size where everything fits and then increase that by some margin (e.g. 15%) so it doesn't look too cramped. I think images may cause problems here though: since they shrink-to-fit they will adjust to whatever size you set, so they will tend to look tiny.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants