Giter VIP home page Giter VIP logo

Comments (17)

edgar-bonet avatar edgar-bonet commented on June 11, 2024 1

Hi! I am experiencing the same issue here, with Ubuntu 22.04, gnome-terminal, LANG=en_US.UTF-8, and LC_CTYPE unset. The command:

$ { ./torture | head -75; sleep 1m; } | ./ttyplot -c ''

displays this:

screenshot

The displayed image is the same whatever non-ASCII character I pass to -c. I tried a bunch of them: ², Œ, à, ß, £, µ, ≤, ÷, →, ©, ™.

Looking at the source code, it is clear that non-ASCII characters cannot possibly work. The option -c is parsed like this:

    case 'c':
        plotchar=optarg[0];
        break;

Here, optarg is an array of char holding the UTF-8 code units of the provided character, and only the first one is stored in plotchar. In the example above, I used the character “╎” (U+254E Box drawings light double dash vertical), which in UTF-8 is encoded as the sequence {0xe2, 0x95, 0x8e}, then plotchar got initialized with 0xe2 (sign-extended to 32 bits).

from ttyplot.

edgar-bonet avatar edgar-bonet commented on June 11, 2024 1

@MIvanchev: I think we could use mbtowc() to convert the character to a wchar_t. This function does not add any dependency: it is in libc since C99. Then use mvvline_set() instead of mvvline(). The difference between these two functions is that the former takes the character as a cchar_t (instead of chtype), which is an array of wchar_t with attributes.

Note that mbtowc() only works after calling setlocale(). I wrote this small code for testing mbtowc():

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main(int argc, char *argv[])
{
    if (argc != 2) {
        fprintf(stderr, "Usage: %s character\n", argv[0]);
        return EXIT_FAILURE;
    }
    setlocale(LC_ALL, "");
    wchar_t c;
    if (mbtowc(&c, argv[1], MB_CUR_MAX) < 1) {
        fprintf(stderr, "Could not convert %s\n", argv[1]);
        return EXIT_FAILURE;
    }
    printf("U+%04X\n", c);
    return EXIT_SUCCESS;
}

It successfully converts non-ASCII characters:

$ ./read-wchar ┆
U+2506

from ttyplot.

MIvanchev avatar MIvanchev commented on June 11, 2024 1

Yeah @edgar-bonet that sounds like the way to go! Let's draw straws to see who has to write the patch. I'll go first.

This is my straw: ~=====~

from ttyplot.

edgar-bonet avatar edgar-bonet commented on June 11, 2024 1

How would you draw vertical lines with this char * then?

ttyplot@master uses mvvline() for this. All the functions from the vline() family take either a chtype (an integer holding an ASCII character, with attributes in the upper bits) or a const cchar_t * (which is based on wchar_t). None of them takes a multibyte sequence as a char *.

Maybe replacing mvvline() with a loop of mvaddstr()? It may be worth a try. If this can work with a non-wchar version of ncurses, this could be a win! Would you write that patch?

from ttyplot.

tenox7 avatar tenox7 commented on June 11, 2024

What OS and terminal is this on?

from ttyplot.

MIvanchev avatar MIvanchev commented on June 11, 2024

Hey, it's on Void Linux, Fish shell.

from ttyplot.

tenox7 avatar tenox7 commented on June 11, 2024

What is the terminal app, font and locale setting, LANG=

thanks

from ttyplot.

MIvanchev avatar MIvanchev commented on June 11, 2024

Alacritty, LiterationMono Nerd Font Mono from https://www.nerdfonts.com/, en_US.UTF-8

from ttyplot.

hartwork avatar hartwork commented on June 11, 2024

@edgar-bonet nice analysis! 👍

from ttyplot.

MIvanchev avatar MIvanchev commented on June 11, 2024

Yes, excellent find! Sadly a 100% correct solution will require something like iconv and a library dependency. A solution for the maybe most common case UTF-8 would require calling nl_langinfo and a UTF-8 parser like this. If the locale is not UTF-8 ttyplot could print a warning and use the default char.

from ttyplot.

edgar-bonet avatar edgar-bonet commented on June 11, 2024

@MIvanchev: Here is mine ====. OK, I'll write the patch...

from ttyplot.

MIvanchev avatar MIvanchev commented on June 11, 2024

You're too fast! I just had another idea that doesn't use wide strings and thus no change in dependencies. We could use mblen to find out how many bytes the first character takes, copy them to a new buffer plus \0 and pass this to ncurses instead. So in essence

int char_len = mblen(argv[1], strlen(argv[1]));
assert(char_len < SIZE_MAX)
char *buf = malloc(char_len + 1);
strncpy(buf, argv[1], char_len + 1);

/* Use buf with ncurses. */

from ttyplot.

MIvanchev avatar MIvanchev commented on June 11, 2024

Let me see if I remember how programming works...

from ttyplot.

MIvanchev avatar MIvanchev commented on June 11, 2024

Scrape my idea, I tested extensively over the weekend and it doesn't really work, ncurses doesn't seem to support multi-byte chars through char.

from ttyplot.

edgar-bonet avatar edgar-bonet commented on June 11, 2024

@MIvanchev: In the mean time, multi-byte characters work file on the development branch.

from ttyplot.

MIvanchev avatar MIvanchev commented on June 11, 2024

Yeah, I know, they have worked for a long time thanks to your effort :D I was just curious whether ncursesw is really necessary but it seems it really is ¯\(ツ)

from ttyplot.

hartwork avatar hartwork commented on June 11, 2024

Closing as fixed by #99

from ttyplot.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.