summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDiep Pham <mrfavadi@gmail.com>2017-02-02 21:28:27 +0700
committerHarrison Healey <harrisonmhealey@gmail.com>2017-02-02 09:28:27 -0500
commitf1a4c0738301f50b6a9e8bd635fbcc172decb199 (patch)
tree698b6337e2c6622b8fdbb965e82568ab393cebb9
parent609d4f43d9eef504d852fbf02af5473b0d1424c8 (diff)
downloadchat-f1a4c0738301f50b6a9e8bd635fbcc172decb199.tar.gz
chat-f1a4c0738301f50b6a9e8bd635fbcc172decb199.tar.bz2
chat-f1a4c0738301f50b6a9e8bd635fbcc172decb199.zip
PLT-495 Improves slack markup conversion (#4914)
* improves slack markup conversion * bold * strikethrough * blockquotes * handles blockquotes in slack_import * removes unnecessary formatting * fixes various format problems
-rw-r--r--app/slackimport.go57
-rw-r--r--app/slackimport_test.go103
2 files changed, 150 insertions, 10 deletions
diff --git a/app/slackimport.go b/app/slackimport.go
index 75a1606af..e54d0724b 100644
--- a/app/slackimport.go
+++ b/app/slackimport.go
@@ -564,12 +564,63 @@ func SlackConvertChannelMentions(channels []SlackChannel, posts map[string][]Sla
}
func SlackConvertPostsMarkup(posts map[string][]SlackPost) map[string][]SlackPost {
- // Convert URLs in Slack's format to Markdown format.
- regex := regexp.MustCompile(`<([^|<>]+)\|([^|<>]+)>`)
+ regexReplaceAllString := []struct {
+ regex *regexp.Regexp
+ rpl string
+ }{
+ // URL
+ {
+ regexp.MustCompile(`<([^|<>]+)\|([^|<>]+)>`),
+ "[$2]($1)",
+ },
+ // bold
+ {
+ regexp.MustCompile(`(^|[\s.;,])\*(\S[^*\n]+)\*`),
+ "$1**$2**",
+ },
+ // strikethrough
+ {
+ regexp.MustCompile(`(^|[\s.;,])\~(\S[^~\n]+)\~`),
+ "$1~~$2~~",
+ },
+ // single paragraph blockquote
+ // Slack converts > character to &gt;
+ {
+ regexp.MustCompile(`(?sm)^&gt;`),
+ ">",
+ },
+ }
+
+ regexReplaceAllStringFunc := []struct {
+ regex *regexp.Regexp
+ fn func(string) string
+ }{
+ // multiple paragraphs blockquotes
+ {
+ regexp.MustCompile(`(?sm)^>&gt;&gt;(.+)$`),
+ func(src string) string {
+ // remove >>> prefix, might have leading \n
+ prefixRegexp := regexp.MustCompile(`^([\n])?>&gt;&gt;(.*)`)
+ src = prefixRegexp.ReplaceAllString(src, "$1$2")
+ // append > to start of line
+ appendRegexp := regexp.MustCompile(`(?m)^`)
+ return appendRegexp.ReplaceAllString(src, ">$0")
+ },
+ },
+ }
for channelName, channelPosts := range posts {
for postIdx, post := range channelPosts {
- posts[channelName][postIdx].Text = regex.ReplaceAllString(post.Text, "[$2]($1)")
+ result := post.Text
+
+ for _, rule := range regexReplaceAllString {
+ result = rule.regex.ReplaceAllString(result, rule.rpl)
+ }
+
+ for _, rule := range regexReplaceAllStringFunc {
+ result = rule.regex.ReplaceAllStringFunc(result, rule.fn)
+ }
+ posts[channelName][postIdx].Text = result
}
}
diff --git a/app/slackimport_test.go b/app/slackimport_test.go
index 3389c5217..6db6adf2d 100644
--- a/app/slackimport_test.go
+++ b/app/slackimport_test.go
@@ -190,7 +190,7 @@ func TestSlackSanitiseChannelProperties(t *testing.T) {
c1s := SlackSanitiseChannelProperties(c1)
if c1.DisplayName != c1s.DisplayName || c1.Name != c1s.Name || c1.Purpose != c1s.Purpose || c1.Header != c1s.Header {
- t.Fatalf("Unexpected alterations to the channel properties.")
+ t.Fatal("Unexpected alterations to the channel properties.")
}
c2 := model.Channel{
@@ -227,14 +227,103 @@ func TestSlackConvertPostsMarkup(t *testing.T) {
{
Text: "This message contains a mailto link to <mailto:me@example.com|me@example.com> in it.",
},
+ {
+ Text: "This message contains a *bold* word.",
+ },
+ {
+ Text: "This is not a * bold * word.",
+ },
+ {
+ Text: `There is *no bold word
+in this*.`,
+ },
+ {
+ Text: "*This* is not a*bold* word.*This* is a bold word, *and* this; *and* this too.",
+ },
+ {
+ Text: "This message contains a ~strikethrough~ word.",
+ },
+ {
+ Text: "This is not a ~ strikethrough ~ word.",
+ },
+ {
+ Text: `There is ~no strikethrough word
+in this~.`,
+ },
+ {
+ Text: "~This~ is not a~strikethrough~ word.~This~ is a strikethrough word, ~and~ this; ~and~ this too.",
+ },
+ {
+ Text: `This message contains multiple paragraphs blockquotes
+&gt;&gt;&gt;first
+second
+third`,
+ },
+ {
+ Text: `This message contains single paragraph blockquotes
+&gt;something
+&gt;another thing`,
+ },
+ {
+ Text: "This message has no > block quote",
+ },
}
- output := SlackConvertPostsMarkup(input)
-
- if output["test"][0].Text != "This message contains a link to [Google](https://google.com)." {
- t.Fatalf("Unexpected message after markup translation: %v", output["test"][0].Text)
+ expectedOutput := make(map[string][]SlackPost)
+ expectedOutput["test"] = []SlackPost{
+ {
+ Text: "This message contains a link to [Google](https://google.com).",
+ },
+ {
+ Text: "This message contains a mailto link to [me@example.com](mailto:me@example.com) in it.",
+ },
+ {
+ Text: "This message contains a **bold** word.",
+ },
+ {
+ Text: "This is not a * bold * word.",
+ },
+ {
+ Text: `There is *no bold word
+in this*.`,
+ },
+ {
+ Text: "**This** is not a*bold* word.**This** is a bold word, **and** this; **and** this too.",
+ },
+ {
+ Text: "This message contains a ~~strikethrough~~ word.",
+ },
+ {
+ Text: "This is not a ~ strikethrough ~ word.",
+ },
+ {
+ Text: `There is ~no strikethrough word
+in this~.`,
+ },
+ {
+ Text: "~~This~~ is not a~strikethrough~ word.~~This~~ is a strikethrough word, ~~and~~ this; ~~and~~ this too.",
+ },
+ {
+ Text: `This message contains multiple paragraphs blockquotes
+>first
+>second
+>third`,
+ },
+ {
+ Text: `This message contains single paragraph blockquotes
+>something
+>another thing`,
+ },
+ {
+ Text: "This message has no > block quote",
+ },
}
- if output["test"][1].Text != "This message contains a mailto link to [me@example.com](mailto:me@example.com) in it." {
- t.Fatalf("Unexpected message after markup translation: %v", output["test"][0].Text)
+
+ actualOutput := SlackConvertPostsMarkup(input)
+
+ for i := range actualOutput["test"] {
+ if actualOutput["test"][i].Text != expectedOutput["test"][i].Text {
+ t.Errorf("Unexpected message after markup translation: %v", actualOutput["test"][i].Text)
+ }
}
}