ส่งอีเมลที่เขียนใน markdown โดยใช้ mutt


21

บางครั้งฉันต้องส่งรหัสในส่วนของ google-inline ข้อความไม่ได้ช่วยที่นี่; ฉันสามารถพิมพ์เป็น markdown แปลงเป็น html (โดยใช้ pandoc เป็นต้น) แนบกับ mutt as text/htmlและส่ง

มีวิธีแก้ไขปัญหาที่ดีอยู่ที่นี่แต่ใช้sendmailโปรแกรมภายนอกเพื่อส่งอีเมล ฉันใช้ mutt ซึ่งมีความสามารถในการส่งอีเมลผ่าน IMAPด้วยตัวเอง


1
ทำไมไม่เพียงแค่ไพพ์เอาท์พุทจากตัวจัดรูปแบบบรรทัดคำสั่ง Markdown เป็นsendmail?
Naftuli Kay 9'14

อืม .. คอมพิวเตอร์ที่ใช้ร่วมกัน! ไม่ต้องการจัดเก็บรหัสผ่านสำหรับ sendmail ภายนอก
Dilawar

มีตัวอย่างใดบ้างที่เราเห็นว่าผลลัพธ์ปัจจุบันของคุณเป็นอย่างไรใน google-groups
slm

นอกจากนี้คุณต้องการที่จะพิมพ์สิ่งต่าง ๆ ใน markdown แต่พวกเขามีการแสดงผลก่อนที่จะแนบไปกับอีเมลของคุณใช่ไหม?
slm

เสียงนี้เหมือนสิ่งที่คุณขอ แต่อาจจะต้องมีการแก้ไข: dgl.cx/2009/03/html-mail-with-mutt-using-markdown นอกจากนี้ยังmarkdownmail.pyฟังเหมือนสิ่งที่คุณสามารถใช้
slm

คำตอบ:


28

หลังจากที่คุณเขียนข้อความ แต่ก่อนที่จะส่งคุณมีตัวเลือกมากมายให้คุณ กด?เพื่อดู

บางอย่างที่อาจช่วยได้ที่นี่:

  • F เพื่อกรองสิ่งที่แนบมาผ่านโปรเซสเซอร์ภายนอก
    • ใช้pandoc -s -f markdown -t htmlในการแปลงเป็น HTML
  • ^T เพื่อแก้ไขประเภทไฟล์แนบ MIME
    • เปลี่ยนจากการtext/plaintext/html

ตอนนี้แมโครที่จะทำทุกอย่างในขั้นตอนเดียว เพิ่มลงในของคุณ.muttrc:

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

ในการใช้มาโครนี้หลังจากที่คุณเขียนข้อความเสร็จแล้ว แต่ก่อนที่จะส่งให้กดEscจากนั้น5เพื่อแปลงข้อความที่จัดรูปแบบมาร์กอัปเป็น HTML

คุณสามารถกำหนดแมโครนี้เองตามที่เห็นเหมาะสม Mutt มีการเชื่อมโยงคีย์จำนวนมากที่สร้างไว้แล้วดังนั้นลำดับคีย์ใด ๆ ที่คุณเลือกที่จะผูกให้แน่ใจว่ามันจะไม่เขียนทับสิ่งอื่นใด (หรือเป็นสิ่งที่คุณขาดไม่ได้)


ตัวเลือกนี้จะset wait_key=noไม่แสดงPress any key to continue...พรอมต์ของ Mutt เมื่อเรียกใช้คำสั่งภายนอก หากwait_keyเป็นyes(ซึ่งเป็นค่าเริ่มต้น) คุณจะต้องกดEscจากนั้นกดปุ่ม5อื่น ๆ เพื่อดำเนินการต่อ


1
นี่เป็นทางออกที่สง่างามจริงๆ! +1
sinisterstuf

5
นี่เป็นสิ่งที่ดี แต่มีข้อบกพร่องหลัก มันกำจัดส่วนข้อความธรรมดาของอีเมลซึ่งทำให้การอ่านในไคลเอนต์เช่น ... mutt;) อีเมล HTML ควรมีข้อความธรรมดาและส่วนประกอบ HTML markdown ดิบควรเป็นข้อความธรรมดา, การแปลงควรเป็น HTML
masukomi

1
เห็นด้วยกับ @masukomi โดยทั่วไปลูกค้าอีเมลจะส่งทั้งอีเมลในรูปแบบ html และข้อความ มันจะเป็นการดีถ้ามีแมโครที่เพิ่มเวอร์ชัน html และปล่อยต้นฉบับเป็นข้อความ / ธรรมดา
pepper_chico

