Skip to content

Commit

Permalink
refactor: Rename from gawk to gchalk to prevent name confusion with G…
Browse files Browse the repository at this point in the history
…NU Awk.
  • Loading branch information
jwalton committed Mar 16, 2021
1 parent 15bfb09 commit 85a935f
Show file tree
Hide file tree
Showing 18 changed files with 198 additions and 198 deletions.
2 changes: 1 addition & 1 deletion LICENSE-chalk
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Gawk is based on the node.js pacakge "chalk", which contained the following license:
GChalk is based on the node.js pacakge "chalk", which contained the following license:

MIT License

Expand Down
130 changes: 65 additions & 65 deletions README.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Chalk

Gawk's architecture is heavily inspired by Chalk's architecture.
GChalk's architecture is heavily inspired by Chalk's architecture.

First of all, in Chalk when you dereference `chalk.blue`, what's actually happening here is that you're calling into a `getter` for `blue`. There are [default getters defined](https://github.com/chalk/chalk/blob/9bf298571eeee20001ba9ff5158b07d2d8a67ec1/source/index.js#L61-L67) through prototype inheritance which don't actually produce a color - instead they redefine `.blue` on the instance you're calling into to create a new "styler" and a new "builder".

Expand All @@ -12,9 +12,9 @@ When we run a styler (in [`applyStyle()`](https://github.com/chalk/chalk/blob/9b

If there are escape codes, then we need to worry about reapplying our styles - if we're coloring something green, and there's a blue bit in the middle, we still need to add the `openAll` and `closeAll` to the start and end, but then we also need to replace every blue "close tag" with a green "open tag". There's a different close tag for each kind of open tag (fg, bg, and one for each kind of modifier). To do this, we start at the leaf and replace all the closeTag instances with openTag, then we walk to the parent and do the same, all the way up the chain.

## Gawk
## GChalk

Gawk operates on more or less the same principal. When you call `WithBlue()`, it will return a Builder instance. Calling `WithBlue().BgGreen(...)` creates a Blue builder (and associated `stylerData`), and then a BgGreen builder. Just like in Chalk, the stylerData in the BgGreen builder will have Blue's stylerData as `.parent`. We of course can't overwrite functions on a receiver in Golang, but instead we store a pointer to each generated child builder in the parent builder; when you call `.WithBlue()` on the root builder, it will create a new builder and store it in `.blue` on the root builder. This mimics Chalk's behavior, with excellent performance. (At one point I tried returning a `Builder` interface from `WithBlue()` and the other `With...()` functions, but surprisingly this made coloring a string about four times slower.)
GChalk operates on more or less the same principal. When you call `WithBlue()`, it will return a Builder instance. Calling `WithBlue().BgGreen(...)` creates a Blue builder (and associated `stylerData`), and then a BgGreen builder. Just like in Chalk, the stylerData in the BgGreen builder will have Blue's stylerData as `.parent`. We of course can't overwrite functions on a receiver in Golang, but instead we store a pointer to each generated child builder in the parent builder; when you call `.WithBlue()` on the root builder, it will create a new builder and store it in `.blue` on the root builder. This mimics Chalk's behavior, with excellent performance. (At one point I tried returning a `Builder` interface from `WithBlue()` and the other `With...()` functions, but surprisingly this made coloring a string about four times slower.)

This does mean that calling `.WithBlue()` will immediately allocate a structure with 41 pointers in it. If you call every permutation of `bgcolor.color.modifier` we end up allocating `16 * 16 * 9 * 41 = 94464` pointers, or about 750K of RAM (although... no one is going to do this). Calling the `RGB()` and other color model functions don't do this (we don't allocate 16.7m pointers) but they do still create an object which will need to be garbage collected eventually. If you're doing something like color gradients, you're better off calling directly into `pkg/ansistyles` to color things.

Expand Down
4 changes: 2 additions & 2 deletions colorModels.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package gawk
package gchalk

import (
"github.com/jwalton/gawk/pkg/ansistyles"
"github.com/jwalton/gchalk/pkg/ansistyles"
)

// Ansi returns a function which colors a string using the ANSI 16 color pallette.
Expand Down
28 changes: 14 additions & 14 deletions colorModels_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package gawk
package gchalk

import (
"testing"
)

func TestAnsi(t *testing.T) {
gawk := New(ForceLevel(LevelAnsi16m))
assertEqual(t, gawk.Ansi(31)("foo"), "\u001b[31mfoo\u001b[39m")
assertEqual(t, gawk.BgAnsi(31)("foo"), "\u001b[41mfoo\u001b[49m")
assertEqual(t, gawk.Ansi(1)("foo"), "\u001b[1mfoo\u001b[22m")
gchalk := New(ForceLevel(LevelAnsi16m))
assertEqual(t, gchalk.Ansi(31)("foo"), "\u001b[31mfoo\u001b[39m")
assertEqual(t, gchalk.BgAnsi(31)("foo"), "\u001b[41mfoo\u001b[49m")
assertEqual(t, gchalk.Ansi(1)("foo"), "\u001b[1mfoo\u001b[22m")

SetLevel(LevelAnsi16m)
assertEqual(t, Ansi(31)("foo"), "\u001b[31mfoo\u001b[39m")
Expand All @@ -17,29 +17,29 @@ func TestAnsi(t *testing.T) {
}

func TestAnsi256(t *testing.T) {
gawk := New(ForceLevel(LevelAnsi16m))
assertEqual(t, gawk.Ansi256(201)("foo"), "\u001b[38;5;201mfoo\u001b[39m")
assertEqual(t, gawk.BgAnsi256(201)("foo"), "\u001b[48;5;201mfoo\u001b[49m")
gchalk := New(ForceLevel(LevelAnsi16m))
assertEqual(t, gchalk.Ansi256(201)("foo"), "\u001b[38;5;201mfoo\u001b[39m")
assertEqual(t, gchalk.BgAnsi256(201)("foo"), "\u001b[48;5;201mfoo\u001b[49m")

SetLevel(LevelAnsi16m)
assertEqual(t, Ansi256(201)("foo"), "\u001b[38;5;201mfoo\u001b[39m")
assertEqual(t, BgAnsi256(201)("foo"), "\u001b[48;5;201mfoo\u001b[49m")
}

func TestRGB(t *testing.T) {
gawk := New(ForceLevel(LevelAnsi16m))
assertEqual(t, gawk.RGB(100, 200, 255)("foo"), "\u001b[38;2;100;200;255mfoo\u001b[39m")
assertEqual(t, gawk.BgRGB(100, 200, 255)("foo"), "\u001b[48;2;100;200;255mfoo\u001b[49m")
gchalk := New(ForceLevel(LevelAnsi16m))
assertEqual(t, gchalk.RGB(100, 200, 255)("foo"), "\u001b[38;2;100;200;255mfoo\u001b[39m")
assertEqual(t, gchalk.BgRGB(100, 200, 255)("foo"), "\u001b[48;2;100;200;255mfoo\u001b[49m")

SetLevel(LevelAnsi16m)
assertEqual(t, RGB(100, 200, 255)("foo"), "\u001b[38;2;100;200;255mfoo\u001b[39m")
assertEqual(t, BgRGB(100, 200, 255)("foo"), "\u001b[48;2;100;200;255mfoo\u001b[49m")
}

func TestHex(t *testing.T) {
gawk := New(ForceLevel(LevelAnsi16m))
assertEqual(t, gawk.Hex("#64c8ff")("foo"), "\u001b[38;2;100;200;255mfoo\u001b[39m")
assertEqual(t, gawk.BgHex("#64c8ff")("foo"), "\u001b[48;2;100;200;255mfoo\u001b[49m")
gchalk := New(ForceLevel(LevelAnsi16m))
assertEqual(t, gchalk.Hex("#64c8ff")("foo"), "\u001b[38;2;100;200;255mfoo\u001b[39m")
assertEqual(t, gchalk.BgHex("#64c8ff")("foo"), "\u001b[48;2;100;200;255mfoo\u001b[49m")

SetLevel(LevelAnsi16m)
assertEqual(t, Hex("#64c8ff")("foo"), "\u001b[38;2;100;200;255mfoo\u001b[39m")
Expand Down
2 changes: 1 addition & 1 deletion colorlevel.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package gawk
package gchalk

//go:generate stringer -type=ColorLevel

Expand Down
2 changes: 1 addition & 1 deletion colorlevel_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 18 additions & 18 deletions gawk.go → gchalk.go
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
// Package gawk is terminal string styling for go done right, with full Linux, MacOS, and painless Windows 10 support.
// Package gchalk is terminal string styling for go done right, with full Linux, MacOS, and painless Windows 10 support.
//
// Gawk is a library heavily inspired by https://github.com/chalk/chalk, the
// GChalk is a library heavily inspired by https://github.com/chalk/chalk, the
// popular Node.js terminal color library, and using golang ports of supports-color
// (https://github.com/jwalton/go-supportscolor) and ansi-styles
// (https://github.com/jwalton/gawk/pkg/ansistyles).
// (https://github.com/jwalton/gchalk/pkg/ansistyles).
//
// A very simple usage example would be:
//
// fmt.Println(gawk.Blue("This line is blue"))
// fmt.Println(gchalk.Blue("This line is blue"))
//
// Note that this works on all platforms - there's no need to write to a special
// stream or use a special print function to get color on Windows 10.
//
// Some examples:
//
// // Combine styled and normal strings
// fmt.Println(gawk.Blue("Hello") + " World" + gawk.Red("!"))
// fmt.Println(gchalk.Blue("Hello") + " World" + gchalk.Red("!"))
//
// // Compose multiple styles using the chainable API
// fmt.Println(gawk.WithBlue().WithBgRed().Bold("Hello world!"))
// fmt.Println(gchalk.WithBlue().WithBgRed().Bold("Hello world!"))
//
// // Pass in multiple arguments
// fmt.Println(gawk.Blue("Hello", "World!", "Foo", "bar", "biz", "baz"))
// fmt.Println(gchalk.Blue("Hello", "World!", "Foo", "bar", "biz", "baz"))
//
// // Nest styles
// fmt.Println(gawk.Green(
// fmt.Println(gchalk.Green(
// "I am a green line " +
// gawk.WithBlue().WithUnderline().Bold("with a blue substring") +
// gchalk.WithBlue().WithUnderline().Bold("with a blue substring") +
// " that becomes green again!"
// ))
//
// // Use RGB colors in terminal emulators that support it.
// fmt.Println(gawk.WithRGB(123, 45, 67).Underline("Underlined reddish color"))
// fmt.Println(gawk.WihHex("#DEADED").Bold("Bold gray!"))
// fmt.Println(gchalk.WithRGB(123, 45, 67).Underline("Underlined reddish color"))
// fmt.Println(gchalk.WihHex("#DEADED").Bold("Bold gray!"))
//
// // Write to stderr:
// os.Stderr.WriteString(gawk.Stderr.Red("Ohs noes!\n"))
// os.Stderr.WriteString(gchalk.Stderr.Red("Ohs noes!\n"))
//
// See the README.md for more details.
//
package gawk
package gchalk

import (
"fmt"
Expand Down Expand Up @@ -127,7 +127,7 @@ func ForceLevel(level ColorLevel) Option {
}
}

// New creates a new instance of Gawk.
// New creates a new instance of GChalk.
func New(options ...Option) *Builder {
builder := &Builder{styler: nil}

Expand All @@ -142,10 +142,10 @@ func New(options ...Option) *Builder {
return builder
}

// rootBuilder is the default Gawk instance, pre-configured for stdout.
// rootBuilder is the default GChalk instance, pre-configured for stdout.
var rootBuilder = New()

// Stderr is an instance of Gawk pre-configured for stderr. Use this when coloring
// Stderr is an instance of GChalk pre-configured for stderr. Use this when coloring
// strings you intend to write the stderr.
var Stderr = New(
ForceLevel(ColorLevel(supportscolor.Stderr().Level)),
Expand Down Expand Up @@ -331,15 +331,15 @@ func (builder *Builder) WithStyle(styles ...string) (*Builder, error) {

// Paint is similar to the `paint()` function from Rust's `ansi_term` crate.
//
// gawk.WithRed().Paint("Hello World!")
// gchalk.WithRed().Paint("Hello World!")
//
func (builder *Builder) Paint(strs ...string) string {
return builder.applyStyle(strs...)
}

// Sprintf is a convenience function for coloring formatted strings.
//
// gawk.WithRed().Sprtinf("Hello %s", "World!")
// gchalk.WithRed().Sprtinf("Hello %s", "World!")
//
func (builder *Builder) Sprintf(format string, a ...interface{}) string {
return builder.applyStyle(fmt.Sprintf(format, a...))
Expand Down
18 changes: 9 additions & 9 deletions gawk_benchmark_test.go → gchalk_benchmark_test.go
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
package gawk
package gchalk

import (
"testing"
)

var benchGawk = New(ForceLevel(LevelAnsi16m))
var benchGChalk = New(ForceLevel(LevelAnsi16m))

func BenchmarkColor(b *testing.B) {
for i := 0; i < b.N; i++ {
benchGawk.Red("Hello world!")
benchGChalk.Red("Hello world!")
}
}

func BenchmarkRgb(b *testing.B) {
for i := 0; i < b.N; i++ {
benchGawk.RGB(10, 30, 255)("Hello world!")
benchGChalk.RGB(10, 30, 255)("Hello world!")
}
}

func BenchmarkColorNoSetup(b *testing.B) {
benchGawk.Red("Hello world!")
benchGChalk.Red("Hello world!")
b.ResetTimer()
for i := 0; i < b.N; i++ {
benchGawk.Red("Hello world!")
benchGChalk.Red("Hello world!")
}
}

func BenchmarkComposed(b *testing.B) {
for i := 0; i < b.N; i++ {
benchGawk.WithBgBlue().WithBold().Red("Hello world!")
benchGChalk.WithBgBlue().WithBold().Red("Hello world!")
}
}

func BenchmarkNested(b *testing.B) {
for i := 0; i < b.N; i++ {
benchGawk.Red("Hello", benchGawk.Green("green"), "world!")
benchGChalk.Red("Hello", benchGChalk.Green("green"), "world!")
}
}

func BenchmarkStyle(b *testing.B) {
for i := 0; i < b.N; i++ {
benchGawk.StyleMust("red")("Hello world!")
benchGChalk.StyleMust("red")("Hello world!")
}
}
Loading

0 comments on commit 85a935f

Please sign in to comment.