代码之家  ›  专栏  ›  技术社区  ›  Chen Levy

tui通过termcap使用纯ascii(7位)字符的俚语

  •  0
  • Chen Levy  · 技术社区  · 15 年前

    我使用newt/snack(tui基于俚语的python图形widgit库)来编写一些交互式脚本。但是对于一些目标终端,这些屏幕的输出不是很好。我可以通过改变 $TERM 变量来删除不可打印的字符,并将其转换为更合适的字符。例如:

    TERM=linux python myscript.py
    

    到目前为止我测试的值 美元条款 ,只取得了中等的成功。

    $term是否有一个已知的值,可以一致地转换图形字符:

    ┌────────────┤ Title ├────────────┐
    │                                 │
    │ Some text for the entry window  │
    │                                 │
    │   foo _______________________   │
    │   bar _______________________   │
    │   baz _______________________   │
    │                                 │
    │    ┌────┐        ┌────────┐     │
    │    │ Ok │        │ Cancel │     │
    │    └────┘        └────────┘     │
    │                                 │
    └─────────────────────────────────┘
    

    非图形字符:

    +------------| Title |------------+
    |                                 |
    | Some text for the entry window  |
    |                                 |
    |   foo _______________________   |
    |   bar _______________________   |
    |   baz _______________________   |
    |                                 |
    |    +----+        +--------+     |
    |    | Ok |        | Cancel |     |
    |    +----+        +--------+     |
    |                                 |
    +---------------------------------+
    
    2 回复  |  直到 15 年前
        1
  •  1
  •   Thomas Dickey    8 年前

    简而言之:不-它(newt和俚语)根本不 那。

    长:

    newt使用函数 SLsmg_draw_box 此处所示为参考:

    void SLsmg_draw_box (int r, int c, unsigned int dr, unsigned int dc)
    {  
       if (Smg_Mode == SMG_MODE_NONE) return;
    
       if (!dr || !dc) return;
       This_Row = r;  This_Col = c;
       dr--; dc--;
       SLsmg_draw_hline (dc);
       SLsmg_draw_vline (dr);
       This_Row = r;  This_Col = c;
       SLsmg_draw_vline (dr);
       SLsmg_draw_hline (dc);
       SLsmg_draw_object (r, c, SLSMG_ULCORN_CHAR);
       SLsmg_draw_object (r, c + (int) dc, SLSMG_URCORN_CHAR);
       SLsmg_draw_object (r + (int) dr, c, SLSMG_LLCORN_CHAR);
       SLsmg_draw_object (r + (int) dr, c + (int) dc, SLSMG_LRCORN_CHAR);
       This_Row = r; This_Col = c;
    }
    

    slsmg.c 文件,俚语有一个表:

    typedef struct
    {  
       unsigned char vt100_char;
       unsigned char ascii;
       SLwchar_Type unicode;               /* may have an ambiguous width */
       SLwchar_Type unicode_narrow;        /* has a narrow width */
    }
    ACS_Def_Type;
    
    static SLCONST ACS_Def_Type UTF8_ACS_Map[] =
    {  
       {'+', '>', 0x2192,  '>'}, /* RIGHTWARDS ARROW [A] */
       {',', '<', 0x2190, '<'}, /* LEFTWARDS ARROW [A] */
       {'-', '^', 0x2191, 0x2303}, /* UPWARDS ARROW [A] */
       {'.', 'v', 0x2193, 0x2304}, /* DOWNWARDS ARROW [A] */
    

    但如果应用程序(newt)告诉它使用utf-8编码,它将自动选择unicode值。newt无条件地这样做,忽略终端和区域设置信息:

    /** 
     * @brief Initialize the newt library 
     * @return int - 0 for success, else < 0 
     */
    int newtInit(void) {  
        char * MonoValue, * MonoEnv = "NEWT_MONO";
        const char *lang;
        int ret;
    
        if ((lang = getenv("LC_ALL")) == NULL)
            if ((lang = getenv("LC_CTYPE")) == NULL)
                if ((lang = getenv("LANG")) == NULL)
                    lang = "";
        /* slang doesn't support multibyte encodings except UTF-8, 
           avoid character corruption by redrawing the screen */
        if (strstr (lang, ".euc") != NULL)
            trashScreen = 1;
    
        (void) strlen(ident);
    
        SLutf8_enable(-1);
        SLtt_get_terminfo();
        SLtt_get_screen_size();
    

    回到 SLSMG , the init_acs() 函数将首先尝试使用Unicode(如果您的语言环境支持UTF-8,则始终成功)。如果它碰巧是其他东西,则函数继续使用终端描述中存在的任何信息。

    通常,如果终端支持线绘制字符,则会编写每个终端描述来说明如何绘制线。如果你 被改进的 一个终端描述要去掉这些功能,你可以只得到ascii(但那是基于仅仅阅读这个函数:俚语有许多硬编码的情况,用来填充终端描述,这些描述并不像俚语作者想要的那样,你可能会被其中的一个绊倒)。

    值得一提的是,俚语使用的terminfo功能有: acsc , enacs , rmacs , smacs .

        2
  •  0
  •   a paid nerd    14 年前

    可能是基于你的 $LANG 被设定成 en_US.UTF-8 . 试着把它改成 en_US (假设您的基本语言环境是 恩努斯 )

    推荐文章