2
ในท้ายที่สุดฉันได้สร้างการตั้งค่าของตัวเองสำหรับnosubstance.me/post/mutt-secret-sauce
pepper_chico


1

Sendmail มักไม่ยืดหยุ่นสำหรับการส่งอีเมล

ฉันใช้ msmtp ร่วมกับ mutt สำหรับบัญชีเฉพาะสำหรับ SMTP แบบยืดหยุ่น

วิธีใช้กับ mutt change:

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

และ

# ~/.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

ฉันสามารถทำมันได้ ฉันไม่พอใจกับวิธีการแก้ปัญหาของฉันทั้งหมด แต่ก็ดีพอ รอให้คนอื่นหาทางออกที่ดีกว่า

กระบวนการดังต่อไปนี้ แปลง markdown เป็น html และแนบไปกับข้อความ เปลี่ยนไฟล์แนบเป็นinlineไฟล์แนบ แต่ตอนนี้ฉันมีไฟล์แนบสองไฟล์สิ่งแรกคือใน markdown และอันที่สองคือ html แทนที่เนื้อหา markdown ด้วยสตริงว่างเพื่อส่งเฉพาะ html

ฉันเพิ่มบรรทัดต่อไปนี้ไปยัง~/.muttrcไฟล์

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

นี่คือemail-editorสิ่งที่ยืมมาจากลิงค์โพสต์ในคำถาม

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

และไฟล์ไพ ธ อนหลักที่เรียกว่ากำลังติดตาม นี่เป็นแรงบันดาลใจจากสคริปต์ Perl จากลิงก์ที่เป็นปัญหา

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

ขึ้นอยู่กับไฟล์งูหลามอีกหนึ่งไฟล์formatter.pyซึ่งใช้pandocในการฟอร์แมตเมลของฉัน แต่ถ้าpandocไม่พร้อมใช้งานก็สามารถใช้python-markdown2แพ็คเกจได้ สคริปต์นี้กำลังติดตาม

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

ไฟล์เหล่านี้มีให้ที่นี่https://github.com/dilawar/mutt


0

ฉันสามารถส่งอีเมล์ในรูปแบบใด ๆ neomuttโดยใช้ ฉันเพียงแค่ใช้Emacs(องค์กรโหมด) vimแทน แม้ว่าฉันเป็นvimผู้ใช้เช่นกัน แต่ส่วนใหญ่ฉันใช้Emacsกับโหมดชั่วร้าย

ในของฉัน.muttrcฉันได้ตั้งค่าแก้ไขที่จะแทนemacs vimเมื่อเขียนอีเมลใหม่neomuttไฟemacsขึ้น จากนั้นฉันเรียกว่า "โหมดองค์กร" เขียนข้อความและส่งออกไปยังรูปแบบใดก็ได้ที่ฉันต้องการ

ฉันสามารถส่งออกเป็นPDFรูปแบบ แล้วฉันบันทึกและแนบไฟล์ในของฉันPDF /tmpหลังจากนั้นฉันสามารถส่งไปที่ใครก็ได้

หากฉันต้องการhtmlรูปแบบฉันส่งออกด้วยวิธีเดียวกันและฉันสามารถดูผลลัพธ์โดยอัตโนมัติก่อนที่จะส่งอีเมล

นอกจากนั้นยังมีรูปแบบการส่งออกอื่น ๆ อีกมากมายในโหมดองค์กร เพียงเลือกสิ่งที่คุณต้องการ สำหรับการส่งรหัสไปยังบุคคลอื่นเพียงเพิ่มซอร์สโค้ดในภาษาที่คุณต้องการ ทุกอย่างจะมีการอธิบายในorg-วิกิพีเดีย


0

คุณสามารถส่งอีเมลยังเป็นmultipart/alternativeที่มีทั้งและtext/plaintext/html

ข้อกำหนด: pandoc

โดยทั่วไปจะสร้างจากข้อความธรรมดามาร์คและ html5 สร้างสิ่งที่แนบมาจากชิ้นส่วนเหล่านั้นทำเครื่องหมายว่าเป็นสิ่งที่แนบมาแบบอินไลน์ตั้งค่าประเภท mime ที่ถูกต้องและรวมไว้ในข้อความ mutlipart

สิ่งที่แนบอื่น ๆ ควรจะเพิ่มหลังจากเรียกใช้แมโครนี้ในเมนูเขียน ข้อความที่เป็นทางเลือกการเซ็นชื่อ / การเข้ารหัสควรทำตามขั้นตอนสุดท้าย

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" 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.