diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 28c6ba7f29..8a32cd1895 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -402,28 +402,30 @@ func (c *compiler) compileLabel(attrs *d2graph.Attributes, f d2ir.Node) { if ok { attrs.Language = fullTag } - switch attrs.Language { - case "latex": - attrs.Shape.Value = d2target.ShapeText - case "markdown": - rendered, err := textmeasure.RenderMarkdown(scalar.ScalarString()) - if err != nil { - c.errorf(f.LastPrimaryKey(), "malformed Markdown") - } - rendered = "
" + rendered + "
" - var xmlParsed interface{} - err = xml.Unmarshal([]byte(rendered), &xmlParsed) - if err != nil { - switch xmlErr := err.(type) { - case *xml.SyntaxError: - c.errorf(f.LastPrimaryKey(), "malformed Markdown: %s", xmlErr.Msg) - default: - c.errorf(f.LastPrimaryKey(), "malformed Markdown: %s", err.Error()) + if attrs.Shape.Value == "" { + switch attrs.Language { + case "latex": + attrs.Shape.Value = d2target.ShapeText + case "markdown": + rendered, err := textmeasure.RenderMarkdown(scalar.ScalarString()) + if err != nil { + c.errorf(f.LastPrimaryKey(), "malformed Markdown") + } + rendered = "
" + rendered + "
" + var xmlParsed interface{} + err = xml.Unmarshal([]byte(rendered), &xmlParsed) + if err != nil { + switch xmlErr := err.(type) { + case *xml.SyntaxError: + c.errorf(f.LastPrimaryKey(), "malformed Markdown: %s", xmlErr.Msg) + default: + c.errorf(f.LastPrimaryKey(), "malformed Markdown: %s", err.Error()) + } } + attrs.Shape.Value = d2target.ShapeText + default: + attrs.Shape.Value = d2target.ShapeCode } - attrs.Shape.Value = d2target.ShapeText - default: - attrs.Shape.Value = d2target.ShapeCode } attrs.Label.Value = scalar.ScalarString() default: diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index a105abaa9a..974ac60aa7 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -1420,7 +1420,23 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape return labelMask, err } gEl := d2themes.NewThemableElement("g", inlineTheme) - gEl.SetTranslate(float64(box.TopLeft.X), float64(box.TopLeft.Y)) + + labelPosition := label.FromString(targetShape.LabelPosition) + if labelPosition == label.Unset { + labelPosition = label.InsideMiddleCenter + } + var box *geo.Box + if labelPosition.IsOutside() { + box = s.GetBox() + } else { + box = s.GetInnerBox() + } + labelTL := labelPosition.GetPointOnBox(box, label.PADDING, + float64(targetShape.LabelWidth), + float64(targetShape.LabelHeight), + ) + gEl.SetTranslate(labelTL.X, labelTL.Y) + gEl.Color = targetShape.Stroke gEl.Content = render fmt.Fprint(writer, gEl.Render()) @@ -1429,9 +1445,26 @@ func drawShape(writer, appendixWriter io.Writer, diagramHash string, targetShape if err != nil { return labelMask, err } + + labelPosition := label.FromString(targetShape.LabelPosition) + if labelPosition == label.Unset { + labelPosition = label.InsideMiddleCenter + } + var box *geo.Box + if labelPosition.IsOutside() { + box = s.GetBox() + } else { + box = s.GetInnerBox() + } + labelTL := labelPosition.GetPointOnBox(box, label.PADDING, + float64(targetShape.LabelWidth), + float64(targetShape.LabelHeight), + ) + fmt.Fprintf(writer, ``, - box.TopLeft.X, box.TopLeft.Y, targetShape.Width, targetShape.Height, + labelTL.X, labelTL.Y, targetShape.LabelWidth, targetShape.LabelHeight, ) + // we need the self closing form in this svg/xhtml context render = strings.ReplaceAll(render, "
", "
") diff --git a/e2etests/testdata/txtar/md-label/dagre/board.exp.json b/e2etests/testdata/txtar/md-label/dagre/board.exp.json index ca5395c76b..424408a9df 100644 --- a/e2etests/testdata/txtar/md-label/dagre/board.exp.json +++ b/e2etests/testdata/txtar/md-label/dagre/board.exp.json @@ -1,5 +1,13 @@ { "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ @@ -18,6 +26,7 @@ "borderRadius": 0, "fill": "B6", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -59,6 +68,7 @@ "borderRadius": 0, "fill": "B6", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -100,6 +110,7 @@ "borderRadius": 0, "fill": "AB4", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -141,6 +152,7 @@ "borderRadius": 0, "fill": "N5", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -182,6 +194,7 @@ "borderRadius": 0, "fill": "AB4", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -223,6 +236,7 @@ "borderRadius": 0, "fill": "AA4", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -264,6 +278,7 @@ "borderRadius": 0, "fill": "N5", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -305,6 +320,7 @@ "borderRadius": 0, "fill": "AA4", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -346,6 +362,7 @@ "borderRadius": 0, "fill": "AB4", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -387,6 +404,7 @@ "borderRadius": 0, "fill": "N7", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -428,6 +446,7 @@ "borderRadius": 0, "fill": "AA4", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -469,6 +488,7 @@ "borderRadius": 0, "fill": "B3", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -510,6 +530,7 @@ "borderRadius": 0, "fill": "N4", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -551,6 +572,7 @@ "borderRadius": 0, "fill": "B6", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -592,6 +614,7 @@ "borderRadius": 0, "fill": "B6", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -633,6 +656,7 @@ "borderRadius": 0, "fill": "N5", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -674,6 +698,7 @@ "borderRadius": 0, "fill": "N7", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -718,6 +743,7 @@ "borderRadius": 0, "fill": "N7", "stroke": "", + "animated": false, "shadow": false, "3d": false, "multiple": false, diff --git a/e2etests/testdata/txtar/md-label/dagre/sketch.exp.svg b/e2etests/testdata/txtar/md-label/dagre/sketch.exp.svg index 53ab94c0a2..66822ca584 100644 --- a/e2etests/testdata/txtar/md-label/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/md-label/dagre/sketch.exp.svg @@ -1,13 +1,13 @@ -

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-
+
diff --git a/e2etests/testdata/txtar/md-label/elk/board.exp.json b/e2etests/testdata/txtar/md-label/elk/board.exp.json index 79cc92a575..221922f892 100644 --- a/e2etests/testdata/txtar/md-label/elk/board.exp.json +++ b/e2etests/testdata/txtar/md-label/elk/board.exp.json @@ -1,5 +1,13 @@ { "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ @@ -18,6 +26,7 @@ "borderRadius": 0, "fill": "B6", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -59,6 +68,7 @@ "borderRadius": 0, "fill": "B6", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -100,6 +110,7 @@ "borderRadius": 0, "fill": "AB4", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -141,6 +152,7 @@ "borderRadius": 0, "fill": "N5", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -182,6 +194,7 @@ "borderRadius": 0, "fill": "AB4", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -223,6 +236,7 @@ "borderRadius": 0, "fill": "AA4", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -264,6 +278,7 @@ "borderRadius": 0, "fill": "N5", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -305,6 +320,7 @@ "borderRadius": 0, "fill": "AA4", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -346,6 +362,7 @@ "borderRadius": 0, "fill": "AB4", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -387,6 +404,7 @@ "borderRadius": 0, "fill": "N7", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -428,6 +446,7 @@ "borderRadius": 0, "fill": "AA4", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -469,6 +488,7 @@ "borderRadius": 0, "fill": "B3", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -510,6 +530,7 @@ "borderRadius": 0, "fill": "N4", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -551,6 +572,7 @@ "borderRadius": 0, "fill": "B6", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -592,6 +614,7 @@ "borderRadius": 0, "fill": "B6", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -633,6 +656,7 @@ "borderRadius": 0, "fill": "N5", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -674,6 +698,7 @@ "borderRadius": 0, "fill": "N7", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -718,6 +743,7 @@ "borderRadius": 0, "fill": "N7", "stroke": "", + "animated": false, "shadow": false, "3d": false, "multiple": false, diff --git a/e2etests/testdata/txtar/md-label/elk/sketch.exp.svg b/e2etests/testdata/txtar/md-label/elk/sketch.exp.svg index 0e7aef9977..14c2e2e9ce 100644 --- a/e2etests/testdata/txtar/md-label/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/md-label/elk/sketch.exp.svg @@ -1,13 +1,13 @@ -

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-

hello

+

hello

  • world

blah blah

-
+
diff --git a/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/board.exp.json b/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/board.exp.json index 4ed4a2f6e6..d067a7fab3 100644 --- a/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/board.exp.json +++ b/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/board.exp.json @@ -1,5 +1,13 @@ { "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ @@ -18,6 +26,7 @@ "borderRadius": 0, "fill": "B5", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -48,7 +57,7 @@ "id": "y", "type": "rectangle", "pos": { - "x": 242, + "x": 265, "y": 52 }, "width": 100, @@ -59,6 +68,7 @@ "borderRadius": 0, "fill": "B5", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -89,17 +99,18 @@ "id": "x.x", "type": "page", "pos": { - "x": -128, - "y": 258 + "x": -150, + "y": 279 }, - "width": 380, - "height": 119, + "width": 425, + "height": 164, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, "fill": "N7", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -130,17 +141,18 @@ "id": "y.z", "type": "page", "pos": { - "x": 211, - "y": 447 + "x": 155, + "y": 513 }, - "width": 162, - "height": 41, + "width": 320, + "height": 64, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, "fill": "N7", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -161,8 +173,8 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 162, - "labelHeight": 41, + "labelWidth": 275, + "labelHeight": 19, "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 5, "level": 2 @@ -171,17 +183,18 @@ "id": "x.z", "type": "page", "pos": { - "x": 27, - "y": 558 + "x": 13, + "y": 647 }, - "width": 69, - "height": 40, + "width": 98, + "height": 69, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, "fill": "N7", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -233,14 +246,15 @@ "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", "labelPercentage": 0, + "link": "", "route": [ { "x": 62, - "y": 188 + "y": 198 }, { - "x": 292, - "y": 188 + "x": 315, + "y": 198 } ], "animated": false, @@ -271,6 +285,7 @@ "labelHeight": 0, "labelPosition": "", "labelPercentage": 0, + "link": "", "route": [ { "x": 62, @@ -278,7 +293,7 @@ }, { "x": 62, - "y": 668 + "y": 786 } ], "animated": false, @@ -309,14 +324,15 @@ "labelHeight": 0, "labelPosition": "", "labelPercentage": 0, + "link": "", "route": [ { - "x": 292, + "x": 315, "y": 118 }, { - "x": 292, - "y": 668 + "x": 315, + "y": 786 } ], "animated": false, @@ -340,6 +356,7 @@ "borderRadius": 0, "fill": "N7", "stroke": "", + "animated": false, "shadow": false, "3d": false, "multiple": false, diff --git a/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/sketch.exp.svg b/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/sketch.exp.svg index dfd8ff0d80..d8d19fe2ea 100644 --- a/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/sketch.exp.svg +++ b/e2etests/testdata/txtar/sequence-diagram-note-md/dagre/sketch.exp.svg @@ -1,34 +1,34 @@ -xy hello

A man who fishes for marlin in ponds

+xy hello

A man who fishes for marlin in ponds

  • ...dramatic pause

will put his money in Etruscan bonds.

-
1 + 1 = 21 + 1 = 2 - +
1 + 1 = 21 + 1 = 2 + - - - - - + + + + +
\ No newline at end of file diff --git a/e2etests/testdata/txtar/sequence-diagram-note-md/elk/board.exp.json b/e2etests/testdata/txtar/sequence-diagram-note-md/elk/board.exp.json index 4ed4a2f6e6..d067a7fab3 100644 --- a/e2etests/testdata/txtar/sequence-diagram-note-md/elk/board.exp.json +++ b/e2etests/testdata/txtar/sequence-diagram-note-md/elk/board.exp.json @@ -1,5 +1,13 @@ { "name": "", + "config": { + "sketch": false, + "themeID": 0, + "darkThemeID": null, + "pad": null, + "center": null, + "layoutEngine": null + }, "isFolderOnly": false, "fontFamily": "SourceSansPro", "shapes": [ @@ -18,6 +26,7 @@ "borderRadius": 0, "fill": "B5", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -48,7 +57,7 @@ "id": "y", "type": "rectangle", "pos": { - "x": 242, + "x": 265, "y": 52 }, "width": 100, @@ -59,6 +68,7 @@ "borderRadius": 0, "fill": "B5", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -89,17 +99,18 @@ "id": "x.x", "type": "page", "pos": { - "x": -128, - "y": 258 + "x": -150, + "y": 279 }, - "width": 380, - "height": 119, + "width": 425, + "height": 164, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, "fill": "N7", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -130,17 +141,18 @@ "id": "y.z", "type": "page", "pos": { - "x": 211, - "y": 447 + "x": 155, + "y": 513 }, - "width": 162, - "height": 41, + "width": 320, + "height": 64, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, "fill": "N7", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -161,8 +173,8 @@ "italic": false, "bold": false, "underline": false, - "labelWidth": 162, - "labelHeight": 41, + "labelWidth": 275, + "labelHeight": 19, "labelPosition": "INSIDE_MIDDLE_CENTER", "zIndex": 5, "level": 2 @@ -171,17 +183,18 @@ "id": "x.z", "type": "page", "pos": { - "x": 27, - "y": 558 + "x": 13, + "y": 647 }, - "width": 69, - "height": 40, + "width": 98, + "height": 69, "opacity": 1, "strokeDash": 0, "strokeWidth": 2, "borderRadius": 0, "fill": "N7", "stroke": "B1", + "animated": false, "shadow": false, "3d": false, "multiple": false, @@ -233,14 +246,15 @@ "labelHeight": 21, "labelPosition": "INSIDE_MIDDLE_CENTER", "labelPercentage": 0, + "link": "", "route": [ { "x": 62, - "y": 188 + "y": 198 }, { - "x": 292, - "y": 188 + "x": 315, + "y": 198 } ], "animated": false, @@ -271,6 +285,7 @@ "labelHeight": 0, "labelPosition": "", "labelPercentage": 0, + "link": "", "route": [ { "x": 62, @@ -278,7 +293,7 @@ }, { "x": 62, - "y": 668 + "y": 786 } ], "animated": false, @@ -309,14 +324,15 @@ "labelHeight": 0, "labelPosition": "", "labelPercentage": 0, + "link": "", "route": [ { - "x": 292, + "x": 315, "y": 118 }, { - "x": 292, - "y": 668 + "x": 315, + "y": 786 } ], "animated": false, @@ -340,6 +356,7 @@ "borderRadius": 0, "fill": "N7", "stroke": "", + "animated": false, "shadow": false, "3d": false, "multiple": false, diff --git a/e2etests/testdata/txtar/sequence-diagram-note-md/elk/sketch.exp.svg b/e2etests/testdata/txtar/sequence-diagram-note-md/elk/sketch.exp.svg index dfd8ff0d80..d8d19fe2ea 100644 --- a/e2etests/testdata/txtar/sequence-diagram-note-md/elk/sketch.exp.svg +++ b/e2etests/testdata/txtar/sequence-diagram-note-md/elk/sketch.exp.svg @@ -1,34 +1,34 @@ -xy hello

A man who fishes for marlin in ponds

+xy hello

A man who fishes for marlin in ponds

  • ...dramatic pause

will put his money in Etruscan bonds.

-
1 + 1 = 21 + 1 = 2 - +
1 + 1 = 21 + 1 = 2 + - - - - - + + + + +
\ No newline at end of file