From 871978ca592b3e408baaeaf37592617237d6afb5 Mon Sep 17 00:00:00 2001 From: melsonic Date: Sat, 17 May 2025 11:40:59 +0530 Subject: [PATCH] updated compile multiple style method --- d2ast/keywords.go | 11 +++++++---- d2compiler/compile.go | 39 +++++++++++++++++++++++++++++++++++---- d2graph/d2graph.go | 28 +++++++++++++++++++--------- 3 files changed, 61 insertions(+), 17 deletions(-) diff --git a/d2ast/keywords.go b/d2ast/keywords.go index a7ece2ef5..65b35e0ae 100644 --- a/d2ast/keywords.go +++ b/d2ast/keywords.go @@ -64,10 +64,9 @@ var StyleKeywords = map[string]struct{}{ "text-transform": {}, // Only for shapes - "shadow": {}, - "multiple": {}, - "multiple.opacity": {}, - "double-border": {}, + "shadow": {}, + "multiple": {}, + "double-border": {}, // Only for squares "3d": {}, @@ -77,6 +76,10 @@ var StyleKeywords = map[string]struct{}{ "filled": {}, } +var CompositeStyleKeywords = map[string]string{ + "multiple": "opacity", +} + // TODO maybe autofmt should allow other values, and transform them to conform // e.g. left-center becomes center-left var NearConstantsArray = []string{ diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 8c3599409..9de79d914 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -760,8 +760,7 @@ func (c *compiler) compileStyleField(styles *d2graph.Style, f *d2ir.Field) { fields := f.Map().Fields for i := 0; i < len(fields); i++ { field := fields[i] - field.Name.SetString(f.Name.ScalarString() + "." + field.Name.ScalarString()) - c.compileStyleField(styles, field) + c.compileCompositeStyle(styles, field, f.Name.ScalarString()) } } if f.Primary() == nil { @@ -776,6 +775,31 @@ func (c *compiler) compileStyleField(styles *d2graph.Style, f *d2ir.Field) { } } +func (c *compiler) compileCompositeStyle(styles *d2graph.Style, f *d2ir.Field, parent string) { + if _, ok := d2ast.CompositeStyleKeywords[strings.ToLower(parent)]; !(ok && f.Name.IsUnquoted()) { + c.errorf(f.LastRef().AST(), `invalid composite style keyword: "%s"`, f.Name.ScalarString()) + return + } + + allowedStyle := d2ast.CompositeStyleKeywords[strings.ToLower(parent)] + + if allowedStyle != strings.ToLower(f.Name.ScalarString()) { + c.errorf(f.LastRef().AST(), `invalid style "%s" for composite style keyword: "%s"`, f.Name.ScalarString(), parent) + } + + if f.Primary() == nil { + return + } + + compileCompositeStyleFieldInit(styles, f, parent) + scalar := f.Primary().Value + err := styles.ApplyComposite(f.Name.ScalarString(), scalar.ScalarString(), parent) + if err != nil { + c.errorf(scalar, err.Error()) + return + } +} + func compileStyleFieldInit(styles *d2graph.Style, f *d2ir.Field) { switch f.Name.ScalarString() { case "opacity": @@ -798,8 +822,6 @@ func compileStyleFieldInit(styles *d2graph.Style, f *d2ir.Field) { styles.ThreeDee = &d2graph.Scalar{MapKey: f.LastPrimaryKey()} case "multiple": styles.Multiple = &d2graph.Scalar{MapKey: f.LastPrimaryKey()} - case "multiple.opacity": - styles.MultipleOpacity = &d2graph.Scalar{MapKey: f.LastPrimaryKey()} case "font": styles.Font = &d2graph.Scalar{MapKey: f.LastPrimaryKey()} case "font-size": @@ -823,6 +845,15 @@ func compileStyleFieldInit(styles *d2graph.Style, f *d2ir.Field) { } } +func compileCompositeStyleFieldInit(styles *d2graph.Style, f *d2ir.Field, parent string) { + switch f.Name.ScalarString() { + case "opacity": + if parent == "multiple" { + styles.MultipleOpacity = &d2graph.Scalar{MapKey: f.LastPrimaryKey()} + } + } +} + func (c *compiler) compileEdge(obj *d2graph.Object, e *d2ir.Edge) { edge, err := obj.Connect(e.ID.SrcPath, e.ID.DstPath, e.ID.SrcArrow, e.ID.DstArrow, "") if err != nil { diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index f97769f4e..5d4d401c2 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -400,15 +400,6 @@ func (s *Style) Apply(key, value string) error { return errors.New(`expected "multiple" to be true or false`) } s.Multiple.Value = value - case "multiple.opacity": - if s.MultipleOpacity == nil { - break - } - f, err := strconv.ParseFloat(value, 64) - if err != nil || (f < 0 || f > 1) { - return errors.New(`expected "opacity" to be a number between 0.0 and 1.0`) - } - s.MultipleOpacity.Value = value case "font": if s.Font == nil { break @@ -503,6 +494,25 @@ func (s *Style) Apply(key, value string) error { return nil } +func (s *Style) ApplyComposite(key, value, parent string) error { + switch key { + case "opacity": + f, err := strconv.ParseFloat(value, 64) + if err != nil || (f < 0 || f > 1) { + return errors.New(`expected "opacity" to be a number between 0.0 and 1.0`) + } + if parent == "multiple" { + if s.MultipleOpacity == nil { + break + } + s.MultipleOpacity.Value = value + } + default: + return fmt.Errorf("unknown style key: %s", key) + } + return nil +} + type ContainerLevel int func (l ContainerLevel) LabelSize() int {