Envoyer un e-mail écrit en démarque à l'aide de mutt


21

Parfois, je dois envoyer un fragment de code sur google-group inline. Le texte n'aide pas ici; Je peux le taper dans markdown, le convertir en html (en utilisant pandoc etc.), l'attacher à mutt as text/htmlet l'envoyer.

Il existe une bonne solution disponible ici, mais elle utilise un sendmailprogramme externe pour envoyer des e-mails. J'utilise mutt qui a la capacité d'envoyer des e-mails sur IMAP par lui-même.


1
Pourquoi ne pas simplement diriger la sortie d'un formateur Markdown en ligne de commande vers sendmail?
Naftuli Kay

Hmm .. ordinateur partagé! Je ne veux pas stocker le mot de passe pour sendmail externe.
Dilawar

Y a-t-il des exemples que nous pouvons voir à quoi ressemblent vos résultats actuels sur google-groups?
slm

Vous voulez également taper les choses dans la démarque, mais les faire rendre avant de les joindre à vos e-mails, non?
slm

Cela ressemble à ce que vous demandez, mais pourrait devoir être modifié: dgl.cx/2009/03/html-mail-with-mutt-using-markdown . Aussi markdownmail.py ressemblait à quelque chose que vous pouvez utiliser.
slm

Réponses:


28

Après avoir composé un message, mais avant de l'envoyer, vous disposez de nombreuses options. Appuyez ?pour les visualiser.

Certains qui peuvent aider ici:

  • F filtrer la pièce jointe via un processeur externe
    • Utiliser pandoc -s -f markdown -t htmlpour convertir en HTML
  • ^T pour modifier le type MIME de la pièce jointe
    • Changer de text/plainà text/html.

Maintenant, une macro qui fera tout en une seule étape. Ajoutez ceci à votre .muttrc:

macro compose \e5 "F pandoc -s -f markdown -t html \ny^T^Utext/html; charset=us-ascii\n"
set wait_key=no

Pour utiliser cette macro, une fois que vous avez fini de composer votre message mais avant de l'envoyer, appuyez sur Escpuis sur 5pour convertir votre message au format Markdown en HTML.

Vous pouvez naturellement personnaliser cette macro comme bon vous semble. Mutt a de nombreuses liaisons de touches déjà intégrées, donc quelle que soit la séquence de touches que vous choisissez de vous lier, assurez-vous qu'elle n'écrase pas autre chose (ou c'est quelque chose dont vous pouvez vous passer).


L'option set wait_key=nosupprime l' Press any key to continue...invite de Mutt lorsque des commandes externes sont exécutées. Si wait_keyc'est yes(qui est la valeur par défaut), vous devrez appuyer sur Esc, puis sur 5, puis sur n'importe quelle autre touche pour continuer.


1
C'est une solution vraiment élégante! +1
sinisterstuf

5
c'est bien, mais il a un défaut fondamental. il élimine la partie en texte brut de l'e-mail, ce qui le rend difficile à lire dans des clients comme ... mutt;) Les e-mails HTML doivent avoir un composant texte brut et html. le markdown brut doit être le texte en clair, le converti doit être le HTML.
masukomi

1
D'accord avec @masukomi, les clients de messagerie envoient généralement des versions HTML et texte de l'e-mail. Ce serait bien d'avoir une macro qui ajoute la version html et laisse l'original en texte / clair.
pepper_chico

2
En fin de compte, j'ai construit ma propre configuration pour ce nosubstance.me/post/mutt-secret-sauce
pepper_chico


1

Sendmail n'est souvent pas enogh flexible pour l'envoi de mails.

J'utilise msmtp avec mutt sur des comptes particuliers pour SMTP flexible.

Pour l'utiliser avec mutt change:

# ~/.muttrc  
set sendmail="/usr/bin/msmtp -a default"   

et

# ~/.msmtprc  
defaults
tls off
logfile ~/.msmtp.log  
account default   
host your.smtp.host  
port 25  
from your-user-name@your-host.com  
auth off  
user username  
password password  

0

J'ai pu le faire. Je ne suis pas entièrement satisfait de ma solution mais elle est assez décente. Attendre que quelqu'un d'autre apporte une meilleure solution.

