Compare commits
2 commits
main
...
html-suppo
Author | SHA1 | Date | |
---|---|---|---|
49bdace2f6 | |||
5df1ebce35 |
5 changed files with 126 additions and 0 deletions
36
commands/compose/markup.go
Normal file
36
commands/compose/markup.go
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package compose
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.sr.ht/~rjarry/aerc/widgets"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MarkUp struct{}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
register(MarkUp{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (MarkUp) Aliases() []string {
|
||||||
|
return []string{"markup"}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (MarkUp) Complete(aerc *widgets.Aerc, args []string) []string {
|
||||||
|
composer, _ := aerc.SelectedTabContent().(*widgets.Composer)
|
||||||
|
return composer.GetMarkups()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (MarkUp) Execute(aerc *widgets.Aerc, args []string) error {
|
||||||
|
if len(args) != 2 {
|
||||||
|
return fmt.Errorf("Usage: :markup <label>")
|
||||||
|
}
|
||||||
|
markupKey := args[1]
|
||||||
|
composer, _ := aerc.SelectedTabContent().(*widgets.Composer)
|
||||||
|
if err := composer.GenerateMarkup(markupKey); err != nil {
|
||||||
|
aerc.PushError(err.Error())
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
aerc.PushSuccess(fmt.Sprintf("Markup generated"))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -253,6 +253,11 @@ type TemplateConfig struct {
|
||||||
Forwards string `ini:"forwards"`
|
Forwards string `ini:"forwards"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MarkupConfig struct {
|
||||||
|
Name string
|
||||||
|
Cmd string
|
||||||
|
}
|
||||||
|
|
||||||
type AercConfig struct {
|
type AercConfig struct {
|
||||||
Bindings BindingConfig
|
Bindings BindingConfig
|
||||||
ContextualBinds []BindingConfigContext
|
ContextualBinds []BindingConfigContext
|
||||||
|
@ -267,6 +272,7 @@ type AercConfig struct {
|
||||||
ContextualUis []UIConfigContext
|
ContextualUis []UIConfigContext
|
||||||
General GeneralConfig
|
General GeneralConfig
|
||||||
Templates TemplateConfig
|
Templates TemplateConfig
|
||||||
|
Markups []MarkupConfig
|
||||||
Openers map[string][]string
|
Openers map[string][]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,6 +622,17 @@ func (config *AercConfig) LoadConfig(file *ini.File) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if markupsSec, err := file.GetSection("markups"); err == nil {
|
||||||
|
for _, markupKey := range markupsSec.KeyStrings() {
|
||||||
|
markupCmd := markupsSec.KeysHash()[markupKey]
|
||||||
|
mark := MarkupConfig{
|
||||||
|
Name: markupKey,
|
||||||
|
Cmd: markupCmd,
|
||||||
|
}
|
||||||
|
config.Markups = append(config.Markups, mark)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// append default paths to template-dirs and styleset-dirs
|
// append default paths to template-dirs and styleset-dirs
|
||||||
for _, dir := range SearchDirs {
|
for _, dir := range SearchDirs {
|
||||||
config.Ui.StyleSetDirs = append(
|
config.Ui.StyleSetDirs = append(
|
||||||
|
|
|
@ -602,6 +602,22 @@ text/plain=gvim {} +125
|
||||||
message/rfc822=thunderbird
|
message/rfc822=thunderbird
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## MARKUPS
|
||||||
|
|
||||||
|
Markups allows you to pipe the content of a message being composed through a
|
||||||
|
shell command to generate HTML markup from the plaintext message. Markups
|
||||||
|
can be defined in *[markups]* section within aerc.conf.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
[markups]
|
||||||
|
work=pandoc -f markdown -t html --template=company.tpl
|
||||||
|
```
|
||||||
|
|
||||||
|
The command *:markup* becomes available during the compose-review stage, and
|
||||||
|
will only append text/html part to the email if the shell command exits
|
||||||
|
successfully and content is written to standard output.
|
||||||
|
|
||||||
## TRIGGERS
|
## TRIGGERS
|
||||||
|
|
||||||
Triggers specify commands to execute when certain events occur.
|
Triggers specify commands to execute when certain events occur.
|
||||||
|
|
|
@ -500,6 +500,12 @@ message list, the message in the message viewer, etc).
|
||||||
*edit*
|
*edit*
|
||||||
(Re-) opens your text editor to edit the message in progress.
|
(Re-) opens your text editor to edit the message in progress.
|
||||||
|
|
||||||
|
*markup* <label>
|
||||||
|
Passes the message to external command, and appends result as text/html
|
||||||
|
message part. The label and command is defined under the *markups* section
|
||||||
|
configuration. For details on configuring markup support consult
|
||||||
|
*aerc-config*(5).
|
||||||
|
|
||||||
*next-field*, *prev-field*
|
*next-field*, *prev-field*
|
||||||
Cycles between input fields in the compose window.
|
Cycles between input fields in the compose window.
|
||||||
|
|
||||||
|
|
|
@ -529,6 +529,57 @@ func (c *Composer) readSignatureFromFile() []byte {
|
||||||
return signature
|
return signature
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Composer) GenerateMarkup(markupKey string) error {
|
||||||
|
markupCmd, err := c.getMarkupCmdByName(markupKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
proc := exec.Command("sh", "-c", markupCmd)
|
||||||
|
stdin, err := proc.StdinPipe()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
defer stdin.Close()
|
||||||
|
_, err := c.email.Seek(0, io.SeekStart)
|
||||||
|
if err != nil {
|
||||||
|
logging.Warnf("failed to seek beginning of mail: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
io.Copy(stdin, c.email)
|
||||||
|
}()
|
||||||
|
outBytes, err := proc.Output()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(outBytes) < 1 {
|
||||||
|
return fmt.Errorf("markup %s did not generate content", markupKey)
|
||||||
|
}
|
||||||
|
ioReader := bytes.NewReader(outBytes)
|
||||||
|
return c.AppendPart("text/html", nil, ioReader)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Composer) GetMarkups() []string {
|
||||||
|
if len(c.config.Markups) < 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
markupKeys := []string{}
|
||||||
|
for _, cmd := range c.config.Markups {
|
||||||
|
markupKeys = append(markupKeys, cmd.Name)
|
||||||
|
}
|
||||||
|
return markupKeys
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Composer) getMarkupCmdByName(markupKey string) (string, error) {
|
||||||
|
for _, markupConfig := range c.config.Markups {
|
||||||
|
if markupConfig.Name == markupKey {
|
||||||
|
return markupConfig.Cmd, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("unknown markup label %s", markupKey)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Composer) FocusTerminal() *Composer {
|
func (c *Composer) FocusTerminal() *Composer {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
defer c.Unlock()
|
defer c.Unlock()
|
||||||
|
|
Loading…
Reference in a new issue