package memelibrary import ( "image" "image/color" "regexp" "strings" yaml "gopkg.in/yaml.v2" "github.com/mattermost/mattermost-plugin-memes/server/meme" ) type Pattern struct { Pattern string Text []string Example string pattern *regexp.Regexp } type Slot struct { X int Y int Width int Height int Font string TextColor []int `yaml:"text_color"` } type Metadata struct { Aliases []string Patterns []*Pattern Slots []*Slot Example []string } func ParseMetadata(in []byte) (*Metadata, error) { var m Metadata if err := yaml.Unmarshal(in, &m); err != nil { return nil, err } for _, pattern := range m.Patterns { r, err := regexp.Compile("(?i)^" + pattern.Pattern + "$") if err != nil { return nil, err } pattern.pattern = r } return &m, nil } func (m *Metadata) PatternMatch(input string) []string { for _, pattern := range m.Patterns { if text := pattern.Match(input); text != nil { return text } } return nil } func (m *Metadata) TextSlots(bounds image.Rectangle) (slots []*meme.TextSlot) { if m.Slots != nil { for _, slot := range m.Slots { textSlot := &meme.TextSlot{ Bounds: image.Rect(slot.X, slot.Y, slot.X+slot.Width, slot.Y+slot.Height), } if slot.Font != "" { textSlot.Font = fonts[slot.Font] } else { textSlot.Font = fonts["Anton-Regular"] textSlot.TextColor = color.White textSlot.OutlineColor = color.Black textSlot.AllUppercase = true } if c := sliceToColor(slot.TextColor); c != nil { textSlot.TextColor = c } slots = append(slots, textSlot) } return } padding := bounds.Dy() / 20 return []*meme.TextSlot{ { Bounds: image.Rect(padding, padding, bounds.Dx()-padding, bounds.Dy()/4), Font: fonts["Anton-Regular"], TextColor: color.White, OutlineColor: color.Black, AllUppercase: true, }, { Bounds: image.Rect(padding, bounds.Dy()*3/4, bounds.Dx()-padding, bounds.Dy()-padding), Font: fonts["Anton-Regular"], TextColor: color.White, OutlineColor: color.Black, AllUppercase: true, }, } } func sliceToColor(s []int) color.Color { switch len(s) { case 1: return color.Gray16{uint16(s[0]) << 1} case 2: return color.RGBA{uint8(s[0]), uint8(s[0]), uint8(s[0]), uint8(s[1])} case 3: return color.RGBA{uint8(s[0]), uint8(s[1]), uint8(s[2]), 255} case 4: return color.RGBA{uint8(s[0]), uint8(s[1]), uint8(s[2]), uint8(s[3])} } return nil } func (p *Pattern) Match(input string) (text []string) { if matches := p.pattern.FindStringSubmatchIndex(input); matches != nil { for _, slotText := range p.Text { text = append(text, strings.TrimSpace(string(p.pattern.ExpandString(nil, slotText, input, matches)))) } } return }