diff --git a/anno.go b/anno.go index b949660..7fa6a5b 100644 --- a/anno.go +++ b/anno.go @@ -87,11 +87,12 @@ func FindMany(src []byte, finders ...Finder) (Notes, error) { // ErrNoMatch will be returned. func FieldFunc(kind string, fn func(b []byte) (bool, []byte)) FinderFunc { return func(src []byte) (Notes, error) { + var pos int var notes Notes fields := bytes.Fields(src) for _, f := range fields { if ok, match := fn(f); ok { - s := bytes.Index(src, match) + s := bytes.Index(src[pos:], match) + pos if s == -1 { // true was returned without the returned bytes // appearing in the match. @@ -103,6 +104,7 @@ func FieldFunc(kind string, fn func(b []byte) (bool, []byte)) FinderFunc { Kind: kind, }) } + pos += len(f) + 1 } return notes, nil } diff --git a/anno_test.go b/anno_test.go index 2c78c3f..b326918 100644 --- a/anno_test.go +++ b/anno_test.go @@ -9,7 +9,6 @@ import ( ) func TestFindMany(t *testing.T) { - is := is.New(t) src := []byte("This is a #long string written by @mat containing links to https://downlist.io/.") @@ -20,7 +19,6 @@ func TestFindMany(t *testing.T) { } func TestFindManyString(t *testing.T) { - is := is.New(t) src := "This is a #long string written by @mat containing links to https://downlist.io/." @@ -30,8 +28,19 @@ func TestFindManyString(t *testing.T) { } -func TestFindManyURLsWithPunctuation(t *testing.T) { +func TestFindManyStringDuplicates(t *testing.T) { + is := is.New(t) + src := `If I @mention and then I @mention again, I hope to get different start values` + + notes, err := anno.FindManyString(src, anno.Mentions) + is.NoErr(err) + is.Equal(len(notes), 2) + is.True(notes[0].Start < notes[1].Start) + +} + +func TestFindManyURLsWithPunctuation(t *testing.T) { is := is.New(t) src := "What do you think about Facebook.com and Yahoo.com and Google.com?" @@ -71,38 +80,38 @@ func TestFieldFinder(t *testing.T) { is.NoErr(err) is.Equal(len(notes), 3) - is.Equal(notes[0].Val, []byte("field")) + is.Equal(string(notes[0].Val), "field") is.Equal(notes[0].Start, 2) is.Equal(notes[0].End(), 2+len(notes[0].Val)) is.Equal(notes[0].Kind, "thiskind") - is.Equal(notes[1].Val, []byte("able")) + is.Equal(string(notes[1].Val), "able") is.Equal(notes[1].Start, 23) is.Equal(notes[1].End(), 23+len(notes[1].Val)) is.Equal(notes[1].Kind, "thiskind") - is.Equal(notes[2].Val, []byte("find")) - is.Equal(notes[2].Start, 8) - is.Equal(notes[2].End(), 8+len(notes[2].Val)) + is.Equal(string(notes[2].Val), "find") + is.Equal(notes[2].Start, 31) + is.Equal(notes[2].End(), 31+len(notes[2].Val)) is.Equal(notes[2].Kind, "thiskind") // sort the notes sort.Sort(notes) is.Equal(len(notes), 3) - is.Equal(notes[0].Val, []byte("field")) + is.Equal(string(notes[0].Val), "field") is.Equal(notes[0].Start, 2) is.Equal(notes[0].End(), 2+len(notes[0].Val)) is.Equal(notes[0].Kind, "thiskind") - is.Equal(notes[1].Val, []byte("find")) - is.Equal(notes[1].Start, 8) - is.Equal(notes[1].End(), 8+len(notes[2].Val)) + is.Equal(string(notes[1].Val), "able") + is.Equal(notes[1].Start, 23) + is.Equal(notes[1].End(), 23+len(notes[1].Val)) is.Equal(notes[1].Kind, "thiskind") - is.Equal(notes[2].Val, []byte("able")) - is.Equal(notes[2].Start, 23) - is.Equal(notes[2].End(), 23+len(notes[1].Val)) + is.Equal(string(notes[2].Val), "find") + is.Equal(notes[2].Start, 31) + is.Equal(notes[2].End(), 31+len(notes[2].Val)) is.Equal(notes[2].Kind, "thiskind") }