Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show color palettes #28

Merged
merged 4 commits into from
Jun 13, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ $ go get -u github.com/jingweno/ccat
$ ccat FILE1 FILE2 ...
$ ccat --bg=dark FILE1 FILE 2 ... # dark background
$ ccat --color-code String="_darkblue_" --color-code Plaintext="darkred" FILE # set color codes
$ ccat --palette # show palette
$ ccat # read from standard input
$ curl https://raw.githubusercontent.com/jingweno/ccat/master/main.go | ccat
```
Expand Down
8 changes: 4 additions & 4 deletions ccat.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,23 @@ type CCatPrinter interface {
}

type AutoColorPrinter struct {
ColorDefs ColorDefs
ColorPalettes ColorPalettes
}

func (a AutoColorPrinter) Print(r io.Reader, w io.Writer) error {
if isatty.IsTerminal(uintptr(syscall.Stdout)) {
return ColorPrinter{a.ColorDefs}.Print(r, w)
return ColorPrinter{a.ColorPalettes}.Print(r, w)
} else {
return PlainTextPrinter{}.Print(r, w)
}
}

type ColorPrinter struct {
ColorDefs ColorDefs
ColorPalettes ColorPalettes
}

func (c ColorPrinter) Print(r io.Reader, w io.Writer) error {
return CPrint(r, w, c.ColorDefs)
return CPrint(r, w, c.ColorPalettes)
}

type PlainTextPrinter struct {
Expand Down
46 changes: 34 additions & 12 deletions color.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,34 @@ package main
import (
"bytes"
"fmt"
"sort"
"strings"
)

const esc = "\033["

var ColorCodes = map[string]string{
type ColorCodes map[string]string

func (c ColorCodes) String() string {
var cc []string
for k, _ := range c {
if k == "" {
continue
}

cc = append(cc, k)
}
sort.Strings(cc)

var s []string
for _, ss := range cc {
s = append(s, Colorize(ss, ss))
}

return strings.Join(s, ", ")
}

var colorCodes = ColorCodes{
"": "",
"reset": esc + "39;49;00m",
"bold": esc + "01m",
Expand Down Expand Up @@ -43,14 +65,14 @@ func init() {
}

for i, x := 0, 30; i < len(darkColors); i, x = i+1, x+1 {
ColorCodes[darkColors[i]] = esc + fmt.Sprintf("%dm", x)
ColorCodes[lightColors[i]] = esc + fmt.Sprintf("%d;01m", x)
colorCodes[darkColors[i]] = esc + fmt.Sprintf("%dm", x)
colorCodes[lightColors[i]] = esc + fmt.Sprintf("%d;01m", x)
}

ColorCodes["darkteal"] = ColorCodes["turquoise"]
ColorCodes["darkyellow"] = ColorCodes["brown"]
ColorCodes["fuscia"] = ColorCodes["fuchsia"]
ColorCodes["white"] = ColorCodes["bold"]
colorCodes["darkteal"] = colorCodes["turquoise"]
colorCodes["darkyellow"] = colorCodes["brown"]
colorCodes["fuscia"] = colorCodes["fuchsia"]
colorCodes["white"] = colorCodes["bold"]
}

/*
Expand All @@ -69,26 +91,26 @@ func Colorize(attr, text string) string {
result := new(bytes.Buffer)

if strings.HasPrefix(attr, "+") && strings.HasSuffix(attr, "+") {
result.WriteString(ColorCodes["blink"])
result.WriteString(colorCodes["blink"])
attr = strings.TrimPrefix(attr, "+")
attr = strings.TrimSuffix(attr, "+")
}

if strings.HasPrefix(attr, "*") && strings.HasSuffix(attr, "*") {
result.WriteString(ColorCodes["bold"])
result.WriteString(colorCodes["bold"])
attr = strings.TrimPrefix(attr, "*")
attr = strings.TrimSuffix(attr, "*")
}

if strings.HasPrefix(attr, "_") && strings.HasSuffix(attr, "_") {
result.WriteString(ColorCodes["underline"])
result.WriteString(colorCodes["underline"])
attr = strings.TrimPrefix(attr, "_")
attr = strings.TrimSuffix(attr, "_")
}

result.WriteString(ColorCodes[attr])
result.WriteString(colorCodes[attr])
result.WriteString(text)
result.WriteString(ColorCodes["reset"])
result.WriteString(colorCodes["reset"])

return result.String()
}
18 changes: 7 additions & 11 deletions color_test.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
package main

import (
"testing"
import "testing"

"github.com/jingweno/ccat/Godeps/_workspace/src/github.com/sourcegraph/syntaxhighlight"
)

func Test_ColorDefs_Set(t *testing.T) {
defs := ColorDefs{
syntaxhighlight.String: "blue",
func Test_ColorPalette_Set(t *testing.T) {
palettes := ColorPalettes{
stringKind: "blue",
}

ok := defs.Set("foo", "bar")
ok := palettes.Set("foo", "bar")
if ok {
t.Errorf("setting color code foo should not be ok")
}

ok = defs.Set("String", "baz")
ok = palettes.Set("String", "baz")
if !ok {
t.Errorf("setting color code String should be ok")
}

if defs[syntaxhighlight.String] != "baz" {
if palettes[stringKind] != "baz" {
t.Errorf("color code of String should be baz")
}
}
Expand Down
42 changes: 32 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,52 @@ const (
)

type ccatCmd struct {
BG string
Color string
ColorCodes mapValue
BG string
Color string
ColorCodes mapValue
ShowPalette bool
}

func (c *ccatCmd) Run(cmd *cobra.Command, args []string) {
var colorDefs ColorDefs
var colorPalettes ColorPalettes
if c.BG == "dark" {
colorDefs = DarkColorDefs
colorPalettes = DarkColorPalettes
} else {
colorDefs = LightColorDefs
colorPalettes = LightColorPalettes
}

// override color codes
for k, v := range c.ColorCodes {
ok := colorDefs.Set(k, v)
ok := colorPalettes.Set(k, v)
if !ok {
log.Fatal(fmt.Errorf("unknown color code: %s", k))
}
}

if c.ShowPalette {
fmt.Printf(`Applied color codes:

