diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index c43456677..aef91878f 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -828,12 +828,14 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler } var dims *d2target.TextDimensions + var innerLabelPadding = 5 if obj.Attributes.Shape.Value == d2target.ShapeText { var err error dims, err = getMarkdownDimensions(mtexts, ruler, obj.Text()) if err != nil { return err } + innerLabelPadding = 0 } else { dims = getTextDimensions(mtexts, ruler, obj.Text()) } @@ -855,7 +857,6 @@ func (g *Graph) SetDimensions(mtexts []*d2target.MText, ruler *textmeasure.Ruler } } - const innerLabelPadding = 5 dims.Width += innerLabelPadding dims.Height += innerLabelPadding obj.LabelDimensions = *dims diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index fb37ececf..14e77f164 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -73,7 +73,7 @@ func Layout(ctx context.Context, d2graph *d2graph.Graph) (err error) { loadScript := "" for _, obj := range d2graph.Objects { id := obj.AbsID() - loadScript += generateAddNodeLine(id, obj.Attributes.Label.Value, int(obj.Width), int(obj.Height)) + loadScript += generateAddNodeLine(id, int(obj.Width), int(obj.Height)) if obj.Parent != d2graph.Root { loadScript += generateAddParentLine(id, obj.Parent.AbsID()) } @@ -93,7 +93,7 @@ func Layout(ctx context.Context, d2graph *d2graph.Graph) (err error) { // for `b <- a`, edge.Edge is `a -> b` and we expect this routing result src, dst = dst, src } - loadScript += generateAddEdgeLine(src.AbsID(), dst.AbsID(), edge.AbsID(), edge.Attributes.Label.Value) + loadScript += generateAddEdgeLine(src.AbsID(), dst.AbsID(), edge.AbsID()) } if debugJS { @@ -234,15 +234,15 @@ func setGraphAttrs(attrs dagreGraphAttrs) string { ) } -func generateAddNodeLine(id, label string, width, height int) string { - return fmt.Sprintf("g.setNode(`%s`, { label: `%s`, width: %d, height: %d });\n", id, label, width, height) +func generateAddNodeLine(id string, width, height int) string { + return fmt.Sprintf("g.setNode(`%s`, { width: %d, height: %d });\n", id, width, height) } func generateAddParentLine(childID, parentID string) string { return fmt.Sprintf("g.setParent(`%s`, `%s`);\n", childID, parentID) } -func generateAddEdgeLine(fromID, toID, edgeID, label string) string { +func generateAddEdgeLine(fromID, toID, edgeID string) string { // in dagre v is from, w is to, name is to uniquely identify - return fmt.Sprintf("g.setEdge({v:`%s`, w:`%s`, name:`%s`, label:`%s`});\n", fromID, toID, edgeID, label) + return fmt.Sprintf("g.setEdge({v:`%s`, w:`%s`, name:`%s` });\n", fromID, toID, edgeID) } diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index 00d348b0c..4409e6045 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -717,8 +717,18 @@ func embedFonts(buf *bytes.Buffer) { break } } - if strings.Contains(content, `class="text-mono"`) { - fmt.Fprintf(buf, ` + + triggers = []string{ + `class="text-mono"`, + `
`,
+		``,
+		``,
+		``,
+	}
+
+	for _, t := range triggers {
+		if strings.Contains(content, t) {
+			fmt.Fprintf(buf, `
 .text-mono {
 	font-family: "font-mono";
 }
@@ -726,7 +736,9 @@ func embedFonts(buf *bytes.Buffer) {
 	font-family: font-mono;
 	src: url("%s");
 }`,
-			d2fonts.FontEncodings[d2fonts.SourceCodePro.Font(0, d2fonts.FONT_STYLE_REGULAR)])
+				d2fonts.FontEncodings[d2fonts.SourceCodePro.Font(0, d2fonts.FONT_STYLE_REGULAR)])
+			break
+		}
 	}
 
 	buf.WriteString(`]]>`)
diff --git a/d2renderers/d2svg/github-markdown.css b/d2renderers/d2svg/github-markdown.css
index 44ff18757..587fdfd84 100644
--- a/d2renderers/d2svg/github-markdown.css
+++ b/d2renderers/d2svg/github-markdown.css
@@ -8,6 +8,18 @@
   font-family: "font-bold";
 }
 
+.md code,
+.md kbd,
+.md pre,
+.md samp {
+  font-family: "font-mono";
+  font-size: 1em;
+}
+
+.md {
+  tab-size: 4;
+}
+
 /* based on https://github.com/sindresorhus/github-markdown-css */
 @media (prefers-color-scheme: dark) {
   .md {
@@ -131,14 +143,6 @@
   background-color: var(--color-canvas-default);
 }
 
-.md code,
-.md kbd,
-.md pre,
-.md samp {
-  font-family: monospace, monospace;
-  font-size: 1em;
-}
-
 .md figure {
   margin: 1em 40px;
 }
@@ -254,9 +258,6 @@
 .md kbd {
   display: inline-block;
   padding: 3px 5px;
-  font: 11px ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono,
-    monospace;
-  line-height: 10px;
   color: var(--color-fg-default);
   vertical-align: middle;
   background-color: var(--color-canvas-subtle);
@@ -341,19 +342,9 @@
   margin-left: 0;
 }
 
-.md tt,
-.md code {
-  font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono,
-    monospace;
-  font-size: 12px;
-}
-
 .md pre {
   margin-top: 0;
   margin-bottom: 0;
-  font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono,
-    monospace;
-  font-size: 12px;
   word-wrap: normal;
 }
 
diff --git a/d2renderers/textmeasure/markdown.go b/d2renderers/textmeasure/markdown.go
index c25907da6..3b538759b 100644
--- a/d2renderers/textmeasure/markdown.go
+++ b/d2renderers/textmeasure/markdown.go
@@ -17,6 +17,7 @@ import (
 
 var markdownRenderer goldmark.Markdown
 
+// these are css values from github-markdown.css so we can accurately compute the rendered dimensions
 const (
 	MarkdownFontSize     = d2fonts.FONT_SIZE_M
 	MarkdownLineHeight   = 1.5
@@ -36,8 +37,13 @@ const (
 	Height_hr          = 4
 	MarginTopBottom_hr = 24
 
-	Padding_pre      = 16
-	MarginBottom_pre = 16
+	Padding_pre          = 16
+	MarginBottom_pre     = 16
+	LineHeight_pre       = 1.45
+	FontSize_pre_code_em = 0.85
+
+	PaddingTopBottom_code_em = 0.2
+	PaddingLeftRight_code_em = 0.4
 
 	PaddingLR_blockquote_em  = 1.
 	MarginBottom_blockquote  = 16
@@ -96,9 +102,11 @@ func MeasureMarkdown(mdText string, ruler *Ruler) (width, height int, err error)
 
 	{
 		originalLineHeight := ruler.LineHeightFactor
+		ruler.boundsWithDot = true
 		ruler.LineHeightFactor = MarkdownLineHeight
 		defer func() {
 			ruler.LineHeightFactor = originalLineHeight
+			ruler.boundsWithDot = false
 		}()
 	}
 
@@ -185,6 +193,11 @@ func hasAncestorElement(n *html.Node, elType string) bool {
 
 // measures node dimensions to match rendering with styles in github-markdown.css
 func (ruler *Ruler) measureNode(depth int, n *html.Node, font d2fonts.Font) (width, height, marginTop, marginBottom float64) {
+	var parentElementType string
+	if n.Parent != nil && n.Parent.Type == html.ElementNode {
+		parentElementType = n.Parent.Data
+	}
+
 	switch n.Type {
 	case html.TextNode:
 		if strings.TrimSpace(n.Data) == "" {
@@ -198,32 +211,39 @@ func (ruler *Ruler) measureNode(depth int, n *html.Node, font d2fonts.Font) (wid
 		spaceWidth := ruler.atlases[font].glyph(spaceRune).advance
 
 		str := n.Data
-		hasCodeParent := n.Parent != nil && n.Parent.Type == html.ElementNode && (n.Parent.Data == "pre" || n.Parent.Data == "code")
-		if !hasCodeParent {
-			str = strings.ReplaceAll(n.Data, "\n", " ")
-		}
-		if strings.HasPrefix(str, " ") {
-			str = strings.TrimPrefix(str, " ")
-			if hasPrev(n) {
-				spaceWidths += spaceWidth
+		isCode := parentElementType == "pre" || parentElementType == "code"
+
+		if !isCode {
+			str = strings.ReplaceAll(str, "\n", " ")
+			str = strings.ReplaceAll(str, "\t", " ")
+			if strings.HasPrefix(str, " ") {
+				str = strings.TrimPrefix(str, " ")
+				if hasPrev(n) {
+					spaceWidths += spaceWidth
+				}
 			}
-		}
-		if strings.HasSuffix(str, " ") {
-			str = strings.TrimSuffix(str, " ")
-			if hasNext(n) {
-				spaceWidths += spaceWidth
+			if strings.HasSuffix(str, " ") {
+				str = strings.TrimSuffix(str, " ")
+				if hasNext(n) {
+					spaceWidths += spaceWidth
+				}
 			}
 		}
 
-		w, h := ruler.MeasurePrecise(font, str)
-		w += spaceWidths
-		// fmt.Printf("%d:%s width %v height %v fontStyle %s\n", depth, n.Data, w, h, font.Style)
-		if h > 0 && h < MarkdownLineHeightPx {
-			h = MarkdownLineHeightPx
+		if parentElementType == "pre" {
+			originalLineHeight := ruler.LineHeightFactor
+			ruler.LineHeightFactor = LineHeight_pre
+			defer func() {
+				ruler.LineHeightFactor = originalLineHeight
+			}()
 		}
-		return w, h, 0, 0
+		w, h := ruler.MeasurePrecise(font, str)
+		if isCode {
+			w *= FontSize_pre_code_em
+			h *= FontSize_pre_code_em
+		}
+		return w + spaceWidths, h, 0, 0
 	case html.ElementNode:
-		// fmt.Printf("%d: %v node\n", depth, n.Data)
 		switch n.Data {
 		case "h1", "h2", "h3", "h4", "h5", "h6":
 			font = HeaderFonts[n.Data]
@@ -237,7 +257,8 @@ func (ruler *Ruler) measureNode(depth int, n *html.Node, font d2fonts.Font) (wid
 		case "b", "strong":
 			font.Style = d2fonts.FONT_STYLE_BOLD
 		case "pre", "code":
-			// TODO monospaced font
+			font.Family = d2fonts.SourceCodePro
+			font.Style = d2fonts.FONT_STYLE_REGULAR
 		}
 
 		if n.FirstChild != nil {
@@ -284,10 +305,10 @@ func (ruler *Ruler) measureNode(depth int, n *html.Node, font d2fonts.Font) (wid
 
 		switch n.Data {
 		case "blockquote":
-			width += float64(font.Size) * (2*PaddingLR_blockquote_em + BorderLeft_blockquote_em)
+			width += (2*PaddingLR_blockquote_em + BorderLeft_blockquote_em) * float64(font.Size)
 			marginBottom = go2.Max(marginBottom, MarginBottom_blockquote)
 		case "p":
-			if n.Parent != nil && n.Parent.Type == html.ElementNode && n.Parent.Data == "li" {
+			if parentElementType == "li" {
 				marginTop = go2.Max(marginTop, MarginTop_li_p)
 			}
 			marginBottom = go2.Max(marginBottom, MarginBottom_p)
@@ -296,7 +317,7 @@ func (ruler *Ruler) measureNode(depth int, n *html.Node, font d2fonts.Font) (wid
 			marginBottom = go2.Max(marginBottom, MarginBottom_h)
 			switch n.Data {
 			case "h1", "h2":
-				height += float64(HeaderToFontSize[n.Data]) * PaddingBottom_h1_h2_em
+				height += PaddingBottom_h1_h2_em * float64(font.Size)
 			}
 		case "li":
 			width += PaddingLeft_ul_ol
@@ -314,12 +335,20 @@ func (ruler *Ruler) measureNode(depth int, n *html.Node, font d2fonts.Font) (wid
 			width += 2 * Padding_pre
 			height += 2 * Padding_pre
 			marginBottom = go2.Max(marginBottom, MarginBottom_pre)
+		case "code":
+			if parentElementType != "pre" {
+				width += 2 * PaddingLeftRight_code_em * float64(font.Size)
+				height += 2 * PaddingTopBottom_code_em * float64(font.Size)
+			}
 		case "hr":
 			height += Height_hr
 			marginTop = go2.Max(marginTop, MarginTopBottom_hr)
 			marginBottom = go2.Max(marginBottom, MarginTopBottom_hr)
 		}
-		// fmt.Printf("%d:%s width %v height %v mt %v mb %v\n", depth, n.Data, width, height, marginTop, marginBottom)
+
+		if height > 0 && height < MarkdownLineHeightPx {
+			height = MarkdownLineHeightPx
+		}
 	}
 	return width, height, marginTop, marginBottom
 }
diff --git a/d2renderers/textmeasure/textmeasure.go b/d2renderers/textmeasure/textmeasure.go
index 251e51b41..4a96c0c3a 100644
--- a/d2renderers/textmeasure/textmeasure.go
+++ b/d2renderers/textmeasure/textmeasure.go
@@ -14,6 +14,8 @@ import (
 	"oss.terrastruct.com/d2/lib/geo"
 )
 
+const TAB_SIZE = 4
+
 // ASCII is a set of all ASCII runes. These runes are codepoints from 32 to 127 inclusive.
 var ASCII []rune
 
@@ -77,6 +79,9 @@ type Ruler struct {
 	buf    []byte
 	prevR  rune
 	bounds *rect
+
+	// when drawing text also union Ruler.bounds with Dot
+	boundsWithDot bool
 }
 
 // New creates a new Ruler capable of drawing runes contained in the provided atlas. Orig and Dot
@@ -118,7 +123,7 @@ func NewRuler() (*Ruler, error) {
 				atlas := NewAtlas(face, ASCII)
 				atlases[font] = atlas
 				lineHeights[font] = atlas.lineHeight
-				tabWidths[font] = atlas.glyph(' ').advance * 4
+				tabWidths[font] = atlas.glyph(' ').advance * TAB_SIZE
 			}
 		}
 	}
@@ -199,10 +204,15 @@ func (txt *Ruler) drawBuf(font d2fonts.Font) {
 
 		txt.prevR = r
 
-		if txt.bounds.w()*txt.bounds.h() == 0 {
-			txt.bounds = bounds
-		} else {
+		if txt.boundsWithDot {
+			txt.bounds = txt.bounds.union(&rect{txt.Dot, txt.Dot})
 			txt.bounds = txt.bounds.union(bounds)
+		} else {
+			if txt.bounds.w()*txt.bounds.h() == 0 {
+				txt.bounds = bounds
+			} else {
+				txt.bounds = txt.bounds.union(bounds)
+			}
 		}
 	}
 }
diff --git a/d2renderers/textmeasure/textmeasure_test.go b/d2renderers/textmeasure/textmeasure_test.go
index 8a8f53110..616c20c5c 100644
--- a/d2renderers/textmeasure/textmeasure_test.go
+++ b/d2renderers/textmeasure/textmeasure_test.go
@@ -88,13 +88,19 @@ _italics are all measured correctly_
 `: {214, 24},
 	`
 **bold is measured correctly**
-`: {187, 24},
+`: {188, 24},
 	`
 **Note:** This document
-`: {141, 24},
+`: {143, 24},
 	`
 **Note:**
-`: {37, 24},
+`: {39, 24},
+	`a`:             {9, 24},
+	`w`:             {12, 24},
+	`ww`:            {24, 24},
+	"`inline code`": {103, 24},
+	"`code`":        {46, 24},
+	"`a`":           {21, 24},
 }
 
 func TestTextMeasureMarkdown(t *testing.T) {
diff --git a/e2etests/stable_test.go b/e2etests/stable_test.go
index dbd033d98..3aafba44d 100644
--- a/e2etests/stable_test.go
+++ b/e2etests/stable_test.go
@@ -677,6 +677,41 @@ x -> hey -> y`,
 			  c -- a: {style.stroke-width: 7}
 			  Oval <-> c`,
 		},
+		{
+			name: "md_code_inline",
+			script: `md: |md
+` + "`code`" + `
+|
+a -> md -> b
+`,
+		},
+		{
+			name: "md_code_block_fenced",
+			script: `md: |md
+` + "```" + `
+{
+	fenced: "block",
+	of: "json",
+}
+` + "```" + `
+|
+a -> md -> b
+`,
+		},
+		{
+			name: "md_code_block_indented",
+			script: `md: |md
+a line of text and an
+
+	{
+		indented: "block",
+		of: "json",
+	}
+
+|
+a -> md -> b
+`,
+		},
 	}
 
 	runa(t, tcs)
diff --git a/e2etests/testdata/stable/chaos2/board.exp.json b/e2etests/testdata/stable/chaos2/board.exp.json
index 9ed5f3b60..8caeb8bd9 100644
--- a/e2etests/testdata/stable/chaos2/board.exp.json
+++ b/e2etests/testdata/stable/chaos2/board.exp.json
@@ -8,8 +8,8 @@
         "x": 0,
         "y": 0
       },
-      "width": 1123,
-      "height": 1659,
+      "width": 1117,
+      "height": 1654,
       "level": 1,
       "opacity": 1,
       "strokeDash": 0,
@@ -46,8 +46,8 @@
         "x": 40,
         "y": 50
       },
-      "width": 779,
-      "height": 1559,
+      "width": 776,
+      "height": 1554,
       "level": 2,
       "opacity": 1,
       "strokeDash": 0,
@@ -84,8 +84,8 @@
         "x": 80,
         "y": 878
       },
-      "width": 513,
-      "height": 681,
+      "width": 510,
+      "height": 676,
       "level": 3,
       "opacity": 1,
       "strokeDash": 0,
@@ -122,7 +122,7 @@
         "x": 120,
         "y": 928
       },
-      "width": 357,
+      "width": 355,
       "height": 226,
       "level": 4,
       "opacity": 1,
@@ -157,11 +157,11 @@
       "id": "aa.bb.cc.dd.ee",
       "type": "text",
       "pos": {
-        "x": 230,
-        "y": 1027
+        "x": 232,
+        "y": 1029
       },
-      "width": 21,
-      "height": 29,
+      "width": 16,
+      "height": 24,
       "level": 5,
       "opacity": 1,
       "strokeDash": 0,
@@ -187,14 +187,14 @@
       "italic": false,
       "bold": true,
       "underline": false,
-      "labelWidth": 21,
-      "labelHeight": 29
+      "labelWidth": 16,
+      "labelHeight": 24
     },
     {
       "id": "aa.bb.cc.dd.ff",
       "type": "",
       "pos": {
-        "x": 311,
+        "x": 308,
         "y": 978
       },
       "width": 117,
@@ -232,11 +232,11 @@
       "id": "aa.bb.cc.gg",
       "type": "text",
       "pos": {
-        "x": 408,
+        "x": 409,
         "y": 1254
       },
-      "width": 22,
-      "height": 29,
+      "width": 17,
+      "height": 24,
       "level": 4,
       "opacity": 1,
       "strokeDash": 0,
@@ -262,15 +262,15 @@
       "italic": false,
       "bold": true,
       "underline": false,
-      "labelWidth": 22,
-      "labelHeight": 29
+      "labelWidth": 17,
+      "labelHeight": 24
     },
     {
       "id": "aa.bb.cc.hh",
       "type": "",
       "pos": {
-        "x": 357,
-        "y": 1383
+        "x": 356,
+        "y": 1378
       },
       "width": 123,
       "height": 126,
@@ -383,8 +383,8 @@
       "id": "aa.bb.kk",
       "type": "oval",
       "pos": {
-        "x": 643,
-        "y": 1383
+        "x": 641,
+        "y": 1378
       },
       "width": 126,
       "height": 126,
@@ -421,7 +421,7 @@
       "id": "aa.ll",
       "type": "",
       "pos": {
-        "x": 919,
+        "x": 915,
         "y": 652
       },
       "width": 114,
@@ -459,7 +459,7 @@
       "id": "aa.mm",
       "type": "cylinder",
       "pos": {
-        "x": 906,
+        "x": 902,
         "y": 426
       },
       "width": 131,
@@ -497,11 +497,11 @@
       "id": "aa.nn",
       "type": "text",
       "pos": {
-        "x": 869,
-        "y": 1432
+        "x": 867,
+        "y": 1429
       },
-      "width": 21,
-      "height": 29,
+      "width": 18,
+      "height": 24,
       "level": 2,
       "opacity": 1,
       "strokeDash": 0,
@@ -527,15 +527,15 @@
       "italic": false,
       "bold": true,
       "underline": false,
-      "labelWidth": 21,
-      "labelHeight": 29
+      "labelWidth": 18,
+      "labelHeight": 24
     },
     {
       "id": "aa.oo",
       "type": "",
       "pos": {
-        "x": 950,
-        "y": 1383
+        "x": 945,
+        "y": 1378
       },
       "width": 123,
       "height": 126,
@@ -597,19 +597,19 @@
       "route": [
         {
           "x": 240,
-          "y": 1055.5
+          "y": 1053
         },
         {
           "x": 240,
-          "y": 1134.3
+          "y": 1133.8
         },
         {
-          "x": 273.55,
-          "y": 1216.1061538461538
+          "x": 273.8,
+          "y": 1215.8
         },
         {
-          "x": 407.75,
-          "y": 1264.5307692307692
+          "x": 409,
+          "y": 1263
         }
       ],
       "isCurve": true,
@@ -643,20 +643,20 @@
       "labelPercentage": 0,
       "route": [
         {
-          "x": 418.75,
-          "y": 1283
+          "x": 417.5,
+          "y": 1278
         },
         {
-          "x": 418.75,
-          "y": 1323
+          "x": 417.5,
+          "y": 1318
         },
         {
-          "x": 418.75,
-          "y": 1343
+          "x": 417.5,
+          "y": 1338
         },
         {
-          "x": 418.75,
-          "y": 1383
+          "x": 417.5,
+          "y": 1378
         }
       ],
       "isCurve": true,
@@ -785,20 +785,20 @@
       "labelPercentage": 0,
       "route": [
         {
-          "x": 918.5,
-          "y": 723.757307953773
+          "x": 914.5,
+          "y": 723.8051948051948
         },
         {
-          "x": 839.3,
-          "y": 735.757307953773
+          "x": 836.1,
+          "y": 735.8051948051948
         },
         {
-          "x": 898.7,
-          "y": 726.757307953773
+          "x": 894.9,
+          "y": 726.8051948051948
         },
         {
-          "x": 819.5,
-          "y": 738.757307953773
+          "x": 816.5,
+          "y": 738.8051948051948
         }
       ],
       "isCurve": true,
@@ -832,11 +832,11 @@
       "labelPercentage": 0,
       "route": [
         {
-          "x": 906,
+          "x": 902,
           "y": 500
         },
         {
-          "x": 405.2,
+          "x": 404.4,
           "y": 581.6
         },
         {
@@ -891,19 +891,19 @@
       "labelPercentage": 0,
       "route": [
         {
-          "x": 974,
+          "x": 970,
           "y": 552
         },
         {
-          "x": 975.2,
+          "x": 971.2,
           "y": 592
         },
         {
-          "x": 975.5,
+          "x": 971.5,
           "y": 612
         },
         {
-          "x": 975.5,
+          "x": 971.5,
           "y": 652
         }
       ],
@@ -938,20 +938,20 @@
       "labelPercentage": 0,
       "route": [
         {
-          "x": 906,
+          "x": 902,
           "y": 500
         },
         {
-          "x": 836.2,
-          "y": 512.2920537428023
+          "x": 833.8,
+          "y": 512.3482425646968
         },
         {
-          "x": 888.55,
-          "y": 503.07301343570055
+          "x": 884.95,
+          "y": 503.08706064117416
         },
         {
-          "x": 818.75,
-          "y": 515.3650671785028
+          "x": 816.75,
+          "y": 515.4353032058709
         }
       ],
       "isCurve": true,
@@ -985,67 +985,67 @@
       "labelPercentage": 0,
       "route": [
         {
-          "x": 918.5,
-          "y": 729.0633187772926
+          "x": 914.5,
+          "y": 729.1095290251917
         },
         {
-          "x": 597.7,
-          "y": 808.2126637554585
+          "x": 594.9,
+          "y": 808.2219058050383
         },
         {
-          "x": 517.5,
+          "x": 515,
           "y": 838
         },
         {
-          "x": 517.5,
+          "x": 515,
           "y": 853
         },
         {
-          "x": 517.5,
+          "x": 515,
           "y": 868
         },
         {
-          "x": 517.5,
+          "x": 515,
           "y": 888
         },
         {
-          "x": 517.5,
+          "x": 515,
           "y": 903
         },
         {
-          "x": 517.5,
+          "x": 515,
           "y": 918
         },
         {
-          "x": 517.5,
+          "x": 515,
           "y": 950.6
         },
         {
-          "x": 517.5,
+          "x": 515,
           "y": 984.5
         },
         {
-          "x": 517.5,
+          "x": 515,
           "y": 1018.4
         },
         {
-          "x": 517.5,
+          "x": 515,
           "y": 1063.6
         },
         {
-          "x": 517.5,
+          "x": 515,
           "y": 1097.5
         },
         {
-          "x": 517.5,
+          "x": 515,
           "y": 1131.4
         },
         {
-          "x": 499.9,
+          "x": 497.2,
           "y": 1215.4
         },
         {
-          "x": 429.5,
+          "x": 426,
           "y": 1261
         }
       ],
@@ -1080,11 +1080,11 @@
       "labelPercentage": 0,
       "route": [
         {
-          "x": 906,
+          "x": 902,
           "y": 476
         },
         {
-          "x": 501.2,
+          "x": 500.4,
           "y": 396
         },
         {
@@ -1127,20 +1127,20 @@
       "labelPercentage": 0,
       "route": [
         {
-          "x": 378.75,
+          "x": 377.5,
           "y": 878
         },
         {
-          "x": 378.75,
+          "x": 377.5,
           "y": 838
         },
         {
-          "x": 486.7,
-          "y": 807.5586929199833
+          "x": 484.9,
+          "y": 807.5686868686869
         },
         {
-          "x": 918.5,
-          "y": 725.7934645999162
+          "x": 914.5,
+          "y": 725.8434343434343
         }
       ],
       "isCurve": true,
@@ -1194,12 +1194,12 @@
           "y": 466.4
         },
         {
-          "x": 471.7,
-          "y": 622.5070674248578
+          "x": 470.9,
+          "y": 622.493376941946
         },
         {
-          "x": 918.5,
-          "y": 704.5353371242892
+          "x": 914.5,
+          "y": 704.4668847097302
         }
       ],
       "isCurve": true,
diff --git a/e2etests/testdata/stable/chaos2/sketch.exp.svg b/e2etests/testdata/stable/chaos2/sketch.exp.svg
index 5463dd7bf..2eed01a57 100644
--- a/e2etests/testdata/stable/chaos2/sketch.exp.svg
+++ b/e2etests/testdata/stable/chaos2/sketch.exp.svg
@@ -2,7 +2,7 @@
 
\ No newline at end of file
diff --git a/e2etests/testdata/stable/hr/board.exp.json b/e2etests/testdata/stable/hr/board.exp.json
index 4c71d5bdb..59e823a02 100644
--- a/e2etests/testdata/stable/hr/board.exp.json
+++ b/e2etests/testdata/stable/hr/board.exp.json
@@ -9,7 +9,7 @@
         "y": 226
       },
       "width": 738,
-      "height": 119,
+      "height": 134,
       "level": 1,
       "opacity": 1,
       "strokeDash": 0,
@@ -36,7 +36,7 @@
       "bold": true,
       "underline": false,
       "labelWidth": 738,
-      "labelHeight": 119
+      "labelHeight": 134
     },
     {
       "id": "a",
@@ -81,7 +81,7 @@
       "type": "",
       "pos": {
         "x": 313,
-        "y": 445
+        "y": 460
       },
       "width": 113,
       "height": 126,
@@ -190,19 +190,19 @@
       "route": [
         {
           "x": 369,
-          "y": 345
+          "y": 360
         },
         {
           "x": 369,
-          "y": 385
+          "y": 400
         },
         {
           "x": 369,
-          "y": 405
+          "y": 420
         },
         {
           "x": 369,
-          "y": 445
+          "y": 460
         }
       ],
       "isCurve": true,
diff --git a/e2etests/testdata/stable/hr/sketch.exp.svg b/e2etests/testdata/stable/hr/sketch.exp.svg
index 8de93a80b..8092ccc57 100644
--- a/e2etests/testdata/stable/hr/sketch.exp.svg
+++ b/e2etests/testdata/stable/hr/sketch.exp.svg
@@ -2,7 +2,7 @@
 
\ No newline at end of file
diff --git a/e2etests/testdata/stable/lone_h1/board.exp.json b/e2etests/testdata/stable/lone_h1/board.exp.json
index 77f5683d2..7c99b7389 100644
--- a/e2etests/testdata/stable/lone_h1/board.exp.json
+++ b/e2etests/testdata/stable/lone_h1/board.exp.json
@@ -8,8 +8,8 @@
         "x": 0,
         "y": 226
       },
-      "width": 268,
-      "height": 55,
+      "width": 266,
+      "height": 50,
       "level": 1,
       "opacity": 1,
       "strokeDash": 0,
@@ -35,14 +35,14 @@
       "italic": false,
       "bold": true,
       "underline": false,
-      "labelWidth": 268,
-      "labelHeight": 55
+      "labelWidth": 266,
+      "labelHeight": 50
     },
     {
       "id": "a",
       "type": "",
       "pos": {
-        "x": 78,
+        "x": 77,
         "y": 0
       },
       "width": 113,
@@ -80,8 +80,8 @@
       "id": "b",
       "type": "",
       "pos": {
-        "x": 78,
-        "y": 381
+        "x": 77,
+        "y": 376
       },
       "width": 113,
       "height": 126,
@@ -142,19 +142,19 @@
       "labelPercentage": 0,
       "route": [
         {
-          "x": 134,
+          "x": 133,
           "y": 126
         },
         {
-          "x": 134,
+          "x": 133,
           "y": 166
         },
         {
-          "x": 134,
+          "x": 133,
           "y": 186
         },
         {
-          "x": 134,
+          "x": 133,
           "y": 226
         }
       ],
@@ -189,20 +189,20 @@
       "labelPercentage": 0,
       "route": [
         {
-          "x": 134,
-          "y": 281
+          "x": 133,
+          "y": 276
         },
         {
-          "x": 134,
-          "y": 321
+          "x": 133,
+          "y": 316
         },
         {
-          "x": 134,
-          "y": 341
+          "x": 133,
+          "y": 336
         },
         {
-          "x": 134,
-          "y": 381
+          "x": 133,
+          "y": 376
         }
       ],
       "isCurve": true,
diff --git a/e2etests/testdata/stable/lone_h1/sketch.exp.svg b/e2etests/testdata/stable/lone_h1/sketch.exp.svg
index c556e6605..e65a6f6ed 100644
--- a/e2etests/testdata/stable/lone_h1/sketch.exp.svg
+++ b/e2etests/testdata/stable/lone_h1/sketch.exp.svg
@@ -2,7 +2,7 @@
 
\ No newline at end of file
diff --git a/e2etests/testdata/stable/md_code_block_indented/board.exp.json b/e2etests/testdata/stable/md_code_block_indented/board.exp.json
new file mode 100644
index 000000000..b3d0d09ea
--- /dev/null
+++ b/e2etests/testdata/stable/md_code_block_indented/board.exp.json
@@ -0,0 +1,214 @@
+{
+  "name": "",
+  "shapes": [
+    {
+      "id": "md",
+      "type": "text",
+      "pos": {
+        "x": 0,
+        "y": 226
+      },
+      "width": 212,
+      "height": 151,
+      "level": 1,
+      "opacity": 1,
+      "strokeDash": 0,
+      "strokeWidth": 2,
+      "borderRadius": 0,
+      "fill": "#FFFFFF",
+      "stroke": "#0D32B2",
+      "shadow": false,
+      "3d": false,
+      "multiple": false,
+      "tooltip": "",
+      "link": "",
+      "icon": null,
+      "iconPosition": "",
+      "fields": null,
+      "methods": null,
+      "columns": null,
+      "label": "a line of text and an\n\n\t{\n\t\tindented: \"block\",\n\t\tof: \"json\",\n\t}\n",
+      "fontSize": 16,
+      "fontFamily": "DEFAULT",
+      "language": "markdown",
+      "color": "#0A0F25",
+      "italic": false,
+      "bold": true,
+      "underline": false,
+      "labelWidth": 212,
+      "labelHeight": 151
+    },
+    {
+      "id": "a",
+      "type": "",
+      "pos": {
+        "x": 50,
+        "y": 0
+      },
+      "width": 113,
+      "height": 126,
+      "level": 1,
+      "opacity": 1,
+      "strokeDash": 0,
+      "strokeWidth": 2,
+      "borderRadius": 0,
+      "fill": "#F7F8FE",
+      "stroke": "#0D32B2",
+      "shadow": false,
+      "3d": false,
+      "multiple": false,
+      "tooltip": "",
+      "link": "",
+      "icon": null,
+      "iconPosition": "",
+      "fields": null,
+      "methods": null,
+      "columns": null,
+      "label": "a",
+      "fontSize": 16,
+      "fontFamily": "DEFAULT",
+      "language": "",
+      "color": "#0A0F25",
+      "italic": false,
+      "bold": true,
+      "underline": false,
+      "labelWidth": 13,
+      "labelHeight": 26,
+      "labelPosition": "INSIDE_MIDDLE_CENTER"
+    },
+    {
+      "id": "b",
+      "type": "",
+      "pos": {
+        "x": 50,
+        "y": 477
+      },
+      "width": 113,
+      "height": 126,
+      "level": 1,
+      "opacity": 1,
+      "strokeDash": 0,
+      "strokeWidth": 2,
+      "borderRadius": 0,
+      "fill": "#F7F8FE",
+      "stroke": "#0D32B2",
+      "shadow": false,
+      "3d": false,
+      "multiple": false,
+      "tooltip": "",
+      "link": "",
+      "icon": null,
+      "iconPosition": "",
+      "fields": null,
+      "methods": null,
+      "columns": null,
+      "label": "b",
+      "fontSize": 16,
+      "fontFamily": "DEFAULT",
+      "language": "",
+      "color": "#0A0F25",
+      "italic": false,
+      "bold": true,
+      "underline": false,
+      "labelWidth": 13,
+      "labelHeight": 26,
+      "labelPosition": "INSIDE_MIDDLE_CENTER"
+    }
+  ],
+  "connections": [
+    {
+      "id": "(a -> md)[0]",
+      "src": "a",
+      "srcArrow": "none",
+      "srcLabel": "",
+      "dst": "md",
+      "dstArrow": "triangle",
+      "dstLabel": "",
+      "opacity": 1,
+      "strokeDash": 0,
+      "strokeWidth": 2,
+      "stroke": "#0D32B2",
+      "label": "",
+      "fontSize": 16,
+      "fontFamily": "DEFAULT",
+      "language": "",
+      "color": "#676C7E",
+      "italic": true,
+      "bold": false,
+      "underline": false,
+      "labelWidth": 0,
+      "labelHeight": 0,
+      "labelPosition": "",
+      "labelPercentage": 0,
+      "route": [
+        {
+          "x": 106,
+          "y": 126
+        },
+        {
+          "x": 106,
+          "y": 166
+        },
+        {
+          "x": 106,
+          "y": 186
+        },
+        {
+          "x": 106,
+          "y": 226
+        }
+      ],
+      "isCurve": true,
+      "animated": false,
+      "tooltip": "",
+      "icon": null
+    },
+    {
+      "id": "(md -> b)[0]",
+      "src": "md",
+      "srcArrow": "none",
+      "srcLabel": "",
+      "dst": "b",
+      "dstArrow": "triangle",
+      "dstLabel": "",
+      "opacity": 1,
+      "strokeDash": 0,
+      "strokeWidth": 2,
+      "stroke": "#0D32B2",
+      "label": "",
+      "fontSize": 16,
+      "fontFamily": "DEFAULT",
+      "language": "",
+      "color": "#676C7E",
+      "italic": true,
+      "bold": false,
+      "underline": false,
+      "labelWidth": 0,
+      "labelHeight": 0,
+      "labelPosition": "",
+      "labelPercentage": 0,
+      "route": [
+        {
+          "x": 106,
+          "y": 377
+        },
+        {
+          "x": 106,
+          "y": 417
+        },
+        {
+          "x": 106,
+          "y": 437
+        },
+        {
+          "x": 106,
+          "y": 477
+        }
+      ],
+      "isCurve": true,
+      "animated": false,
+      "tooltip": "",
+      "icon": null
+    }
+  ]
+}
diff --git a/e2etests/testdata/stable/md_code_block_indented/sketch.exp.svg b/e2etests/testdata/stable/md_code_block_indented/sketch.exp.svg
new file mode 100644
index 000000000..d274e7b3b
--- /dev/null
+++ b/e2etests/testdata/stable/md_code_block_indented/sketch.exp.svg
@@ -0,0 +1,818 @@
+
+

a line of text and an

+
{
+	indented: "block",
+	of: "json",
+}
+
+
ab
\ No newline at end of file diff --git a/e2etests/testdata/stable/md_code_inline/board.exp.json b/e2etests/testdata/stable/md_code_inline/board.exp.json new file mode 100644 index 000000000..903f3b439 --- /dev/null +++ b/e2etests/testdata/stable/md_code_inline/board.exp.json @@ -0,0 +1,214 @@ +{ + "name": "", + "shapes": [ + { + "id": "md", + "type": "text", + "pos": { + "x": 34, + "y": 226 + }, + "width": 46, + "height": 24, + "level": 1, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#FFFFFF", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "fields": null, + "methods": null, + "columns": null, + "label": "`code`", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "markdown", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 46, + "labelHeight": 24 + }, + { + "id": "a", + "type": "", + "pos": { + "x": 0, + "y": 0 + }, + "width": 113, + "height": 126, + "level": 1, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "fields": null, + "methods": null, + "columns": null, + "label": "a", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 13, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER" + }, + { + "id": "b", + "type": "", + "pos": { + "x": 0, + "y": 350 + }, + "width": 113, + "height": 126, + "level": 1, + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "borderRadius": 0, + "fill": "#F7F8FE", + "stroke": "#0D32B2", + "shadow": false, + "3d": false, + "multiple": false, + "tooltip": "", + "link": "", + "icon": null, + "iconPosition": "", + "fields": null, + "methods": null, + "columns": null, + "label": "b", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#0A0F25", + "italic": false, + "bold": true, + "underline": false, + "labelWidth": 13, + "labelHeight": 26, + "labelPosition": "INSIDE_MIDDLE_CENTER" + } + ], + "connections": [ + { + "id": "(a -> md)[0]", + "src": "a", + "srcArrow": "none", + "srcLabel": "", + "dst": "md", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 56.5, + "y": 126 + }, + { + "x": 56.5, + "y": 166 + }, + { + "x": 56.5, + "y": 186 + }, + { + "x": 56.5, + "y": 226 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null + }, + { + "id": "(md -> b)[0]", + "src": "md", + "srcArrow": "none", + "srcLabel": "", + "dst": "b", + "dstArrow": "triangle", + "dstLabel": "", + "opacity": 1, + "strokeDash": 0, + "strokeWidth": 2, + "stroke": "#0D32B2", + "label": "", + "fontSize": 16, + "fontFamily": "DEFAULT", + "language": "", + "color": "#676C7E", + "italic": true, + "bold": false, + "underline": false, + "labelWidth": 0, + "labelHeight": 0, + "labelPosition": "", + "labelPercentage": 0, + "route": [ + { + "x": 56.5, + "y": 250 + }, + { + "x": 56.5, + "y": 290 + }, + { + "x": 56.5, + "y": 310 + }, + { + "x": 56.5, + "y": 350 + } + ], + "isCurve": true, + "animated": false, + "tooltip": "", + "icon": null + } + ] +} diff --git a/e2etests/testdata/stable/md_code_inline/sketch.exp.svg b/e2etests/testdata/stable/md_code_inline/sketch.exp.svg new file mode 100644 index 000000000..7ddde7814 --- /dev/null +++ b/e2etests/testdata/stable/md_code_inline/sketch.exp.svg @@ -0,0 +1,813 @@ + +

code

+
ab
\ No newline at end of file diff --git a/e2etests/testdata/stable/p/board.exp.json b/e2etests/testdata/stable/p/board.exp.json index c652c90fa..e7bf9c0a9 100644 --- a/e2etests/testdata/stable/p/board.exp.json +++ b/e2etests/testdata/stable/p/board.exp.json @@ -8,8 +8,8 @@ "x": 0, "y": 226 }, - "width": 1861, - "height": 29, + "width": 1857, + "height": 24, "level": 1, "opacity": 1, "strokeDash": 0, @@ -35,14 +35,14 @@ "italic": false, "bold": true, "underline": false, - "labelWidth": 1861, - "labelHeight": 29 + "labelWidth": 1857, + "labelHeight": 24 }, { "id": "a", "type": "", "pos": { - "x": 874, + "x": 872, "y": 0 }, "width": 113, @@ -80,8 +80,8 @@ "id": "b", "type": "", "pos": { - "x": 874, - "y": 355 + "x": 872, + "y": 350 }, "width": 113, "height": 126, @@ -142,19 +142,19 @@ "labelPercentage": 0, "route": [ { - "x": 930.5, + "x": 928.5, "y": 126 }, { - "x": 930.5, + "x": 928.5, "y": 166 }, { - "x": 930.5, + "x": 928.5, "y": 186 }, { - "x": 930.5, + "x": 928.5, "y": 226 } ], @@ -189,20 +189,20 @@ "labelPercentage": 0, "route": [ { - "x": 930.5, - "y": 255 + "x": 928.5, + "y": 250 }, { - "x": 930.5, - "y": 295 + "x": 928.5, + "y": 290 }, { - "x": 930.5, - "y": 315 + "x": 928.5, + "y": 310 }, { - "x": 930.5, - "y": 355 + "x": 928.5, + "y": 350 } ], "isCurve": true, diff --git a/e2etests/testdata/stable/p/sketch.exp.svg b/e2etests/testdata/stable/p/sketch.exp.svg index 87bcaf7a2..d28ab538f 100644 --- a/e2etests/testdata/stable/p/sketch.exp.svg +++ b/e2etests/testdata/stable/p/sketch.exp.svg @@ -2,7 +2,7 @@ \ No newline at end of file diff --git a/e2etests/todo_test.go b/e2etests/todo_test.go index 8a6adebab..3459d052a 100644 --- a/e2etests/todo_test.go +++ b/e2etests/todo_test.go @@ -6,19 +6,7 @@ import ( ) func testTodo(t *testing.T) { - tcs := []testCase{ - // https://github.com/terrastruct/d2/issues/24 - // string monstrosity from not being able to escape backticks within string literals - { - skip: true, - name: "backtick", - script: `md: |md - ` + "`" + "code`" + ` -| -a -> md -> b -`, - }, - } + tcs := []testCase{} runa(t, tcs) }