markdown: sanitize links
This commit is contained in:
parent
ad629356cb
commit
b4382a6793
5 changed files with 153 additions and 1 deletions
|
|
@ -9,3 +9,4 @@
|
|||
#### Bugfixes ⛑️
|
||||
|
||||
- Imports: fixes using substitutions in `icon` values [#2207](https://github.com/terrastruct/d2/pull/2207)
|
||||
- Markdown: fixes ampersands in URLs in markdown [#2219](https://github.com/terrastruct/d2/pull/2219)
|
||||
|
|
|
|||
|
|
@ -935,6 +935,13 @@ b.(x -> y)[0]: two
|
|||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "markdown_ampersand",
|
||||
text: `memo: |md
|
||||
<a href="https://www.google.com/search?q=d2&newwindow=1&bar">d2</a>
|
||||
|
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "unsemantic_markdown",
|
||||
|
||||
|
|
|
|||
26
lib/textmeasure/links.go
Normal file
26
lib/textmeasure/links.go
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
package textmeasure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func sanitizeLinks(input string) (string, error) {
|
||||
re := regexp.MustCompile(`href="([^"]*)"`)
|
||||
|
||||
return re.ReplaceAllStringFunc(input, func(href string) string {
|
||||
matches := re.FindStringSubmatch(href)
|
||||
if len(matches) < 2 {
|
||||
return href
|
||||
}
|
||||
|
||||
value := matches[1]
|
||||
|
||||
value = strings.ReplaceAll(value, "&", "TEMP_AMP")
|
||||
value = strings.ReplaceAll(value, "&", "&")
|
||||
value = strings.ReplaceAll(value, "TEMP_AMP", "&")
|
||||
|
||||
return fmt.Sprintf(`href="%s"`, value)
|
||||
}), nil
|
||||
}
|
||||
|
|
@ -83,7 +83,11 @@ func RenderMarkdown(m string) (string, error) {
|
|||
if err := markdownRenderer.Convert([]byte(m), &output); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return output.String(), nil
|
||||
sanitized, err := sanitizeLinks(output.String())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return sanitized, nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
|
|||
114
testdata/d2compiler/TestCompile/markdown_ampersand.exp.json
generated
vendored
Normal file
114
testdata/d2compiler/TestCompile/markdown_ampersand.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
{
|
||||
"graph": {
|
||||
"name": "",
|
||||
"isFolderOnly": false,
|
||||
"ast": {
|
||||
"range": "d2/testdata/d2compiler/TestCompile/markdown_ampersand.d2,0:0:0-3:0:86",
|
||||
"nodes": [
|
||||
{
|
||||
"map_key": {
|
||||
"range": "d2/testdata/d2compiler/TestCompile/markdown_ampersand.d2,0:0:0-2:1:85",
|
||||
"key": {
|
||||
"range": "d2/testdata/d2compiler/TestCompile/markdown_ampersand.d2,0:0:0-0:4:4",
|
||||
"path": [
|
||||
{
|
||||
"unquoted_string": {
|
||||
"range": "d2/testdata/d2compiler/TestCompile/markdown_ampersand.d2,0:0:0-0:4:4",
|
||||
"value": [
|
||||
{
|
||||
"string": "memo",
|
||||
"raw_string": "memo"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"primary": {},
|
||||
"value": {
|
||||
"block_string": {
|
||||
"range": "d2/testdata/d2compiler/TestCompile/markdown_ampersand.d2,0:6:6-2:1:85",
|
||||
"quote": "",
|
||||
"tag": "md",
|
||||
"value": "<a href=\"https://www.google.com/search?q=d2&newwindow=1&bar\">d2</a>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"root": {
|
||||
"id": "",
|
||||
"id_val": "",
|
||||
"attributes": {
|
||||
"label": {
|
||||
"value": ""
|
||||
},
|
||||
"labelDimensions": {
|
||||
"width": 0,
|
||||
"height": 0
|
||||
},
|
||||
"style": {},
|
||||
"near_key": null,
|
||||
"shape": {
|
||||
"value": ""
|
||||
},
|
||||
"direction": {
|
||||
"value": ""
|
||||
},
|
||||
"constraint": null
|
||||
},
|
||||
"zIndex": 0
|
||||
},
|
||||
"edges": null,
|
||||
"objects": [
|
||||
{
|
||||
"id": "memo",
|
||||
"id_val": "memo",
|
||||
"references": [
|
||||
{
|
||||
"key": {
|
||||
"range": "d2/testdata/d2compiler/TestCompile/markdown_ampersand.d2,0:0:0-0:4:4",
|
||||
"path": [
|
||||
{
|
||||
"unquoted_string": {
|
||||
"range": "d2/testdata/d2compiler/TestCompile/markdown_ampersand.d2,0:0:0-0:4:4",
|
||||
"value": [
|
||||
{
|
||||
"string": "memo",
|
||||
"raw_string": "memo"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"key_path_index": 0,
|
||||
"map_key_edge_index": -1
|
||||
}
|
||||
],
|
||||
"attributes": {
|
||||
"label": {
|
||||
"value": "<a href=\"https://www.google.com/search?q=d2&newwindow=1&bar\">d2</a>"
|
||||
},
|
||||
"labelDimensions": {
|
||||
"width": 0,
|
||||
"height": 0
|
||||
},
|
||||
"style": {},
|
||||
"near_key": null,
|
||||
"language": "markdown",
|
||||
"shape": {
|
||||
"value": "text"
|
||||
},
|
||||
"direction": {
|
||||
"value": ""
|
||||
},
|
||||
"constraint": null
|
||||
},
|
||||
"zIndex": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"err": null
|
||||
}
|
||||
Loading…
Reference in a new issue