昨日はHTML出力したアイコンファイルの16色ビットマップを、今日はConEmu上のpsqlで表示。一部のRGBが指定どおりでないけど、SELECT文にエスケープシーケンスを挿入することでカラーのドット絵を出せました。

Contents



実行環境

• Windows7 x64
• ConEmu 150813g + CMD.exe(普通のコマンドプロンプトのシェル)
• PostgreSQL 9.5.3(Windowsネイティブ。psqlも一緒)


エスケープシーケンスによる文字色変更のテスト

25日の記事では、psqlのメタコマンドから回りくどい方法でプロンプトの色を変えました。今日は直接、SELECT文で表示する文字列の前にエスケープシーケンスを挿入して色付け。↓ こんなテストでカラーになれば準備OKです。
# \t on \\ \pset format unaligned
# select e'\x1b[38;2;255;0;0m' || repeat('■', 32) || e'\n' 
    || e'\x1b[38;2;0;255;0m' || repeat('▲', 32) || e'\n'
    || e'\x1b[38;2;0;0;255m' || repeat('●', 32) || e'\n'
    || e'\x1b[38;2;255;255;255m';


最初にメタコマンド\t\psetで表示内容をクエリ結果にしぼり、列名や整形用スペースを省きます。これがあると何故かエスケープシーケンスが効かないので。また最後に文字色を戻すシーケンスを付加。ConEmuでは白と黒が逆らしく、普通の黒文字に戻すのにrgb(255, 255, 255)を指定します。

上の画像は、ConEmuにプリセットされてるカラー設定 ↓ のうちSolarized Lightで実行したもの。原色の緑(0, 255, 0)がくすんでる気がします。他のカラーだともっと極端な場合もあり(2つ目の画像、Solarized (John Doe)で実行)単純なRGB指定とは違うぽいけど、とりあえず今回は妥協。



RGBHEX形式をエスケープシーケンスに変えるテスト

最初から10進数の色指定(0255)になってれば不要ですが、昨日はICOファイル中のバイナリのまま、HEX形式(00FF)でした。これをエスケープシーケンスのRGB指定に変えるテストクエリが ↓ こんな感じ。実行の前に、前項と同様クエリ結果だけを表示するメタコマンドを打ちます。
# \t on \\ \pset format unaligned
# select concat(e'\x1b[38;2;',
            concat('x', ary[1]) :: bit(8) :: int, ';',
            concat('x', ary[2]) :: bit(8) :: int, ';',
            concat('x', ary[3]) :: bit(8) :: int, 'm■', 
        e'\x1b[38;2;255;255;255m')
from (
    values ('fabfab')  -- input HEX color as you want
) as foo (rgb),
    regexp_matches(rgb, '(.{2})(.{2})(.{2})') as ary;



最終形、いろんなカラー設定での結果

昨日、抽出したビットマップをHTML出力する直前の状態は ↓ こうでした。nrowncolが行と列の番号、trが透過セルか否か、rgbHEX形式の色。ここから、色を前項のようにエスケープシーケンスに変換しつつ、各行をncolの順に連結し、行番号順に並べれば最終形になります。
# with lines (nrow, hex, tr) as (
    select nrow,
        regexp_split_to_table(pixel_lines, ''),
        regexp_split_to_table(trans_lines, '')
    from icon_pixels natural join icon_trans
)
select *, row_number() over(partition by nrow) as ncol 
from lines natural join icon_colors;
+-----+------+----+--------+------+
| hex | nrow | tr |  rgb   | ncol |
+-----+------+----+--------+------+
| 0   |    1 | 1  | 000000 |    1 |
| 0   |    1 | 1  | 000000 |    2 |
| 0   |    1 | 1  | 000000 |    3 |
| 0   |    1 | 1  | 000000 |    4 |
| 0   |    1 | 1  | 000000 |    5 |
| 0   |    1 | 1  | 000000 |    6 |
...
| 0   |    6 | 0  | 000000 |   27 |
| 7   |    6 | 0  | c0c0c0 |   28 |
| 7   |    6 | 0  | c0c0c0 |   29 |
| 0   |    6 | 0  | 000000 |   30 |
| 8   |    6 | 0  | 808080 |   31 |
| 0   |    6 | 0  | 000000 |   32 |
| 8   |    7 | 0  | 808080 |    1 |
| 7   |    7 | 0  | c0c0c0 |    2 |
| 4   |    7 | 0  | 000080 |    3 |
| 4   |    7 | 0  | 000080 |    4 |
...


↓ というわけで最終形。途中で切れないようページャをOFFにして実行します。RGBを単純に表すだけでなく(1)透過部分は■を□に(2)白と黒の指定を逆に(3)最後に黒文字に戻すエスケープシーケンスを追加、と処理が増えて長くなりました。
# \t on \\ \pset format unaligned \\ \pset pager off
# with lines (nrow, hex, tr) as (
    select nrow,
        regexp_split_to_table(pixel_lines, ''),
        regexp_split_to_table(trans_lines, '') :: int
    from icon_pixels natural join icon_trans
    order by nrow
), pixels (nrow, ncol, chr) as (
    select nrow, row_number() over(partition by nrow),
        case tr when 0 then concat(e'\x1b[38;2;',
            concat('x', ary[1]) :: bit(8) :: int, ';',
            concat('x', ary[2]) :: bit(8) :: int, ';',
            concat('x', ary[3]) :: bit(8) :: int, 'm■'
        )
        else '□'
        end, rgb
    from lines natural join icon_colors,
        regexp_matches(case rgb when '000000' then 'ffffff' 
            when 'ffffff' then '000000' else rgb end,
        '(.{2})(.{2})(.{2})') as ary
)
(select string_agg(chr, '' order by ncol)
from pixels
group by nrow order by nrow)
union all
select e'\x1b[38;2;255;255;255m';


↓ 実行した様子。クエリ結果(カラービットマップ)は冒頭の画像と同じです。


この先はおまけ。ConEmuの便利な点として、カラー設定を変えると実行済み結果を含めてターミナルの配色が変わります。つまりクエリを実行し直さずに様々な配色で比較できるので、プリセット全てについて試しました。

結果、プリセット先頭のDefault Windows scheme↓ が本来のRGB指定に最も近い感じ。白と黒も逆にする必要はなかった模様。以下、全ての画像を並べておきます。

Base16

Cobalt2

ConEmu

Gamma 1

Monokai

Murena scheme

PowerShell

Solarized

Solarized Git

Solarized (Luke Maciak)

Solarized (John Doe)

SolarMe

Standard VGA

tc-maxx

Terminal.app

Tomorrow

Tomorrow Night

Tomorrow Night Blue

Tomorrow Night Bright

Tomorrow Night Eighties

Twilight

Ubuntu

xterm

Zenburn