diff --git a/d2layouts/d2dagrelayout/layout.go b/d2layouts/d2dagrelayout/layout.go index def678ee0..e1d29175e 100644 --- a/d2layouts/d2dagrelayout/layout.go +++ b/d2layouts/d2dagrelayout/layout.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "math" + "regexp" "strings" "cdr.dev/slog" @@ -257,7 +258,11 @@ func setGraphAttrs(attrs dagreGraphAttrs) string { } func escapeID(id string) string { - id = strings.ReplaceAll(id, `\n`, `\\n`) + // fixes \\ + id = strings.ReplaceAll(id, "\\", `\\`) + // replaces \n with \\n whenever \n is not preceded by \ (does not replace \\n) + re := regexp.MustCompile(`[^\\](\n)`) + id = re.ReplaceAllString(id, `\\n`) // avoid an unescaped \r becoming a \n in the layout result id = strings.ReplaceAll(id, "\r", `\r`) return id diff --git a/e2etests/regression_test.go b/e2etests/regression_test.go index 8170bc359..373ee5acd 100644 --- a/e2etests/regression_test.go +++ b/e2etests/regression_test.go @@ -7,11 +7,14 @@ import ( func testRegression(t *testing.T) { tcs := []testCase{ { - name: "dagre_id_with_newline", + name: "dagre_special_ids", script: ` ninety\nnine eighty\reight seventy\r\nseven +a\\yode -> there +a\\"ode -> there +a\\node -> there `, }, {