markdown code tabsize and measurement accuracy
This commit is contained in:
parent
c83a55f26b
commit
bffb018651
12 changed files with 158 additions and 124 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
}
|
||||
|
||||
.md {
|
||||
tab-size: 8;
|
||||
tab-size: 4;
|
||||
}
|
||||
|
||||
/* based on https://github.com/sindresorhus/github-markdown-css */
|
||||
|
|
|
|||
|
|
@ -205,17 +205,17 @@ func (ruler *Ruler) measureNode(depth int, n *html.Node, font d2fonts.Font) (wid
|
|||
spaceRune, _ := utf8.DecodeRuneInString(" ")
|
||||
// measure will not include leading or trailing whitespace, so we have to add in the space width
|
||||
spaceWidth := ruler.atlases[font].glyph(spaceRune).advance
|
||||
tabWidth := 8 * spaceWidth
|
||||
tabWidth := TAB_SIZE * spaceWidth
|
||||
|
||||
str := n.Data
|
||||
|
||||
htmlWhitespace := true
|
||||
isCode := false
|
||||
switch parentElementType {
|
||||
case "pre", "code":
|
||||
htmlWhitespace = false
|
||||
isCode = true
|
||||
}
|
||||
|
||||
if htmlWhitespace {
|
||||
if !isCode {
|
||||
str = strings.ReplaceAll(str, "\n", " ")
|
||||
str = strings.ReplaceAll(str, "\t", " ")
|
||||
if strings.HasPrefix(str, " ") {
|
||||
|
|
@ -258,7 +258,13 @@ func (ruler *Ruler) measureNode(depth int, n *html.Node, font d2fonts.Font) (wid
|
|||
}
|
||||
}
|
||||
|
||||
if isCode {
|
||||
ruler.boundsWithDot = true
|
||||
}
|
||||
w, h := ruler.MeasurePrecise(font, str)
|
||||
if isCode {
|
||||
ruler.boundsWithDot = false
|
||||
}
|
||||
// fmt.Printf("%d:'%s' width %v (%v) height %v fontStyle %s fontSize %v family %v\n", depth, n.Data, w, w+spaceWidths, h, font.Style, font.Size, font.Family)
|
||||
|
||||
return w + spaceWidths, h, 0, 0
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,6 +95,12 @@ _italics are all measured correctly_
|
|||
`
|
||||
**Note:**
|
||||
`: {37, 24},
|
||||
`a`: {7, 24},
|
||||
`w`: {12, 24},
|
||||
`ww`: {24, 24},
|
||||
"`inline code`": {119, 27},
|
||||
"`code`": {52, 27},
|
||||
"`a`": {23, 27},
|
||||
}
|
||||
|
||||
func TestTextMeasureMarkdown(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
"x": 0,
|
||||
"y": 226
|
||||
},
|
||||
"width": 157,
|
||||
"height": 130,
|
||||
"width": 224,
|
||||
"height": 125,
|
||||
"level": 1,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
|
|
@ -35,14 +35,14 @@
|
|||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 157,
|
||||
"labelHeight": 130
|
||||
"labelWidth": 224,
|
||||
"labelHeight": 125
|
||||
},
|
||||
{
|
||||
"id": "a",
|
||||
"type": "",
|
||||
"pos": {
|
||||
"x": 22,
|
||||
"x": 56,
|
||||
"y": 0
|
||||
},
|
||||
"width": 113,
|
||||
|
|
@ -80,8 +80,8 @@
|
|||
"id": "b",
|
||||
"type": "",
|
||||
"pos": {
|
||||
"x": 22,
|
||||
"y": 456
|
||||
"x": 56,
|
||||
"y": 451
|
||||
},
|
||||
"width": 113,
|
||||
"height": 126,
|
||||
|
|
@ -142,19 +142,19 @@
|
|||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 78.5,
|
||||
"x": 112,
|
||||
"y": 126
|
||||
},
|
||||
{
|
||||
"x": 78.5,
|
||||
"x": 112,
|
||||
"y": 166
|
||||
},
|
||||
{
|
||||
"x": 78.5,
|
||||
"x": 112,
|
||||
"y": 186
|
||||
},
|
||||
{
|
||||
"x": 78.5,
|
||||
"x": 112,
|
||||
"y": 226
|
||||
}
|
||||
],
|
||||
|
|
@ -189,20 +189,20 @@
|
|||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 78.5,
|
||||
"y": 356
|
||||
"x": 112,
|
||||
"y": 351
|
||||
},
|
||||
{
|
||||
"x": 78.5,
|
||||
"y": 396
|
||||
"x": 112,
|
||||
"y": 391
|
||||
},
|
||||
{
|
||||
"x": 78.5,
|
||||
"y": 416
|
||||
"x": 112,
|
||||
"y": 411
|
||||
},
|
||||
{
|
||||
"x": 78.5,
|
||||
"y": 456
|
||||
"x": 112,
|
||||
"y": 451
|
||||
}
|
||||
],
|
||||
"isCurve": true,
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 660 KiB After Width: | Height: | Size: 841 KiB |
|
|
@ -8,8 +8,8 @@
|
|||
"x": 0,
|
||||
"y": 226
|
||||
},
|
||||
"width": 213,
|
||||
"height": 29,
|
||||
"width": 208,
|
||||
"height": 24,
|
||||
"level": 1,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
|
|
@ -35,14 +35,14 @@
|
|||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 213,
|
||||
"labelHeight": 29
|
||||
"labelWidth": 208,
|
||||
"labelHeight": 24
|
||||
},
|
||||
{
|
||||
"id": "a",
|
||||
"type": "",
|
||||
"pos": {
|
||||
"x": 50,
|
||||
"x": 48,
|
||||
"y": 0
|
||||
},
|
||||
"width": 113,
|
||||
|
|
@ -80,8 +80,8 @@
|
|||
"id": "b",
|
||||
"type": "",
|
||||
"pos": {
|
||||
"x": 50,
|
||||
"y": 355
|
||||
"x": 48,
|
||||
"y": 350
|
||||
},
|
||||
"width": 113,
|
||||
"height": 126,
|
||||
|
|
@ -142,19 +142,19 @@
|
|||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 106.5,
|
||||
"x": 104,
|
||||
"y": 126
|
||||
},
|
||||
{
|
||||
"x": 106.5,
|
||||
"x": 104,
|
||||
"y": 166
|
||||
},
|
||||
{
|
||||
"x": 106.5,
|
||||
"x": 104,
|
||||
"y": 186
|
||||
},
|
||||
{
|
||||
"x": 106.5,
|
||||
"x": 104,
|
||||
"y": 226
|
||||
}
|
||||
],
|
||||
|
|
@ -189,20 +189,20 @@
|
|||
"labelPercentage": 0,
|
||||
"route": [
|
||||
{
|
||||
"x": 106.5,
|
||||
"y": 255
|
||||
"x": 104,
|
||||
"y": 250
|
||||
},
|
||||
{
|
||||
"x": 106.5,
|
||||
"y": 295
|
||||
"x": 104,
|
||||
"y": 290
|
||||
},
|
||||
{
|
||||
"x": 106.5,
|
||||
"y": 315
|
||||
"x": 104,
|
||||
"y": 310
|
||||
},
|
||||
{
|
||||
"x": 106.5,
|
||||
"y": 355
|
||||
"x": 104,
|
||||
"y": 350
|
||||
}
|
||||
],
|
||||
"isCurve": true,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<svg
|
||||
style="background: white;"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="413" height="681" viewBox="-100 -100 413 681"><style type="text/css">
|
||||
width="408" height="676" viewBox="-100 -100 408 676"><style type="text/css">
|
||||
<![CDATA[
|
||||
.shape {
|
||||
shape-rendering: geometricPrecision;
|
||||
|
|
@ -22,6 +22,18 @@ width="413" height="681" viewBox="-100 -100 413 681"><style type="text/css">
|
|||
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 {
|
||||
|
|
@ -145,14 +157,6 @@ width="413" height="681" viewBox="-100 -100 413 681"><style type="text/css">
|
|||
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;
|
||||
}
|
||||
|
|
@ -355,19 +359,15 @@ width="413" height="681" viewBox="-100 -100 413 681"><style type="text/css">
|
|||
margin-left: 0;
|
||||
}
|
||||
|
||||
.md tt,
|
||||
/* .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;
|
||||
/* font-size: 12px; */
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
|
|
@ -653,7 +653,7 @@ width="413" height="681" viewBox="-100 -100 413 681"><style type="text/css">
|
|||
.md tt {
|
||||
padding: 0.2em 0.4em;
|
||||
margin: 0;
|
||||
font-size: 85%;
|
||||
/* font-size: 85%; */
|
||||
background-color: var(--color-neutral-muted);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
|
@ -693,8 +693,8 @@ width="413" height="681" viewBox="-100 -100 413 681"><style type="text/css">
|
|||
.md pre {
|
||||
padding: 16px;
|
||||
overflow: auto;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
/* font-size: 85%;
|
||||
line-height: 1.45; */
|
||||
background-color: var(--color-canvas-subtle);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
|
@ -797,11 +797,11 @@ width="413" height="681" viewBox="-100 -100 413 681"><style type="text/css">
|
|||
.md .contains-task-list:dir(rtl) .task-list-item-checkbox {
|
||||
margin: 0 -1.6em 0.25em 0.2em;
|
||||
}
|
||||
</style><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="0.000000" y="226.000000" width="213" height="29"><div xmlns="http://www.w3.org/1999/xhtml" class="md"><p>{
|
||||
</style><g><foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" x="0.000000" y="226.000000" width="208" height="24"><div xmlns="http://www.w3.org/1999/xhtml" class="md"><p>{
|
||||
indented: "block",
|
||||
of: "json",
|
||||
}</p>
|
||||
</div></foreignObject></g><rect class="shape" x="50" y="0" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /><text class="text-bold" x="106.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:black">a</text><rect class="shape" x="50" y="355" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /><text class="text-bold" x="106.500000" y="421.000000" style="text-anchor:middle;font-size:16px;fill:black">b</text><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="8.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 106.500000 127.000000 C 106.500000 166.000000 106.500000 186.000000 106.500000 223.000000" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" /><path d="M 106.500000 256.000000 C 106.500000 295.000000 106.500000 315.000000 106.500000 352.000000" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" /><style type="text/css"><![CDATA[
|
||||
</div></foreignObject></g><rect class="shape" x="48" y="0" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /><text class="text-bold" x="104.500000" y="66.000000" style="text-anchor:middle;font-size:16px;fill:black">a</text><rect class="shape" x="48" y="350" width="113" height="126" style="fill:#F7F8FE;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" /><text class="text-bold" x="104.500000" y="416.000000" style="text-anchor:middle;font-size:16px;fill:black">b</text><marker id="mk-3990223579" markerWidth="10.000000" markerHeight="12.000000" refX="8.000000" refY="6.000000" viewBox="0.000000 0.000000 10.000000 12.000000" orient="auto" markerUnits="userSpaceOnUse"> <polygon class="connection" fill="#0D32B2" stroke-width="2" points="0.000000,0.000000 10.000000,6.000000 0.000000,12.000000" /> </marker><path d="M 104.000000 127.000000 C 104.000000 166.000000 104.000000 186.000000 104.000000 223.000000" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" /><path d="M 104.000000 251.000000 C 104.000000 290.000000 104.000000 310.000000 104.000000 347.000000" class="connection" style="fill:none;stroke:#0D32B2;opacity:1.000000;stroke-width:2;" marker-end="url(#mk-3990223579)" /><style type="text/css"><![CDATA[
|
||||
.text {
|
||||
font-family: "font-regular";
|
||||
}
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 660 KiB After Width: | Height: | Size: 660 KiB |
|
|
@ -5,11 +5,11 @@
|
|||
"id": "md",
|
||||
"type": "text",
|
||||
"pos": {
|
||||
"x": 38,
|
||||
"x": 31,
|
||||
"y": 226
|
||||
},
|
||||
"width": 38,
|
||||
"height": 29,
|
||||
"width": 52,
|
||||
"height": 27,
|
||||
"level": 1,
|
||||
"opacity": 1,
|
||||
"strokeDash": 0,
|
||||
|
|
@ -35,8 +35,8 @@
|
|||
"italic": false,
|
||||
"bold": true,
|
||||
"underline": false,
|
||||
"labelWidth": 38,
|
||||
"labelHeight": 29
|
||||
"labelWidth": 52,
|
||||
"labelHeight": 27
|
||||
},
|
||||
{
|
||||
"id": "a",
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
"type": "",
|
||||
"pos": {
|
||||
"x": 0,
|
||||
"y": 355
|
||||
"y": 353
|
||||
},
|
||||
"width": 113,
|
||||
"height": 126,
|
||||
|
|
@ -190,19 +190,19 @@
|
|||
"route": [
|
||||
{
|
||||
"x": 56.5,
|
||||
"y": 255
|
||||
"y": 253
|
||||
},
|
||||
{
|
||||
"x": 56.5,
|
||||
"y": 295
|
||||
"y": 293
|
||||
},
|
||||
{
|
||||
"x": 56.5,
|
||||
"y": 315
|
||||
"y": 313
|
||||
},
|
||||
{
|
||||
"x": 56.5,
|
||||
"y": 355
|
||||
"y": 353
|
||||
}
|
||||
],
|
||||
"isCurve": true,
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 660 KiB After Width: | Height: | Size: 841 KiB |
|
|
@ -10,7 +10,6 @@ func testTodo(t *testing.T) {
|
|||
// https://github.com/terrastruct/d2/issues/24
|
||||
// string monstrosity from not being able to escape backticks within string literals
|
||||
{
|
||||
skip: false,
|
||||
name: "md_code_inline",
|
||||
script: `md: |md
|
||||
` + "`code`" + `
|
||||
|
|
@ -19,7 +18,6 @@ a -> md -> b
|
|||
`,
|
||||
},
|
||||
{
|
||||
skip: false,
|
||||
name: "md_code_block_fenced",
|
||||
script: `md: |md
|
||||
` + "```" + `
|
||||
|
|
@ -33,7 +31,6 @@ a -> md -> b
|
|||
`,
|
||||
},
|
||||
{
|
||||
skip: false,
|
||||
name: "md_code_block_indented",
|
||||
script: `md: |md
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue