初歩のシェルスクリプトで遊ぶ[端末の256色カラーセレクタ(4)]
バージョン3.1でいったん置いとく
入れようと思ってた機能は入れたんで、ここらでいったんスクリプトを置いときます。
こっちはメインの256色版。
2000行あるけれど、いちおうファイル一つにまとまってます。丸ごとコピーして実行権限つければいけるはず。
Ubuntu20.04,xfce-terminalあたりで、無料・無保証で構わない人のみどうぞ。
端末が違うと動かない機能があったりしますが、それも含めて端末のテストも兼ねてます。こっちの端末は太字が出ないんだな、とか。
#!/bin/sh #!/bin/bash #!/usr/bin/ksh #!/usr/bin/posh #!/bin/busybox sh #!/usr/bin/zsh #!/usr/bin/yash #!/bin/dash # ======================================================================================== # ■ 端末カラーセレクター256色 v3.1 # https://twitter.com/beta_reverse_2 # ======================================================================================== # ************************************************************************************** # ユーザ設定_任意 # ************************************************************************************** # サンプルテキスト # 横幅推奨値=' ' STD_SAMPLE=' standard sample text ' MAIN_SAMPLE=' main sample text ' SUB_SAMPLE=' sub sample text ' FREE_SAMPLE=' free sample text ' # カラーパレットの横幅初期値 paletteWidth='96' # カラーパレットの並び順データ # # ====[shMerge]==== colorTableListSh 20201101_085854 colorTableListSh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # 引数に数字を与えると、その番号のカラーパレットデータを出力する # パレットデータの数字は「0-255」 # 行のデータはタブ区切りにする # 1行に入れる数値データの数は、360の約数にする # 行数に制限は無いが、端末表示に収まる行数に。 # 「0-255」を、すべて必ず1回ずつ使わなければならない。 # 同じ数字を複数回使ってはいけない。 # カスタマイズするなら、既存のカラーパレットをベースにして、行単位で入れ替えると簡単。 # HSL S -> L -> H Palette0='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 16 59 102 145 188 231 95 101 65 66 60 96 138 144 108 109 103 139 131 137 143 107 71 72 73 67 61 97 133 132 181 187 151 152 146 182 174 180 186 150 114 115 116 110 104 140 176 175 167 173 179 185 149 113 77 78 79 80 74 68 62 98 134 170 169 168 52 58 22 23 17 53 88 94 100 64 28 29 30 24 18 54 90 89 124 130 136 142 106 70 34 35 36 37 31 25 19 55 91 127 126 125 160 166 172 178 184 148 112 76 40 41 42 43 44 38 32 26 20 56 92 128 164 163 162 161 196 202 208 214 220 226 190 154 118 82 46 47 48 49 50 51 45 39 33 27 21 57 93 129 165 201 200 199 198 197 203 209 215 221 227 191 155 119 83 84 85 86 87 81 75 69 63 99 135 171 207 206 205 204 210 216 222 228 192 156 120 121 122 123 117 111 105 141 177 213 212 211 217 223 229 193 157 158 159 153 147 183 219 218 224 230 194 195 189 225' # HSL L -> S -> H Palette1='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 16 59 102 145 188 231 52 58 22 23 17 53 88 94 100 64 28 29 30 24 18 54 90 89 124 130 136 142 106 70 34 35 36 37 31 25 19 55 91 127 126 125 160 166 172 178 184 148 112 76 40 41 42 43 44 38 32 26 20 56 92 128 164 163 162 161 95 101 65 66 60 96 196 202 208 214 220 226 190 154 118 82 46 47 48 49 50 51 45 39 33 27 21 57 93 129 165 201 200 199 198 197 131 137 143 107 71 72 73 67 61 97 133 132 138 144 108 109 103 139 167 173 179 185 149 113 77 78 79 80 74 68 62 98 134 170 169 168 174 180 186 150 114 115 116 110 104 140 176 175 203 209 215 221 227 191 155 119 83 84 85 86 87 81 75 69 63 99 135 171 207 206 205 204 181 187 151 152 146 182 210 216 222 228 192 156 120 121 122 123 117 111 105 141 177 213 212 211 217 223 229 193 157 158 159 153 147 183 219 218 224 230 194 195 189 225' # カラーパレット_色番号順 Palette2='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231' # HSV S -> V -> H Palette3='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 16 59 102 145 188 231 224 230 194 195 189 225 181 187 151 152 146 182 138 144 108 109 103 139 95 101 65 66 60 96 217 223 229 193 157 158 159 153 147 183 219 218 174 180 186 150 114 115 116 110 104 140 176 175 131 137 143 107 71 72 73 67 61 97 133 132 210 216 222 228 192 156 120 121 122 123 117 111 105 141 177 213 212 211 167 173 179 185 149 113 77 78 79 80 74 68 62 98 134 170 169 168 203 209 215 221 227 191 155 119 83 84 85 86 87 81 75 69 63 99 135 171 207 206 205 204 52 58 22 23 17 53 88 94 100 64 28 29 30 24 18 54 90 89 124 130 136 142 106 70 34 35 36 37 31 25 19 55 91 127 126 125 160 166 172 178 184 148 112 76 40 41 42 43 44 38 32 26 20 56 92 128 164 163 162 161 196 202 208 214 220 226 190 154 118 82 46 47 48 49 50 51 45 39 33 27 21 57 93 129 165 201 200 199 198 197' # HSV V -> S -> H Palette4='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 16 59 102 145 188 231 52 58 22 23 17 53 95 101 65 66 60 96 88 94 100 64 28 29 30 24 18 54 90 89 138 144 108 109 103 139 131 137 143 107 71 72 73 67 61 97 133 132 124 130 136 142 106 70 34 35 36 37 31 25 19 55 91 127 126 125 181 187 151 152 146 182 174 180 186 150 114 115 116 110 104 140 176 175 167 173 179 185 149 113 77 78 79 80 74 68 62 98 134 170 169 168 160 166 172 178 184 148 112 76 40 41 42 43 44 38 32 26 20 56 92 128 164 163 162 161 224 230 194 195 189 225 217 223 229 193 157 158 159 153 147 183 219 218 210 216 222 228 192 156 120 121 122 123 117 111 105 141 177 213 212 211 203 209 215 221 227 191 155 119 83 84 85 86 87 81 75 69 63 99 135 171 207 206 205 204 196 202 208 214 220 226 190 154 118 82 46 47 48 49 50 51 45 39 33 27 21 57 93 129 165 201 200 199 198 197' # 存在するデータの番号を入力されたとき、そのデータを出力して、exit 0 # 存在しないデータの番号を入力されたとき、exit 1 eval 'XX=`echo "${Palette'${1:-0}'}"`' if test -n "${XX}" ; then eval 'echo "${Palette'${1:-0}'}"' exit 0 else exit 1 fi # [EOF] ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== effectCodeList256Sh 20201101_085854 effectCodeList256Sh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # 1行に6個ずつ # 空なら0を埋めておく LF=' ' codeList="0${LF}1${LF}2${LF}3${LF}4${LF}5 6${LF}7${LF}8${LF}9${LF}10${LF}11 12${LF}13${LF}14${LF}15${LF}16${LF}17 18${LF}19${LF}20${LF}21${LF}22${LF}23 24${LF}25${LF}26${LF}27${LF}28${LF}29 51${LF}52${LF}53${LF}54${LF}55${LF}56 60${LF}61${LF}62${LF}63${LF}64${LF}65" echo "${codeList}" ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== helpMessageC256sh 20201101_085854 helpMessageC256sh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # 操作説明 printf \ '\033[7m%s\033[27m %s '\ '\033[7m%s\033[27m %s '\ '\033[7m%s\033[27m %s\n'\ '\033[7m%s\033[27m %s '\ '\033[7m%s\033[27m %s '\ '\033[7m%s\033[27m %s '\ '\033[7m%s\033[27m %s '\ '\033[7m%s\033[27m %s\n' \ ' up down left right ' '選択決定' \ ' PgUp PgDn ' 'フォーカス切替' \ ' space 0 ' 'チェック' \ ' + a ' '色情報詳細' \ ' - s ' 'mainとsubを入替' \ ' . ' '色配置' \ ' * ' '拡張操作' \ ' / q ' '終了' true ) } # ====[shMerge</ins>]==== # ====================================================================================== # グローバル定数 シェル関数内での再定義と検索タグは必須 # ====================================================================================== ESC=`printf '\033'` # 【gloval const ESC】 ctrl_plus_C=`printf '\003'` # 【gloval const ctrl_plus_C】 ENTER_KEY=`printf '\015'` # 【gloval const ENTER_KEY】 # ====================================================================================== # シェル関数_外部へ分離可能 # ====================================================================================== # cd $(dirname `readlink -f "${0}"`) # ====[shMerge<disable>]==== #_shMergeDisabled # PATH="./lib:${PATH}" # ====[shMerge<disable>]==== #_shMergeDisabled # # ====[shMerge]==== ansi256matrixToViewCodeSh 20201101_085854 ansi256matrixToViewCodeSh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # カラーパレット表を読み込んで、パレットを端末表示するためのデータを作成する。 # 表示幅(文字数)は指定できる。 # 一行に指定されるパレットの数が増減しても、表示幅を同じ幅に揃える。 roundSh(){ ( Width=${1:?'横幅指定が必要'} Part=${2:?'分割数指定が必要'} # 余った文字数 Remaind=$(( ${Width} % ${Part} )) # 余った文字を振り分ける行番号リスト addLines='' NN=1 while test ${NN} -le ${Remaind} ; do addLines="${addLines}$(( ( ${Part} * ${NN} ) / ( ${Remaind} + 1 ) + 1 )) " NN=$(( ${NN} + 1 )) done #echo "${addLines}" # 【debug】 partNo='1' while test "${partNo}" -le "${Part}" ; do addLineFlag='false' # ${partNo}が 指定値と同じなら フラグtrue while read addLine ; do if test -z "${addLine}" ; then continue elif test "${partNo}" -eq "${addLine}" ; then addLineFlag='true' fi done << ____ADD_LINES ${addLines} ____ADD_LINES #printf '%d:' "${partNo}" # 【debug】 # trueのとき1加算 if ${addLineFlag} ; then echo $(( ${Width} / ${Part} + 1 )) else echo $(( ${Width} / ${Part} )) fi partNo=$(( ${partNo} + 1 )) done exit 0 ) } # 全体の横幅は何文字にするのか Cols=${1:-78} while read LINE ; do eval set -- ${LINE} addChars=`roundSh ${Cols} ${#}` NUM=0 while read NN ; do NUM=$(( ${NUM} + 1 )) eval 'wordLength_'${NUM}'=${NN}' done << ____add ${addChars} ____add NUM=0 for Index in ${@} ; do NUM=$(( ${NUM} + 1 )) # wordLength インデックスカラーを表示する幅を文字数で eval 'wordLength=${wordLength_'${NUM}'}' # Index インデックス番号 # wordLength 表示幅を文字数で echo "${Index} ${wordLength}" done echo '0 -1' done ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== ansi256matrixToMagSh 20201101_085854 ansi256matrixToMagSh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # ansi256matrixデータの、 # 各行のカーソル移動によるX座標の移動値 # 開始値を0、最大値を359として、360を各行の要素数で割る # カーソル移動して数値を増減させるときは、この数値を倍して増減する。 # この数値を倍率で割って、マトリックスから行を抜き出し、 # 商に1加算してcut -fすると、インデックス番号が得られる。 while read TR ; do # ansi256matrixデータの、各行のデータ数を数える eval set -- ${TR} # データを1つズラす度に増減させる値 echo $(( 360 / ${#} )) done # テーブル数が6のとき # 0 60 120 180 240 300 360 # 1 2 3 4 5 6 # # 1:0-59 # 2:60-119 # 3:120-179 # 4:180-239 # 5:240-299 # 6:300-359 # ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== ansi256matrixToGridSh 20201101_085854 ansi256matrixToGridSh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # 色番号からカーソルXY座標を得るデータを作成 # インデックス番号表データを、 # 「カラーインデックス番号+1」行:カーソルX座標(0-359):Y座標(0-) # へ変換する。 # インデックス番号+1行目のデータを取り出すと、カーソルXY座標が得られる。 # インデックス番号は「0-255」で、重複と欠番があってはならない matrixTR='-1' indexCheck='-1' while read LINE ; do matrixTR=$(( ${matrixTR} + 1 )) eval 'set -- '${LINE} # X座標値の倍率を計算する Mag=$(( 360 / ${#} )) # カラーインデックス番号 X座標 Y座標 matrixTD='-1' for Index in ${@} ; do matrixTD=$(( ${matrixTD} + 1 )) echo "${matrixTR} $(( ${matrixTD} * Mag )) ${Index}" done # カラーインデックスでソート done | sort -k3n ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== ansi256viewToSepCode2sh 20201101_085854 ansi256viewToSepCode2sh(){ ( # ====[shMerge<ins>]==== #!/bin/sh #!/usr/bin/ksh #!/bin/bash # viewCodeを受け取って、見えない数字が埋め込まれた端末表示画像データを作成する # このスクリプトで作成するデータは、呼び出し元プロセスの # シェル変数に保存して、繰り返し利用する # セパレータを4つ作成,ESC作成 ESC=`printf "\033"` FS=`printf "\034"` # 3 GS=`printf "\035"` # 2 RS=`printf "\036"` # 1 US=`printf "\037"` # 0 numToQuotCodeFunc(){ XX="${1}" shift 1 quotCode='' for NN in ${@} ; do case "${NN}" in ( 0 ) quotCode="${quotCode}${US}" ;; ( 1 ) quotCode="${quotCode}${RS}" ;; ( 2 ) quotCode="${quotCode}${GS}" ;; ( 3 ) quotCode="${quotCode}${FS}" ;; esac done eval ${XX}'="${quotCode}"' } while read Palette Nums ; do # パレット表示幅Numsと同じ数連続した半角空白を作る NN=0 paletteSp='' while test ${NN} -lt ${Nums} ; do paletteSp="${paletteSp} " NN=$(( ${NN} + 1 )) done case "${Nums}" in # ---------------------------------------------------------------------- ( -* ) # 改行_負の数はすべて改行を意味する # ---------------------------------------------------------------------- echo "${ESC}[0mN" continue ;; # ---------------------------------------------------------------------- ( 0 ) # 文字幅が0文字のとき # ---------------------------------------------------------------------- continue ;; # ---------------------------------------------------------------------- ( * ) # 文字幅がすべて1文字以上のとき # ---------------------------------------------------------------------- Quot64=$(( ${Palette} / 64 )) Quot16=$(( ${Palette} % 64 / 16 )) Quot4=$(( ${Palette} % 64 % 16 / 4 )) Quot1=$(( ${Palette} % 64 % 16 % 4 )) # 見えない数字を読み込む numToQuotCodeFunc quotSepNo ${Quot64} ${Quot16} ${Quot4} ${Quot1} echo "${ESC}[48;5;${Palette}m${paletteSp}${quotSepNo}" #printf "${ESC}[48;5;${Palette}m${paletteSp}${quotSepNo}" ;; esac done | tr -d '\n' | tr 'N' '\n' | sed -e '{ s/^/colorSep\o037\o036\o035\o034/1 }' #done | sed -e '{ s/^/colorSep\o037\o036\o035\o034/1 }' #done | sed -n -e ' #/N$/!{H;d} #/N$/{H;g;s/\n//g;s/N$//;s/^/colorSep\o037\o036\o035\o034/1;p;s/.*//;h;d}' ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== sepDrawFocusOvewWrite1sh 20201101_085854 sepDrawFocusOvewWrite1sh(){ ( # ====[shMerge<ins>]==== #!/bin/sh #!/usr/bin/ksh #!/bin/dash #!/usr/bin/yash #!/usr/bin/zsh #!/bin/busybox sh #!/bin/bash # ---------------------------------------------------------------------- # セパレータコード可視化 # ---------------------------------------------------------------------- # 見えない数字が埋め込まれたセパレータ埋め込みコードを受け取り、 # 指定された見えない数字の場所にカーソルを表示する fgNo=${1:-245} bgNo=${2:-250} fgNoQ64=$(( ${fgNo} / 64 )) fgNoQ16=$(( ${fgNo} % 64 / 16 )) fgNoQ4=$(( ${fgNo} % 64 % 16 / 4 )) fgNoQ1=$(( ${fgNo} % 64 % 16 % 4 )) bgNoQ64=$(( ${bgNo} / 64 )) bgNoQ16=$(( ${bgNo} % 64 / 16 )) bgNoQ4=$(( ${bgNo} % 64 % 16 / 4 )) bgNoQ1=$(( ${bgNo} % 64 % 16 % 4 )) arabicToSepNumFunc(){ # ${1}:代入変数名 # ${2}:Q64位_[0-3] # ${3}:Q16位_[0-3] # ${4}:Q4位_[0-3] # ${5}:Q1位_[0-3] for NN in ${2} ${3} ${4} ${5} ; do if test ${NN} -eq 0 ; then eval ${1}'="${'${1}'}${US}"' elif test ${NN} -eq 1 ; then eval ${1}'="${'${1}'}${RS}"' elif test ${NN} -eq 2 ; then eval ${1}'="${'${1}'}${GS}"' elif test ${NN} -eq 3 ; then eval ${1}'="${'${1}'}${FS}"' fi done } QfgNo='' QbgNo='' # 疑似4進数の値(FS,GS,RS,US)を番号名に設定 eval `printf "FS=\034 GS=\035 RS=\036 US=\037 "` arabicToSepNumFunc QfgNo ${fgNoQ64} ${fgNoQ16} ${fgNoQ4} ${fgNoQ1} arabicToSepNumFunc QbgNo ${bgNoQ64} ${bgNoQ16} ${bgNoQ4} ${bgNoQ1} # ---------------------------------------------------------------------- # フォーカスマーク付加 # ---------------------------------------------------------------------- focusNo="${3}" sed -n -e '#n # overWrite 1行目行頭にエスケープシーケンス埋め込み 1{ s/^/\o033[1;1H\o033[?25l/ } # overWrite 行末改行前にエスケープシーケンス埋め込み ${ s/$/\o033[?0J\o033[?25h/ } # sepCodeDraw 不可視セパレータコードを可視化 --------------------------- /^colorSep\o037\o036\o035\o034/{ # 色用セパレータ行開始マークを削除 s/^colorSep\o037\o036\o035\o034//1 # /231/231色S/ 数字を残したまま「色S」を挿入 { s/'${QfgNo}'/'${QfgNo}'\o033[0;30;103mS/ # / 231/色| 数字と直前の半角空白を削って「色|」を挿入 s/ '${QbgNo}'/\o033[0;30;106m|/ } # もし「色|色S」があるならば /\o033\[0;30;106m|\o033\[0;30;103mS/{ # 「色$」に入れ替え s/\o033\[0;30;106m|\o033\[0;30;103mS/\o033[0;30;107m$/ } # / 231色S/色S S前の半角空白を削除 { s/ '${QfgNo}'\o033\[0;30;103mS/\o033[0;30;103mS/ } } # focusMark フォーカスしているならば /^FOCUS_ID_'${focusNo}'$/{ # 上書きして次の行を読み込む n # 矢印を右端に付加 s/$/ \o033[7m <= \o033[0m/ # ↓のフォーカスID削除には該当せず通常出力へ } /^FOCUS_ID_/ { # フォーカスID行を出力せずにcontinue d } # overWrite フォーカスIDではない他の全行ならば { s/$/\o033[0K/ # 行末尾に行右側消去を埋め込み p # 出力 }' ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== subMenuSh 20201101_085854 subMenuSh(){ ( # ====[shMerge<ins>]==== #!/bin/sh #!/usr/bin/posh #!/bin/busybox sh #!/bin/bash #!/usr/bin/yash #!/usr/bin/ksh #!/usr/bin/zsh #!/bin/dash # 簡単なサブメニューを表示 # リストから一つ選択を求め、リスト番号を出力する # 標準出力するのはリスト番号の数字のみ # それ以外のメニュー表示等は、全てエラー出力する selectList="${1}" # 選択リストの内容 改行区切りのテキストデータで windowWidth="${2:-36}" # 表示メニューの幅 文字数 orientY="${3:-4}" # 表示位置の原点左上の位置 Y orientX="${4:-10}" # 表示位置の原点左上の位置 X # CSIシーケンス開始後、末尾mの前まで # '\033[97;45m' なら '97;45' と書く menuColor="${5:-97;45}" #printf "\033#8" 1>&2 # 【debug】 listCount=`echo "${selectList}" | wc -l` focusLine='0' pressKeySh(){ ( stty_BAK=`stty -g` stty -echo raw dd count=1 2>/dev/null stty "${stty_BAK}" ) } UP____KEY=`printf '\033[A'` DOWN__KEY=`printf '\033[B'` ENTER_KEY=`printf '\015'` #tput sc printf '\0337' 1>&2 # tput sc # カーソル消去 printf '\033[?25l' 1>&2 # 表示領域の枠を描画 { printf "\033[${orientY};${orientX}H" for NN in `seq 1 ${listCount}` ; do printf "\033[${orientX}G\033[${menuColor}m%${windowWidth}s\033[0m\n" ' ' done } 1>&2 while true ; do { printf "\033[${orientY};${orientX}H" echo "${selectList}" | sed -e 's/^/ /1' \ -e "$(( ${focusLine} + 1 ))s/^ />/1" \ -e "s/.*/\o033[${orientX}G\o033[${menuColor}m&\o033[0m/" } 1>&2 case "`pressKeySh`" in ( 8 | ${UP____KEY} ) focusLine=$(( ( ${focusLine} - 1 + ${listCount} ) % ${listCount} )) ;; ( 2 | ${DOWN__KEY} ) focusLine=$(( ( ${focusLine} + 1 + ${listCount} ) % ${listCount} )) ;; ( ${ENTER_KEY} | 0 | ' ' ) #tput rc printf '\0338' 1>&2 # tput rc printf '\033[?25h' 1>&2 echo $(( ${focusLine} + 1 )) exit 0 ;; ( '*' ) echo '' exit 1 ;; esac done ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== effectCodeCheckSh 20201101_085854 effectCodeCheckSh(){ ( # ====[shMerge<ins>]==== #!/bin/sh #!/usr/bin/zsh # 文字装飾コードのチェックシートを表示する # ESC=`printf '\033'` # 【gloval const ESC】# ====[shMerge<disable>]==== #_shMergeDisabled # ${1}:フォーカスのID値(${2}のデータの行番号-1) focusIdNo=${1} # コードリストの行番号(${1}で指定される数値) codeIdCount='-1' # forループ1回ごとに+1 # 出力は1行ずつechoで echoLine='' # ${2}:コードの番号*1000 のリスト 有効/無効(正/負) # コマンド置換で「-1000 LF -1001 LF 1002 LF 1-1003 ....」の改行を空白に変換(zsh) set -- `echo ${2}` for flagNo in ${@} ; do codeIdCount=$(( ${codeIdCount} + 1 )) codeNo=$(( ${flagNo#-} - 1000 )) # 表示文字と色も変数に格納しておく # コードが有効化されているならば case "${flagNo}" in ( -* ) Ast=' ' ;; ( * ) Ast="${ESC}[7m*${ESC}[27m" ;; esac # 表示文字と色も変数に格納しておく # フォーカスが当たっているならば case ${focusIdNo} in ( ${codeIdCount} ) brL="${ESC}[7m[${ESC}[27m" brR="${ESC}[7m]${ESC}[27m" ;; ( * ) brL=' ' brR=' ' ;; esac case "${codeNo}" in # 桁数に合わせて横幅調整 ( ? ) # 1文字ならば echoLine="${echoLine}${brL}${Ast}${brR} ${codeNo}:${ESC}[${codeNo}mCode ${codeNo}${ESC}[0m" ;; ( * ) # 2文字以上ならば echoLine="${echoLine}${brL}${Ast}${brR}${codeNo}:${ESC}[${codeNo}mCode${codeNo}${ESC}[0m" ;; esac if test $(( ( ${codeIdCount} + 1 ) % 6 )) -eq 0 ; then echo "${echoLine}" echoLine='' fi done # 16色版は6の倍数以外もサポートする if test -n "${echoLine}" then echo "${echoLine}" fi ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== effectCodeBuildSh 20201101_085854 effectCodeBuildSh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # 実用できる文字装飾コードを組み立て eval 'set -- '${1} IFS=';' echo "${*}" ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== effectCodeRemoveSh 20201101_085854 effectCodeRemoveSh(){ ( # ====[shMerge<ins>]==== #!/bin/sh #!/usr/bin/zsh # 文字装飾コードを有効リストから削除する # ${1}:'1' # ${2}以降:' 2 15 1 3 6' # output:'2 15 3 6' MM=${1} ; shift 1 LL='' for NN in ${@} ; do if test ${NN} -eq ${MM} then true else LL="${LL} ${NN}" fi done echo ${LL} ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== effectCodeInversionSh 20201101_085854 effectCodeInversionSh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # 指定行の数値を、正負反転させる NN=$(( ${1} + 1 )) sed -n -e "#n ${NN}{ s/^-/m/ s/^[^m]/-&/ s/^m// } { p } " ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== ansi256_216colorSetSh 20201101_085854 ansi256_216colorSetSh(){ ( # ====[shMerge<ins>]==== #!/usr/bin/zsh #!/bin/sh # 256カラーパレットの彩色216に、任意のbitカラーを上書きセットする numTo256colFunc(){ # ${1}:代入する変数名 RR,GG,BBのいずれか # ${2}:「0-5」の数値 RGBのレベル指定 # ${3}-${8} 0-5レベルで設定する整数値 case "${2}" in ( 0 ) eval ${1}'=${3:-0}' ;; ( 1 ) eval ${1}'=${4:-95}' ;; ( 2 ) eval ${1}'=${5:-135}' ;; ( 3 ) eval ${1}'=${6:-175}' ;; ( 4 ) eval ${1}'=${7:-215}' ;; ( 5 ) eval ${1}'=${8:-255}' ;; esac } for RRR in 0 1 2 3 4 5 ; do # 36の位 numTo256colFunc 'RR' "${RRR}" ${1} ${2} ${3} ${4} ${5} ${6} for GGG in 0 1 2 3 4 5 ; do # 6の位 numTo256colFunc 'GG' "${GGG}" ${1} ${2} ${3} ${4} ${5} ${6} for BBB in 0 1 2 3 4 5 ; do # 1の位 numTo256colFunc 'BB' "${BBB}" ${1} ${2} ${3} ${4} ${5} ${6} Index=$(( 36 * ${RRR} + 6 * ${GGG} + ${BBB} + 16 )) printf "\033]4;${Index};rgb:%02x/%02x/%02x\007" "${RR}" "${GG}" "${BB}" #printf "%02x %02x %02x\n" "${RR}" "${GG}" "${BB}" done done done ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== ansi256_24rampSetSh 20201101_085854 ansi256_24rampSetSh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # 256カラーパレットのグレーランプ24に、任意の明るさを上書きセットする # インデックス:232-255 # (明るさの段階)=Index-231 # (明るさ0-255で)=10l+8 # ${1} 掛け算の係数 # ${2} 加減算値 for Index in `seq 232 255` ; do Step=$(( ${Index} - 231 )) Luminous=$(( ${1:-10} * ${Step} + ${2:-8} )) if test ${Luminous} -gt 255 ; then Luminous='255' elif test ${Luminous} -lt 0 ; then Luminous='0' fi printf "\033]4;${Index};rgb:%02x/%02x/%02x\007" "${Luminous}" "${Luminous}" "${Luminous}" #printf "%d %02x/%02x/%02x\n" "${Index}" "${Luminous}" "${Luminous}" "${Luminous}" done ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== ansi256_numToRGBsh 20201101_085854 ansi256_numToRGBsh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # 標準入力から「0-255」の数字を入力すると、 # RGB256階調の数値を出力する。 # 「0-16」のときは「__」を出力する。(「--」「-」は不適切 「set --」関係) while read Index ; do RR='__' GG='__' BB='__' if test "${Index}" -ge 0 && test "${Index}" -le 15 ; then echo "${RR} ${GG} ${BB} ${Index}" elif test "${Index}" -ge 16 && test "${Index}" -le 231 ; then numTo256Func(){ # ${1}:代入する変数名 RR,GG,BBのいずれか # ${2}:「0-5」の数値 RGBのレベル指定 case "${2}" in ( 0 ) eval ${1}'=0' ;; ( 1 ) eval ${1}'=95' ;; ( 2 ) eval ${1}'=135' ;; ( 3 ) eval ${1}'=175' ;; ( 4 ) eval ${1}'=215' ;; ( 5 ) eval ${1}'=255' ;; esac } numTo256Func RR $(( ( ${Index} - 16 ) / 36 )) numTo256Func GG $(( ( ( ${Index} - 16 ) % 36 ) / 6 )) numTo256Func BB $(( ( ( ${Index} - 16 ) % 36 ) % 6 )) echo "${RR} ${GG} ${BB} ${Index}" elif test "${Index}" -ge 232 && test "${Index}" -le 255 ; then RR=$(( ( ( ${Index} - 232 ) * 10 ) + 8 )) GG="${RR}" BB="${RR}" echo "${RR} ${GG} ${BB} ${Index}" fi done ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== rgbToHSLawk1sh 20201101_085854 rgbToHSLawk1sh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # RGB to HSL # RGB in:0-255 # H 0-359 S 0-255 L 0-255 ofmt_parm="%.${1:-0}f" awk -v range_select="${2:-0}" -v OFMT="${ofmt_parm}" -- ' BEGIN{ #OFMT="%.2f" #OFMT="%.0f" #OFMT="%d" #range_select=1 FS = "\t" OFS = "\t" } /__/ { print ( $0 ) next } { rr = $1 gg = $2 bb = $3 index_no = $4 # 計算方法の振り分け if ( rr == gg && rr == bb ) { hsl_calc = 0 } else if ( rr >= gg && rr > bb ) { hsl_calc = 1 } else if ( gg >= bb && gg > rr ) { hsl_calc = 2 } else if ( bb >= rr && bb > gg ) { hsl_calc = 3 } if ( hsl_calc == 1 ) { # red ------------------------------------------- g_m_b = gg - bb if ( g_m_b >= 0 ){ max_p_min = rr + bb max_m_min = rr - bb } else { max_p_min = rr + gg max_m_min = rr - gg } hhsl = ( 60 * g_m_b ) / max_m_min if ( hhsl < 0 ){ hhsl = hhsl + 360 } } else if ( hsl_calc == 2 ) { # green ---------------------------------- b_m_r = bb - rr if ( b_m_r >= 0 ){ max_p_min = gg + rr max_m_min = gg - rr } else { max_p_min = gg + bb max_m_min = gg - bb } hhsl = ( 60 * b_m_r ) / max_m_min + 120 if ( hhsl < 0 ){ hhsl = hhsl + 360 } } else if ( hsl_calc == 3 ) { # blue ----------------------------------- r_m_g = rr - gg if ( r_m_g >= 0 ){ max_p_min = bb + gg max_m_min = bb - gg } else { max_p_min = bb + rr max_m_min = bb - rr } hhsl = ( 60 * r_m_g ) / max_m_min + 240 if ( hhsl < 0 ){ hhsl = hhsl + 360 } } else if ( hsl_calc == 0 ) { # white ---------------------------------- hhsl = 0 } if ( hsl_calc == 1 || hsl_calc == 2 || hsl_calc == 3 ) { cnt = max_p_min / 2 if ( cnt <= 127.5 ){ hssl = ( max_m_min * 255 ) / max_p_min }else { # if ( cnt > 127.5 ) hssl = ( max_m_min * 255 ) / ( 510 - max_p_min ) } hsll = max_p_min / 2 } else { hssl = 0 hsll = rr } if ( range_select == 0 ){ print ( hhsl , hssl , hsll , index_no ) } else { hhsl = hhsl * 100 / 360 hssl = hssl * 100 / 255 hsll = hsll * 100 / 255 print ( hhsl , hssl , hsll , index_no ) } }' ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== rgbToHSVawk1sh 20201101_085854 rgbToHSVawk1sh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # RGB to HSV # RGB in:0-255 # H 0-359 S 0-255 V 0-255 ofmt_parm="%.${1:-0}f" awk -v range_select="${2:-0}" -v OFMT="${ofmt_parm}" -- ' BEGIN{ #OFMT="%.2f" #OFMT="%.0f" #OFMT="%d" #range_select=1 FS = "\t" OFS = "\t" } /__/ { print ( $0 ) next } { rr = $1 gg = $2 bb = $3 index_no = $4 # 計算方法の振り分け if ( rr == gg && rr == bb ) { hsv_calc = 0 } else if ( rr >= gg && rr > bb ) { hsv_calc = 1 } else if ( gg >= bb && gg > rr ) { hsv_calc = 2 } else if ( bb >= rr && bb > gg ) { hsv_calc = 3 } if ( hsv_calc == 1 ) { # red ------------------------------------------- max = rr g_m_b = gg - bb if ( g_m_b >= 0 ){ max_m_min = rr - bb } else { max_m_min = rr - gg } hhsv = ( 60 * g_m_b ) / max_m_min if ( hhsv < 0 ){ hhsv = hhsv + 360 } } else if ( hsv_calc == 2 ) { # green ---------------------------------- max = gg b_m_r = bb - rr if ( b_m_r >= 0 ){ max_m_min = gg - rr } else { max_m_min = gg - bb } hhsv = ( 60 * b_m_r ) / max_m_min + 120 if ( hhsv < 0 ){ hhsv = hhsv + 360 } } else if ( hsv_calc == 3 ) { # blue ----------------------------------- max = bb r_m_g = rr - gg if ( r_m_g >= 0 ){ max_m_min = bb - gg } else { max_m_min = bb - rr } hhsv = ( 60 * r_m_g ) / max_m_min + 240 if ( hhsv < 0 ){ hhsv = hhsv + 360 } } else if ( hsv_calc == 0 ) { # white ---------------------------------- max = rr hhsv = 0 } if ( hsv_calc == 1 || hsv_calc == 2 || hsv_calc == 3 ) { hssv = ( max_m_min * 255 ) / max hsvv = max } else { hssv = 0 hsvv = max } if ( range_select == 0 ){ print ( hhsv , hssv , hsvv , index_no ) } else { hhsv = hhsv * 100 / 360 hssv = hssv * 100 / 255 hsvv = hsvv * 100 / 255 print ( hhsv , hssv , hsvv , index_no ) } }' ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== term256ColorLevelGet1sh 20201101_085854 term256ColorLevelGet1sh(){ ( # ====[shMerge<ins>]==== #!/bin/sh #!/bin/busybox sh #!/usr/bin/yash #!/usr/bin/posh #!/usr/bin/zsh #!/bin/bash #!/usr/bin/ksh # 端末に現在設定されている色レベルを取得する # 位置パラメータに数値「0-255」を指定すること getColorLevelSh(){ ( stty_BAK="`stty -g`" # rawは複合設定で、その一部は「-icanon min 1 time 0」である。 # min,timeは-icanonと共に使用する。 # min は制限時間中の読み込み成功と見なす文字数の最少数 # time は読み込みのタイムアウト時間を0.1秒単位で指定する # min 0 time 10 は「入力データが無くとも1秒で戻る」 stty -echo raw min 0 time 10 printf '\033]4;'${1}';?\007' 1>&2 dd count=1 2>/dev/null stty "${stty_BAK}" ) } #223 ]4;223;rgb:ffff/d7d7/afaf IFS_BAK="${IFS}" BEL=`printf '\007'` ESC=`printf '\033'` for NN in ${@} ; do termReturn=`getColorLevelSh ${NN}` case "${termReturn}" in ( "${ESC}]4;${NN};rgb:"*"${BEL}" ) true ;; ( * ) exit 1 ;; esac # ${ESC}]4;223;rgb:ffff/d7d7/afaf${BEL} -> 223;rgb:ffff/d7d7/afaf${BEL} termReturnTrim="${termReturn#*;}" # 223;rgb:ffff/d7d7/afaf${BEL} -> 223;rgb:ffff/d7d7/afaf termReturnTrim="${termReturnTrim%${BEL}}" # 223;rgb:ffff/d7d7/afaf -> 223 indexNo="${termReturnTrim%;*}" # 223;rgb:ffff/d7d7/afaf -> ffff/d7d7/afaf termReturnTrim="${termReturnTrim#*:}" RR=${termReturnTrim%%/*} termReturnTrim=${termReturnTrim#*/} GG=${termReturnTrim%/*} BB=${termReturnTrim#*/} # 下2桁を削って数字が残るなら4桁とみなす if test -n "${RR%??}" ; then RR="${RR%??}" GG="${GG%??}" BB="${BB%??}" fi # 16進数出力 #echo "${RR} ${GG} ${BB} ${indexNo}" # 10進数出力 printf '%d %d %d %d\n' "0x${RR}" "0x${GG}" "0x${BB}" "${indexNo}" done ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== pressKeySh 20201101_085854 pressKeySh(){ ( # ====[shMerge<ins>]==== #!/bin/sh # キー入力を1回のみ受け取る stty_BAK=`stty -g` stty -echo raw dd count=1 2>/dev/null stty "${stty_BAK}" ) } # ====[shMerge</ins>]==== # # ====[shMerge]==== pressKeyScan256sh 20201101_085854 pressKeyScan256sh(){ ( # ====[shMerge<ins>]==== #!/bin/sh focusID=${1:-0} # 操作キー取得 # eval `printf 'ESC=\033 ctrl_plus_C=\003 ENTER_KEY=\015 '` # 【gloval const ESC ctrl_plus_C ENTER_KEY】# ====[shMerge<disable>]==== #_shMergeDisabled UP____KEY="${ESC}[A" DOWN__KEY="${ESC}[B" RIGHT_KEY="${ESC}[C" LEFT__KEY="${ESC}[D" SPACE_KEY=' ' TAB______KEY=' ' PAGE_UP___KEY="${ESC}[5~" PAGE_DOWN_KEY="${ESC}[6~" stty_BAK=`stty -g` stty -echo raw while true ; do case "`dd count=1 2>/dev/null`" in # ---------------------------------------------------------------------- ( 8 | "${UP____KEY}" ) # ---------------------------------------------------------------------- case "${focusID}" in ( 0 ) echo '0__UP' break 1 ;; ( 1 ) echo '1__UP' break 1 ;; ( 2 ) echo '2__UP' break 1 ;; esac ;; # ---------------------------------------------------------------------- ( 2 | "${DOWN__KEY}" ) # ---------------------------------------------------------------------- case "${focusID}" in ( 0 ) echo '0__DOWN' break 1 ;; ( 1 ) echo '1__DOWN' break 1 ;; ( 2 ) echo '2__DOWN' break 1 ;; esac ;; # ---------------------------------------------------------------------- ( 6 | "${RIGHT_KEY}" ) # ---------------------------------------------------------------------- case "${focusID}" in ( 0 ) echo '0__RIGHT' break 1 ;; ( 1 ) echo '1__RIGHT' break 1 ;; ( 2 ) echo '2__RIGHT' break 1 ;; esac ;; # ---------------------------------------------------------------------- ( 4 | "${LEFT__KEY}" ) # ---------------------------------------------------------------------- case "${focusID}" in ( 0 ) echo '0__LEFT' break 1 ;; ( 1 ) echo '1__LEFT' break 1 ;; ( 2 ) echo '2__LEFT' break 1 ;; esac ;; # ---------------------------------------------------------------------- ( s | '-' ) # ---------------------------------------------------------------------- echo '_MINUS' break 1 ;; # ---------------------------------------------------------------------- ( 0 | "${SPACE_KEY}" ) # ---------------------------------------------------------------------- case "${focusID}" in ( 0 ) true ;; ( 1 ) true ;; ( 2 ) echo '2__SPACE' break 1 ;; esac ;; # ---------------------------------------------------------------------- ( "${PAGE_UP___KEY}" | 9 ) # ---------------------------------------------------------------------- echo '_PAGE_UP' break 1 ;; # ---------------------------------------------------------------------- ( "${PAGE_DOWN_KEY}" | 3 ) # ---------------------------------------------------------------------- echo '_PAGE_DOWN' break 1 ;; # ---------------------------------------------------------------------- ( '*' ) # ---------------------------------------------------------------------- echo '_ASTER' break 1 ;; # ---------------------------------------------------------------------- ( '.' ) # ---------------------------------------------------------------------- echo '_PERIOD' break 1 ;; # ---------------------------------------------------------------------- ( '+' | a ) # ---------------------------------------------------------------------- echo '_PLUS' break 1 ;; # ---------------------------------------------------------------------- ( "${ENTER_KEY}" ) # ---------------------------------------------------------------------- echo '_ENTER' break 1 ;; # ---------------------------------------------------------------------- ( '/' | 'q' | "${ctrl_plus_C}" ) # ---------------------------------------------------------------------- echo '_QUIT' break 1 ;; esac done stty "${stty_BAK}" exit 0 ) } # ====[shMerge</ins>]==== # ====================================================================================== # シェル関数_外部へ分離できない # ====================================================================================== matrixToArrFunc(){ # 表形式データを疑似配列に変換する # matrixName_NN行目_MM列目 # ${2}を変数名として、行を_NN,列を_MMとしたシェル変数を作成する # NN,MMは[0]開始 matrixData="${1}" matrixName="${2}" NN='-1' while read LINE ; do NN=$(( ${NN} + 1 )) MM='-1' eval set -- ${LINE} for TD in ${@} ; do MM=$(( ${MM} + 1 )) eval ${matrixName}_${NN}_${MM}'="${TD}"' done done << ____MATRIX ${matrixData} ____MATRIX } resetFunc(){ # 初期起動時とリセット時 # これから処理するカラーパレット表を読み込む currentPalette=`colorTableListSh ${colorTableNo}` # 列データ(X座標値)は、それぞれの行で何倍するのか currentMags=`echo "${currentPalette}" | ansi256matrixToMagSh` # 表データは何行あるのか paletteLineCount=`echo "${currentPalette}" | wc -l` # 表データに横幅データを組み込んだデータを作成し、 colorTableViewCode=`echo "${currentPalette}" | ansi256matrixToViewCodeSh ${paletteWidth} ` # 横幅指定込みのデータから、不可視数値埋め込み画像データを作成 colorTableSepImg=`echo "${colorTableViewCode}" | ansi256viewToSepCode2sh` # 現在選択中のカラーパレットのデータを、シェル変数の疑似配列に変換する(高速化目的) matrixToArrFunc "${currentPalette}" colorTableArr # 列データの倍率をシェル変数の疑似配列化する(高速化目的) matrixToArrFunc "${currentMags}" colorTableMagsArr # 初期色番号設定 # 初期値を設定しつつ、継承もする mainFgNo="${mainFgNo:-15}" mainBgNo="${mainBgNo:-0}" subFgNo="${subFgNo:-8}" subBgNo="${subBgNo:-11}" # ---- リセット処理しても色番号を維持するため --------------------------- # 1.色番号指定で起動 # 2.起動時カラーテーブルの${colorTableGrid}を新規作成 # 3.XY座標を${colorTableGrid}から割り出す # 4.${colorTableGrid}を破棄 # 5.XY座標で通常処理ループを処理 # 6.カラーテーブル切替(リセット)時は、色番号を保持してXY座標を破棄 # 7.${colorTableGrid}を作成...以後は起動時と同様に # 色インデックス番号からXY座標を得る表 colorTableGrid=`echo "${currentPalette}" | ansi256matrixToGridSh` # カーソル位置 Y座標,X座標 設定 # ${colorTableGrid}を読み 色番号データを X変数に代入 Y変数に代入 set -- `echo "${colorTableGrid}" | sed -n -e $(( ${mainFgNo} + 1 ))'{ p;q }'` MAIN_FG_Y="${1}" MAIN_FG_X="${2}" set -- `echo "${colorTableGrid}" | sed -n -e $(( ${mainBgNo} + 1 ))'{ p;q }'` MAIN_BG_Y="${1}" MAIN_BG_X="${2}" set -- `echo "${colorTableGrid}" | sed -n -e $(( ${subFgNo} + 1 ))'{ p;q }'` SUB_FG_Y="${1}" SUB_FG_X="${2}" set -- `echo "${colorTableGrid}" | sed -n -e $(( ${subBgNo} + 1 ))'{ p;q }'` SUB_BG_Y="${1}" SUB_BG_X="${2}" # 使用完了シェル変数を消去 colorTableGrid='' colorTableViewCode='' currentPalette='' # リセット処理完了 resetFlag='false' } # ====================================================================================== # シェル関数_ メインループ キーアクション # ====================================================================================== keyActionFunc__QUIT(){ exit 0 } keyActionFunc_0__UP(){ MAIN_FG_Y=$(( ( ${MAIN_FG_Y} - 1 + ${paletteLineCount} ) % ${paletteLineCount} )) } keyActionFunc_1__UP(){ MAIN_BG_Y=$(( ( ${MAIN_BG_Y} - 1 + ${paletteLineCount} ) % ${paletteLineCount} )) } keyActionFunc_2__UP(){ effectCodeFocusY=$(( ( ${effectCodeFocusY} - 1 + ${effectCodeLineCount} ) % ${effectCodeLineCount} )) } keyActionFunc_0__DOWN(){ MAIN_FG_Y=$(( ( ${MAIN_FG_Y} + 1 + ${paletteLineCount} ) % ${paletteLineCount} )) } keyActionFunc_1__DOWN(){ MAIN_BG_Y=$(( ( ${MAIN_BG_Y} + 1 + ${paletteLineCount} ) % ${paletteLineCount} )) } keyActionFunc_2__DOWN(){ effectCodeFocusY=$(( ( ${effectCodeFocusY} + 1 + ${effectCodeLineCount} ) % ${effectCodeLineCount} )) } keyActionFunc_0__RIGHT(){ MAIN_FG_X=$(( ( ${MAIN_FG_X} + 1 * ${mainFgMag} + 360 ) % 360 )) } keyActionFunc_1__RIGHT(){ MAIN_BG_X=$(( ( ${MAIN_BG_X} + 1 * ${mainBgMag} + 360 ) % 360 )) } keyActionFunc_2__RIGHT(){ effectCodeFocusX=$(( ( ${effectCodeFocusX} + 1 + 6 ) % 6 )) } keyActionFunc_0__LEFT(){ MAIN_FG_X=$(( ( ${MAIN_FG_X} - 1 * ${mainFgMag} + 360 ) % 360 )) } keyActionFunc_1__LEFT(){ MAIN_BG_X=$(( ( ${MAIN_BG_X} - 1 * ${mainBgMag} + 360 ) % 360 )) } keyActionFunc_2__LEFT(){ effectCodeFocusX=$(( ( ${effectCodeFocusX} - 1 + 6 ) % 6 )) } keyActionFunc__MINUS(){ FFXX="${MAIN_FG_X}" FFYY="${MAIN_FG_Y}" BBXX="${MAIN_BG_X}" BBYY="${MAIN_BG_Y}" MAIN_FG_X="${SUB_FG_X}" MAIN_FG_Y="${SUB_FG_Y}" MAIN_BG_X="${SUB_BG_X}" MAIN_BG_Y="${SUB_BG_Y}" SUB_FG_X="${FFXX}" SUB_FG_Y="${FFYY}" SUB_BG_X="${BBXX}" SUB_BG_Y="${BBYY}" } keyActionFunc__PLUS(){ ( clear codeSampSub(){ ( fgNo="${1}" bgNo="${2}" effectCode="${3}" printf "\033[7m%"`tput cols`"s\015" ' ' # 背景マーカーラインを引いてからCR if test -z "${effectCode}" ; then printf ' %s\033[0m\n' "\033[38;5;${fgNo}m\033[48;5;${bgNo}m" else printf ' %s\033[0m\n' "\033[38;5;${fgNo}m\033[48;5;${bgNo}m\033[${effectCode}m" fi ) } colorDetailSub(){ ( colorNo="${1}" eval 'RR=${colorLevelRGBarr_'${colorNo}'_0}' eval 'GG=${colorLevelRGBarr_'${colorNo}'_1}' eval 'BB=${colorLevelRGBarr_'${colorNo}'_2}' printf "\033[48;5;${colorNo}m%26s\033[0m %s\n" ' ' "256color \\033[48;5;${colorNo}m" printf "\033[48;2;${RR};${GG};${BB}m%26s\033[0m %s\n" ' ' "24bit \\033[48;2;${RR};${GG};${BB}m" printf '%s%2s%6s%4s %2s%6s%4s %2s%6s%5s\n' \ 'RGB(' "R:" "${RR}" "/255" "G:" "${GG}" "/255" "B:" "${BB}" "/255)" if expr "${RR}" + 1 2>/dev/null 1>&2 ; then printf '%s%2s x%02X%4s %2s x%02X%4s %2s x%02X%5s\n' \ 'RGB(' "R:" "${RR}" "/xFF" "G:" "${GG}" "/xFF" "B:" "${BB}" "/xFF)" fi echo "${RR} ${GG} ${BB} ${colorNo}" | rgbToHSLawk1sh 2 0 | { read HH SS LL INDEX printf '%s%2s%6s%4s %2s%6s%4s %2s%6s%5s\n' \ 'HSL(' "H:" "${HH}" "/360" "S:" "${SS}" "/255" "L:" "${LL}" "/255)" } echo "${RR} ${GG} ${BB} ${colorNo}" | rgbToHSLawk1sh 2 1 | { read HH SS LL INDEX printf '%s%2s%6s%4s %2s%6s%4s %2s%6s%5s\n' \ 'HSL(' "H:" "${HH}" "/100" "S:" "${SS}" "/100" "L:" "${LL}" "/100)" } echo "${RR} ${GG} ${BB} ${colorNo}" | rgbToHSVawk1sh 2 0 | { read HH SS VV INDEX printf '%s%2s%6s%4s %2s%6s%4s %2s%6s%5s\n' \ 'HSV(' "H:" "${HH}" "/360" "S:" "${SS}" "/255" "V:" "${VV}" "/255)" } echo "${RR} ${GG} ${BB} ${colorNo}" | rgbToHSVawk1sh 2 1 | { read HH SS VV INDEX printf '%s%2s%6s%4s %2s%6s%4s %2s%6s%5s\n' \ 'HSV(' "H:" "${HH}" "/100" "S:" "${SS}" "/100" "V:" "${VV}" "/100)" } ) } codeSampSub "${mainFgNo}" "${mainBgNo}" "${EFFECT_CODE}" printf \ "\033[${EFFECT_CODE}m\033[38;5;${mainFgNo};48;5;${mainBgNo}m%s\033[0m %6s %s\n"\ "\033[${EFFECT_CODE}m\033[38;5;${mainFgNo};48;5;${mainBgNo}m%s\033[0m\n"\ "${MAIN_SAMPLE}" "${mainFgNo};${mainBgNo}" "${EFFECT_CODE}" \ "${FREE_SAMPLE:- }" colorDetailSub ${mainFgNo} colorDetailSub ${mainBgNo} codeSampSub "${subFgNo}" "${subBgNo}" "${EFFECT_CODE}" printf \ "\033[${EFFECT_CODE}m\033[38;5;${subFgNo};48;5;${subBgNo}m%s\033[0m %6s %s\n"\ "\033[${EFFECT_CODE}m\033[38;5;${subFgNo};48;5;${subBgNo}m%s\033[0m\n"\ "${SUB_SAMPLE}" "${subFgNo};${subBgNo}" "${EFFECT_CODE}" \ "${FREE_SAMPLE:- }" colorDetailSub ${subFgNo} colorDetailSub ${subBgNo} pressKeySh ) } keyActionFunc__ASTER(){ if NN=`subMenuSh "${subMenuAst}" ${subMenuAstParm2} ${subMenuAstParm3} \ ${subMenuAstParm4} ${subMenuAstParm5}` ; then subMenuAst${NN} else true fi } keyActionFunc_2__SPACE(){ XY=$(( ${effectCodeFocusY} * 6 + ${effectCodeFocusX} )) # idフラグ番号_$((id + 1000 * -1)) MM=`echo "${effectCodeFlags}" | sed -n -e "$(( ${XY} + 1 )){ p;q }"` # id番号 NN=$(( ${MM#-} - 1000 )) if test ${MM} -le -1 ; then # 現在無効 effectCodeList="${effectCodeList} ${NN}" else eval 'set -- '${effectCodeList} effectCodeList=`effectCodeRemoveSh ${NN} ${@}` fi # 有効無効を反転 effectCodeFlags="`echo "${effectCodeFlags}" | effectCodeInversionSh ${XY}`" # テキスト装飾コードを構築 EFFECT_CODE=`effectCodeBuildSh "${effectCodeList}"` } keyActionFunc__PERIOD(){ # 色配置切替 if colorTableListSh $(( ${colorTableNo} + 1 )) 1>/dev/null ; then colorTableNo=$(( ${colorTableNo} + 1 )) else colorTableNo='0' fi resetFlag='true' } keyActionFunc__ENTER(){ # 再描画 clear } keyActionFunc__PAGE_UP(){ focusID=$(( ( ${focusID} - 1 + 3 ) % 3 )) } keyActionFunc__PAGE_DOWN(){ focusID=$(( ( ${focusID} + 1 + 3 ) % 3 )) } # ====================================================================================== # シェル関数_アスタリスクで起動するサブメニュー # ====================================================================================== subMenuAst='文字色をインデックス番号で指定する 背景色をインデックス番号で指定する サンプルテキストを書き換える カラーパレットの幅を画面に合わせる カラーパレットを標準色にセットする カラーレベル情報を端末から読み出す シェルもどき【debug】 疑似配列,シェル変数 閲覧【debug】' subMenuAstParm2='40' # ウィンドウ幅文字数 subMenuAstParm3='8' # 原点行数 subMenuAstParm4='4' # 原点文字数 subMenuAstParm5='97;45' # 色指定_16色指定で subMenuAst1(){ echo '------ 文字色をインデックス番号で指定する ------------------------' echo '(0-255) 数値を指定' read NN if test "${NN}" -ge 0 && test "${NN}" -le 255 ; then mainFgNo=${NN} resetFlag='true' else return 0 fi } subMenuAst2(){ echo '------ 背景色をインデックス番号で指定する ------------------------' echo '(0-255) 数値を指定' read NN if test "${NN}" -ge 0 && test "${NN}" -le 255 ; then mainBgNo=${NN} resetFlag='true' else return 0 fi } subMenuAst3(){ echo '------ サンプルテキストを入力 ------------------------------------' FREE_SAMPLE=`read XX ; echo "${XX}"` } subMenuAst4(){ # カラーパレットを画面幅に合わせる paletteWidth=`tput cols` resetFlag='true' } subMenuAst5(){ ( echo '------ 彩色領域216色の設定を上書き パラメータを指定 -------------- default 0 95 135 175 215 255 (0-5の階調レベル)' read XX eval 'set -- '${XX} ansi256_216colorSetSh ${@} echo '------ 白黒階調領域24色の設定を上書き パラメータを指定 ----------- default 10 8 (直線の傾き オフセット)' read XX eval 'set -- '${XX} ansi256_24rampSetSh ${@} ) } subMenuAst6(){ echo '------ カラーレベル情報を端末から取得して再構築 ------------------' XX="`term256ColorLevelGet1sh $(seq 0 255) | tee /dev/stderr`" if test -z "${XX}" ; then echo '端末から色レベル情報を読み出せませんでした。' 1>&2 read WAIT return fi matrixToArrFunc "${XX}" colorLevelRGBarr matrixToArrFunc "`echo "${XX}" | rgbToHSLawk1sh 0 0 2>/dev/null`" colorLevelHSLarr matrixToArrFunc "`echo "${XX}" | rgbToHSVawk1sh 0 0 2>/dev/null`" colorLevelHSVarr } subMenuAst7(){ echo '------ shell ----------------------------------------------------- 主処理と同一プロセスでコマンドを入力実行します。 何も入力せずにEnterすると戻ります。' while read XX ; do if test -z "${XX}" ; then return 0 else eval "${XX}" fi done } subMenuAst8(){ ( # 擬似配列の全て,シェル変数の一部を一覧表示 matrixScanSub(){ ( echo "----疑似配列読み出しテスト ${1} ----------------------------------" NN='-1' while true ; do NN=$(( ${NN} + 1 )) eval 'if test -z "${'${1}'_'${NN}'_0}" then break fi' printf '%d: ' ${NN} MM='-1' while true ; do MM=$(( ${MM} + 1 )) eval 'if test -z "${'${1}'_'${NN}'_'${MM}}'" then break fi' eval 'printf "%s " "${'${1}'_'${NN}'_'${MM}}'"' done echo done ) } for XX in colorLevelRGBarr colorLevelHSLarr colorLevelHSVarr colorTableMagsArr colorTableArr ; do matrixScanSub ${XX} | less done { echo '---- ${colorTableViewCode} -------------------------------------------' colorTableListSh ${colorTableNo} | ansi256matrixToViewCodeSh ${paletteWidth} | nl -v1 -s':' ; } | less { echo '---- ${colorTableGrid} -----------------------------------------------' colorTableListSh ${colorTableNo} | ansi256matrixToGridSh | nl -v0 -s':' ; } | less clear echo '---- ${colorTableSepImg} 不可視数字の可視化 ----------------------------' echo "${colorTableSepImg}" | awk --posix '{ gsub( "\034" , "3" , $0 ) ; gsub( "\035" , "2" , $0 ) gsub( "\036" , "1" , $0 ) gsub( "\037" , "0" , $0 ) ; print $0 }' echo 'read WAIT' read WAIT ) } # ====================================================================================== # デバッグ # ====================================================================================== debug1Sub(){ ( printf '\033[?0J' printf '%s' "${PRESS_KEY}" | od -An -tc -v printf '%s' "${PRESS_KEY}" | od -An -to1 -v ) } debug2Sub(){ ( printf '\033[?0J' echo '\ mainFgNo mainBgNo subFgNo subBgNo MAIN_FG_X MAIN_BG_X SUB_FG_X SUB_BG_X MAIN_FG_Y MAIN_BG_Y SUB_FG_Y SUB_BG_Y mainFgMag mainBgMag subFgMag subBgMag' | while read TD0 TD1 TD2 TD3 ; do eval 'echo "${TD0}:${'${TD0}'}:${TD1}:${'${TD1}'}:${TD2}:${'${TD2}'}:${TD3}:${'${TD3}'}"' done | column -t -s':' | column eval 'echo mainFgNo="\${colorTableArr_'${MAIN_FG_Y}'_\$(( '${MAIN_FG_X}' / '${mainFgMag}' ))}"' eval 'echo mainBgNo="\${colorTableArr_'${MAIN_BG_Y}'_\$(( '${MAIN_BG_X}' / '${mainBgMag}' ))}"' eval 'echo subFgNo="\${colorTableArr_'${SUB_FG_Y}'_\$(( '${SUB_FG_X}' / '${subFgMag}' ))}"' eval 'echo subBgNo="\${colorTableArr_'${SUB_BG_Y}'_\$(( '${SUB_BG_X}' / '${subBgMag}' ))}"' ) } debug3Sub(){ ( printf '\033[?0J' for XX in \ focusID colorTableNo \ effectCodeFocusX effectCodeFocusY effectCodeLineCount do eval 'echo "${XX}:${'${XX}'}"' done | column -t -s':' | column ) } debug4Sub(){ ( # RGB,HSV,HSL for XX in \ mainFgRR mainFgGG mainFgBB mainFgHHSL mainFgHSSL mainFgHSLL mainFgHHSV mainFgHSSV mainFgHSVV \ mainBgRR mainBgGG mainBgBB mainBgHHSL mainBgHSSL mainBgHSLL mainBgHHSV mainBgHSSV mainBgHSVV do eval 'echo "${XX}:${'${XX}'}"' done | column -t -s':' | column ) } debug5Sub(){ ( # 文字装飾コード echo "${effectCodeList}" echo "${EFFECT_CODE}" echo ${effectCodeFlags} ) } # ====================================================================================== # スタートアップ処理_定数、リセットしても維持する変数 # ====================================================================================== # 色番号 メインサンプルとサブサンプルの前景色(文字色)と背景色 # 空白のときはデフォルト値が代入される # 処理途中でリセットされると、処理中の値が継承される # ここで数値を入れておくと、継承と同じ処理で起動する mainFgNo='' mainBgNo='' subFgNo='' subBgNo='' # 色インデックス表の何番を初期起動するのか colorTableNo='0' # カーソルで選択する対象を選ぶ # 0:MAIN_FG_X,Y # 1:MAIN_BG_X,Y # 2:テキスト装飾コード focusID='0' # 文字装飾コードチェックシート カーソル初期位置 effectCodeFocusX='0' effectCodeFocusY='0' # テキスト装飾コードの表示行数 effectCodeLineCount=$(( `effectCodeList256Sh | wc -l` / 6 )) # テキスト装飾コードからフラグ用定数を作成 # 1000を足して負にしたもの(「0」に正負をつけるため) effectCodeFlags=`effectCodeList256Sh | while read NN ; do echo '-'$(( ${NN} + 1000 )) done` # テキスト装飾コード有効リスト # 有効にした「順番に」改行区切りでコード番号が入る # 「1,2,3」と「2,3,1」は異なる effectCodeList='' # テキスト装飾コードチェック表を端末表示する、作成済みデータを一時保存 # 色の選択中には再作成せず、この変数内のデータを再出力する。 effectCodeViewData='' # カラーレベルデータを擬似配列化 # colorLevelRGBarr_[色番号]_[0:RR,1:GG,2:BB] matrixToArrFunc "`seq 0 255 | ansi256_numToRGBsh`" colorLevelRGBarr # colorLevelHSLarr_[色番号]_[0:HHSL,1:HSSL,1:HSLL] matrixToArrFunc "`seq 0 255 | ansi256_numToRGBsh | rgbToHSLawk1sh 0 0 2>/dev/null`" colorLevelHSLarr # colorLevelHSVarr_[色番号]_[0:HHSV,1:HSSV,2:HSVV] matrixToArrFunc "`seq 0 255 | ansi256_numToRGBsh | rgbToHSVawk1sh 0 0 2>/dev/null`" colorLevelHSVarr # 初回リセット処理を実行 resetFlag='true' # ====================================================================================== # メインループ # ====================================================================================== while true ; do if "${resetFlag}" then resetFunc fi # X座標の倍率データを元データで作成した擬似配列から読み込む eval 'mainFgMag="${colorTableMagsArr_'${MAIN_FG_Y:?}'_0}"' eval 'mainBgMag="${colorTableMagsArr_'${MAIN_BG_Y}'_0}"' eval 'subFgMag="${colorTableMagsArr_'${SUB_FG_Y}'_0}"' eval 'subBgMag="${colorTableMagsArr_'${SUB_BG_Y}'_0}"' # 選択中の色番号を元データから作成した疑似配列から読み込む eval 'mainFgNo="${colorTableArr_'${MAIN_FG_Y}'_'$(( ${MAIN_FG_X} / ${mainFgMag:?} ))'}"' eval 'mainBgNo="${colorTableArr_'${MAIN_BG_Y}'_'$(( ${MAIN_BG_X} / ${mainBgMag} ))'}"' eval 'subFgNo="${colorTableArr_'${SUB_FG_Y}'_'$(( ${SUB_FG_X} / ${subFgMag} ))'}"' eval 'subBgNo="${colorTableArr_'${SUB_BG_Y}'_'$(( ${SUB_BG_X} / ${subBgMag} ))'}"' # カラーレベルを疑似配列から読み込む eval 'mainFgRR=${colorLevelRGBarr_'${mainFgNo}'_0}' eval 'mainFgGG=${colorLevelRGBarr_'${mainFgNo}'_1}' eval 'mainFgBB=${colorLevelRGBarr_'${mainFgNo}'_2}' eval 'mainFgHHSL=${colorLevelHSLarr_'${mainFgNo}'_0}' eval 'mainFgHSSL=${colorLevelHSLarr_'${mainFgNo}'_1}' eval 'mainFgHSLL=${colorLevelHSLarr_'${mainFgNo}'_2}' eval 'mainFgHHSV=${colorLevelHSVarr_'${mainFgNo}'_0}' eval 'mainFgHSSV=${colorLevelHSVarr_'${mainFgNo}'_1}' eval 'mainFgHSVV=${colorLevelHSVarr_'${mainFgNo}'_2}' eval 'mainBgRR=${colorLevelRGBarr_'${mainBgNo}'_0}' eval 'mainBgGG=${colorLevelRGBarr_'${mainBgNo}'_1}' eval 'mainBgBB=${colorLevelRGBarr_'${mainBgNo}'_2}' eval 'mainBgHHSL=${colorLevelHSLarr_'${mainBgNo}'_0}' eval 'mainBgHSSL=${colorLevelHSLarr_'${mainBgNo}'_1}' eval 'mainBgHSLL=${colorLevelHSLarr_'${mainBgNo}'_2}' eval 'mainBgHHSV=${colorLevelHSVarr_'${mainBgNo}'_0}' eval 'mainBgHSSV=${colorLevelHSVarr_'${mainBgNo}'_1}' eval 'mainBgHSVV=${colorLevelHSVarr_'${mainBgNo}'_2}' # 文字装飾チェックにフォーカスが当たっているとき再作成(高速化目的) if test ${focusID} -eq 2 || test -z "${effectCodeViewData}" ; then effectCodeViewData=`effectCodeCheckSh $(( ${effectCodeFocusY} * 6 + ${effectCodeFocusX} )) \ "${effectCodeFlags}" ` else true fi { # overWriteSh printf "\033[${EFFECT_CODE}m"'\033[39;49m%s\033[0m %6s %s\n'\ "\033[${EFFECT_CODE}m""\033[38;5;${mainFgNo};48;5;${mainBgNo}m%s\033[0m %6s %s\n"\ "\033[${EFFECT_CODE}m""\033[38;5;${subFgNo};48;5;${subBgNo}m%s\033[0m %6s %s\n"\ "\033[${EFFECT_CODE}m"'\033[38;5;'"${mainFgNo};48;5;${mainBgNo}m%s\033[0m\n"\ "\033[${EFFECT_CODE}m"'\033[38;5;'"${subFgNo};48;5;${subBgNo}m%s\033[0m\n"\ "${STD_SAMPLE}" '39;49' "${EFFECT_CODE}" \ "${MAIN_SAMPLE}" "${mainFgNo};${mainBgNo}" "${EFFECT_CODE}" \ "${SUB_SAMPLE}" "${subFgNo};${subBgNo}" "${EFFECT_CODE}" \ "${FREE_SAMPLE:- }" \ "${FREE_SAMPLE:- }" echo 'FOCUS_ID_0' printf "\033[48;5;${mainFgNo}m%30s\033[0m"" %3s,%3s,%3s L(%3s,%3s,%3s) V(%3s,%3s,%3s)\n" ' ' \ ${mainFgRR} ${mainFgGG} ${mainFgBB} ${mainFgHHSL} ${mainFgHSSL} ${mainFgHSLL} \ ${mainFgHHSV} ${mainFgHSSV} ${mainFgHSVV} echo 'FOCUS_ID_1' printf "\033[48;5;${mainBgNo}m%30s\033[0m"" %3s,%3s,%3s L(%3s,%3s,%3s) V(%3s,%3s,%3s)\n" ' ' \ ${mainBgRR} ${mainBgGG} ${mainBgBB} ${mainBgHHSL} ${mainBgHSSL} ${mainBgHSLL} \ ${mainBgHHSV} ${mainBgHSSV} ${mainBgHSVV} # 作成済みのカラーパレット画像データにカーソルを乗せて表示 echo "${colorTableSepImg}" echo 'FOCUS_ID_2' echo "${effectCodeViewData}" helpMessageC256sh } | sepDrawFocusOvewWrite1sh ${mainFgNo} ${mainBgNo} ${focusID} 1>&2 #debug1Sub # 【debug】 #debug2Sub # 【debug】 #debug3Sub # 【debug】 #debug4Sub # 【debug】 #debug5Sub # 【debug】 PRESS_KEY=`pressKeyScan256sh ${focusID}` keyActionFunc_${PRESS_KEY} done exit 255 #