LoginSignup
1
0

More than 3 years have passed since last update.

Kinx ライブラリ - エスケープ・シーケンス

Last updated at Posted at 2020-06-05

Kinx ライブラリ - エスケープ・シーケンス

はじめに

「見た目は JavaScript、頭脳(中身)は Ruby、(安定感は AC/DC)」 でお届けしているスクリプト言語 Kinx。言語はライブラリが命。ということでライブラリの使い方編。

今回はエスケープ・シーケンスです。なんのこっちゃと思うかもしれませんが、Windows でも VT100 のエスケープ・シーケンスを使えるようにしたので、この部分でも Windows/Linux で共通化が(一部)可能に。

将来的に curses を使う話もなくはない。ただ大掛かりで高機能なので、まずは簡単にエスケープ・シーケンスが使える程度でも役に立つかと。

エスケープ・シーケンスって何?

制御端末って味気ないですよね。エスケープ・シーケンスを使うとホラ、今すぐあなたもカラフルに色をつけたり、ページングしたり、ちょっとした見栄えの良い操作性を提供できます。

どうやって実現?

ます、レキサーのほうでは \e\x1b の代わりとして使えるようにした。短く書けて便利です。

Linux 端末は VT100 系統のエスケープ・シーケンスは最初から使える想定。Windows は以下を利用させていただきました。

これで Windows のエスケープ・シーケンスもサポート完了。なんて素晴らしいライブラリなんだ。MIT ライセンス。しかし、いくつか修正した。

  • ESC [ 38;2;r;g;b mESC [ 38;5;d m に対応してなかったので対応。
  • ESC [ 48;2;r;g;b mESC [ 48;5;d m に対応してなかったので対応。
  • アンダーラインがボールドと同じ対応で違和感があったので削除。アンダーラインは未サポート アンダーラインを正式にサポート(0.9.2リリースには入ってません)。

この記事を投稿した直後、ほんとにアンダーラインできんものなのか?と調べたらやり方が分かった。。。なので、たった今修正してコミットした。アンダーライン、サポートしたよ!(最新ソースでは)

Windows のコマンドプロンプトはかなり制限がきつく、16色しかサポートできない。なので、上記 3848 では近い色になるように結構細工している。しかしこんなに頑張る必要あったのだろうか、という気が若干しないでもない。しかもそんなにうまくいってる気がしない。まあいいか。

では、いくつかサンプルを見てみよう。

サンプル

サンプル 1

まずは色サンプル。これは ansicolor-w32.c でサポートしている範囲。ただし、アンダーラインだけは 未サポートにした 下記の結果に出ていないが自分で実装して最新ソースではサポートされている。尚、左側がコマンドプロンプト。右側の黄色い枠線内は WSL 上で動かしている ubuntu での結果。

ちなみに、このソースのオリジナルは ここ です。これを Kinx 用に書き換えています。

System.print("  --   ");
for (b in 40..47) {
  System.print("\e[%{b}m    %{b}   \e[0m ");
}
System.print("\n");
for (c in [ 30, 31, 32, 33, 34, 35, 36, 37, 90, 91, 92, 93, 94, 95, 96, 97 ]) {
  s = (""+c);
  System.print("\e[%{c}m %{c}   \e[0m ");
  for (b in 40..47) {
    s = "%{c};%{b}";
    System.print("\e[%{s}m %{s}   \e[0m ");
  }
  System.print("\n");
  for (a in [ 1, 4 ]) {
    s = "%{c};%{a}";
    System.print("\e[%{s}m %{s} \e[0m ");
    for (b in 40..47) {
      s = "%{c};%{b};%{a}";
      System.print("\e[%{s}m %{s} \e[0m ");
    }
    System.print("\n");
  }
}

この範囲ならばっちり使えると思う。アンダーラインは 無いけど 最新ソースでは追加した。

sample5.png

ここからが自分で追加実装した部分。

サンプル 2

256色指定での文字色。

for (i = 0; i < 16; i++) {
    for (j = 0; j < 16; j++) {
        const v = i*16+j;
        System.print("\e[38;5;%dm%02X\e[0m " % v % v);
    }
    System.print("\n");
}

こんな感じになる。16色しかないのでこんな感じか。個別に色を設定してはおらず RGB 情報から計算して 16 色に変換しているので、微妙に色の入れ替わりがスムーズでもない気もするが、こんなものか...。

sample1.png

サンプル 3

続いて256色指定での背景色。

for (i = 0; i < 16; i++) {
    for (j = 0; j < 16; j++) {
        const v = (i<<4) | j;
        System.print(" \e[48;5;%dm%02X" % v % v);
    }
    System.print("\e[0m\n");
}

出力結果。微妙に濃い感じに見えるな。

sample2.png

サンプル 4

RGB 指定での文字色。

for (i = 0; i < 16; i++) {
    for (j = 0; j < 32; j++) {
        System.print("\e[38;2;%d;%d;255mX" % (i<<4) % (j<<3));
    }
    System.print("\e[0m\n");
}

この辺から怪しさが増す。が、それっぽく...

sample3.png

サンプル 5

RGB 指定での背景色。

for (i = 0; i < 16; i++) {
    for (j = 0; j < 32; j++) {
        System.print("\e[48;2;%d;%d;255m " % (i<<4) % (j<<3));
    }
    System.print("\e[0m\n");
}

こうすると違いが目立つ。

sample4.png

サンプル 6

基本的なところに戻って、テキストベースでのプログレスバーなんかも出せる。元ネタは ここ の「エスケープシーケンスの利用」です。

System.print("0%       50%       100%\n");
System.print("+---------+---------+\n");
for (i = 0; i <= 100; i++) {
    for (j = 0; j < i / 5 + 1; j++) {
        System.print("#");
    }
    System.print("\n");
    System.print("%3d%%\n" % i);
    System.sleep(100);
    System.print("\e[2A");
}
System.print("\n\nfinish!\n");

sample7.png

おわりに

エスケープ・シーケンスは今時そんなに重要ではないとは思うが、ちょっとしたコマンドを見栄え良くするのに便利なので、個人的には好き。Windows で使えるって、そこそこ嬉しい人いるんじゃなかろうか。

ではまた、次回。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0