PerBothner / DomTerm

DOM/JavaScript-based terminal-emulator/console

Home Page:https://domterm.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question on formatting

csik opened this issue · comments

Hi, I'm hoping to do a project with DomTerm because it's great, and it's the only html terminal I'm seeing that is able to display images easily.

That said, I'm also hoping to use the python rich library, which does a great job of doing curses-like text rendering without having to curse as much. I'm finding that while rich works perfectly in ttyd, it doesn't seem to work in DomTerm as flawlessly (both in the browser). I just want to check if this is an error like the image display issue was, or if it's something fundamental to DomTerm.

  1. Here is a rich display (fullscreen.py) on ttyd:
    image
    The box corners and etc are aligned correctly and the progress bars at the bottom are creeping along.

  2. Here is the same execution in DomTerm. Note the corners and vertical lines are spaced differently, and the progress bars are expanding to the right in an odd way. I tried in several monospace fonts.
    image

The layout in DomTerm mis-renders, while ttyd/xterm renders very well (except for the line with the emoji! damned emojis.). Am I greedy that I want both the nice text rendering and the ability to have images at the command line? Yes, but I'm wondering if this fixable in DomTerm? As always, happy to test, and thanks for your work.

I'm guessing the problem is similar to that of double-width characters: When the browser doesn't find a character (like an Emoji or Japanese Kanji) in the specified monospace font, it substitutes a character from other font. However, that substitute character doesn't have the correct width - which for terminal-emulator applications should be double the width of a "regular" character.

DomTerm works around this by wrapping each double-width character in a <wc-node>element and then using CSS to force the correct width and height. (This is done in the insertSimpleOutput function in terminal.js.) It's a bit heavy-duty (an extra element for each character), but works resonably well.

I'm guessing rich works under tttd because it uses xterm.js, which explicitly paints each character, as either single- or double-width. xterm.js enforces a traditional rectangular grid.

DomTerm could handle these problematic characters in a similar way to how it handles double-width characters, buywrapping it in sothing similar to a wc-node element, but force the width to be a single column. This wouldn't guarantee that everything aligns properly, but it might work. Other substitutions may be possible. It might make sense to have a user-settable hook to customize this.

I've downloaded rich, bu haven't tried it out. If you could write a trivial script (and give instructions for someone who is not fluent in Python) I could try to figure out specifically what is going on

I did try python -m rich and noticed some problems.

I fixed a bug in escape sequence handling that was breaking the colors in python -m rich.

Hi! Thank you, Indeed it looks better, and the animation is much improved!

I suspect at this point the only misalignment seems to be happening with some graphical characters, like the left/right arrows (wider than other characters) and up/down (narrower) in
python3.8 -m rich.layout
image

If you look at:
wget https://raw.githubusercontent.com/willmcgugan/rich/master/examples/fullscreen.py
python fullscreen.py
you can see some other artifacts:
image

This is all very close -- and this may be too niche to support -- but I'm guessing it might show in other situations too?

When you say user-settable hook, would this be per-character or a global setting? Is there a way I could add problematic character exceptions to the code base as a pull request?

The problem with the progress bars causing misalignment appears to the the Spinner component, which uses Braille Pattern dots. Presumably these don't appear in regular monospace fonts so they need to be substituted. Other alignment problems probably have similar cause.

This can probably by fixed by placing the character in a separate <span> and forcing the latter's width to be 1 column-wide, similar to how we do for double-width characters.

I'd like to figure out a more general framework, that also handles grapheme clusters such as national flags (see in the python -m rich test). Conceptually simple (though the Unicode graphme-splitting rules are complex.)This may require some thought and research.

Slightly off-topic: Do you think the rich maintainers might be interested in adding support for images? These is more than one terminal emulator that supports images, and the fallback on unsupported terminals could be just display the Alternative Text and the URL (which could be clickable in many terminals). The API would specify an image and the size (rows*columns) to display it in.

I'm not a Python person, so I'm not going to propose it, but I'd be happy to advise and help out.

I don't know, but I'll ask him on twitter!

I'm trying to fix some bugs/issues that are mostly done, to get them out of the way. I'm also researching and thinking about the rendering and alignment problems you reported. I'd like to work out a general approach that will also handle "grapheme clusters" better (including national flags and other "complex" emojis that are generated by rich.) It may take while, but hopefully not too long.

However, if these glitches are holding up your work or preventing you from using DomTerm, let me know and I can put in some short-term fixes.

Hi sorry for the delay in responding. No, please don't do any busy work on my account, though your offer is very generous. I'd be much more in a maintainable and thorough solution! PS the rich maintainer didn't respond yet...