%s

Color code is in the format of:

color normal color
*color* bold color
_color_ underlined color
+color+ blinking color

Value of color can be %s
`, colorPalettes, colorCodes)
return
}

var printer CCatPrinter
if c.Color == "always" {
printer = ColorPrinter{colorDefs}
printer = ColorPrinter{colorPalettes}
} else if c.Color == "never" {
printer = PlainTextPrinter{}
} else {
printer = AutoColorPrinter{colorDefs}
printer = AutoColorPrinter{colorPalettes}
}

// if there's no args, read from stdin
Expand All @@ -66,6 +85,7 @@ func main() {
Example: `$ ccat FILE1 FILE2 ...
$ ccat --bg=dark FILE1 FILE2 ... # dark background
$ ccat --color-code String="_darkblue_" --color-code Plaintext="darkred" FILE # set color codes
$ ccat --palette # show palette
$ ccat # read from standard input
$ curl https://raw.githubusercontent.com/jingweno/ccat/master/main.go | ccat`,
Run: ccatCmd.Run,
Expand All @@ -79,7 +99,8 @@ Flags:
{{.LocalFlags.FlagUsages}}
Using color is auto both by default and with --color=auto. With --color=auto,
ccat emits color codes only when standard output is connected to a terminal.
Color codes can be changed with --color-code KEY=VALUE.
Color codes can be changed with --color-code KEY=VALUE. List of color codes can
be found with --palette.

Examples:
{{ .Example }}`
Expand All @@ -88,6 +109,7 @@ Examples:
rootCmd.PersistentFlags().StringVarP(&ccatCmd.BG, "bg", "", "light", `set to "light" or "dark" depending on the terminal's background`)
rootCmd.PersistentFlags().StringVarP(&ccatCmd.Color, "color", "C", "auto", `colorize the output; value can be "never", "always" or "auto"`)
rootCmd.PersistentFlags().VarP(&ccatCmd.ColorCodes, "color-code", "G", `set color codes`)
rootCmd.PersistentFlags().BoolVarP(&ccatCmd.ShowPalette, "palette", "", false, `show color palettes`)

rootCmd.Execute()
}
Loading