diff --git a/d2compiler/compile.go b/d2compiler/compile.go index e6b9eb6d2..3d4d1fcb1 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -17,6 +17,7 @@ import ( "oss.terrastruct.com/d2/d2ir" "oss.terrastruct.com/d2/d2parser" "oss.terrastruct.com/d2/d2target" + "oss.terrastruct.com/d2/lib/color" "oss.terrastruct.com/d2/lib/textmeasure" ) @@ -54,7 +55,11 @@ func Compile(p string, r io.Reader, opts *CompileOptions) (*d2graph.Graph, *d2ta g.FS = opts.FS g.SortObjectsByAST() g.SortEdgesByAST() - return g, compileConfig(ir), nil + config, err := compileConfig(ir) + if err != nil { + return nil, nil, err + } + return g, config, nil } func compileIR(ast *d2ast.Map, m *d2ir.Map) (*d2graph.Graph, error) { @@ -1336,10 +1341,10 @@ func parentSeqDiagram(n d2ir.Node) *d2ir.Map { } } -func compileConfig(ir *d2ir.Map) *d2target.Config { +func compileConfig(ir *d2ir.Map) (*d2target.Config, error) { f := ir.GetField("vars", "d2-config") if f == nil || f.Map() == nil { - return nil + return nil, nil } configMap := f.Map() @@ -1377,82 +1382,85 @@ func compileConfig(ir *d2ir.Map) *d2target.Config { f = configMap.GetField("theme-overrides") if f != nil { - config.ThemeOverrides = compileThemeOverrides(f.Map()) + overrides, err := compileThemeOverrides(f.Map()) + if err != nil { + return nil, err + } + config.ThemeOverrides = overrides } f = configMap.GetField("dark-theme-overrides") if f != nil { - config.DarkThemeOverrides = compileThemeOverrides(f.Map()) + overrides, err := compileThemeOverrides(f.Map()) + if err != nil { + return nil, err + } + config.DarkThemeOverrides = overrides } - return config + return config, nil } -func compileThemeOverrides(m *d2ir.Map) *d2target.ThemeOverrides { +func compileThemeOverrides(m *d2ir.Map) (*d2target.ThemeOverrides, error) { if m == nil { - return nil + return nil, nil } themeOverrides := d2target.ThemeOverrides{} - if m.GetField("N1") != nil { - themeOverrides.N1 = go2.Pointer(m.GetField("N1").Primary().Value.ScalarString()) + err := &d2parser.ParseError{} +FOR: + for _, f := range m.Fields { + switch strings.ToUpper(f.Name) { + case "N1": + themeOverrides.N1 = go2.Pointer(f.Primary().Value.ScalarString()) + case "N2": + themeOverrides.N2 = go2.Pointer(f.Primary().Value.ScalarString()) + case "N3": + themeOverrides.N3 = go2.Pointer(f.Primary().Value.ScalarString()) + case "N4": + themeOverrides.N4 = go2.Pointer(f.Primary().Value.ScalarString()) + case "N5": + themeOverrides.N5 = go2.Pointer(f.Primary().Value.ScalarString()) + case "N6": + themeOverrides.N6 = go2.Pointer(f.Primary().Value.ScalarString()) + case "N7": + themeOverrides.N7 = go2.Pointer(f.Primary().Value.ScalarString()) + case "B1": + themeOverrides.B1 = go2.Pointer(f.Primary().Value.ScalarString()) + case "B2": + themeOverrides.B2 = go2.Pointer(f.Primary().Value.ScalarString()) + case "B3": + themeOverrides.B3 = go2.Pointer(f.Primary().Value.ScalarString()) + case "B4": + themeOverrides.B4 = go2.Pointer(f.Primary().Value.ScalarString()) + case "B5": + themeOverrides.B5 = go2.Pointer(f.Primary().Value.ScalarString()) + case "B6": + themeOverrides.B6 = go2.Pointer(f.Primary().Value.ScalarString()) + case "AA2": + themeOverrides.AA2 = go2.Pointer(f.Primary().Value.ScalarString()) + case "AA4": + themeOverrides.AA4 = go2.Pointer(f.Primary().Value.ScalarString()) + case "AA5": + themeOverrides.AA5 = go2.Pointer(f.Primary().Value.ScalarString()) + case "AB4": + themeOverrides.AB4 = go2.Pointer(f.Primary().Value.ScalarString()) + case "AB5": + themeOverrides.AB5 = go2.Pointer(f.Primary().Value.ScalarString()) + default: + err.Errors = append(err.Errors, d2parser.Errorf(f.LastPrimaryKey(), fmt.Sprintf(`"%s" is not a valid theme code`, f.Name)).(d2ast.Error)) + continue FOR + } + if !go2.Contains(color.NamedColors, strings.ToLower(f.Primary().Value.ScalarString())) && !color.ColorHexRegex.MatchString(f.Primary().Value.ScalarString()) { + err.Errors = append(err.Errors, d2parser.Errorf(f.LastPrimaryKey(), fmt.Sprintf(`expected "%s" to be a valid named color ("orange") or a hex code ("#f0ff3a")`, f.Name)).(d2ast.Error)) + } } - if m.GetField("B1") != nil { - themeOverrides.B1 = go2.Pointer(m.GetField("B1").Primary().Value.ScalarString()) - } - if m.GetField("B2") != nil { - themeOverrides.B2 = go2.Pointer(m.GetField("B2").Primary().Value.ScalarString()) - } - if m.GetField("B3") != nil { - themeOverrides.B3 = go2.Pointer(m.GetField("B3").Primary().Value.ScalarString()) - } - if m.GetField("B4") != nil { - themeOverrides.B4 = go2.Pointer(m.GetField("B4").Primary().Value.ScalarString()) - } - if m.GetField("B5") != nil { - themeOverrides.B5 = go2.Pointer(m.GetField("B5").Primary().Value.ScalarString()) - } - if m.GetField("B6") != nil { - themeOverrides.B6 = go2.Pointer(m.GetField("B6").Primary().Value.ScalarString()) - } - if m.GetField("AA2") != nil { - themeOverrides.AA2 = go2.Pointer(m.GetField("AA2").Primary().Value.ScalarString()) - } - if m.GetField("AA4") != nil { - themeOverrides.AA4 = go2.Pointer(m.GetField("AA4").Primary().Value.ScalarString()) - } - if m.GetField("AA5") != nil { - themeOverrides.AA5 = go2.Pointer(m.GetField("AA5").Primary().Value.ScalarString()) - } - if m.GetField("AB4") != nil { - themeOverrides.AB4 = go2.Pointer(m.GetField("AB4").Primary().Value.ScalarString()) - } - if m.GetField("AB5") != nil { - themeOverrides.AB5 = go2.Pointer(m.GetField("AB5").Primary().Value.ScalarString()) - } - if m.GetField("N1") != nil { - themeOverrides.N1 = go2.Pointer(m.GetField("N1").Primary().Value.ScalarString()) - } - if m.GetField("N2") != nil { - themeOverrides.N2 = go2.Pointer(m.GetField("N2").Primary().Value.ScalarString()) - } - if m.GetField("N3") != nil { - themeOverrides.N3 = go2.Pointer(m.GetField("N3").Primary().Value.ScalarString()) - } - if m.GetField("N4") != nil { - themeOverrides.N4 = go2.Pointer(m.GetField("N4").Primary().Value.ScalarString()) - } - if m.GetField("N5") != nil { - themeOverrides.N5 = go2.Pointer(m.GetField("N5").Primary().Value.ScalarString()) - } - if m.GetField("N6") != nil { - themeOverrides.N6 = go2.Pointer(m.GetField("N6").Primary().Value.ScalarString()) - } - if m.GetField("N7") != nil { - themeOverrides.N7 = go2.Pointer(m.GetField("N7").Primary().Value.ScalarString()) + + if !err.Empty() { + return nil, err } if themeOverrides != (d2target.ThemeOverrides{}) { - return &themeOverrides + return &themeOverrides, nil } - return nil + return nil, nil } diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 4ba50f013..c74398934 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -2812,6 +2812,21 @@ g: |md d2/testdata/d2compiler/TestCompile/text_no_label.d2:15:1: block string cannot be empty d2/testdata/d2compiler/TestCompile/text_no_label.d2:4:1: shape text must have a non-empty label d2/testdata/d2compiler/TestCompile/text_no_label.d2:7:1: shape text must have a non-empty label`, + }, + { + name: "var-not-color", + text: `vars: { + d2-config: { + theme-overrides: { + B1: potato + potato: B1 + } + } +} +a +`, + expErr: `d2/testdata/d2compiler/TestCompile/var-not-color.d2:4:7: expected "B1" to be a valid named color ("orange") or a hex code ("#f0ff3a") +d2/testdata/d2compiler/TestCompile/var-not-color.d2:5:4: "potato" is not a valid theme code`, }, { name: "no_arrowheads_in_shape", diff --git a/d2graph/color_helper.go b/d2graph/color_helper.go deleted file mode 100644 index 4615847a4..000000000 --- a/d2graph/color_helper.go +++ /dev/null @@ -1,159 +0,0 @@ -package d2graph - -import "regexp" - -// namedColors is a list of valid CSS colors -var namedColors = []string{ - "currentcolor", - "transparent", - "aliceblue", - "antiquewhite", - "aqua", - "aquamarine", - "azure", - "beige", - "bisque", - "black", - "blanchedalmond", - "blue", - "blueviolet", - "brown", - "burlywood", - "cadetblue", - "chartreuse", - "chocolate", - "coral", - "cornflowerblue", - "cornsilk", - "crimson", - "cyan", - "darkblue", - "darkcyan", - "darkgoldenrod", - "darkgray", - "darkgrey", - "darkgreen", - "darkkhaki", - "darkmagenta", - "darkolivegreen", - "darkorange", - "darkorchid", - "darkred", - "darksalmon", - "darkseagreen", - "darkslateblue", - "darkslategray", - "darkslategrey", - "darkturquoise", - "darkviolet", - "deeppink", - "deepskyblue", - "dimgray", - "dimgrey", - "dodgerblue", - "firebrick", - "floralwhite", - "forestgreen", - "fuchsia", - "gainsboro", - "ghostwhite", - "gold", - "goldenrod", - "gray", - "grey", - "green", - "greenyellow", - "honeydew", - "hotpink", - "indianred", - "indigo", - "ivory", - "khaki", - "lavender", - "lavenderblush", - "lawngreen", - "lemonchiffon", - "lightblue", - "lightcoral", - "lightcyan", - "lightgoldenrodyellow", - "lightgray", - "lightgrey", - "lightgreen", - "lightpink", - "lightsalmon", - "lightseagreen", - "lightskyblue", - "lightslategray", - "lightslategrey", - "lightsteelblue", - "lightyellow", - "lime", - "limegreen", - "linen", - "magenta", - "maroon", - "mediumaquamarine", - "mediumblue", - "mediumorchid", - "mediumpurple", - "mediumseagreen", - "mediumslateblue", - "mediumspringgreen", - "mediumturquoise", - "mediumvioletred", - "midnightblue", - "mintcream", - "mistyrose", - "moccasin", - "navajowhite", - "navy", - "oldlace", - "olive", - "olivedrab", - "orange", - "orangered", - "orchid", - "palegoldenrod", - "palegreen", - "paleturquoise", - "palevioletred", - "papayawhip", - "peachpuff", - "peru", - "pink", - "plum", - "powderblue", - "purple", - "rebeccapurple", - "red", - "rosybrown", - "royalblue", - "saddlebrown", - "salmon", - "sandybrown", - "seagreen", - "seashell", - "sienna", - "silver", - "skyblue", - "slateblue", - "slategray", - "slategrey", - "snow", - "springgreen", - "steelblue", - "tan", - "teal", - "thistle", - "tomato", - "turquoise", - "violet", - "wheat", - "white", - "whitesmoke", - "yellow", - "yellowgreen", -} - -var colorHexRegex = regexp.MustCompile(`^#(([0-9a-fA-F]{2}){3}|([0-9a-fA-F]){3})$`) diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 9fece76c1..b70c887bd 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -252,7 +252,7 @@ func (s *Style) Apply(key, value string) error { if s.Stroke == nil { break } - if !go2.Contains(namedColors, strings.ToLower(value)) && !colorHexRegex.MatchString(value) { + if !go2.Contains(color.NamedColors, strings.ToLower(value)) && !color.ColorHexRegex.MatchString(value) { return errors.New(`expected "stroke" to be a valid named color ("orange") or a hex code ("#f0ff3a")`) } s.Stroke.Value = value @@ -260,7 +260,7 @@ func (s *Style) Apply(key, value string) error { if s.Fill == nil { break } - if !go2.Contains(namedColors, strings.ToLower(value)) && !colorHexRegex.MatchString(value) { + if !go2.Contains(color.NamedColors, strings.ToLower(value)) && !color.ColorHexRegex.MatchString(value) { return errors.New(`expected "fill" to be a valid named color ("orange") or a hex code ("#f0ff3a")`) } s.Fill.Value = value @@ -347,7 +347,7 @@ func (s *Style) Apply(key, value string) error { if s.FontColor == nil { break } - if !go2.Contains(namedColors, strings.ToLower(value)) && !colorHexRegex.MatchString(value) { + if !go2.Contains(color.NamedColors, strings.ToLower(value)) && !color.ColorHexRegex.MatchString(value) { return errors.New(`expected "font-color" to be a valid named color ("orange") or a hex code ("#f0ff3a")`) } s.FontColor.Value = value diff --git a/e2etests-cli/testdata/TestCLI_E2E/import_vars.exp.svg b/e2etests-cli/testdata/TestCLI_E2E/import_vars.exp.svg index 543997887..d844683d1 100644 --- a/e2etests-cli/testdata/TestCLI_E2E/import_vars.exp.svg +++ b/e2etests-cli/testdata/TestCLI_E2E/import_vars.exp.svg @@ -1,9 +1,9 @@ -xy + .d2-2712468095 .fill-N1{fill:#CDD6F4;} + .d2-2712468095 .fill-N2{fill:#BAC2DE;} + .d2-2712468095 .fill-N3{fill:#A6ADC8;} + .d2-2712468095 .fill-N4{fill:#585B70;} + .d2-2712468095 .fill-N5{fill:#45475A;} + .d2-2712468095 .fill-N6{fill:#313244;} + .d2-2712468095 .fill-N7{fill:#1E1E2E;} + .d2-2712468095 .fill-B1{fill:#CBA6f7;} + .d2-2712468095 .fill-B2{fill:#CBA6f7;} + .d2-2712468095 .fill-B3{fill:#6C7086;} + .d2-2712468095 .fill-B4{fill:#585B70;} + .d2-2712468095 .fill-B5{fill:#45475A;} + .d2-2712468095 .fill-B6{fill:#313244;} + .d2-2712468095 .fill-AA2{fill:#f38BA8;} + .d2-2712468095 .fill-AA4{fill:#45475A;} + .d2-2712468095 .fill-AA5{fill:#313244;} + .d2-2712468095 .fill-AB4{fill:#45475A;} + .d2-2712468095 .fill-AB5{fill:#313244;} + .d2-2712468095 .stroke-N1{stroke:#CDD6F4;} + .d2-2712468095 .stroke-N2{stroke:#BAC2DE;} + .d2-2712468095 .stroke-N3{stroke:#A6ADC8;} + .d2-2712468095 .stroke-N4{stroke:#585B70;} + .d2-2712468095 .stroke-N5{stroke:#45475A;} + .d2-2712468095 .stroke-N6{stroke:#313244;} + .d2-2712468095 .stroke-N7{stroke:#1E1E2E;} + .d2-2712468095 .stroke-B1{stroke:#CBA6f7;} + .d2-2712468095 .stroke-B2{stroke:#CBA6f7;} + .d2-2712468095 .stroke-B3{stroke:#6C7086;} + .d2-2712468095 .stroke-B4{stroke:#585B70;} + .d2-2712468095 .stroke-B5{stroke:#45475A;} + .d2-2712468095 .stroke-B6{stroke:#313244;} + .d2-2712468095 .stroke-AA2{stroke:#f38BA8;} + .d2-2712468095 .stroke-AA4{stroke:#45475A;} + .d2-2712468095 .stroke-AA5{stroke:#313244;} + .d2-2712468095 .stroke-AB4{stroke:#45475A;} + .d2-2712468095 .stroke-AB5{stroke:#313244;} + .d2-2712468095 .background-color-N1{background-color:#CDD6F4;} + .d2-2712468095 .background-color-N2{background-color:#BAC2DE;} + .d2-2712468095 .background-color-N3{background-color:#A6ADC8;} + .d2-2712468095 .background-color-N4{background-color:#585B70;} + .d2-2712468095 .background-color-N5{background-color:#45475A;} + .d2-2712468095 .background-color-N6{background-color:#313244;} + .d2-2712468095 .background-color-N7{background-color:#1E1E2E;} + .d2-2712468095 .background-color-B1{background-color:#CBA6f7;} + .d2-2712468095 .background-color-B2{background-color:#CBA6f7;} + .d2-2712468095 .background-color-B3{background-color:#6C7086;} + .d2-2712468095 .background-color-B4{background-color:#585B70;} + .d2-2712468095 .background-color-B5{background-color:#45475A;} + .d2-2712468095 .background-color-B6{background-color:#313244;} + .d2-2712468095 .background-color-AA2{background-color:#f38BA8;} + .d2-2712468095 .background-color-AA4{background-color:#45475A;} + .d2-2712468095 .background-color-AA5{background-color:#313244;} + .d2-2712468095 .background-color-AB4{background-color:#45475A;} + .d2-2712468095 .background-color-AB5{background-color:#313244;} + .d2-2712468095 .color-N1{color:#CDD6F4;} + .d2-2712468095 .color-N2{color:#BAC2DE;} + .d2-2712468095 .color-N3{color:#A6ADC8;} + .d2-2712468095 .color-N4{color:#585B70;} + .d2-2712468095 .color-N5{color:#45475A;} + .d2-2712468095 .color-N6{color:#313244;} + .d2-2712468095 .color-N7{color:#1E1E2E;} + .d2-2712468095 .color-B1{color:#CBA6f7;} + .d2-2712468095 .color-B2{color:#CBA6f7;} + .d2-2712468095 .color-B3{color:#6C7086;} + .d2-2712468095 .color-B4{color:#585B70;} + .d2-2712468095 .color-B5{color:#45475A;} + .d2-2712468095 .color-B6{color:#313244;} + .d2-2712468095 .color-AA2{color:#f38BA8;} + .d2-2712468095 .color-AA4{color:#45475A;} + .d2-2712468095 .color-AA5{color:#313244;} + .d2-2712468095 .color-AB4{color:#45475A;} + .d2-2712468095 .color-AB5{color:#313244;}.appendix text.text{fill:#CDD6F4}.md{--color-fg-default:#CDD6F4;--color-fg-muted:#BAC2DE;--color-fg-subtle:#A6ADC8;--color-canvas-default:#1E1E2E;--color-canvas-subtle:#313244;--color-border-default:#CBA6f7;--color-border-muted:#CBA6f7;--color-neutral-muted:#313244;--color-accent-fg:#CBA6f7;--color-accent-emphasis:#CBA6f7;--color-attention-subtle:#BAC2DE;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-B2{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-B3{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-B4{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-B5{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B6{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-AA2{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-AA4{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-AA5{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-AB4{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-AB5{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N1{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N2{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N5{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N6{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N7{fill:url(#streaks-darker);mix-blend-mode:lighten}.light-code{display: none}.dark-code{display: block}]]>xy diff --git a/e2etests-cli/testdata/TestCLI_E2E/internal_linked_pdf.exp.pdf b/e2etests-cli/testdata/TestCLI_E2E/internal_linked_pdf.exp.pdf index 751aa45ac..ca96dd593 100644 Binary files a/e2etests-cli/testdata/TestCLI_E2E/internal_linked_pdf.exp.pdf and b/e2etests-cli/testdata/TestCLI_E2E/internal_linked_pdf.exp.pdf differ diff --git a/e2etests-cli/testdata/TestCLI_E2E/no-nav-pdf.exp.pdf b/e2etests-cli/testdata/TestCLI_E2E/no-nav-pdf.exp.pdf index bfc825b34..887985d78 100644 Binary files a/e2etests-cli/testdata/TestCLI_E2E/no-nav-pdf.exp.pdf and b/e2etests-cli/testdata/TestCLI_E2E/no-nav-pdf.exp.pdf differ diff --git a/e2etests-cli/testdata/TestCLI_E2E/no-nav-pptx.exp.pptx b/e2etests-cli/testdata/TestCLI_E2E/no-nav-pptx.exp.pptx index acca7f844..657a8e60f 100644 Binary files a/e2etests-cli/testdata/TestCLI_E2E/no-nav-pptx.exp.pptx and b/e2etests-cli/testdata/TestCLI_E2E/no-nav-pptx.exp.pptx differ diff --git a/e2etests-cli/testdata/TestCLI_E2E/renamed-board.exp.pdf b/e2etests-cli/testdata/TestCLI_E2E/renamed-board.exp.pdf index 6a9b2b0eb..dd0b54a1c 100644 Binary files a/e2etests-cli/testdata/TestCLI_E2E/renamed-board.exp.pdf and b/e2etests-cli/testdata/TestCLI_E2E/renamed-board.exp.pdf differ diff --git a/lib/color/color.go b/lib/color/color.go index 7a54573e6..7a7a4d9c1 100644 --- a/lib/color/color.go +++ b/lib/color/color.go @@ -348,3 +348,158 @@ func Name2RGB(name string) RGB { } return RGB{} } + +var NamedColors = []string{ + "currentcolor", + "transparent", + "aliceblue", + "antiquewhite", + "aqua", + "aquamarine", + "azure", + "beige", + "bisque", + "black", + "blanchedalmond", + "blue", + "blueviolet", + "brown", + "burlywood", + "cadetblue", + "chartreuse", + "chocolate", + "coral", + "cornflowerblue", + "cornsilk", + "crimson", + "cyan", + "darkblue", + "darkcyan", + "darkgoldenrod", + "darkgray", + "darkgrey", + "darkgreen", + "darkkhaki", + "darkmagenta", + "darkolivegreen", + "darkorange", + "darkorchid", + "darkred", + "darksalmon", + "darkseagreen", + "darkslateblue", + "darkslategray", + "darkslategrey", + "darkturquoise", + "darkviolet", + "deeppink", + "deepskyblue", + "dimgray", + "dimgrey", + "dodgerblue", + "firebrick", + "floralwhite", + "forestgreen", + "fuchsia", + "gainsboro", + "ghostwhite", + "gold", + "goldenrod", + "gray", + "grey", + "green", + "greenyellow", + "honeydew", + "hotpink", + "indianred", + "indigo", + "ivory", + "khaki", + "lavender", + "lavenderblush", + "lawngreen", + "lemonchiffon", + "lightblue", + "lightcoral", + "lightcyan", + "lightgoldenrodyellow", + "lightgray", + "lightgrey", + "lightgreen", + "lightpink", + "lightsalmon", + "lightseagreen", + "lightskyblue", + "lightslategray", + "lightslategrey", + "lightsteelblue", + "lightyellow", + "lime", + "limegreen", + "linen", + "magenta", + "maroon", + "mediumaquamarine", + "mediumblue", + "mediumorchid", + "mediumpurple", + "mediumseagreen", + "mediumslateblue", + "mediumspringgreen", + "mediumturquoise", + "mediumvioletred", + "midnightblue", + "mintcream", + "mistyrose", + "moccasin", + "navajowhite", + "navy", + "oldlace", + "olive", + "olivedrab", + "orange", + "orangered", + "orchid", + "palegoldenrod", + "palegreen", + "paleturquoise", + "palevioletred", + "papayawhip", + "peachpuff", + "peru", + "pink", + "plum", + "powderblue", + "purple", + "rebeccapurple", + "red", + "rosybrown", + "royalblue", + "saddlebrown", + "salmon", + "sandybrown", + "seagreen", + "seashell", + "sienna", + "silver", + "skyblue", + "slateblue", + "slategray", + "slategrey", + "snow", + "springgreen", + "steelblue", + "tan", + "teal", + "thistle", + "tomato", + "turquoise", + "violet", + "wheat", + "white", + "whitesmoke", + "yellow", + "yellowgreen", +} + +var ColorHexRegex = regexp.MustCompile(`^#(([0-9a-fA-F]{2}){3}|([0-9a-fA-F]){3})$`) diff --git a/testdata/d2compiler/TestCompile/var-not-color.exp.json b/testdata/d2compiler/TestCompile/var-not-color.exp.json new file mode 100644 index 000000000..8b6feccbf --- /dev/null +++ b/testdata/d2compiler/TestCompile/var-not-color.exp.json @@ -0,0 +1,15 @@ +{ + "graph": null, + "err": { + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile/var-not-color.d2,3:6:52-3:16:62", + "errmsg": "d2/testdata/d2compiler/TestCompile/var-not-color.d2:4:7: expected \"B1\" to be a valid named color (\"orange\") or a hex code (\"#f0ff3a\")" + }, + { + "range": "d2/testdata/d2compiler/TestCompile/var-not-color.d2,4:3:66-4:13:76", + "errmsg": "d2/testdata/d2compiler/TestCompile/var-not-color.d2:5:4: \"potato\" is not a valid theme code" + } + ] + } +}