Надіслати електронний лист, написаний у розмітці, використовуючи mutt


21

Іноді мені потрібно надіслати фрагмент коду в рядку google-group. Текст тут не допомагає; Я можу ввести його в розмітку, перетворити її в html (використовуючи pandoc тощо), прикласти до mutt як text/htmlі надіслати.

Існує одне рішення добре доступний тут , але він використовує зовнішню sendmailпрограму для відправки електронної пошти. Я використовую mutt, який має можливості самостійно надсилати електронні листи через IMAP .


1
Чому б не просто вивести трубу з форматера Markdown командного рядка до sendmail?
Naftuli Kay

Хм .. спільний комп'ютер! Не хочете зберігати пароль для зовнішньої sendmail.
Ділавар

Чи є якісь приклади, які ми можемо побачити, як виглядають ваші поточні результати у google-групах?
slm

Крім того, ви хочете ввести речі в розмітку, але чи винесли їх перед приєднанням до своїх електронних листів, правда?
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/plainдо text/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. необмеженою відміткою повинен бути простий текст, перетвореним - HTML.
masukomi

1
Погодьтеся з @masukomi, клієнти електронної пошти взагалі надсилають як html, так і текстові версії електронного листа. Було б непогано мати макрос, який додає html-версію і залишає оригінал як текст / звичайний.
pepper_chico

2
Зрештою, я створив
pepper_chico


1

Sendmail часто не є гнучким enogh для надсилання електронної пошти.

Я використовую msmtp разом з mutt для конкретних акаунтів для гнучких SMTP.

Щоб використовувати його зі зміною mutt:

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

Я зміг це зробити. Я не зовсім радий своєму рішенню, але це досить пристойно. Чекаємо, коли хтось інший запропонує краще рішення.

Процес наступний. Перетворіть розмітку в HTML і приєднайте її до повідомлення. Перетворіть це вкладення на inlineвкладення. Але зараз у мене є два вкладення, перше - у розмітці, а друге - html. Замініть вміст розмітки порожнім рядком, щоб надсилався лише 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

І основний файл python, який викликається, наступний. Це натхнене сценарієм 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)

Це залежить від ще одного файлу python, 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(org-mode), а не vim. Хоча, я і vimкористувач. Але я здебільшого використовую Emacsзлий режим.

По моєму .muttrcя встановив редактор бути emacsзамість vim. Під час написання нового електронного листа neomuttзапускається emacs. Потім я закликаю "org-mode", пишу повідомлення та експортую в потрібний формат.

Я можу експортувати у PDFформат. Потім я зберігаю його і додаю PDFфайл до свого /tmp. Після цього я можу відправити когось.

Якщо я бажаю htmlформату, я експортую його таким же чином, і я автоматично бачу вихід, перш ніж надсилати електронний лист.

Крім цього, існує багато інших форматів експорту в org-режимі. Просто виберіть те, що ви хочете. Щоб надсилати код іншим людям, просто додайте вихідний код будь-якою мовою. Все пояснено в org-wiki .


0

Ви можете надсилати електронні листи також як та, multipart/alternativeщо містить text/plainі text/html.

Вимоги: пандок

В основному він створюється з розмітки повідомлення plaintext і html5. Створює вкладені файли з цих частин, позначає їх як вбудовані вкладення, встановлює правильний тип mime та поєднує їх у взаємне повідомлення.

Передбачається, що будь-які інші вкладення будуть додані після запуску цього макросу в меню складання. Необов'язково підписання / шифрування повідомлення повинно бути виконано як завершальний крок

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" 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.