diff options
author | Srivathsan Murali <sri@vathsan.com> | 2019-11-03 13:51:14 +0100 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2019-11-10 10:15:49 -0500 |
commit | 3ba69edab5f0c787424dac9649e43a7743da13ca (patch) | |
tree | bccbdd4e1844cc89f011839f0d6557012a14d1d0 /lib/templates | |
parent | ad68a9e4e471eb708893ad16601ab14a4672a2da (diff) | |
download | aerc-3ba69edab5f0c787424dac9649e43a7743da13ca.tar.gz |
Add Templates with Parsing
+ Changes NewComposer to return error.
+ Add lib to handle templates using "text/template".
+ Add -T option to following commands
- compose.
- reply
- forward
+ Quoted replies using templates.
+ Forwards as body using templates
+ Default templates are installed similar to filters.
+ Templates Config in aerc.conf.
- Required templates are parsed while loading config.
+ Add aerc-templates.7 manual for using template data.
Diffstat (limited to 'lib/templates')
-rw-r--r-- | lib/templates/template.go | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/lib/templates/template.go b/lib/templates/template.go new file mode 100644 index 00000000..c09bf4d2 --- /dev/null +++ b/lib/templates/template.go @@ -0,0 +1,160 @@ +package templates + +import ( + "bytes" + "errors" + "net/mail" + "os" + "path" + "strings" + "text/template" + "time" + + "github.com/mitchellh/go-homedir" +) + +type TemplateData struct { + To []*mail.Address + Cc []*mail.Address + Bcc []*mail.Address + From []*mail.Address + Date time.Time + Subject string + // Only available when replying with a quote + OriginalText string + OriginalFrom []*mail.Address + OriginalDate time.Time +} + +func TestTemplateData() TemplateData { + defaults := map[string]string{ + "To": "John Doe <john@example.com>", + "Cc": "Josh Doe <josh@example.com>", + "From": "Jane Smith <jane@example.com>", + "Subject": "This is only a test", + "OriginalText": "This is only a test text", + "OriginalFrom": "John Doe <john@example.com>", + "OriginalDate": time.Now().Format("Mon Jan 2, 2006 at 3:04 PM"), + } + + return ParseTemplateData(defaults) +} + +func ParseTemplateData(defaults map[string]string) TemplateData { + originalDate, _ := time.Parse("Mon Jan 2, 2006 at 3:04 PM", defaults["OriginalDate"]) + td := TemplateData{ + To: parseAddressList(defaults["To"]), + Cc: parseAddressList(defaults["Cc"]), + Bcc: parseAddressList(defaults["Bcc"]), + From: parseAddressList(defaults["From"]), + Date: time.Now(), + Subject: defaults["Subject"], + OriginalText: defaults["Original"], + OriginalFrom: parseAddressList(defaults["OriginalFrom"]), + OriginalDate: originalDate, + } + return td +} + +func parseAddressList(list string) []*mail.Address { + addrs, err := mail.ParseAddressList(list) + if err != nil { + return nil + } + + return addrs +} + +func wrapLine(text string, lineWidth int) string { + words := strings.Fields(text) + if len(words) == 0 { + return text + } + wrapped := words[0] + spaceLeft := lineWidth - len(wrapped) + for _, word := range words[1:] { + if len(word)+1 > spaceLeft { + wrapped += "\n" + word + spaceLeft = lineWidth - len(word) + } else { + wrapped += " " + word + spaceLeft -= 1 + len(word) + } + } + + return wrapped +} + +func wrapText(text string, lineWidth int) string { + text = strings.ReplaceAll(text, "\r\n", "\n") + lines := strings.Split(text, "\n") + var wrapped string + + for _, line := range lines { + wrapped += wrapLine(line, lineWidth) + "\n" + } + return wrapped +} + +// Wraping lines at 70 so that with the "> " of the quote it is under 72 +func quote(text string) string { + text = strings.ReplaceAll(text, "\r\n", "\n") + + quoted := "> " + wrapText(text, 70) + quoted = strings.ReplaceAll(quoted, "\n", "\n> ") + return quoted +} + +var templateFuncs = template.FuncMap{ + "quote": quote, + "wrapText": wrapText, + "dateFormat": time.Time.Format, +} + +func findTemplate(templateName string, templateDirs []string) (string, error) { + for _, dir := range templateDirs { + templateFile, err := homedir.Expand(path.Join(dir, templateName)) + if err != nil { + return "", err + } + + if _, err := os.Stat(templateFile); os.IsNotExist(err) { + continue + } + return templateFile, nil + } + + return "", errors.New("Can't find template - " + templateName) +} + +func ParseTemplateFromFile(templateName string, templateDirs []string, data interface{}) ([]byte, error) { + templateFile, err := findTemplate(templateName, templateDirs) + if err != nil { + return nil, err + } + emailTemplate, err := + template.New(templateName).Funcs(templateFuncs).ParseFiles(templateFile) + if err != nil { + return nil, err + } + + var outString bytes.Buffer + if err := emailTemplate.Execute(&outString, data); err != nil { + return nil, err + } + return outString.Bytes(), nil +} + +func ParseTemplate(templateText string, data interface{}) ([]byte, error) { + emailTemplate, err := + template.New("email_template").Funcs(templateFuncs).Parse(templateText) + if err != nil { + return nil, err + } + + var outString bytes.Buffer + if err := emailTemplate.Execute(&outString, data); err != nil { + return nil, err + } + return outString.Bytes(), nil +} |