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