matryer / anno Goto Github PK
View Code? Open in Web Editor NEWGo package for text annotation.
License: MIT License
Go package for text annotation.
License: MIT License
Hi Mat,
I was brought here by the Medium article so this is very much a learning question for me.
In trying to grok the article and figure out why you used an interface I refactored anno.go without the interface and it seemed to work but I wonder have I missed something.
Listening to "Go Time" you said that you had overused interfaces early on and I have Googled the subject and found opposing advice: 'use interfaces freely' and 'don't overuse interfaces'.
I've only refactored anno.go and run its test so there may be something in the rest of the code that's pertinent to the interface.
So, I'll stop rambling, is there something in this code that is not idiomatic or will come and bite me in the bum or is it just a matter of style:
package main
// This has bare minimum changes to make work without interface.
import (
"bytes"
"fmt"
"log"
)
// ErrNoMatch is returned when a match was expected but
// can not be found.
// Can be returned from FieldFunc.
type ErrNoMatch []byte
func (e ErrNoMatch) Error() string {
return "no match for '" + string(e) + "'"
}
// Note represents something interesting within
// text.
type Note struct {
Val []byte `json:"val"`
Start int `json:"start"`
Kind string `json:"kind"`
}
// Notes is a sortable slice of Note objects.
type Notes []*Note
// End calculates the end position of this note.
func (n *Note) End() int {
return n.Start + len(n.Val)
}
// This satisfies sort.Interface
func (n Notes) Len() int { return len(n) }
func (n Notes) Swap(i, j int) { n[i], n[j] = n[j], n[i] }
func (n Notes) Less(i, j int) bool { return n[i].Start < n[j].Start }
// FinderFunc represents a function capable of finding
// notes.
type FinderFunc func(s []byte) (Notes, error)
// FieldFunc returns a FinderFunc that finds notes on a per field basis.
// The fn returns true if it's a match, and optionally a subset of the the
// match.
// The returned []byte must be contained in the source string, otherwise
// 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[pos:], match) + pos
if s == -1 {
// true was returned without the returned bytes
// appearing in the match.
return nil, ErrNoMatch(match)
}
notes = append(notes, &Note{
Val: match,
Start: s,
Kind: kind,
})
}
pos += len(f) + 1
}
return notes, nil
}
}
// FindManyString runs all finders against the source and returns a
// slice of notes or an error.
func FindManyString(src string, finders ...FinderFunc) (Notes, error) {
return FindMany([]byte(src), finders...)
}
// FindMany runs all finders against the source and returns a
// slice of notes or an error.
func FindMany(src []byte, finders ...FinderFunc) (Notes, error) {
var allNotes Notes
for _, finder := range finders {
notes, err := finder(src)
if err != nil {
return nil, err
}
allNotes = append(allNotes, notes...)
}
return allNotes, nil
}
func main() {
// s := "Find http://www.websites.com/ and # #hashtags and @mentions and @more mentions easily"
s := "A simple string with no notes."
notes, err := FindManyString(s, Emails, URLs, Mentions, Hashtags)
if err != nil {
log.Fatalln(err)
}
fmt.Println("Source:", s)
for _, note := range notes {
fmt.Printf("Found a %s at [%d:%d]: \"%s\"\n", note.Kind, note.Start, note.End(), note.Val)
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.