はじめに
ANSIエスケープシーケンスとは、ターミナルを制御するために使い、主に「カーソル移動、スクリーン消去」と「文字色と各種修飾」を 制御することができます。
この記事では「 文字色と修飾子 」について、Swift で簡単に扱う方法を紹介します。
Swift による ANSIエスケープシーケンス は、@kanetaiさんの 次の記事でも紹介されています。
一方、本稿は、エスケープシーケンス付き文字列作成を 汎用化する ことを目的にしています。また、256Color や 24bit RGB Color を使用する形式も扱います。
「文字色と修飾子」エスケープシーケンスの概要
ターミナルに出力する「文字列」の文字色や背景色を指定します。
また、「文字列」を修飾する修飾子として、「太字・薄字」「斜体」「下線付き」「ブリンク」「取消線付き」等 を組み合わせて指定することができます。
ここでは、色や修飾子 を 総称 して「属性」と呼ぶことにします。
ソースコードは最後に示すとして、さっそく 使い方について説明します。
「属性」の種類
以下の種類があります。
- 色(いずれか)
- 単純色
- 明るい色
- 256 Color
- 24bit RGB Color
- 修飾子(複合可)
- 太字・薄字
- 斜体
- 下線付き
- ブリンク
- 反転
- 非表示
- 取消線付き
- リセット(色・修飾子)
使い方
・ 単純色
| 色 | 文字色 | 背景色 |
|---|---|---|
| Black | .black | .bgBlack |
| Red | .red | .bgRed |
| Green | .green | .bgGreen |
| Yellow | .yellow | .bgYellow |
| Blue | .blue | .bgBlue |
| Magenta | .magenta | .bgMagenta |
| Cyan | .cyan | .bgCyan |
| White | .white | .bgWhite |
| Default | .default | .bgDefault |
print("文字列".red())
print("文字列".red.bgWhite())
・ 明るい色
| 色 | 文字色 | 背景色 |
|---|---|---|
| 明るいBlack | .brightBlack | .bgBrightBlack |
| 明るいRed | .brightRed | .bgBrightRed |
| 明るいGreen | .brightGreen | .bgBrightGreen |
| 明るいYellow | .brightYellow | .bgBrightYellow |
| 明るいBlue | .brightBlue | .bgBrightBlue |
| 明るいMagenta | .brightMagenta | .bgBrightMagenta |
| 明るいCyan | .brightCyan | .bgBrightCyan |
| 明るいWhite | .brightWhite | .bgBrightWhite |
print("文字列".brightRed())
print("文字列".red.bgBrightWhite())
・ 修飾子
組み合わせて指定できます。
| 修飾子 | 設定 | 解除 | 備考 |
|---|---|---|---|
| リセット | .reset | - | 色および修飾子をリセット |
| 太字 | .bold | .resetBold | 「薄字」と排他 |
| 薄字 | .dim | .resetDim | 「太字」と排他 |
| 斜体 | .italic | .resetItalic | 標準ターミナルでは 日本語は機能しない |
| 下線付き | .underline | .resetUnderline | |
| ブリンク | .blink | .resetBlink | |
| 反転 | .reverse | .resetReverse | |
| 非表示 | .hidden | .resetHidden | |
| 取消線付き | .strikethrough | .resetStrikethrough | 標準ターミナルでは 機能しない |
print("文字列".green.bold.italic())
print("string".green.bold.italic())
print("文字列".red.underline())
print("文字列".reverse())
Mac標準のターミナルでは 日本語の斜体は機能しないようです。
(ターミナルで使用している日本語フォントが影響している可能性もあります。)
・ 256 Color
0 〜 255 で色を指定します。
| 色 | 文字色 | 背景色 | 値 |
|---|---|---|---|
| 256 色 | .color256(値) | .bgColor256(値) | 下表参照 |
| 値 | 意味する色 |
|---|---|
| 0〜7 | 単純色(black 〜 white と同じ) |
| 8〜15 | 明るい色(brightBlack 〜 brightWhite と同じ) |
| 16〜231 | $6 × 6 × 6$ (216 色) $値 = 16 + 36 × r + 6 × g + b$ $(0 ≤ r, g, b ≤ 5)$ |
| 232〜255 | 24 階調のグレースケール |
for r in 1...5 {
print("Red:\(r)".color256(16 + 36 * r)())
}
for gray in 232 ..< 256 {
print(String(format: "%2d.", gray - 232),
"grayscale-color".color256(gray)(),
"background-grayscale-color".bgColor256(gray)())
}
・ 24bit RGB Color
R, G, B の各色を 0 〜 255 で指定します。
| 色 | 文字色 | 背景色 | 値 |
|---|---|---|---|
| 24bit RGB | .colorRGB(r, g, b) | .bgColorRGB(r, g, b) | $0 ≤ r, g, b ≤ 255$ |
print("紅色".colorRGB(190, 0, 63)())
print("群青色".bgColorRGB(56, 77, 152)())

