diff --git a/README.md b/README.md
index 775f014..b522afc 100644
--- a/README.md
+++ b/README.md
@@ -343,6 +343,29 @@ konstrukt gen fallingdaggers --color1 "#e55039" --color2 "#f39c12" --filename f
+### Whitegold2
+
+The pattern and default implementation is [MarcelMues](https://github.com/MarcelMue) work titled `whitegold2`.
+
+
+Usage examples
+
+The default can be generated with:
+```
+konstrukt gen whitegold2
+```
+
+
+
+Changing the colors can be easily done like this:
+```
+konstrukt gen whitegold2 --color1 "#1e272e" --color2 "#f53b57" --filename whitegold2-se.svg
+```
+
+
+
+
+
## Guidelines
Additions to this project should follow these guidelines:
diff --git a/cmd/gen/command.go b/cmd/gen/command.go
index f8b33ee..5096f8c 100644
--- a/cmd/gen/command.go
+++ b/cmd/gen/command.go
@@ -19,6 +19,7 @@ import (
"github.com/marcelmue/konstrukt/cmd/gen/shining"
"github.com/marcelmue/konstrukt/cmd/gen/swiss16"
"github.com/marcelmue/konstrukt/cmd/gen/whitegold"
+ "github.com/marcelmue/konstrukt/cmd/gen/whitegold2"
)
const (
@@ -199,6 +200,20 @@ func New(config Config) (*cobra.Command, error) {
}
}
+ var whitegold2Cmd *cobra.Command
+ {
+ c := whitegold2.Config{
+ Logger: config.Logger,
+ Stderr: config.Stderr,
+ Stdout: config.Stdout,
+ }
+
+ whitegold2Cmd, err = whitegold2.New(c)
+ if err != nil {
+ return nil, microerror.Mask(err)
+ }
+ }
+
f := &flag{}
r := &runner{
@@ -228,6 +243,7 @@ func New(config Config) (*cobra.Command, error) {
c.AddCommand(interlockingCmd)
c.AddCommand(whitegoldCmd)
c.AddCommand(fallingdaggersCmd)
+ c.AddCommand(whitegold2Cmd)
return c, nil
}
diff --git a/cmd/gen/whitegold2/command.go b/cmd/gen/whitegold2/command.go
new file mode 100644
index 0000000..f354dcd
--- /dev/null
+++ b/cmd/gen/whitegold2/command.go
@@ -0,0 +1,53 @@
+package whitegold2
+
+import (
+ "io"
+ "os"
+
+ "github.com/giantswarm/microerror"
+ "github.com/giantswarm/micrologger"
+ "github.com/spf13/cobra"
+)
+
+const (
+ name = "whitegold2"
+ description = "Draws MarcelMues 'whitegold2'."
+)
+
+type Config struct {
+ Logger micrologger.Logger
+ Stderr io.Writer
+ Stdout io.Writer
+}
+
+func New(config Config) (*cobra.Command, error) {
+ if config.Logger == nil {
+ return nil, microerror.Maskf(invalidConfigError, "%T.Logger must not be empty", config)
+ }
+ if config.Stderr == nil {
+ config.Stderr = os.Stderr
+ }
+ if config.Stdout == nil {
+ config.Stdout = os.Stdout
+ }
+
+ f := &flag{}
+
+ r := &runner{
+ flag: f,
+ logger: config.Logger,
+ stderr: config.Stderr,
+ stdout: config.Stdout,
+ }
+
+ c := &cobra.Command{
+ Use: name,
+ Short: description,
+ Long: description,
+ RunE: r.Run,
+ }
+
+ f.Init(c)
+
+ return c, nil
+}
diff --git a/cmd/gen/whitegold2/command_test.go b/cmd/gen/whitegold2/command_test.go
new file mode 100644
index 0000000..e203ec5
--- /dev/null
+++ b/cmd/gen/whitegold2/command_test.go
@@ -0,0 +1,88 @@
+package whitegold2
+
+import (
+ "fmt"
+ "strconv"
+ "testing"
+
+ "github.com/giantswarm/micrologger"
+)
+
+func Test_command(t *testing.T) {
+ testCases := []struct {
+ name string
+ c1 string
+ c2 string
+ filename string
+ height int
+ width int
+ }{
+ {
+ name: "case 0: default pattern",
+ filename: "whitegold2",
+ },
+ {
+ name: "case 1: se color pattern",
+ filename: "whitegold2-se",
+ c1: "#1e272e",
+ c2: "#f53b57",
+ },
+ {
+ name: "case 2: banner resize",
+ filename: "whitegold2-wide",
+ width: 2000,
+ height: 400,
+ },
+ }
+
+ for i, tc := range testCases {
+ t.Run(strconv.Itoa(i), func(t *testing.T) {
+ t.Log(tc.name)
+
+ var err error
+
+ var logger micrologger.Logger
+ {
+ c := micrologger.Config{}
+
+ logger, err = micrologger.New(c)
+ if err != nil {
+ t.Fatal("expected", nil, "got", err)
+ }
+ }
+
+ c := Config{
+ Logger: logger,
+ }
+
+ testCommand, err := New(c)
+ if err != nil {
+ t.Fatal("expected", nil, "got", err)
+ }
+
+ args := []string{}
+ if tc.filename != "" {
+ args = append(args, []string{"--filename", fmt.Sprintf("../../../samples/%s.svg", tc.filename)}...)
+ }
+ if tc.c1 != "" {
+ args = append(args, []string{"--color1", tc.c1}...)
+ }
+ if tc.c2 != "" {
+ args = append(args, []string{"--color2", tc.c2}...)
+ }
+ if tc.height != 0 {
+ args = append(args, []string{"--height", strconv.Itoa(tc.height)}...)
+ }
+ if tc.width != 0 {
+ args = append(args, []string{"--width", strconv.Itoa(tc.width)}...)
+ }
+
+ testCommand.SetArgs(args)
+
+ err = testCommand.Execute()
+ if err != nil {
+ t.Fatal("expected", nil, "got", err)
+ }
+ })
+ }
+}
diff --git a/cmd/gen/whitegold2/error.go b/cmd/gen/whitegold2/error.go
new file mode 100644
index 0000000..99369eb
--- /dev/null
+++ b/cmd/gen/whitegold2/error.go
@@ -0,0 +1,21 @@
+package whitegold2
+
+import "github.com/giantswarm/microerror"
+
+var invalidConfigError = µerror.Error{
+ Kind: "invalidConfigError",
+}
+
+// IsInvalidConfig asserts invalidConfigError.
+func IsInvalidConfig(err error) bool {
+ return microerror.Cause(err) == invalidConfigError
+}
+
+var invalidFlagError = µerror.Error{
+ Kind: "invalidFlagError",
+}
+
+// IsInvalidFlag asserts invalidFlagError.
+func IsInvalidFlag(err error) bool {
+ return microerror.Cause(err) == invalidFlagError
+}
diff --git a/cmd/gen/whitegold2/flag.go b/cmd/gen/whitegold2/flag.go
new file mode 100644
index 0000000..a1151b6
--- /dev/null
+++ b/cmd/gen/whitegold2/flag.go
@@ -0,0 +1,65 @@
+package whitegold2
+
+import (
+ "github.com/giantswarm/microerror"
+ "github.com/spf13/cobra"
+
+ "github.com/marcelmue/konstrukt/pkg/validate"
+)
+
+const (
+ flagFilename = "filename"
+
+ flagHeight = "height"
+ flagWidth = "width"
+
+ flagColor1 = "color1"
+ flagColor2 = "color2"
+
+ flagRandomize = "randomize"
+)
+
+type flag struct {
+ Filename string
+
+ Height int
+ Width int
+
+ Color1 string
+ Color2 string
+
+ Randomize bool
+}
+
+func (f *flag) Init(cmd *cobra.Command) {
+ cmd.Flags().StringVar(&f.Filename, flagFilename, "whitegold2.svg", `Name of the output file.`)
+
+ cmd.Flags().IntVar(&f.Height, flagHeight, 500, `Height of the output file in pixels.`)
+ cmd.Flags().IntVar(&f.Width, flagWidth, 500, `Width of the output file in pixels.`)
+
+ cmd.Flags().StringVar(&f.Color1, flagColor1, "#95a5a6", `First color.`)
+ cmd.Flags().StringVar(&f.Color2, flagColor2, "#ecf0f1", `Second color.`)
+
+ cmd.Flags().BoolVar(&f.Randomize, flagRandomize, false, "Randomize all colors in the pattern, ignore other color flags.")
+}
+
+func (f *flag) Validate() error {
+ if !validate.Color(f.Color1) {
+ validate.PrintFailure(flagColor1)
+ return microerror.Mask(invalidFlagError)
+ }
+ if !validate.Color(f.Color2) {
+ validate.PrintFailure(flagColor2)
+ return microerror.Mask(invalidFlagError)
+ }
+ if !validate.Size(f.Height) {
+ validate.PrintFailure(flagHeight)
+ return microerror.Mask(invalidFlagError)
+ }
+ if !validate.Size(f.Width) {
+ validate.PrintFailure(flagWidth)
+ return microerror.Mask(invalidFlagError)
+ }
+
+ return nil
+}
diff --git a/cmd/gen/whitegold2/runner.go b/cmd/gen/whitegold2/runner.go
new file mode 100644
index 0000000..4a27154
--- /dev/null
+++ b/cmd/gen/whitegold2/runner.go
@@ -0,0 +1,96 @@
+package whitegold2
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "os"
+
+ svg "github.com/ajstarks/svgo"
+ "github.com/giantswarm/microerror"
+ "github.com/giantswarm/micrologger"
+ "github.com/spf13/cobra"
+
+ "github.com/marcelmue/konstrukt/pkg/color"
+ "github.com/marcelmue/konstrukt/pkg/project"
+)
+
+type runner struct {
+ flag *flag
+ logger micrologger.Logger
+ stdout io.Writer
+ stderr io.Writer
+}
+
+func (r *runner) Run(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+
+ err := r.flag.Validate()
+ if err != nil {
+ return microerror.Mask(err)
+ }
+
+ if r.flag.Randomize {
+ r.flag.Color1 = color.Random()
+ r.flag.Color2 = color.Random()
+ fmt.Printf("Set Color1:%s Color2:%s\n", r.flag.Color1, r.flag.Color2)
+ }
+
+ err = r.run(ctx, cmd, args)
+ if err != nil {
+ return microerror.Mask(err)
+ }
+
+ return nil
+}
+
+func (r *runner) run(ctx context.Context, cmd *cobra.Command, args []string) error {
+ f, err := os.Create(r.flag.Filename)
+ if err != nil {
+ return microerror.Mask(err)
+ }
+ width, height := r.flag.Width, r.flag.Height
+ c1, c2 := r.flag.Color1, r.flag.Color2
+ stylefmt := "stroke:%s;stroke-width:%d;fill:none"
+
+ canvas := svg.New(f)
+ canvas.Start(width, height)
+ canvas.Desc(project.PatternDesc())
+ canvas.Rect(0, 0, width, height, "fill:"+c1)
+
+ // Polygon.
+ xp := []int{40, 0, 40, 80}
+ yp := []int{0, 40, 80, 40}
+
+ // Polyline.
+ xl := []int{70, 40, 70}
+ yl := []int{10, 40, 70}
+
+ canvas.Def()
+ canvas.Gid("unit")
+ canvas.Polygon(xp, yp, "fill:"+c2)
+ canvas.Polyline(xl, yl, fmt.Sprintf(stylefmt, c1, 10))
+ canvas.Gend()
+ canvas.Gid("runit")
+ canvas.ScaleXY(-1, 1)
+ canvas.Use(0, 0, "#unit")
+ canvas.Gend()
+ canvas.Gend()
+ canvas.DefEnd()
+
+ ypositioncounter := 0
+ for y := -100; y < height+200; y += 50 {
+ for x := -200; x < width+200; x += 100 {
+ if ypositioncounter%2 == 0 {
+ canvas.Use(x, y, "#unit")
+ }
+ if ypositioncounter%2 == 1 {
+ canvas.Use(x+30, y, "#runit")
+ }
+ }
+ ypositioncounter++
+ }
+ canvas.End()
+
+ return nil
+}
diff --git a/samples/whitegold2-se.svg b/samples/whitegold2-se.svg
new file mode 100644
index 0000000..911500f
--- /dev/null
+++ b/samples/whitegold2-se.svg
@@ -0,0 +1,163 @@
+
+
+
diff --git a/samples/whitegold2-wide.svg b/samples/whitegold2-wide.svg
new file mode 100644
index 0000000..56b8758
--- /dev/null
+++ b/samples/whitegold2-wide.svg
@@ -0,0 +1,355 @@
+
+
+
diff --git a/samples/whitegold2.svg b/samples/whitegold2.svg
new file mode 100644
index 0000000..3c25013
--- /dev/null
+++ b/samples/whitegold2.svg
@@ -0,0 +1,163 @@
+
+
+