github.com/coveo/gotemplate@v2.7.7+incompatible/utils/color.go (about) 1 package utils 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/coveo/gotemplate/errors" 8 "github.com/fatih/color" 9 ) 10 11 // Attribute is imported from color attribute 12 type Attribute color.Attribute 13 14 // The following constant are copied from the color package in order to get 15 // the actual names 16 const ( 17 Reset Attribute = iota 18 Bold 19 Faint 20 Italic 21 Underline 22 BlinkSlow 23 BlinkRapid 24 ReverseVideo 25 Concealed 26 CrossedOut 27 ) 28 29 // Foreground attributes 30 const ( 31 FgBlack Attribute = iota + 30 32 FgRed 33 FgGreen 34 FgYellow 35 FgBlue 36 FgMagenta 37 FgCyan 38 FgWhite 39 ) 40 41 // Foreground attributes high intensity 42 const ( 43 FgHiBlack Attribute = iota + 90 44 FgHiRed 45 FgHiGreen 46 FgHiYellow 47 FgHiBlue 48 FgHiMagenta 49 FgHiCyan 50 FgHiWhite 51 ) 52 53 // Background attributes 54 const ( 55 BgBlack Attribute = iota + 40 56 BgRed 57 BgGreen 58 BgYellow 59 BgBlue 60 BgMagenta 61 BgCyan 62 BgWhite 63 ) 64 65 // Background attributes high intensity 66 const ( 67 BgHiBlack Attribute = iota + 100 68 BgHiRed 69 BgHiGreen 70 BgHiYellow 71 BgHiBlue 72 BgHiMagenta 73 BgHiCyan 74 BgHiWhite 75 ) 76 77 var EOL = fmt.Sprintln() 78 79 //go:generate stringer -type=Attribute -output generated_colors.go 80 81 // Color returns a color attribute build from supplied attribute names 82 func Color(attributes ...string) (*color.Color, error) { 83 if nameValues == nil { 84 nameValues = make(map[string]color.Attribute, BgHiWhite) 85 for i := Reset; i < BgHiWhite; i++ { 86 name := strings.ToLower(Attribute(i).String()) 87 if strings.HasPrefix(name, "attribute(") { 88 continue 89 } 90 nameValues[name] = color.Attribute(i) 91 if strings.HasPrefix(name, "fg") { 92 nameValues[name[2:]] = color.Attribute(i) 93 } 94 } 95 } 96 97 result := color.New() 98 var containsColor bool 99 var err errors.Array 100 for _, attr := range attributes { 101 for _, attr := range String(attr).FieldsID().Strings() { 102 if a, match := nameValues[strings.ToLower(attr)]; match { 103 result.Add(a) 104 containsColor = true 105 106 } else { 107 err = append(err, fmt.Errorf("Attribute not found %s", attr)) 108 } 109 } 110 } 111 112 if !containsColor { 113 return result, fmt.Errorf("No color specified") 114 } 115 if len(err) > 0 { 116 return result, err 117 } 118 return result, nil 119 } 120 121 // SprintColor returns a string formated with attributes that are supplied before 122 func SprintColor(args ...interface{}) (string, error) { 123 var i int 124 colorArgs := make([]string, len(args)) 125 for i = 0; i < len(args); i++ { 126 if _, err := Color(fmt.Sprint(args[i])); err != nil { 127 break 128 } 129 colorArgs[i] = fmt.Sprint(args[i]) 130 } 131 132 c, _ := Color(colorArgs...) 133 return c.Sprint(FormatMessage(args[i:]...)), nil 134 } 135 136 // FormatMessage analyses the arguments to determine if printf or println should be used. 137 func FormatMessage(args ...interface{}) string { 138 switch len(args) { 139 case 0: 140 return "" 141 case 1: 142 return fmt.Sprint(args[0]) 143 default: 144 if format, args := fmt.Sprint(args[0]), args[1:]; strings.Contains(format, "%") { 145 if result := fmt.Sprintf(format, args...); !strings.Contains(result, "%!") { 146 return result 147 } 148 } 149 return strings.TrimSuffix(fmt.Sprintln(args...), EOL) 150 } 151 } 152 153 var nameValues map[string]color.Attribute 154 155 // ColorPrintln call standard fmt.Println function but using the color out stream. 156 func ColorPrintln(args ...interface{}) (int, error) { 157 return fmt.Fprintln(color.Output, args...) 158 } 159 160 // ColorPrintf call standard fmt.Printf function but using the color out stream. 161 func ColorPrintf(format string, args ...interface{}) (int, error) { 162 return fmt.Fprintf(color.Output, format, args...) 163 } 164 165 // ColorPrint call standard fmt.Printf function but using the color out stream. 166 func ColorPrint(args ...interface{}) (int, error) { 167 return fmt.Fprint(color.Output, args...) 168 } 169 170 // ColorErrorPrintln call standard fmt.Println function but using the color out stream. 171 func ColorErrorPrintln(args ...interface{}) (int, error) { 172 return fmt.Fprintln(color.Error, args...) 173 } 174 175 // ColorErrorPrintf call standard fmt.Printf function but using the color out stream. 176 func ColorErrorPrintf(format string, args ...interface{}) (int, error) { 177 return fmt.Fprintf(color.Error, format, args...) 178 } 179 180 // ColorErrorPrint call standard fmt.Printf function but using the color out stream. 181 func ColorErrorPrint(args ...interface{}) (int, error) { 182 return fmt.Fprint(color.Error, args...) 183 }