参考:和名色
24bit RGB Color は、Mac の 標準ターミナル では機能しないため、iTerm2で実行した。
また、iTerm2 であれば 日本語の斜体 や 取消線付き も機能した。
・ 重要な注意点
print("文字列".red.bgWhite())
最後の属性にのみ、必ず ()を付けてください。
最後の属性を関数呼び出しすることで、エスケープシーケンスを生成します。
print("文字列".red().bgWhite())
途中の属性に()を付けても エラーになりません。
しかし、属性が正しく反映されません。
くれぐれも、最後の属性にのみ ()を付けてください。
・ 生成したエスケープシーケンスを確認する(デバッグ機能)
引数に 'print: true'を指定すると、実際に生成したエスケープシーケンスを 標準エラー出力(stderr) に出力します。(デバック時の使用を想定)
print("文字列".red.blink(print: true))
エスケープシーケンスを見てお分かりだと思いますが、文字列の最後に reset を生成し、属性をリセットします。
・ 属性を変数で指定する
String.colorStyles(...:print:)を使用すると、属性を変数で指定できます。
for (f, b) in zip(AnsiColorStyle.colors, AnsiColorStyle.bgColors.reversed()) {
print("\(f) + \(b)".colorStyles(f, b, .italic))
}
ソースコード
ソースコードを見る (ここをクリック)
import Foundation
struct AnsiColorStyles {
let string: String
var styles: [AnsiColorStyle] = []
fileprivate init(_ str: String, _ style: AnsiColorStyle) {
string = str
styles.append(style)
}
func callAsFunction() -> String { string.colorStyles(styles) }
func callAsFunction(print debug: Bool) -> String { string.colorStyles(styles, print: debug) }
private func addStyle(_ style: AnsiColorStyle) -> Self {
var a = self
a.styles.append(style)
return a
}
private func addStyles(_ styles: [AnsiColorStyle]) -> Self {
var a = self
a.styles += styles
return a
}
func colorStyles(_ styles: AnsiColorStyle...) -> Self {
return addStyles(styles)
}
}
enum AnsiColorStyle: Comparable, Hashable {
// リセット
case reset
//文字色
case `default`
case black
case red
case green
case yellow
case blue
case magenta
case cyan
case white
// 明るい文字色
case brightBlack
case brightRed
case brightGreen
case brightYellow
case brightBlue
case brightMagenta
case brightCyan
case brightWhite
// 拡張色
case color256(Int)
case colorRGB(Int, Int, Int)
//背景色
case bgDefault
case bgBlack
case bgRed
case bgGreen
case bgYellow
case bgBlue
case bgMagenta
case bgCyan
case bgWhite
// 明るい背景色
case bgBrightBlack
case bgBrightRed
case bgBrightGreen
case bgBrightYellow
case bgBrightBlue
case bgBrightMagenta
case bgBrightCyan
case bgBrightWhite
// 拡張色
case bgColor256(Int)
case bgColorRGB(Int, Int, Int)
//装飾
case bold
case dim
case italic
case underline
case blink
case reverse
case hidden
case strikethrough
var rawValue: Int {
switch self {
case .reset: return 0
case .default: return 39
case .black: return 30
case .red: return 31
case .green: return 32
case .yellow: return 33
case .blue: return 34
case .magenta: return 35
case .cyan: return 36
case .white: return 37
case .brightBlack: return 90
case .brightRed: return 91
case .brightGreen: return 92
case .brightYellow: return 93
case .brightBlue: return 94
case .brightMagenta: return 95
case .brightCyan: return 96
case .brightWhite: return 97
case .color256: return -1
case .colorRGB: return -2
case .bgDefault: return 49
case .bgBlack: return 40
case .bgRed: return 41
case .bgGreen: return 42
case .bgYellow: return 43
case .bgBlue: return 44
case .bgMagenta: return 45
case .bgCyan: return 46
case .bgWhite: return 47
case .bgBrightBlack: return 100
case .bgBrightRed: return 101
case .bgBrightGreen: return 102
case .bgBrightYellow: return 103
case .bgBrightBlue: return 104
case .bgBrightMagenta: return 105
case .bgBrightCyan: return 106
case .bgBrightWhite: return 107
case .bgColor256: return -3
case .bgColorRGB: return -4
case .bold: return 1
case .dim: return 2
case .italic: return 3
case .underline: return 4
case .blink: return 5
case .reverse: return 7
case .hidden: return 8
case .strikethrough: return 9
}
}
}
extension AnsiColorStyle: CaseIterable {
static let allCases: [AnsiColorStyle] = [
.reset,
.default,
.black,
.red,
.green,
.yellow,
.blue,
.magenta,
.cyan,
.white,
.brightBlack,
.brightRed,
.brightGreen,
.brightYellow,
.brightBlue,
.brightMagenta,
.brightCyan,
.brightWhite,
.bgDefault,
.bgBlack,
.bgRed,
.bgGreen,
.bgYellow,
.bgBlue,
.bgMagenta,
.bgCyan,
.bgWhite,
.bgBrightBlack,
.bgBrightRed,
.bgBrightGreen,
.bgBrightYellow,
.bgBrightBlue,
.bgBrightMagenta,
.bgBrightCyan,
.bgBrightWhite,
.bold,
.dim,
.italic,
.underline,
.blink,
.reverse,
.hidden,
.strikethrough,
]
static var array: [AnsiColorStyle] { AnsiColorStyle.allCases }
static var colors: [AnsiColorStyle] { AnsiColorStyle.allCases.filter { .black ... .brightWhite ~= $0 } }
static var bgColors: [AnsiColorStyle] { AnsiColorStyle.allCases.filter { .bgBlack ... .bgBrightWhite ~= $0 } }
static var styles: [AnsiColorStyle] { AnsiColorStyle.allCases.filter { .bold ... .strikethrough ~= $0 } }
}
extension Array where Element == AnsiColorStyle {
private var associatedValuesColor256: Int? {
for e in self.reversed() { if case .color256(let c) = e { return c % 256} }
return nil
}
private var associatedValuesColorRGB: (Int, Int, Int)? {
for e in self.reversed() { if case .colorRGB(let r, let g, let b) = e { return (r % 256, g % 256, b % 256) } }
return nil
}
private var associatedValuesBackgroundColor256: Int? {
for e in self.reversed() { if case .bgColor256(let c) = e { return c % 256} }
return nil
}
private var associatedValuesColorBackgroundRGB: (Int, Int, Int)? {
for e in self.reversed() { if case .bgColorRGB(let r, let g, let b) = e { return (r % 256, g % 256, b % 256) } }
return nil
}
var escapeSequence: String {
if self.isEmpty { return "" }
let simpleAttrs = self.filter { $0.rawValue >= 0 }
var str = simpleAttrs.isEmpty ? "" :
"\u{1b}[\(simpleAttrs.map { String($0.rawValue) }.joined(separator: ";"))m"
if let (r, g, b) = self.associatedValuesColorRGB {
str += "\u{1b}[38;2;\(r);\(g);\(b)m"
}
if let c = self.associatedValuesColor256 {
str += "\u{1b}[38;5;\(c)m"
}
if let (r, g, b) = self.associatedValuesColorBackgroundRGB {
str += "\u{1b}[48;2;\(r);\(g);\(b)m"
}
if let c = self.associatedValuesBackgroundColor256 {
str += "\u{1b}[48;5;\(c)m"
}
return str
}
private var caselabels: String {
"\(self)".replacingOccurrences(of: "AnsiEscape.AnsiColorStyle", with: "")
}
}
extension String {
private func debugPrint(_ debug: Bool = false) -> String {
if debug {
fputs(self.replacingOccurrences(of: "\u{1b}", with: "\u{241b}") + "\n", stderr)
}
return self
}
func colorStyles(_ prefix: AnsiColorStyle..., print: Bool = false) -> String {
return colorStyles(prefix, suffix: [.reset], print: print)
}
fileprivate func colorStyles(_ prefix: AnsiColorStyle..., suffix: AnsiColorStyle..., print: Bool = false) -> String {
let str = prefix.escapeSequence + self + suffix.escapeSequence
return str.debugPrint(print)
}
fileprivate func colorStyles(_ prefix: [AnsiColorStyle], suffix: [AnsiColorStyle] = [.reset], print: Bool = false) -> String {
let str = prefix.escapeSequence + self + suffix.escapeSequence
return str.debugPrint(print)
}
fileprivate func colorStyles(_ prefix: Set<AnsiColorStyle>, suffix: Set<AnsiColorStyle> = [.reset], print: Bool = false) -> String {
let str = Array(prefix).escapeSequence + self + Array(suffix).escapeSequence
return str.debugPrint(print)
}
}
extension String {
var reset: AnsiColorStyles { AnsiColorStyles(self, .reset) }
var `default`: AnsiColorStyles { AnsiColorStyles(self, .default) }
var black: AnsiColorStyles { AnsiColorStyles(self, .black) }
var red: AnsiColorStyles { AnsiColorStyles(self, .red) }
var green: AnsiColorStyles { AnsiColorStyles(self, .green) }
var yellow: AnsiColorStyles { AnsiColorStyles(self, .yellow) }
var blue: AnsiColorStyles { AnsiColorStyles(self, .blue) }
var magenta: AnsiColorStyles { AnsiColorStyles(self, .magenta) }
var cyan: AnsiColorStyles { AnsiColorStyles(self, .cyan) }
var white: AnsiColorStyles { AnsiColorStyles(self, .white) }
var brightBlack: AnsiColorStyles { AnsiColorStyles(self, .brightBlack) }
var brightRed: AnsiColorStyles { AnsiColorStyles(self, .brightRed) }
var brightGreen: AnsiColorStyles { AnsiColorStyles(self, .brightGreen) }
var brightYellow: AnsiColorStyles { AnsiColorStyles(self, .brightYellow) }
var brightBlue: AnsiColorStyles { AnsiColorStyles(self, .brightBlue) }
var brightMagenta: AnsiColorStyles { AnsiColorStyles(self, .brightMagenta) }
var brightCyan: AnsiColorStyles { AnsiColorStyles(self, .brightCyan) }
var brightWhite: AnsiColorStyles { AnsiColorStyles(self, .brightWhite) }
func color256(_ c: Int) -> AnsiColorStyles { AnsiColorStyles(self, .color256(c)) }
func colorRGB(_ r: Int, _ g: Int, _ b: Int) -> AnsiColorStyles { AnsiColorStyles(self, .colorRGB(r, g, b)) }
var bgDefault: AnsiColorStyles { AnsiColorStyles(self, .bgDefault) }
var bgBlack: AnsiColorStyles { AnsiColorStyles(self, .bgBlack) }
var bgRed: AnsiColorStyles { AnsiColorStyles(self, .bgRed) }
var bgGreen: AnsiColorStyles { AnsiColorStyles(self, .bgGreen) }
var bgYellow: AnsiColorStyles { AnsiColorStyles(self, .bgYellow) }
var bgBlue: AnsiColorStyles { AnsiColorStyles(self, .bgBlue) }
var bgMagenta: AnsiColorStyles { AnsiColorStyles(self, .bgMagenta) }
var bgCyan: AnsiColorStyles { AnsiColorStyles(self, .bgCyan) }
var bgWhite: AnsiColorStyles { AnsiColorStyles(self, .bgWhite) }
var bgBrightBlack: AnsiColorStyles { AnsiColorStyles(self, .bgBrightBlack) }
var bgBrightRed: AnsiColorStyles { AnsiColorStyles(self, .bgBrightRed) }
var bgBrightGreen: AnsiColorStyles { AnsiColorStyles(self, .bgBrightGreen) }
var bgBrightYellow: AnsiColorStyles { AnsiColorStyles(self, .bgBrightYellow) }
var bgBrightBlue: AnsiColorStyles { AnsiColorStyles(self, .bgBrightBlue) }
var bgBrightMagenta: AnsiColorStyles { AnsiColorStyles(self, .bgBrightMagenta) }
var bgBrightCyan: AnsiColorStyles { AnsiColorStyles(self, .bgBrightCyan) }
var bgBrightWhite: AnsiColorStyles { AnsiColorStyles(self, .bgBrightWhite) }
func bgColor256(_ c: Int) -> AnsiColorStyles { AnsiColorStyles(self, .bgColor256(c)) }
func bgColorRGB(_ r: Int, _ g: Int, _ b: Int) -> AnsiColorStyles { AnsiColorStyles(self, .bgColorRGB(r, g, b)) }
var bold: AnsiColorStyles { AnsiColorStyles(self, .bold) }
var dim: AnsiColorStyles { AnsiColorStyles(self, .dim) }
var italic: AnsiColorStyles { AnsiColorStyles(self, .italic) }
var underline: AnsiColorStyles { AnsiColorStyles(self, .underline) }
var blink: AnsiColorStyles { AnsiColorStyles(self, .blink) }
var reverse: AnsiColorStyles { AnsiColorStyles(self, .reverse) }
var hidden: AnsiColorStyles { AnsiColorStyles(self, .hidden) }
var strikethrough: AnsiColorStyles { AnsiColorStyles(self, .strikethrough) }
}
extension AnsiColorStyles {
var reset: AnsiColorStyles { self.addStyle(.reset) }
var `default`: AnsiColorStyles { self.addStyle(.default) }
var black: AnsiColorStyles { self.addStyle(.black) }
var red: AnsiColorStyles { self.addStyle(.red) }
var green: AnsiColorStyles { self.addStyle(.green) }
var yellow: AnsiColorStyles { self.addStyle(.yellow) }
var blue: AnsiColorStyles { self.addStyle(.blue) }
var magenta: AnsiColorStyles { self.addStyle(.magenta) }
var cyan: AnsiColorStyles { self.addStyle(.cyan) }
var white: AnsiColorStyles { self.addStyle(.white) }
var brightBlack: AnsiColorStyles { self.addStyle(.brightBlack) }
var brightRed: AnsiColorStyles { self.addStyle(.brightRed) }
var brightGreen: AnsiColorStyles { self.addStyle(.brightGreen) }
var brightYellow: AnsiColorStyles { self.addStyle(.brightYellow) }
var brightBlue: AnsiColorStyles { self.addStyle(.brightBlue) }
var brightMagenta: AnsiColorStyles { self.addStyle(.brightMagenta) }
var brightCyan: AnsiColorStyles { self.addStyle(.brightCyan) }
var brightWhite: AnsiColorStyles { self.addStyle(.brightWhite) }
func color256(_ c: Int) -> AnsiColorStyles { self.addStyle(.color256(c)) }
func colorRGB(_ r: Int, _ g: Int, _ b: Int) -> AnsiColorStyles { self.addStyle(.colorRGB(r, g, b)) }
var bgDefault: AnsiColorStyles { self.addStyle(.bgDefault) }
var bgBlack: AnsiColorStyles { self.addStyle(.bgBlack) }
var bgRed: AnsiColorStyles { self.addStyle(.bgRed) }
var bgGreen: AnsiColorStyles { self.addStyle(.bgGreen) }
var bgYellow: AnsiColorStyles { self.addStyle(.bgYellow) }
var bgBlue: AnsiColorStyles { self.addStyle(.bgBlue) }
var bgMagenta: AnsiColorStyles { self.addStyle(.bgMagenta) }
var bgCyan: AnsiColorStyles { self.addStyle(.bgCyan) }
var bgWhite: AnsiColorStyles { self.addStyle(.bgWhite) }
var bgBrightBlack: AnsiColorStyles { self.addStyle(.bgBrightBlack) }
var bgBrightRed: AnsiColorStyles { self.addStyle(.bgBrightRed) }
var bgBrightGreen: AnsiColorStyles { self.addStyle(.bgBrightGreen) }
var bgBrightYellow: AnsiColorStyles { self.addStyle(.bgBrightYellow) }
var bgBrightBlue: AnsiColorStyles { self.addStyle(.bgBrightBlue) }
var bgBrightMagenta: AnsiColorStyles { self.addStyle(.bgBrightMagenta) }
var bgBrightCyan: AnsiColorStyles { self.addStyle(.bgBrightCyan) }
var bgBrightWhite: AnsiColorStyles { self.addStyle(.bgBrightWhite) }
func bgColor256(_ c: Int) -> AnsiColorStyles { self.addStyle(.bgColor256(c)) }
func bgColorRGB(_ r: Int, _ g: Int, _ b: Int) -> AnsiColorStyles { self.addStyle(.bgColorRGB(r, g, b)) }
var bold: AnsiColorStyles { self.addStyle(.bold) }
var dim: AnsiColorStyles { self.addStyle(.dim) }
var italic: AnsiColorStyles { self.addStyle(.italic) }
var underline: AnsiColorStyles { self.addStyle(.underline) }
var blink: AnsiColorStyles { self.addStyle(.blink) }
var reverse: AnsiColorStyles { self.addStyle(.reverse) }
var hidden: AnsiColorStyles { self.addStyle(.hidden) }
var strikethrough: AnsiColorStyles { self.addStyle(.strikethrough) }
}
・ 256 Color の拡張表記
- 216色カラー(r, g, b を指定する)
| 色 | 文字色 | 背景色 | 値 |
|---|---|---|---|
| 216色カラー | .color216(r, g, b) | .bgColor216(r, g, b) | $0 ≤ r, g, b ≤ 5$ |
| 24階調グレースケール | .grayscale(値) | .bgGrayscale(値) | $0 ≤ 値 ≤ 23$ |
let sp4 = String(repeating: " ", count: 4)
print(sp4 + ((0...5).map { g in "g:\(g)" }).joined(separator: sp4))
for r in 0...5 {
print("r:\(r)", terminator: " ")
for g in 0...5 {
for b in 0...5 {
print("\(b)".brightWhite.bgColor216(r, g, b)(), terminator: "")
}
print(terminator: " ")
}
print()
}
- 24階調グレースケール
print((0 ..< 24).map { gray in "\(gray)".grayscale(gray)() }.joined())
print((0 ..< 24).map { gray in "\(gray)".brightWhite.bgGrayscale(gray)() }.joined())
・ 24bit Color の拡張表記
- r, g, b をタプルで指定する
| 色 | 文字色 | 背景色 | 値 |
|---|---|---|---|
| 24bit RGB | .colorRGB((r, g, b)) | .bgColorRGB((r, g, b)) | $0 ≤ r, g, b ≤ 255$ |
func 補色(_ rgb: (Int, Int, Int)) -> (Int, Int, Int) {
let mix = [rgb.0, rgb.1, rgb.2].min()! + [rgb.0, rgb.1, rgb.2].max()!
return (mix - rgb.0, mix - rgb.1, mix - rgb.2)
}
let あか = (255, 0, 0)
let みどり = (0, 255, 0)
let あお = (0, 0, 255)
let 赤 = "あか".colorRGB(あか).bgColorRGB(補色(あか))
let 緑 = "みどり".colorRGB(みどり).bgColorRGB(補色(みどり))
let 青 = "あお".colorRGB(あお).bgColorRGB(補色(あお))
print(赤() + 緑() + 青())
-
拡張表記の追加コード
extension String { func color216(_ r: Int, _ g: Int, _ b: Int) -> AnsiColorStyles { AnsiColorStyles(self, .color256(16 + 36 * r + 6 * g + b)) } func grayscale(_ g: Int) -> AnsiColorStyles { AnsiColorStyles(self, .color256(g + 232)) } func bgColor216(_ r: Int, _ g: Int, _ b: Int) -> AnsiColorStyles { AnsiColorStyles(self, .bgColor256(16 + 36 * r + 6 * g + b)) } func bgGrayscale(_ g: Int) -> AnsiColorStyles { AnsiColorStyles(self, .bgColor256(g + 232)) } func colorRGB(_ rgb: (Int, Int, Int)) -> AnsiColorStyles { AnsiColorStyles(self, .colorRGB(rgb.0, rgb.1, rgb.2)) } func bgColorRGB(_ rgb: (Int, Int, Int)) -> AnsiColorStyles { AnsiColorStyles(self, .bgColorRGB(rgb.0, rgb.1, rgb.2)) } } extension AnsiColorStyles { func color216(_ r: Int, _ g: Int, _ b: Int) -> AnsiColorStyles { self.addStyle(.color256(16 + 36 * r + 6 * g + b)) } func grayscale(_ g: Int) -> AnsiColorStyles { self.addStyle(.color256(g + 232)) } func bgColor216(_ r: Int, _ g: Int, _ b: Int) -> AnsiColorStyles { self.addStyle(.bgColor256(16 + 36 * r + 6 * g + b)) } func bgGrayscale(_ g: Int) -> AnsiColorStyles { self.addStyle(.bgColor256(g + 232)) } func colorRGB(_ rgb: (Int, Int, Int)) -> AnsiColorStyles { self.addStyle(.colorRGB(rgb.0, rgb.1, rgb.2)) } func bgColorRGB(_ rgb: (Int, Int, Int)) -> AnsiColorStyles { self.addStyle(.bgColorRGB(rgb.0, rgb.1, rgb.2)) } }
何かのお役に立てれば幸いです。
以上











