Merge pull request #2219 from alixander/markdown-comment
markdown: sanitize links
This commit is contained in:
commit
fed65bcb51
5 changed files with 153 additions and 1 deletions
|
|
@ -9,3 +9,4 @@
|
||||||
#### Bugfixes ⛑️
|
#### Bugfixes ⛑️
|
||||||
|
|
||||||
- Imports: fixes using substitutions in `icon` values [#2207](https://github.com/terrastruct/d2/pull/2207)
|
- 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",
|
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 {
|
if err := markdownRenderer.Convert([]byte(m), &output); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return output.String(), nil
|
sanitized, err := sanitizeLinks(output.String())
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return sanitized, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
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