summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclsr <clsr@clsr.net>2021-12-23 01:54:47 +0000
committerclsr <clsr@clsr.net>2021-12-23 02:51:49 +0000
commit43428e759d9fbc5a319c2b929bfb4469938cc386 (patch)
tree1ee452ff23249bf10653481599f8639aa46ceb25
parent690a7183d7eca35b59e23e556b0c6492df08ffa5 (diff)
downloadcnm-go-43428e759d9fbc5a319c2b929bfb4469938cc386.tar.gz
cnm-go-43428e759d9fbc5a319c2b929bfb4469938cc386.zip
Add EscapeAll and escape all spaces in linksHEADv0.4.2master
-rw-r--r--cnmfmt/cnmfmt.go2
-rw-r--r--cnmfmt/cnmfmt_test.go15
-rw-r--r--content.go2
-rw-r--r--document.go4
-rw-r--r--parse_test.go6
-rw-r--r--simpletext.go32
-rw-r--r--simpletext_test.go29
-rw-r--r--write_test.go11
8 files changed, 87 insertions, 14 deletions
diff --git a/cnmfmt/cnmfmt.go b/cnmfmt/cnmfmt.go
index 1e5b6ee..3e38978 100644
--- a/cnmfmt/cnmfmt.go
+++ b/cnmfmt/cnmfmt.go
@@ -195,7 +195,7 @@ func (t Text) WriteIndent(w io.Writer, n int) error {
if span.Text != "" {
pad = " "
}
- line = append(line, "@@", cnm.Escape(span.Format.Link), pad)
+ line = append(line, "@@", cnm.EscapeAll(span.Format.Link), pad)
}
}
}
diff --git a/cnmfmt/cnmfmt_test.go b/cnmfmt/cnmfmt_test.go
index 5d50b18..2ad92cb 100644
--- a/cnmfmt/cnmfmt_test.go
+++ b/cnmfmt/cnmfmt_test.go
@@ -127,6 +127,9 @@ var parseTests = map[string]Text{
"@@foo ": Text{[]Span{
Span{Format{Link: "foo"}, ""},
}},
+ "@@foo\\ bar baz quux@@": Text{[]Span{
+ Span{Format{Link: "foo bar"}, "baz quux"},
+ }},
"@@foo\\": Text{[]Span{
Span{Format{Link: "foo\\"}, ""},
}},
@@ -213,9 +216,9 @@ func textEqual(a, b Text) bool {
}
var escapeTests = map[string]string{
- "\n\r\t\v\x00": "\\n\\r\\t\v\\x00",
+ "\n\r\t\v\x00": "\\n\\r\\t\v\\x00",
"@@!!##\"\"//\"\"__``**%%^^&&++==\x01\x01\\": "\\@\\@!!##\\\"\\\"//\\\"\\\"\\_\\_\\`\\`\\*\\*%%^^&&++==\x01\x01\\\\",
- `foo\@\@bar`: `foo\\\@\\\@bar`,
+ `foo\@\@bar`: `foo\\\@\\\@bar`,
}
func TestEscape(t *testing.T) {
@@ -269,6 +272,10 @@ var parseTextTests = map[string]TextFmtContents{
Text{[]Span{Span{Format{Emphasized: true}, "foo"}}},
Text{[]Span{Span{Format{}, "bar"}}},
}},
+
+ "@@foo\\ bar baz quux@@": TextFmtContents{[]Text{
+ Text{[]Span{Span{Format{Link: "foo bar"}, "baz quux"}}},
+ }},
}
func TestParseTextFmt(t *testing.T) {
@@ -335,6 +342,10 @@ var writeTests = map[string]TextFmtContents{
}},
}},
+ "@@foo\\ bar baz quux\n": TextFmtContents{[]Text{
+ Text{[]Span{Span{Format{Link: "foo bar"}, "baz quux"}}},
+ }},
+
"foo**bar``baz**quux\n\n" +
"\\ \"\"qwe\\ \"\"__\\ asd \\ __``zxc``**\\ \n\n" +
"__@@http://example.com/__/ exa__mple@@ @@href text@@__ test\n": TextFmtContents{[]Text{
diff --git a/content.go b/content.go
index dbe0fa4..572305a 100644
--- a/content.go
+++ b/content.go
@@ -589,7 +589,7 @@ func (e *EmbedBlock) WriteIndent(w io.Writer, n int) error {
} else {
s += Escape(e.Type)
}
- s += " " + Escape(e.URL)
+ s += " " + EscapeAll(e.URL)
if err := WriteIndent(w, s, n); err != nil {
return err
}
diff --git a/document.go b/document.go
index 65eac3e..236782b 100644
--- a/document.go
+++ b/document.go
@@ -197,7 +197,7 @@ type Link struct {
// WriteIndent writes the link URL, name and description indented by n tabs.
func (link Link) WriteIndent(w io.Writer, n int) error {
- s := Escape(link.URL)
+ s := EscapeAll(link.URL)
if link.Name != "" {
s += " " + Escape(link.Name)
}
@@ -226,7 +226,7 @@ type Site struct {
// WriteIndent writes the sitemap indented by n tabs.
func (site Site) WriteIndent(w io.Writer, n int) error {
- s := Escape(site.Path)
+ s := EscapeAll(site.Path)
if site.Name != "" {
s += " " + Escape(site.Name)
}
diff --git a/parse_test.go b/parse_test.go
index e70b833..1c7dad9 100644
--- a/parse_test.go
+++ b/parse_test.go
@@ -269,7 +269,7 @@ var parseTests = map[string]*Document{
"title\n\tfoo bar\n" +
"links\n\tqwe asd\n\tzxc 123\n" +
- "site\n\tfoo\n\t\tbar\n\t\tbaz/quux\n\t\t\t123\n" +
+ "site\n\tfoo Foo\n\t\tbar\n\t\tbaz/qu\\ ux Test\n\t\t\t123\n" +
"title\n\tbaz\n" +
"links\n\tfoo\n" +
"site\n\ttest": &Document{
@@ -283,10 +283,12 @@ var parseTests = map[string]*Document{
Children: []Site{
Site{
Path: "foo",
+ Name: "Foo",
Children: []Site{
Site{Path: "bar"},
Site{
- Path: "baz/quux",
+ Path: "baz/qu ux",
+ Name: "Test",
Children: []Site{
Site{Path: "123"},
},
diff --git a/simpletext.go b/simpletext.go
index 4d86d6d..00d82ec 100644
--- a/simpletext.go
+++ b/simpletext.go
@@ -70,7 +70,9 @@ func CollapseWhitespace(raw string) string {
var escapeRe = regexp.MustCompile(`[\t\n\f\r\\\x00]|^ | $| `)
-// Escape escapes whitespace, backslash and and U+0000 within s.
+// Escape escapes whitespace, backslash and U+0000 within s.
+//
+// Only leading, trailing or multiple consecutive spaces are escaped.
func Escape(s string) string {
return escapeRe.ReplaceAllStringFunc(s, func(match string) string {
switch match {
@@ -115,6 +117,34 @@ func EscapeSpace(s string) string {
})
}
+var escapeAllRe = regexp.MustCompile(`[\t\n\f\r\\\x00 ]`)
+
+// EscapeAll escapes all whitespace, backslash and and U+0000 within s.
+//
+// Unlike Escape, all spaces are escaped, not just ones that would be collapsed
+// into one.
+func EscapeAll(s string) string {
+ return escapeAllRe.ReplaceAllStringFunc(s, func(match string) string {
+ switch match {
+ case "\t":
+ return `\t`
+ case "\n":
+ return `\n`
+ case "\f":
+ return `\f`
+ case "\r":
+ return `\r`
+ case "\\":
+ return `\\`
+ case "\x00":
+ return `\x00`
+ case " ":
+ return `\ `
+ }
+ return match // this shouldn't happen
+ })
+}
+
var escapeNonspaceRe = regexp.MustCompile(`[\f\r\\\x00]`)
// EscapeNonspace works like Escape, except it does not escape spaces, tabs and
diff --git a/simpletext_test.go b/simpletext_test.go
index c5b4cf9..d75a741 100644
--- a/simpletext_test.go
+++ b/simpletext_test.go
@@ -92,6 +92,35 @@ func TestEscapeSpace(t *testing.T) {
}
}
+var allEscapes = map[string]string{
+ "": ``,
+ "ContNet": `ContNet`,
+ "\t": `\t`,
+ "\n": `\n`,
+ "\f": `\f`,
+ "\r": `\r`,
+ " ": `\ `,
+ "\\": `\\`,
+ "\x00": `\x00`,
+ " ": `\ \ \ \ \ \ \ `,
+ " ": `\ \ \ \ \ \ `,
+ " ": `\ \ \ \ `,
+ " ": `\ \ \ `,
+ " ": `\ \ `,
+ "\b\v\\\x00\xff\u00ff\\xff": "\b\v\\\\\\x00\xff\u00ff\\\\xff",
+}
+
+func TestEscapeAll(t *testing.T) {
+ for k, v := range allEscapes {
+ t.Run(k, func(t *testing.T) {
+ e := EscapeAll(k)
+ if e != v {
+ t.Errorf("EscapeAll(%q) -> %q, expected %q", k, e, v)
+ }
+ })
+ }
+}
+
var simpleUnescapes = map[string]string{
``: "",
`ContNet`: "ContNet",
diff --git a/write_test.go b/write_test.go
index 18809b1..8cca449 100644
--- a/write_test.go
+++ b/write_test.go
@@ -13,22 +13,23 @@ var writeTests = map[string]*Document{
},
"title\n\tfoo bar baz\n" +
- "links\n\tqwe asd\n\tzxc 123\n\tfoo\n" +
- "site\n\tfoo\n\t\tbar\n\t\tbaz/quux\n\t\t\t123\n\ttest\n": &Document{
+ "links\n\tqwe\\ asd zxc 123\n\tfoo\n" +
+ "site\n\tfoo Foo\n\t\tbar\n\t\tbaz/qu\\ ux Test\n\t\t\t123\n\ttest\n": &Document{
Title: "foo bar baz",
Links: []Link{
- Link{"qwe", "asd", ""},
- Link{"zxc", "123", ""},
+ Link{"qwe asd", "zxc 123", ""},
Link{"foo", "", ""},
},
Site: Site{
Children: []Site{
Site{
Path: "foo",
+ Name: "Foo",
Children: []Site{
Site{Path: "bar"},
Site{
- Path: "baz/quux",
+ Path: "baz/qu ux",
+ Name: "Test",
Children: []Site{
Site{Path: "123"},
},