This commit is contained in:
Alexander Wang 2023-12-14 11:35:35 -08:00
parent 27ea8314e9
commit a098ba80ec
No known key found for this signature in database
GPG key ID: D89FA31966BDBECE
11 changed files with 337 additions and 303 deletions

View file

@ -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
}

View file

@ -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",

View file

@ -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})$`)

View file

@ -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

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" d2Version="v0.6.2-HEAD" preserveAspectRatio="xMinYMin meet" viewBox="0 0 256 434"><svg id="d2-svg" class="d2-3600758884" width="256" height="434" viewBox="-101 -101 256 434"><rect x="-101.000000" y="-101.000000" width="256.000000" height="434.000000" rx="0.000000" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
.d2-3600758884 .text-bold {
font-family: "d2-3600758884-font-bold";
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" d2Version="v0.6.2-HEAD" preserveAspectRatio="xMinYMin meet" viewBox="0 0 256 434"><svg id="d2-svg" class="d2-2712468095" width="256" height="434" viewBox="-101 -101 256 434"><rect x="-101.000000" y="-101.000000" width="256.000000" height="434.000000" rx="0.000000" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
.d2-2712468095 .text-bold {
font-family: "d2-2712468095-font-bold";
}
@font-face {
font-family: d2-3600758884-font-bold;
font-family: d2-2712468095-font-bold;
src: url("data:application/font-woff;base64,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");
}]]></style><style type="text/css"><![CDATA[.shape {
shape-rendering: geometricPrecision;
@ -18,78 +18,78 @@
opacity: 0.5;
}
.d2-3600758884 .fill-N1{fill:#CDD6F4;}
.d2-3600758884 .fill-N2{fill:#BAC2DE;}
.d2-3600758884 .fill-N3{fill:#A6ADC8;}
.d2-3600758884 .fill-N4{fill:#585B70;}
.d2-3600758884 .fill-N5{fill:#45475A;}
.d2-3600758884 .fill-N6{fill:#313244;}
.d2-3600758884 .fill-N7{fill:#1E1E2E;}
.d2-3600758884 .fill-B1{fill:#CBA6f7;}
.d2-3600758884 .fill-B2{fill:#CBA6f7;}
.d2-3600758884 .fill-B3{fill:#6C7086;}
.d2-3600758884 .fill-B4{fill:#585B70;}
.d2-3600758884 .fill-B5{fill:#45475A;}
.d2-3600758884 .fill-B6{fill:#313244;}
.d2-3600758884 .fill-AA2{fill:#f38BA8;}
.d2-3600758884 .fill-AA4{fill:#45475A;}
.d2-3600758884 .fill-AA5{fill:#313244;}
.d2-3600758884 .fill-AB4{fill:#45475A;}
.d2-3600758884 .fill-AB5{fill:#313244;}
.d2-3600758884 .stroke-N1{stroke:#CDD6F4;}
.d2-3600758884 .stroke-N2{stroke:#BAC2DE;}
.d2-3600758884 .stroke-N3{stroke:#A6ADC8;}
.d2-3600758884 .stroke-N4{stroke:#585B70;}
.d2-3600758884 .stroke-N5{stroke:#45475A;}
.d2-3600758884 .stroke-N6{stroke:#313244;}
.d2-3600758884 .stroke-N7{stroke:#1E1E2E;}
.d2-3600758884 .stroke-B1{stroke:#CBA6f7;}
.d2-3600758884 .stroke-B2{stroke:#CBA6f7;}
.d2-3600758884 .stroke-B3{stroke:#6C7086;}
.d2-3600758884 .stroke-B4{stroke:#585B70;}
.d2-3600758884 .stroke-B5{stroke:#45475A;}
.d2-3600758884 .stroke-B6{stroke:#313244;}
.d2-3600758884 .stroke-AA2{stroke:#f38BA8;}
.d2-3600758884 .stroke-AA4{stroke:#45475A;}
.d2-3600758884 .stroke-AA5{stroke:#313244;}
.d2-3600758884 .stroke-AB4{stroke:#45475A;}
.d2-3600758884 .stroke-AB5{stroke:#313244;}
.d2-3600758884 .background-color-N1{background-color:#CDD6F4;}
.d2-3600758884 .background-color-N2{background-color:#BAC2DE;}
.d2-3600758884 .background-color-N3{background-color:#A6ADC8;}
.d2-3600758884 .background-color-N4{background-color:#585B70;}
.d2-3600758884 .background-color-N5{background-color:#45475A;}
.d2-3600758884 .background-color-N6{background-color:#313244;}
.d2-3600758884 .background-color-N7{background-color:#1E1E2E;}
.d2-3600758884 .background-color-B1{background-color:#CBA6f7;}
.d2-3600758884 .background-color-B2{background-color:#CBA6f7;}
.d2-3600758884 .background-color-B3{background-color:#6C7086;}
.d2-3600758884 .background-color-B4{background-color:#585B70;}
.d2-3600758884 .background-color-B5{background-color:#45475A;}
.d2-3600758884 .background-color-B6{background-color:#313244;}
.d2-3600758884 .background-color-AA2{background-color:#f38BA8;}
.d2-3600758884 .background-color-AA4{background-color:#45475A;}
.d2-3600758884 .background-color-AA5{background-color:#313244;}
.d2-3600758884 .background-color-AB4{background-color:#45475A;}
.d2-3600758884 .background-color-AB5{background-color:#313244;}
.d2-3600758884 .color-N1{color:#CDD6F4;}
.d2-3600758884 .color-N2{color:#BAC2DE;}
.d2-3600758884 .color-N3{color:#A6ADC8;}
.d2-3600758884 .color-N4{color:#585B70;}
.d2-3600758884 .color-N5{color:#45475A;}
.d2-3600758884 .color-N6{color:#313244;}
.d2-3600758884 .color-N7{color:#1E1E2E;}
.d2-3600758884 .color-B1{color:#CBA6f7;}
.d2-3600758884 .color-B2{color:#CBA6f7;}
.d2-3600758884 .color-B3{color:#6C7086;}
.d2-3600758884 .color-B4{color:#585B70;}
.d2-3600758884 .color-B5{color:#45475A;}
.d2-3600758884 .color-B6{color:#313244;}
.d2-3600758884 .color-AA2{color:#f38BA8;}
.d2-3600758884 .color-AA4{color:#45475A;}
.d2-3600758884 .color-AA5{color:#313244;}
.d2-3600758884 .color-AB4{color:#45475A;}
.d2-3600758884 .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}]]></style><g id="x"><g class="shape" ><rect x="1.000000" y="0.000000" width="53.000000" height="66.000000" class=" stroke-B1 fill-B6" style="stroke-width:2;" /></g><text x="27.500000" y="38.500000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">x</text></g><g id="y"><g class="shape" ><rect x="0.000000" y="166.000000" width="54.000000" height="66.000000" class=" stroke-B1 fill-B6" style="stroke-width:2;" /></g><text x="27.000000" y="204.500000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">y</text></g><g id="(x -&gt; y)[0]"><marker id="mk-3488378134" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" class="connection fill-B1" stroke-width="2" /> </marker><path d="M 27.000000 68.000000 C 27.000000 106.000000 27.000000 126.000000 27.000000 162.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-3600758884)" /></g><mask id="d2-3600758884" maskUnits="userSpaceOnUse" x="-101" y="-101" width="256" height="434">
.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}]]></style><g id="x"><g class="shape" ><rect x="1.000000" y="0.000000" width="53.000000" height="66.000000" class=" stroke-B1 fill-B6" style="stroke-width:2;" /></g><text x="27.500000" y="38.500000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">x</text></g><g id="y"><g class="shape" ><rect x="0.000000" y="166.000000" width="54.000000" height="66.000000" class=" stroke-B1 fill-B6" style="stroke-width:2;" /></g><text x="27.000000" y="204.500000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">y</text></g><g id="(x -&gt; y)[0]"><marker id="mk-3488378134" markerWidth="10.000000" markerHeight="12.000000" refX="7.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" class="connection fill-B1" stroke-width="2" /> </marker><path d="M 27.000000 68.000000 C 27.000000 106.000000 27.000000 126.000000 27.000000 162.000000" fill="none" class="connection stroke-B1" style="stroke-width:2;" marker-end="url(#mk-3488378134)" mask="url(#d2-2712468095)" /></g><mask id="d2-2712468095" maskUnits="userSpaceOnUse" x="-101" y="-101" width="256" height="434">
<rect x="-101" y="-101" width="256" height="434" fill="white"></rect>
<rect x="23.500000" y="22.500000" width="8" height="21" fill="rgba(0,0,0,0.75)"></rect>
<rect x="22.500000" y="188.500000" width="9" height="21" fill="rgba(0,0,0,0.75)"></rect>

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

View file

@ -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})$`)

15
testdata/d2compiler/TestCompile/var-not-color.exp.json generated vendored Normal file
View file

@ -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"
}
]
}
}