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"`
|
||||
}
|
||||
|
||||
type MarkupConfig struct {
|
||||
Name string
|
||||
Cmd string
|
||||
}
|
||||
|
||||
type AercConfig struct {
|
||||
Bindings BindingConfig
|
||||
ContextualBinds []BindingConfigContext
|
||||
|
@ -267,6 +272,7 @@ type AercConfig struct {
|
|||
ContextualUis []UIConfigContext
|
||||
General GeneralConfig
|
||||
Templates TemplateConfig
|
||||
Markups []MarkupConfig
|
||||
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
|
||||
for _, dir := range SearchDirs {
|
||||
config.Ui.StyleSetDirs = append(
|
||||
|
|
|
@ -602,6 +602,22 @@ text/plain=gvim {} +125
|
|||
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 specify commands to execute when certain events occur.
|
||||
|
|
|
@ -500,6 +500,12 @@ message list, the message in the message viewer, etc).
|
|||
*edit*
|
||||
(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*
|
||||
Cycles between input fields in the compose window.
|
||||
|
||||
|
|
|
@ -529,6 +529,57 @@ func (c *Composer) readSignatureFromFile() []byte {
|
|||
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 {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
|
|
Loading…
Reference in a new issue