Le processus suit. Convertissez le markdown en html et joignez-le au message. Transformez cette pièce jointe en inlinepièce jointe. Mais maintenant, j'ai deux pièces jointes, la première est en démarque et la seconde en html. Remplacez le contenu de démarque par une chaîne vide afin que seul le html soit envoyé.

J'ai ajouté la ligne suivante au ~/.muttrcfichier.

macro compose B ":set editor=text2mime-markdown.py<enter>E:set editor=email-editor<enter>Da/tmp/html-markdown-alternative.html<enter>^Du"

Voici email-editorce qui est emprunté au lien affiché en question.

#!/bin/sh
if grep -q In-Reply-To $1; then
  # Jump to first line of message
  exec vim -c 'norm }j' $1
else
  # Enter insert mode on the To: line
  exec vim  $1
fi

Et le fichier python principal qui est appelé suit. Ceci est inspiré du script perl du lien en question.

#!/usr/bin/env python
import os
import sys
from formatter import *
version = "0.1"

file = sys.argv[1]
new_file = "/tmp/html-markdown-alternative.html"
with open(file, "r") as f:
    text = f.read()

lines = text.split('\n')
header = []
body = []
headerStart = True
for l in lines:
    if headerStart:
        m = re.search(r'^[\w\-]+\:', l)
        if m:
            header.append(l)
        else:
            headerStart = False
            body.append(l)
    else:
        body.append(l)

header = '\n'.join(header)
body = '\n'.join(body)

htmlBody = markdownToHtml(body);

html = []
html.append('<html>')
html.append('<head>')
html.append('<meta name=\"generator\" content=\"text2mime-markdown{}\">'.format(version))
html.append('<style>')
html.append("code { font-family: 'Andale Mono', 'Lucida Console', \
        'Bitstream Vera Sans Mono', 'Courier New', monospace; }")
html.append('pre { border-left: 20px solid #ddd; margin-left: 10px; \
        padding-left: 5px; }')
html.append('</style>')
html.append('</head>')
html.append('<body>')
html.append('{0}'.format(body))
html.append('</body>')
html.append('</html>')
html = '\n'.join(html)

with open(new_file, "w") as newF:
    newF.write(html)

with open(file, 'w') as f:
    f.write(header)

Cela dépend d'un autre fichier python appelé formatter.pyqui utilise pandocpour formater mon courrier mais s'il pandocn'est pas disponible, il peut utiliser le python-markdown2package. Ce script suit.

import subprocess
import re
import os 
import sys
import html2text 
import collections

# check if pandoc exists
panDoc = True
try:
    subprocess.call(["pandoc", '--version']
            , stdout=subprocess.PIPE
            , stdin=subprocess.PIPE
            )
except OSError:
    panDoc = False

if not panDoc:
    import text.html2text as html2text
    import markdown 

def decodeText(text):
    return text.decode('utf-8')

def markdownToHtml(content, convertor='pandoc'):
    global panDoc
    if panDoc:
        cmd = ["pandoc", "-f", "markdown", "-t", "html"]
        p = subprocess.Popen(cmd
                , stdin = subprocess.PIPE
                , stdout = subprocess.PIPE
                )
        p.stdin.write(content)
        content = p.communicate()[0]
        return decodeText(content)
    else:
        return markdown.markdown(decodeText(content))


def htmlToMarkdown(content, convertor='pandoc'):
    global panDoc
    if panDoc and convertor == 'pandoc':
        cmd = ["pandoc", "-t", "markdown", "-f", "html"]
        p = subprocess.Popen(cmd
                , stdin = subprocess.PIPE
                , stdout = subprocess.PIPE
                )
        p.stdin.write(content)
        content = p.communicate()[0]
        return decodeText(content)
    # Use markdown package to convert markdown to html
    else:
        h = html2text.HTML2Text()
        content = h.handle(decodeText(content))
        return content

def titleToBlogDir(title):
    if title is None:
        return ''
    if len(title.strip()) == 0:
        return ''
    blogDir = title.replace(" ","_").replace(':', '-').replace('(', '')
    blogDir = blogDir.replace('/', '').replace('\\', '').replace('`', '')
    blogDir = blogDir.replace(')', '').replace("'", '').replace('"', '')
    return blogDir

def titleToFilePath(title, blogDir):
    if len(blogDir.strip()) == 0:
        return ''
    fileName = os.path.join(blogDir, titleToBlogDir(title))
    return fileName


