昨日はHTML出力したアイコンファイルの16色ビットマップを、今日はConEmu上のpsqlで表示。一部のRGBが指定どおりでないけど、SELECT文にエスケープシーケンスを挿入することでカラーのドット絵を出せました。
実行環境
Windows7 x64
ConEmu 150813g + CMD.exe(普通のコマンドプロンプトのシェル)
PostgreSQL 9.5.3(Windowsネイティブ。psqlも一緒)
エスケープシーケンスによる文字色変更のテスト
2月5日の記事では、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指定とは違うぽいけど、とりあえず今回は妥協。
RGBのHEX形式をエスケープシーケンスに変えるテスト
最初から10進数の色指定(0~255)になってれば不要ですが、昨日はICOファイル中のバイナリのまま、HEX形式(00~FF)でした。これをエスケープシーケンスの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出力する直前の状態は ↓ こうでした。nrowとncolが行と列の番号、trが透過セルか否か、rgbがHEX形式の色。ここから、色を前項のようにエスケープシーケンスに変換しつつ、各行を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