From a098ba80ec167d35a817212d2b6bfb1e3e1ee9d9 Mon Sep 17 00:00:00 2001 From: Alexander Wang Date: Thu, 14 Dec 2023 11:35:35 -0800 Subject: [PATCH] validate --- d2compiler/compile.go | 138 ++++++++------- d2compiler/compile_test.go | 15 ++ d2graph/color_helper.go | 159 ------------------ d2graph/d2graph.go | 6 +- .../testdata/TestCLI_E2E/import_vars.exp.svg | 152 ++++++++--------- .../TestCLI_E2E/internal_linked_pdf.exp.pdf | Bin 66069 -> 66069 bytes .../testdata/TestCLI_E2E/no-nav-pdf.exp.pdf | Bin 96035 -> 96035 bytes .../testdata/TestCLI_E2E/no-nav-pptx.exp.pptx | Bin 122134 -> 122133 bytes .../TestCLI_E2E/renamed-board.exp.pdf | Bin 109973 -> 109973 bytes lib/color/color.go | 155 +++++++++++++++++ .../TestCompile/var-not-color.exp.json | 15 ++ 11 files changed, 337 insertions(+), 303 deletions(-) delete mode 100644 d2graph/color_helper.go create mode 100644 testdata/d2compiler/TestCompile/var-not-color.exp.json 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 751aa45ac35d4ebf45eee114ecf3b5d4c374485a..ca96dd5936cdfb67a03aa2a59a2afee62afdb508 100644 GIT binary patch delta 50 zcmbQ*!ZNjmWrO&CWfMa~BXa|DO)h=k{1lhOl2io^7b_zJBV$7&L#W(ltN*u|0Dij; A+5i9m delta 50 zcmbQ*!ZNjmWrO&CWg`PiQxhX&O)h=k{1lhOl2io^7b_zJBV$7&L#W(ltN*u|0DoH! A-~a#s 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 bfc825b34a4e0b676a85bca4fa8b5cbc92c907eb..887985d7881b5dbe97d3046df9e668f96b7618b1 100644 GIT binary patch delta 68 zcmZ4dj&<=n)`l&N?~A4@6f+u3e_O<8I6a`4@v5?kp`nqvfr%!UzHfetOJYf?f`*Hg Tk%5u1p^+g}Zo5Yb<83AYR}vM` delta 68 zcmZ4dj&<=n)`l&N?~A4@7BlKke_O<8G(Di0@v5?sfu*U5k&z~szHfetOJYf?f`*Hg Tk%5u1p^+g}Zo5Yb<83AYSU(lq 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 acca7f84489ec69f33b19b8f2e8a14888ed84516..657a8e60fa3c9f552f2731da74bbba6ea28072a8 100644 GIT binary patch delta 438 zcmV;n0ZIOrx(AiI2Y|EzA;$&=dp>=M(3dC20VRKDXUPksY=Ym>uH}?~S3w&;?&!Du zeRD%eM(MS*!NZQ8Ak*97YOA79A;Dt`5fU26SA-BUJL|JhaYqk`Q81R(0i4Wjh~Q^u zpF(mHa~smgqEydv1lDu@KXZUmOO$MZHnCFa8?06p8;{8rh*k_NIPjQR*LI9nFG6zp z!$5yg*d^H+JVp4>zKR!#Ih$&prm3Aa#olw?u^$g#zLwgJ@ypdIphJmnwGwF1!Vr$Q zWp%1zKK}d#3ah-%)u0kc3~7)SX6ZGgN&2x^SLJL~Q9Q$G3Q1?eUgH|FN+zNSet1lf z!J}LTGJ=OB5j2?$9>`r!8nU#@f-&7&>BoOo1y>Gw%czH0neicL^JGAOI=x@-Z$k|x zcrnYTH+02T$93iMR_Ah{$()TiztgIG-+aE?-_xPz{if;qru%Q-b)vr({JP;cg7anP z3&=aP`?J))u~*7#F(nbkkWS0>mui=P%kVn@0RR6`O9u$d3&C%q0RRAb0{{R}O9Qvc g$N|X{1zU?RhuYxvy+|h6Q zyXKmbjM8gqgNGeGL8dpu)mBBJLV|}BA|y1BuLvPzcGhR1;*K5=qhKtn12~!65W&yR zK8EBZ<~F2}MX8?T2#j~#2j&2!mMGZ*ZDOU;S6HnoHXf5L5Um(kaNseszU>*UUWDZG zyMceAuuHNtc#80@eHAYfb2imHO;bB#xGZ=fDR?P)k>g23qv^K zmer|>`S|k}D6H~2SA$9*F{D9Sn5EZ{Ch5mwU6r#{MeziuDI}ckvDw&8T_~9Wz z29I(X$Os;iM9^e1cp$f&G-PR)1!J09>BoOo1y>Gw&8UZ2nejeo^JqYSI=x-*Z$k|x zcs9$YH}u6;$93iMR_Ah{$()TiztgIG-+aE^-_e10eAD#2>G{6@3dP)oPS g$N|a|1-av6=A)OF+yPVp$CvEf0V4({%K-oY04n9wnE(I) diff --git a/e2etests-cli/testdata/TestCLI_E2E/renamed-board.exp.pdf b/e2etests-cli/testdata/TestCLI_E2E/renamed-board.exp.pdf index 6a9b2b0eb12cb3d51318d2b522ed3b4dfed7f77b..dd0b54a1ccd06d2c08c9c26894fd7b6194c3fa06 100644 GIT binary patch delta 53 zcmbPwn{DcCwuUW?(^e^)7#bRx8yaYG>HFrVxFnXODrmS^85tNE8yXox<+kr!#dwDa E0M#=PUjP6A delta 53 zcmbPwn{DcCwuUW?(^e@P8CaT{7#V4D>HFrVxFnXODrmS^85tNE8yXox<+kr!#dwDa E0M@AxZvX%Q 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" + } + ] + } +}