def htmlToHtml(html):
    return decodeText(html)

def metadataDict(txt):
    mdict = collections.defaultdict(list)
    md = getMetadata(txt)
    for c in ["title", 'type', "layout", "status", "id", "published", "category", "tag"]:
        pat = re.compile(r'{0}\:\s*(?P<name>.+)'.format(c), re.IGNORECASE)
        m = pat.findall(txt)
        for i in m:
            mdict[c].append(i)
    return mdict

def getMetadata(txt):
   """
   Get metadata out of a txt
   """
   if not "---" in txt:
       print txt
       sys.exit(1)

   pat = re.compile(r'\-\-\-+(?P<metadata>.+?)\-\-\-+', re.DOTALL)
   m = pat.search(txt)
   if m:
       return m.group('metadata')
   else:
       sys.exit(0)

def getContent(txt):
    """ 
    Return only text of the post.
    """
    pat = re.compile(r'\-\-\-+(?P<metadata>.+?)\-\-\-+', re.DOTALL)
    return re.sub(pat, "", txt)

def readInputFile(fileName):
    """
    read file and return its format. html or markdown
    """
    assert fileName
    if not os.path.exists(fileName):
        raise IOError, "File %s does not exists" % fileName

    # Check the fmt of file.
    fmt = os.path.splitext(fileName)[1].lower()
    if fmt in ["htm", "html", "xhtml"]:
        fmt = "html"
    elif fmt in ["md", "markdown"]:
        fmt = "markdown"
    else:
        fmt = "markdown"
    txt = open(fileName, 'r').read()   
    return (fmt, txt)

def formatContent(txt, fmt):
    """
    Format the content as per fmt.
    """
    content = getContent(txt)
    if fmt == "html":
        content = htmlToHtml(content)
    elif fmt == "markdown":
        content = markdownToHtml(content)
    else:
        content = markdownToHtml(content)
    return content

Ces fichiers sont également disponibles ici https://github.com/dilawar/mutt


0

Je peux envoyer des e-mails dans n'importe quel format en utilisant neomutt. J'utilise simplement Emacs(org-mode), au lieu de vim. Bien que je sois également un vimutilisateur. Mais, j'utilise principalement Emacsavec le mode diabolique.

Dans mon .muttrcj'ai mis en place l'éditeur pour être emacsau lieu de vim. Lors de la rédaction d'un nouvel e-mail, se neomuttdéclenche emacs. Ensuite, j'appelle "org-mode", j'écris le message et je l'exporte dans le format que je veux.

Je peux exporter au PDFformat. Ensuite, je l'enregistre et attache le PDFfichier dans mon /tmp. Après cela, je peux envoyer à qui que ce soit.

Si je veux le htmlformat, je l'exporte de la même manière et je peux automatiquement voir la sortie, avant d'envoyer l'e-mail.

En dehors de cela, il existe de nombreux autres formats d'exportation en mode org. Choisissez simplement ce que vous voulez. Pour envoyer du code à d'autres personnes, ajoutez simplement le code source dans la langue de votre choix. Tout est expliqué dans l' org-wiki .


0

Vous pouvez également envoyer des e-mails en tant que multipart/alternativecontenant à la fois text/plainet text/html.

Exigences: pandoc

Fondamentalement, il crée à partir du texte en clair du message de démarquage et du html5. Crée des pièces jointes à partir de ces pièces, les marque comme pièces jointes en ligne, définit le type MIME correct et les combine dans un message à plusieurs parties.

Toutes les autres pièces jointes sont censées être ajoutées après l'exécution de cette macro dans le menu de composition. En option, la signature / le cryptage du message doit être effectué comme étape finale

macro compose ,m \
"<enter-command>set pipe_decode<enter>\
<pipe-message>pandoc -f gfm -t plain -o /tmp/msg.txt<enter>\
<pipe-message>pandoc -s -f gfm -t html5 -o /tmp/msg.html<enter>\
<enter-command>unset pipe_decode<enter>a^U/tmp/msg.txt\n^Da^U/tmp/msg.html\n^D^T^Utext/html; charset=utf-8\n=DTT&d^U\n" \
"Convert markdown gfm to HTML and plain" 
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.