Kirim email yang ditulis dalam bentuk markdown menggunakan mutt

21

Terkadang saya perlu mengirim sebuah fragmen kode di inline grup google. Teks tidak membantu di sini; Saya dapat mengetiknya di markdown, mengonversinya menjadi html (menggunakan pandoc dll), melampirkan mutt as text/htmldan mengirimkannya.

Ada satu solusi bagus yang tersedia di sini tetapi menggunakan sendmailprogram eksternal untuk mengirim email. Saya menggunakan mutt yang memiliki kemampuan untuk mengirim email melalui IMAP dengan sendirinya.

Dilawar
sumber
1
Mengapa tidak hanya pipa output dari baris perintah penurunan harga formatter ke sendmail?
Naftuli Kay
Hmm .. komputer bersama! Tidak ingin menyimpan kata sandi untuk sendmail eksternal.
Dilawar
Apakah ada contoh yang dapat kita lihat dari hasil pencarian Anda saat ini di google-groups?
slm
Anda juga ingin mengetikkan hal-hal dalam penurunan harga, tetapi sudahkah membuatnya sebelum melampirkannya di email Anda, bukan?
slm
Ini terdengar seperti apa yang Anda minta, tetapi mungkin perlu diubah: dgl.cx/2009/03/html-mail-with-mutt-using-markdown . Markdownmail.py juga terdengar seperti sesuatu yang bisa Anda gunakan.
slm

Jawaban:

28

Setelah Anda menulis pesan, tetapi sebelum mengirim Anda memiliki banyak pilihan yang tersedia untuk Anda. Tekan ?untuk melihatnya.

Beberapa yang mungkin membantu di sini:

  • F untuk memfilter lampiran melalui prosesor eksternal
    • Gunakan pandoc -s -f markdown -t htmluntuk mengonversi ke HTML
  • ^T untuk mengedit jenis lampiran MIME
    • Ubah dari text/plainmenjadi text/html.

Sekarang makro yang akan melakukan semuanya dalam satu langkah. Tambahkan ini ke Anda .muttrc:

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

Untuk menggunakan makro ini, setelah Anda selesai menulis pesan, tetapi sebelum mengirim, tekan Esclalu 5untuk mengonversi pesan berformat penurunan harga menjadi HTML.

Anda dapat menyesuaikan makro ini secara alami sesuai keinginan Anda. Mutt memiliki banyak ikatan kunci yang sudah ada di dalamnya, jadi apa pun urutan kunci yang Anda pilih untuk mengikat, pastikan itu tidak menimpa sesuatu yang lain (atau itu adalah sesuatu yang Anda dapat hidup tanpanya).


Opsi ini set wait_key=nomenekan Press any key to continue...prompt Mutt ketika perintah eksternal dijalankan. Jika wait_keyadalah yes(yang merupakan default) Anda harus pers Esc, maka 5, maka tombol lain untuk melanjutkan.

bahamat
sumber
1
Ini adalah solusi yang sangat elegan! +1
sinisterstuf
5
ini bagus, tapi ada cacat intinya. itu menghilangkan bagian plaintext dari email yang membuatnya payah untuk membaca di klien seperti ... mutt;) Email HTML harus memiliki komponen plaintext dan html. markdown mentah harus menjadi plaintext, yang dikonversi harus menjadi HTML.
masukomi
1
Setuju dengan @masukomi, klien email secara umum mengirim versi html dan teks email. Alangkah baiknya memiliki makro yang menambahkan versi html dan meninggalkan yang asli sebagai teks / polos.
pepper_chico
2
Pada akhirnya saya telah membangun pengaturan saya sendiri untuk nosubstance.me/post/mutt-secret-sauce
pepper_chico
1

Sendmail sering tidak fleksibel untuk mengirim surat.

Saya menggunakan msmtp bersama dengan mutt pada akun tertentu untuk SMTP fleksibel.

Untuk menggunakannya dengan perubahan mutt:

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

dan

# ~/.msmtprc  
defaults
tls off
logfile ~/.msmtp.log  
account default   
host your.smtp.host  
port 25  
from [email protected]  
auth off  
user username  
password password  

sumber
0

Saya bisa melakukannya. Saya tidak sepenuhnya senang dengan solusi saya tetapi cukup layak. Menunggu orang lain memberikan solusi yang lebih baik.

Prosesnya mengikuti. Konversikan markdown ke html dan lampirkan ke pesan. Ubah lampiran ini menjadi inlinelampiran. Tetapi sekarang saya memiliki dua lampiran, yang pertama adalah penurunan harga dan yang kedua adalah html. Ganti konten penurunan harga dengan string kosong sehingga hanya html yang dikirim.

Saya menambahkan baris berikut ke ~/.muttrcfile.

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

Disini adalah email-editor yang dipinjam dari tautan yang diposting dalam pertanyaan.

#!/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

Dan file python utama yang disebut mengikuti. Ini terinspirasi dari skrip perl dari tautan yang dimaksud.

#!/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)

Ini tergantung pada satu lagi file python yang disebut formatter.pyyang digunakan pandocuntuk memformat email saya tetapi jika pandoctidak tersedia dapat digunakanpython-markdown2 paket. Script ini mengikuti.

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

File-file ini juga tersedia di sini https://github.com/dilawar/mutt

Dilawar
sumber
0

Saya dapat mengirim email dalam format apa pun menggunakan neomutt. Saya hanya menggunakan Emacs(mode-org), bukan vim. Meskipun, saya juga vimpengguna. Tapi, saya lebih sering menggunakanEmacs mode kejahatan.

Di saya, .muttrcsaya telah mengatur editor menjadi emacsbukan vim. Saat menulis email baru, neomuttaktifkanemacs . Kemudian saya memanggil "mode-org", menulis pesan, dan mengekspor ke format apa pun yang saya inginkan.

Saya dapat mengekspor ke PDFformat. Lalu saya simpan dan lampirkan PDFfile di file saya/tmp . Setelah itu saya bisa mengirim ke siapa pun.

Jika saya mau html formatnya, saya mengekspornya dengan cara yang sama dan saya secara otomatis dapat melihat hasilnya, sebelum mengirim email.

Selain itu, ada banyak format ekspor lainnya dalam mode-org. Pilih saja yang Anda inginkan. Untuk mengirim kode ke orang lain, cukup tambahkan kode sumber ke bahasa apa pun yang Anda inginkan. Semuanya dijelaskan dalam org-wiki .

Achylles
sumber
0

Anda dapat mengirim email juga sebagai yang multipart/alternativemengandung keduanya text/plaindantext/html .

Persyaratan: pandoc

Pada dasarnya itu dibuat dari plaintext pesan markdown dan html5. Membuat lampiran dari bagian-bagian itu, menandainya sebagai lampiran sebaris, mengatur tipe mime yang benar dan menggabungkannya ke dalam pesan mutlipart.

Setiap lampiran lain seharusnya ditambahkan setelah menjalankan makro ini di menu penulisan. Secara opsional menandatangani / mengenkripsi pesan harus dilakukan sebagai langkah terakhir

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" 
Jakub Jindra
sumber