pax_global_header00006660000000000000000000000064131354423760014522gustar00rootroot0000000000000052 comment=850f5519aa33f02a71bd8b6915a3f3d84a626e1d go-technicolor-0.1/000077500000000000000000000000001313544237600142765ustar00rootroot00000000000000go-technicolor-0.1/.gitignore000066400000000000000000000000051313544237600162610ustar00rootroot00000000000000*swp go-technicolor-0.1/LICENSE000066400000000000000000000020741313544237600153060ustar00rootroot00000000000000Copyright (c) 2017, Paul R. Tagliamonte Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. go-technicolor-0.1/cmd/000077500000000000000000000000001313544237600150415ustar00rootroot00000000000000go-technicolor-0.1/cmd/technicolor/000077500000000000000000000000001313544237600173525ustar00rootroot00000000000000go-technicolor-0.1/cmd/technicolor/main.go000066400000000000000000000003671313544237600206330ustar00rootroot00000000000000package main import ( "os" "pault.ag/go/technicolor" ) func main() { output := technicolor.NewWriter(os.Stdout) output.Bold().Red().Printf("U") output.White().Printf("S") output.Cyan().Printf("A\n") output.ResetColor().Write([]byte{}) } go-technicolor-0.1/colors.go000066400000000000000000000107571313544237600161400ustar00rootroot00000000000000package technicolor func (w Writer) Red() Writer { return w.Add(RedFg) } func (w Writer) Black() Writer { return w.Add(BlackFg) } func (w Writer) Green() Writer { return w.Add(GreenFg) } func (w Writer) Yellow() Writer { return w.Add(YellowFg) } func (w Writer) Blue() Writer { return w.Add(BlueFg) } func (w Writer) Magenta() Writer { return w.Add(MagentaFg) } func (w Writer) White() Writer { return w.Add(WhiteFg) } func (w Writer) ResetColor() Writer { return w.Reset().White() } func (w Writer) Cyan() Writer { return w.Add(CyanFg) } func Color(color string) ANSISequence { return NewANSISequence([]string{color}, 'm') } func ResetColor() ANSISequence { return Color("0") } func XTermColor(color string) ANSISequence { return NewANSISequence([]string{"38", "5", color}, 'm') } func XTermBackgroundColor(color string) ANSISequence { return NewANSISequence([]string{"48", "5", color}, 'm') } func XTermTheme(fg, bg string) ANSISequences { return ANSISequences{XTermColor(fg), XTermBackgroundColor(bg)} } var Primary = "025" var PrimaryDarker = "024" var PrimaryDarkest = "017" var Base = "016" var White = "231" var PrimaryAlt = "038" var PrimaryAltDarkest = "024" var PrimaryAltDark = "038" var PrimaryAltLight = "153" var PrimaryAltLightest = "195" var Secondary = "161" var SecondaryDarkest = "088" var SecondaryDark = "160" var SecondaryLight = "174" var SecondaryLightest = "224" var GrayDark = "059" var Gray = "059" var GrayLight = "145" var GrayLighter = "188" var GrayLightest = "231" var GrayWarmDark = "059" var GrayWarmLight = "188" var GrayCoolLight = "189" var Gold = "214" var GoldLight = "221" var GoldLighter = "222" var GoldLightest = "230" var Green = "029" var GreenLight = "071" var GreenLighter = "109" var GreenLightest = "194" var CoolBlue = "024" var CoolBlueLight = "067" var CoolBlueLighter = "110" var CoolBlueLightest = "189" var Focus = "068" var Visited = "054" var BlackFg = XTermColor(Base) var RedFg = XTermColor(SecondaryDark) var GreenFg = XTermColor(GreenLight) var YellowFg = XTermColor(GoldLight) var BlueFg = XTermColor(PrimaryAltLightest) var MagentaFg = XTermColor(Visited) var CyanFg = XTermColor(Focus) var WhiteFg = Color("0") var PrimaryDarkestOnWhite = XTermTheme(PrimaryDarkest, White) var PrimaryDarkerOnWhite = XTermTheme(PrimaryDarker, White) var PrimaryOnWhite = XTermTheme(Primary, White) var CoolBlueLightOnWhite = XTermTheme(CoolBlueLight, White) var PrimaryAltDarkestOnWhite = XTermTheme(PrimaryAltDarkest, White) var GreenOnWhite = XTermTheme(Green, White) var VisitedOnWhite = XTermTheme(Visited, White) var BaseOnWhite = XTermTheme(Base, White) var GrayDarkOnWhite = XTermTheme(GrayDark, White) var GrayOnWhite = XTermTheme(Gray, White) var GrayWarmDarkOnWhite = XTermTheme(GrayWarmDark, White) var SecondaryDarkestOnWhite = XTermTheme(SecondaryDarkest, White) var SecondaryDarkOnWhite = XTermTheme(SecondaryDark, White) var SecondaryOnWhite = XTermTheme(Secondary, White) var WhiteOnBase = XTermTheme(White, Base) var WhiteOnGrayWarmDark = XTermTheme(White, GrayWarmDark) var WhiteOnGrayDark = XTermTheme(White, GrayDark) var WhiteOnGray = XTermTheme(White, Gray) var WhiteOnPrimaryDarkest = XTermTheme(White, PrimaryDarkest) var WhiteOnPrimaryDarker = XTermTheme(White, PrimaryDarker) var WhiteOnPrimary = XTermTheme(White, Primary) var WhiteOnCoolBlueLight = XTermTheme(White, CoolBlueLight) var WhiteOnPrimaryAltDarkest = XTermTheme(White, PrimaryAltDarkest) var BaseOnPrimaryAltDark = XTermTheme(Base, PrimaryAltDark) var BaseOnPrimaryAlt = XTermTheme(Base, PrimaryAlt) var WhiteOnGreen = XTermTheme(White, Green) var BaseOnGreenLight = XTermTheme(Base, GreenLight) var BaseOnGold = XTermTheme(Base, Gold) var BaseOnGoldLight = XTermTheme(Base, GoldLight) var WhiteOnSecondaryDarkest = XTermTheme(White, SecondaryDarkest) var WhiteOnSecondaryDark = XTermTheme(White, SecondaryDark) var WhiteOnSecondary = XTermTheme(White, Secondary) var BaseOnGrayLight = XTermTheme(Base, GrayLight) var BaseOnGrayLighter = XTermTheme(Base, GrayLighter) var BaseOnGrayWarmLight = XTermTheme(Base, GrayWarmLight) var BaseOnCoolBlueLighter = XTermTheme(Base, CoolBlueLighter) var BaseOnCoolBlueLightest = XTermTheme(Base, CoolBlueLightest) var BaseOnPrimaryAltLightest = XTermTheme(Base, PrimaryAltLightest) var BaseOnGreenLighter = XTermTheme(Base, GreenLighter) var BaseOnGreenLightest = XTermTheme(Base, GreenLightest) var BaseOnGoldLighter = XTermTheme(Base, GoldLighter) var BaseOnGoldLightest = XTermTheme(Base, GoldLightest) var BaseOnSecondaryLightest = XTermTheme(Base, SecondaryLightest) go-technicolor-0.1/data.go000066400000000000000000000052301313544237600155360ustar00rootroot00000000000000package technicolor import ( "fmt" "io" "os" "strings" "syscall" "unsafe" ) type ANSISequence []byte type ANSISequences []ANSISequence // "Flatten" the ANSI Sequences into a single byte stream func (a ANSISequences) Sequence() []byte { out := []byte{} for _, seq := range a { out = append(out, seq...) } return out } func NewANSISequence(arguments []string, ansiType byte) ANSISequence { return ANSISequence(append(append([]byte{0x1b, 0x5b}, []byte(strings.Join(arguments, ";"))..., ), ansiType)) } func NewTerminalWriter(file *os.File) Writer { output := NewWriter(file) if IsFileTerminal(file) { output = output.EnableColor() } else { output = output.DisableColor() } return output } func NewWriter(o io.Writer) Writer { return Writer{ aNSISequences: ANSISequences{}, output: o, enableColor: false, } } type Writer struct { aNSISequences ANSISequences output io.Writer enableColor bool } func (w Writer) DisableColor() Writer { return Writer{ aNSISequences: w.aNSISequences, output: w.output, enableColor: false, } } func (w Writer) EnableColor() Writer { return Writer{ aNSISequences: w.aNSISequences, output: w.output, enableColor: true, } } func (w Writer) Bold() Writer { return w.Add(NewANSISequence([]string{"1"}, 'm')) } func (w Writer) Add(seqs ...ANSISequence) Writer { return Writer{ aNSISequences: append(w.aNSISequences, seqs...), output: w.output, enableColor: w.enableColor, } } func (w Writer) Reset(seqs ...ANSISequence) Writer { return Writer{ aNSISequences: ANSISequences{}, output: w.output, enableColor: w.enableColor, } } func (w Writer) Printf(format string, args ...interface{}) (int, error) { return fmt.Fprintf(w, format, args...) } func (w Writer) Write(out []byte) (int, error) { if w.enableColor { return w.output.Write(append(w.aNSISequences.Sequence(), out...)) } return w.output.Write(out) } // This is some yanked nasty shaz that will check to see if a file descriptor // we have is a terminal or something else. This is handy for color stuff, // since we want to be able to pipe things without seeing colors in the // processing pipeline, but also make things sane for a user. func IsTerminal(fd uintptr) bool { var termios syscall.Termios var ioctlReadTermios uintptr = 0x5401 // syscall.TCGETS _, _, err := syscall.Syscall6( syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0, ) return err == 0 } // Check to see if a given os.File is a Terminal. Notibly, `os.Stdout` is // one of these, as is `os.Stderr`. func IsFileTerminal(file *os.File) bool { return IsTerminal(file.Fd()) }