| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- package ansi
- import (
- "image/color"
- "strconv"
- "strings"
- )
- // ResetStyle is a SGR (Select Graphic Rendition) style sequence that resets
- // all attributes.
- // See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
- const ResetStyle = "\x1b[m"
- // Attr is a SGR (Select Graphic Rendition) style attribute.
- type Attr = string
- // Style represents an ANSI SGR (Select Graphic Rendition) style.
- type Style []Attr
- // String returns the ANSI SGR (Select Graphic Rendition) style sequence for
- // the given style.
- func (s Style) String() string {
- if len(s) == 0 {
- return ResetStyle
- }
- return "\x1b[" + strings.Join(s, ";") + "m"
- }
- // Styled returns a styled string with the given style applied.
- func (s Style) Styled(str string) string {
- if len(s) == 0 {
- return str
- }
- return s.String() + str + ResetStyle
- }
- // Reset appends the reset style attribute to the style.
- func (s Style) Reset() Style {
- return append(s, ResetAttr)
- }
- // Bold appends the bold style attribute to the style.
- func (s Style) Bold() Style {
- return append(s, BoldAttr)
- }
- // Faint appends the faint style attribute to the style.
- func (s Style) Faint() Style {
- return append(s, FaintAttr)
- }
- // Italic appends the italic style attribute to the style.
- func (s Style) Italic() Style {
- return append(s, ItalicAttr)
- }
- // Underline appends the underline style attribute to the style.
- func (s Style) Underline() Style {
- return append(s, UnderlineAttr)
- }
- // DoubleUnderline appends the double underline style attribute to the style.
- func (s Style) DoubleUnderline() Style {
- return append(s, DoubleUnderlineAttr)
- }
- // CurlyUnderline appends the curly underline style attribute to the style.
- func (s Style) CurlyUnderline() Style {
- return append(s, CurlyUnderlineAttr)
- }
- // DottedUnderline appends the dotted underline style attribute to the style.
- func (s Style) DottedUnderline() Style {
- return append(s, DottedUnderlineAttr)
- }
- // DashedUnderline appends the dashed underline style attribute to the style.
- func (s Style) DashedUnderline() Style {
- return append(s, DashedUnderlineAttr)
- }
- // SlowBlink appends the slow blink style attribute to the style.
- func (s Style) SlowBlink() Style {
- return append(s, SlowBlinkAttr)
- }
- // RapidBlink appends the rapid blink style attribute to the style.
- func (s Style) RapidBlink() Style {
- return append(s, RapidBlinkAttr)
- }
- // Reverse appends the reverse style attribute to the style.
- func (s Style) Reverse() Style {
- return append(s, ReverseAttr)
- }
- // Conceal appends the conceal style attribute to the style.
- func (s Style) Conceal() Style {
- return append(s, ConcealAttr)
- }
- // Strikethrough appends the strikethrough style attribute to the style.
- func (s Style) Strikethrough() Style {
- return append(s, StrikethroughAttr)
- }
- // NoBold appends the no bold style attribute to the style.
- func (s Style) NoBold() Style {
- return append(s, NoBoldAttr)
- }
- // NormalIntensity appends the normal intensity style attribute to the style.
- func (s Style) NormalIntensity() Style {
- return append(s, NormalIntensityAttr)
- }
- // NoItalic appends the no italic style attribute to the style.
- func (s Style) NoItalic() Style {
- return append(s, NoItalicAttr)
- }
- // NoUnderline appends the no underline style attribute to the style.
- func (s Style) NoUnderline() Style {
- return append(s, NoUnderlineAttr)
- }
- // NoBlink appends the no blink style attribute to the style.
- func (s Style) NoBlink() Style {
- return append(s, NoBlinkAttr)
- }
- // NoReverse appends the no reverse style attribute to the style.
- func (s Style) NoReverse() Style {
- return append(s, NoReverseAttr)
- }
- // NoConceal appends the no conceal style attribute to the style.
- func (s Style) NoConceal() Style {
- return append(s, NoConcealAttr)
- }
- // NoStrikethrough appends the no strikethrough style attribute to the style.
- func (s Style) NoStrikethrough() Style {
- return append(s, NoStrikethroughAttr)
- }
- // DefaultForegroundColor appends the default foreground color style attribute to the style.
- func (s Style) DefaultForegroundColor() Style {
- return append(s, DefaultForegroundColorAttr)
- }
- // DefaultBackgroundColor appends the default background color style attribute to the style.
- func (s Style) DefaultBackgroundColor() Style {
- return append(s, DefaultBackgroundColorAttr)
- }
- // DefaultUnderlineColor appends the default underline color style attribute to the style.
- func (s Style) DefaultUnderlineColor() Style {
- return append(s, DefaultUnderlineColorAttr)
- }
- // ForegroundColor appends the foreground color style attribute to the style.
- func (s Style) ForegroundColor(c Color) Style {
- return append(s, ForegroundColorAttr(c))
- }
- // BackgroundColor appends the background color style attribute to the style.
- func (s Style) BackgroundColor(c Color) Style {
- return append(s, BackgroundColorAttr(c))
- }
- // UnderlineColor appends the underline color style attribute to the style.
- func (s Style) UnderlineColor(c Color) Style {
- return append(s, UnderlineColorAttr(c))
- }
- // SGR (Select Graphic Rendition) style attributes.
- // See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
- const (
- ResetAttr Attr = "0"
- BoldAttr Attr = "1"
- FaintAttr Attr = "2"
- ItalicAttr Attr = "3"
- UnderlineAttr Attr = "4"
- DoubleUnderlineAttr Attr = "4:2"
- CurlyUnderlineAttr Attr = "4:3"
- DottedUnderlineAttr Attr = "4:4"
- DashedUnderlineAttr Attr = "4:5"
- SlowBlinkAttr Attr = "5"
- RapidBlinkAttr Attr = "6"
- ReverseAttr Attr = "7"
- ConcealAttr Attr = "8"
- StrikethroughAttr Attr = "9"
- NoBoldAttr Attr = "21" // Some terminals treat this as double underline.
- NormalIntensityAttr Attr = "22"
- NoItalicAttr Attr = "23"
- NoUnderlineAttr Attr = "24"
- NoBlinkAttr Attr = "25"
- NoReverseAttr Attr = "27"
- NoConcealAttr Attr = "28"
- NoStrikethroughAttr Attr = "29"
- DefaultForegroundColorAttr Attr = "39"
- DefaultBackgroundColorAttr Attr = "49"
- DefaultUnderlineColorAttr Attr = "59"
- )
- // ForegroundColorAttr returns the style SGR attribute for the given foreground
- // color.
- // See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
- func ForegroundColorAttr(c Color) Attr {
- switch c := c.(type) {
- case BasicColor:
- // 3-bit or 4-bit ANSI foreground
- // "3<n>" or "9<n>" where n is the color number from 0 to 7
- if c < 8 {
- return "3" + string('0'+c)
- } else if c < 16 {
- return "9" + string('0'+c-8)
- }
- case ExtendedColor:
- // 256-color ANSI foreground
- // "38;5;<n>"
- return "38;5;" + strconv.FormatUint(uint64(c), 10)
- case TrueColor, color.Color:
- // 24-bit "true color" foreground
- // "38;2;<r>;<g>;<b>"
- r, g, b, _ := c.RGBA()
- return "38;2;" +
- strconv.FormatUint(uint64(shift(r)), 10) + ";" +
- strconv.FormatUint(uint64(shift(g)), 10) + ";" +
- strconv.FormatUint(uint64(shift(b)), 10)
- }
- return DefaultForegroundColorAttr
- }
- // BackgroundColorAttr returns the style SGR attribute for the given background
- // color.
- // See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
- func BackgroundColorAttr(c Color) Attr {
- switch c := c.(type) {
- case BasicColor:
- // 3-bit or 4-bit ANSI foreground
- // "4<n>" or "10<n>" where n is the color number from 0 to 7
- if c < 8 {
- return "4" + string('0'+c)
- } else {
- return "10" + string('0'+c-8)
- }
- case ExtendedColor:
- // 256-color ANSI foreground
- // "48;5;<n>"
- return "48;5;" + strconv.FormatUint(uint64(c), 10)
- case TrueColor, color.Color:
- // 24-bit "true color" foreground
- // "38;2;<r>;<g>;<b>"
- r, g, b, _ := c.RGBA()
- return "48;2;" +
- strconv.FormatUint(uint64(shift(r)), 10) + ";" +
- strconv.FormatUint(uint64(shift(g)), 10) + ";" +
- strconv.FormatUint(uint64(shift(b)), 10)
- }
- return DefaultBackgroundColorAttr
- }
- // UnderlineColorAttr returns the style SGR attribute for the given underline
- // color.
- // See: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
- func UnderlineColorAttr(c Color) Attr {
- switch c := c.(type) {
- // NOTE: we can't use 3-bit and 4-bit ANSI color codes with underline
- // color, use 256-color instead.
- //
- // 256-color ANSI underline color
- // "58;5;<n>"
- case BasicColor:
- return "58;5;" + strconv.FormatUint(uint64(c), 10)
- case ExtendedColor:
- return "58;5;" + strconv.FormatUint(uint64(c), 10)
- case TrueColor, color.Color:
- // 24-bit "true color" foreground
- // "38;2;<r>;<g>;<b>"
- r, g, b, _ := c.RGBA()
- return "58;2;" +
- strconv.FormatUint(uint64(shift(r)), 10) + ";" +
- strconv.FormatUint(uint64(shift(g)), 10) + ";" +
- strconv.FormatUint(uint64(shift(b)), 10)
- }
- return DefaultUnderlineColorAttr
- }
- func shift(v uint32) uint32 {
- if v > 0xff {
- return v >> 8
- }
- return v
- }
|