cwensley / pablodraw

PabloDraw is an Ansi/Ascii text and RIPscrip vector graphic art editor/viewer with multi-user capabilities.
MIT License
309 stars 21 forks source link

Line endings for macOS/Unix terminals: A 29-row ansi art has only 6-rows on macOS terminal #70

Open poetaman opened 1 year ago

poetaman commented 1 year ago

This same problem exists for same art in moebius too. Perhaps not many users have tried using their unix terminal to view ANSI art. Copying the contents of issue here:

It seems there is something missing about line endings or the way lines are broken in ANSI art. It displays correctly in Moebius, but both input and utf8 converted output file has only 6 lines instead of seeming 29 in the art. This leads to incorrect rendering in terminal.

Moebius screenshot:

Screenshot 2022-10-28 at 8 58 23 PM

The way it shows in text editor vim in macOS (only 6 lines):

Screenshot 2022-10-28 at 9 25 17 PM

Manually changing the terminal width to 80 characters does the trick (check left vs right):

Screenshot 2022-10-28 at 9 04 36 PM

Is there an automated way to get line breaks at 80 characters? I tried some CLI converters but none seem to work.

Steps I used to convert for utf-8 format:

cat LU-Holiday.ans  | iconv -f CP437 | sed 'H;$!d;x;s/\x1A.*$//'
wkitty42 commented 1 year ago

On 10/29/22 2:52 AM, poetaman wrote: [...]

Is there an automated way to get line breaks at 80 characters?

not without a tool that can analyze the ANSI sequences properly and inject EoLs or cursor placement (save and restore) codes based on a specified rendered line width while not breaking ANSI sequences...

FWIW: back in the day, it was common practice when using TheDraw, to block save the image being worked on... this "forced" newlines at the right edge of the blocked section... this had to be done when the original was saved... if block save wasn't used, the image was saved in long lines which then relied on the terminal being 80 chars wide for proper rendering... wider terminals would display the image fine but smaller ones ran into the line wrapping problem...

another option was using "animation" which used cursor placement to position the cursor where needed when needed... in this case, saving with long lines didn't matter and the image was rendered properly when the terminal was 80 chars wide or more... terminals smaller than 80 chars, on the other hand, didn't look so good due to wrapping and cursor placement leading to overwriting when it was moved to the proper line...

tldr; block save and animation are long time missing elements in the magic of ANSI drawings and varying terminal widths... relying on EoLs is not really good juju but it was one of the most common methods used...

poetaman commented 1 year ago

@wkitty42 Ah, that's useful information to have! I did not know why it was done like that.

Check my first hand-edited version is now available for modern terminal emulators (colors depend on terminal colors):

https://github.com/poetaman/arttime/commit/153cd08e2c21903efd0ed90a9d0b54388823e274#commitcomment-88263554

An ideal and concise spec for outputting ANSI for modern terminal emulators would be: 1) break every line at art width, 2) start and end every line with with clear escape code \E[0, 3) patch places where author assumes default black background and default white foreground within art so it picks terminal's black/white instead of terminal's background/foreground (can require a combination of: a) replacing \E[49m with \E[40m, b) \E[39m with \E[30m, c) adding/adjusting spaces at edges).

Am not suggesting pablodraw to not do what it does today, additionally implementing an export option that follows the spec above will make it easy to use ANSI art in modern terminal emulator based applications. Terminal emulators are the most natural home for ANSI.

tracker1 commented 1 year ago

I think just having an option to open a work without line endings and save with them might be useful.

poetaman commented 1 year ago

@tracker1 Sooner or later users will also hit the issue where they cat the file on a wide terminal (wider than art) and the area to the right of art has stripes of different colors than the terminals background. Given modern terminals can be arbitrary size, and user might want to place the content anywhere on the screen, it would be good if styling of art does not interfere with contents around it. One could argue that every application that wants to display ANSI art in modern terminals should parse escape sequences in prior line, save it, clear it at boundary, and recreate it at the beginning of next line. It would be difficult to say the least, and error prone. I would assume such state information already exists in some form in pablodraw as its renderer is able to render every glyph accurately with desired style. Here's the suggestion from my above post (copied here):

An ideal and concise spec for outputting ANSI for modern terminal emulators would be: 1) break every line at art width, 2) start and end every line with with clear escape code \E[0, 3) patch places where author assumes default black background and default white foreground within art so it picks terminal's black/white instead of terminal's background/foreground (can require a combination of: a) replacing \E[49m with \E[40m, b) \E[39m with \E[30m, c) adding/adjusting spaces at edges).

Think of it as placing an image in modern day UI, the stylizing of the image and its caption shouldn't affect the style of the contents around it (hence the trailing \E[0). Same goes the other way round, an application's line styling shouldn't affect the image being placed (hence the beginning \E[0). Whoever is coding their application and placing such a text-element on a wide terminal, they are responsible to recreate the styling they want after the trailing \E[0 that marks end of art (i.e for the region of their application). IMHO it will make developing for modern terminal's UI easier if such pattern is followed in general.

P.S. I may be slow to respond in coming days.

haliphax commented 1 year ago

This also prevents folks from drawing for terminal widths outside of the old DOS dimensions without needing to save as XBIN, etc.