colors.go (2118B)
1 // Copyright 2022 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 // Package terminal contains helper for the terminal, such as coloring output.
15 package terminal
16
17 import (
18 "fmt"
19 "os"
20 "runtime"
21 "strings"
22
23 isatty "github.com/mattn/go-isatty"
24 )
25
26 const (
27 errorColor = "\033[1;31m%s\033[0m"
28 warningColor = "\033[0;33m%s\033[0m"
29 noticeColor = "\033[1;36m%s\033[0m"
30 )
31
32 // PrintANSIColors returns false if NO_COLOR env variable is set,
33 // else IsTerminal(f).
34 func PrintANSIColors(f *os.File) bool {
35 if os.Getenv("NO_COLOR") != "" {
36 return false
37 }
38 return IsTerminal(f)
39 }
40
41 // IsTerminal return true if the file descriptor is terminal and the TERM
42 // environment variable isn't a dumb one.
43 func IsTerminal(f *os.File) bool {
44 if runtime.GOOS == "windows" {
45 return false
46 }
47
48 fd := f.Fd()
49 return os.Getenv("TERM") != "dumb" && (isatty.IsTerminal(fd) || isatty.IsCygwinTerminal(fd))
50 }
51
52 // Notice colorizes the string in a noticeable color.
53 func Notice(s string) string {
54 return colorize(s, noticeColor)
55 }
56
57 // Error colorizes the string in a colour that grabs attention.
58 func Error(s string) string {
59 return colorize(s, errorColor)
60 }
61
62 // Warning colorizes the string in a colour that warns.
63 func Warning(s string) string {
64 return colorize(s, warningColor)
65 }
66
67 // colorize s in color.
68 func colorize(s, color string) string {
69 s = fmt.Sprintf(color, doublePercent(s))
70 return singlePercent(s)
71 }
72
73 func doublePercent(str string) string {
74 return strings.Replace(str, "%", "%%", -1)
75 }
76
77 func singlePercent(str string) string {
78 return strings.Replace(str, "%%", "%", -1)
79 }