forked from domi/mattermost-meme
125 lines
2.7 KiB
Go
125 lines
2.7 KiB
Go
|
package memelibrary
|
||
|
|
||
|
import (
|
||
|
"image"
|
||
|
"image/color"
|
||
|
"regexp"
|
||
|
"strings"
|
||
|
|
||
|
yaml "gopkg.in/yaml.v2"
|
||
|
|
||
|
"github.com/mattermost/mattermost-plugin-memes/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
|
||
|
}
|