ttk.go
func DecodeColor(esc string) (*Attributes, int, error) {
	var a Attributes

	if len(esc) < 2 || !strings.HasPrefix(esc, "\x1b[") {
		return nil, 0, ErrNotEscSequence
	}

	// find trailing m
	i := strings.Index(esc[2:], "m")
	if i == -1 {
		return nil, 0, ErrNotEscSequence
	}

	foundM := false
	parameters := strings.Split(esc[2:i+2+1], ";")
	for _, v := range parameters {
		if strings.HasSuffix(v, "m") {
			v = v[:len(v)-1]
			foundM = true
		}
		n, err := strconv.Atoi(v)
		if err != nil {
			return nil, 0, err
		}
		switch {
		case n == AttrReset:
			// return defaults
			a.Fg = fg
			a.Bg = bg
		case n == AttrBold:
			a.Fg |= termbox.AttrBold
		case n == AttrUnderline:
			a.Fg |= termbox.AttrUnderline
		case n == AttrReverse:
			a.Fg |= termbox.AttrReverse
		case n >= ColorBlack+ANSIFg && n <= ColorWhite+ANSIFg:
			// note that termbox colors are off by one
			a.Fg |= termbox.Attribute(n - ANSIFg + 1)
		case n >= ColorBlack+ANSIBg && n <= ColorWhite+ANSIBg:
			// note that termbox colors are off by one
			a.Bg |= termbox.Attribute(n - ANSIBg + 1)
		default:
			return nil, 0, ErrNotEscSequence
		}
	}

	if !foundM {
		return nil, 0, ErrNotEscSequence
	}

	skip := strings.Index(esc, "m")
	if skip == -1 {
		// can't happen
		return nil, 0, ErrNotEscSequence
	}
	skip++ // character past m

	return &a, skip, nil
}
func DecodeColor(esc string) (*Attributes, int, error) {
	var a Attributes

	if len(esc) < 2 || !strings.HasPrefix(esc, "\x1b[") {
		return nil, 0, ErrNotEscSequence
	}

	// find trailing m
	i := strings.Index(esc[2:], "m")
	if i == -1 {
		return nil, 0, ErrNotEscSequence
	}

	foundM := false
	parameters := strings.Split(esc[2:i+2+1], ";")
	for _, v := range parameters {
		if strings.HasSuffix(v, "m") {
			v = v[:len(v)-1]
			foundM = true
		}
		n, err := strconv.Atoi(v)
		if err != nil {
			return nil, 0, err
		}
		switch {
		case n == AttrReset:
			// return defaults
			a.Fg = fg
			a.Bg = bg
		case n == AttrBold:
			a.Fg |= termbox.AttrBold
		case n == AttrUnderline:
			a.Fg |= termbox.AttrUnderline
		case n == AttrReverse:
			a.Fg |= termbox.AttrReverse
		case n >= ColorBlack+ANSIFg && n <= ColorWhite+ANSIFg:
			// note that termbox colors are off by one
			a.Fg |= termbox.Attribute(n - ANSIFg + 1)
		case n >= ColorBlack+ANSIBg && n <= ColorWhite+ANSIBg:
			// note that termbox colors are off by one
			a.Bg |= termbox.Attribute(n - ANSIBg + 1)
		default:
			return nil, 0, ErrNotEscSequence
		}
	}

	if !foundM {
		return nil, 0, ErrNotEscSequence
	}

	skip := strings.Index(esc, "m")
	if skip == -1 {
		// can't happen
		return nil, 0, ErrNotEscSequence
	}
	skip++ // character past m

	return &a, skip, nil
}
// DecodeColor decodes an ANSI color escape sequence and ignores trailing
// characters.  It returns an Attributs type that can be used directly in
// termbox (note that the termbox colors are off by one).  The skip contains
// the location of the next character that was not consumed by the escape
// sequence.