Skip to content

Commit

Permalink
Merge pull request #65 from nobe4/markdown
Browse files Browse the repository at this point in the history
refactor: use slack's internal markdown converter
  • Loading branch information
rneatherway authored Apr 15, 2024
2 parents 299963f + b4a4c31 commit 8b1c7f7
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 141 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ toolchain go1.21.4

require (
github.com/cli/go-gh v1.2.1
github.com/rneatherway/slack v0.0.0-20240323132214-0af54ceb5c65
github.com/rneatherway/slack v0.0.0-20240412070247-8ea7ec9fab1c
github.com/spf13/cobra v1.6.1
github.com/spf13/pflag v1.0.5
nhooyr.io/websocket v1.8.7
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rneatherway/slack v0.0.0-20240323132214-0af54ceb5c65 h1:aKxOcmudHNIZz2C0ncYCoRIiHAP1Js4EMsmOPG19eDQ=
github.com/rneatherway/slack v0.0.0-20240323132214-0af54ceb5c65/go.mod h1:2WA0D8ytQf+d/hE4QqppWRjFOz86WFG6XX8rpsRLHT8=
github.com/rneatherway/slack v0.0.0-20240412070247-8ea7ec9fab1c h1:P6rQJVjkF3pLp1nCJbE/S82nEV5ilx2AVoUY4PwkC5g=
github.com/rneatherway/slack v0.0.0-20240412070247-8ea7ec9fab1c/go.mod h1:2WA0D8ytQf+d/hE4QqppWRjFOz86WFG6XX8rpsRLHT8=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
Expand Down
65 changes: 4 additions & 61 deletions internal/markdown/markdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,20 @@ package markdown

import (
"fmt"
"regexp"
"sort"
"strconv"
"strings"
"time"

"github.com/rneatherway/gh-slack/internal/slackclient"
"github.com/rneatherway/slack/pkg/markdown"
)

var userRE = regexp.MustCompile("<@[A-Z0-9]+>")
var linkRE = regexp.MustCompile(`<(https?://[^|>]+)\|([^>]+)>`)
var openCodefence = regexp.MustCompile("(?m)^```")
var closeCodefence = regexp.MustCompile("(?m)(.)```$")

type UserProvider interface {
UsernameForID(string) (string, error)
}

func interpolateUsers(client UserProvider, s string) (string, error) {
userLocations := userRE.FindAllStringIndex(s, -1)
out := &strings.Builder{}
last := 0
for _, userLocation := range userLocations {
start := userLocation[0]
end := userLocation[1]

username, err := client.UsernameForID(s[start+2 : end-1])
if err != nil {
return "", err
}
out.WriteString(s[last:start])
out.WriteString("`@")
out.WriteString(username)
out.WriteRune('`')
last = end
}
out.WriteString(s[last:])

return out.String(), nil
}

func parseUnixTimestamp(s string) (*time.Time, error) {
tsParts := strings.Split(s, ".")
if len(tsParts) != 2 {
return nil, fmt.Errorf("timestamp '%s' is not in <seconds>.<milliseconds> format", s)
}

seconds, err := strconv.ParseInt(tsParts[0], 10, 64)
if err != nil {
return nil, err
}

nanos, err := strconv.ParseInt(tsParts[1], 10, 64)
if err != nil {
return nil, err
}

result := time.Unix(seconds, nanos)
return &result, nil
}

func convert(client UserProvider, b *strings.Builder, s string) error {
text, err := interpolateUsers(client, s)
func convert(client *slackclient.SlackClient, b *strings.Builder, s string) error {
text, err := markdown.Convert(client, s)
if err != nil {
return err
}

text = linkRE.ReplaceAllString(text, "[$2]($1)")
text = openCodefence.ReplaceAllString(text, "```\n")
text = closeCodefence.ReplaceAllString(text, "$1\n```")

for _, line := range strings.Split(text, "\n") {
// TODO: Might be a good idea to escape 'line'
fmt.Fprintf(b, "> %s\n", line)
Expand All @@ -87,7 +30,7 @@ func FromMessages(client *slackclient.SlackClient, history *slackclient.HistoryR
msgTimes := make(map[string]time.Time, len(messages))

for _, message := range messages {
tm, err := parseUnixTimestamp(message.Ts)
tm, err := markdown.ParseUnixTimestamp(message.Ts)
if err != nil {
return "", err
}
Expand Down
77 changes: 0 additions & 77 deletions internal/markdown/markdown_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package markdown

import (
"fmt"
"strings"
"testing"

Expand Down Expand Up @@ -127,79 +126,3 @@ func TestFromMessagesSeparatesMessagesFromSameUserWhenNotAdjacent(t *testing.T)
t.Fatal("expected:\n\n", expected, "\n\ngot:\n\n", actual)
}
}

func TestUserRE(t *testing.T) {
results := userRE.FindAllStringIndex("<@UP7UAV3NH> <@UPA5ANVNJ> hello", -1)
if len(results) != 2 {
t.Errorf("results length %d", len(results))
}
if !(results[0][0] == 0 && results[0][1] == 12) {
t.Errorf("first match %v", results[0])
}
if !(results[1][0] == 13 && results[1][1] == 25) {
t.Errorf("second match %v", results[1])
}
}

type TestUserProvider struct {
counter int
}

func (c *TestUserProvider) UsernameForID(id string) (string, error) {
c.counter += 1
return fmt.Sprintf("test_username_%d", c.counter), nil
}

func TestInterpolateUsers(t *testing.T) {
table := [][]string{
{"<@UP7UAV3NH>", "`@test_username_1`"},
{"<@UP7UAV3NH> hi hi", "`@test_username_1` hi hi"},
{"hi<@UP7UAV3NH> hi hi", "hi`@test_username_1` hi hi"},
{"<@UP7UAV3NH> hello <@UP756V3NH>", "`@test_username_1` hello `@test_username_2`"},
{"<@UP7UAV3NH> <@UP756V3NH> hello", "`@test_username_1` `@test_username_2` hello"},
}

for _, test := range table {
input := test[0]
expected := test[1]
actual, _ := interpolateUsers(&TestUserProvider{}, input)

if actual != expected {
t.Errorf("expected %q, actual %q", expected, actual)
}
}
}

func TestLinkify(t *testing.T) {
table := [][]string{
{"Hello <https://example.com|text> end", "Hello [text](https://example.com) end"},
{"Hello <https://example.com|text> end and here is another link <http://github.com|GitHub!!> go check it out", "Hello [text](https://example.com) end and here is another link [GitHub!!](http://github.com) go check it out"},
}

for _, test := range table {
input := test[0]
expected := test[1]
actual := linkRE.ReplaceAllString(input, "[$2]($1)")

if actual != expected {
t.Errorf("expected %q, actual %q", expected, actual)
}
}
}

func TestFixCodefence(t *testing.T) {
table := [][]string{
{"```{\n x: y,\n a: b\n}```", "```\n{\n x: y,\n a: b\n}\n```"},
}

for _, test := range table {
input := test[0]
expected := test[1]
actual := openCodefence.ReplaceAllLiteralString(input, "```\n")
actual = closeCodefence.ReplaceAllString(actual, "$1\n```")

if actual != expected {
t.Errorf("expected %q, actual %q", expected, actual)
}
}
}

0 comments on commit 8b1c7f7

Please sign in to comment.