X-Git-Url: https://git.madduck.net/etc/mutt.git/blobdiff_plain/0e22b3603ff0a4f8c672ff9585b32ccb2ee4c424..a83d50d5a64488deb3796bbd0ca0a03b0516cc77:/.mutt/markdown2html?ds=inline diff --git a/.mutt/markdown2html b/.mutt/markdown2html index 7853ae5..487d3db 100755 --- a/.mutt/markdown2html +++ b/.mutt/markdown2html @@ -48,18 +48,21 @@ except ImportError: DEFAULT_CSS += ''' -.quote { +.block { + padding: 0 0.5em; + margin: 0; + border-left: 2px solid #eee; +} +.quote, blockquote { padding: 0 0.5em; margin: 0; font-style: italic; - border-left: 2px solid #ccc; - color: #999; + border-left: 2px solid #666; + color: #666; font-size: 80%; } .quotelead { - font-style: italic; margin-bottom: -1em; - color: #999; font-size: 80%; } .quotechar { display: none; } @@ -80,6 +83,19 @@ th, td { padding: 0.5em; } background: #eee; } .even { background: #eee; } +h1, h2, h3, h4, h5, h6 { + color: #666; + background-color: #eee; + padding-left: 0.5em +} +h1 { font-size: 130%; } +h2 { font-size: 120%; } +h3 { font-size: 110%; } +h4 { font-size: 107%; } +h5 { font-size: 103%; } +h6 { font-size: 100%; } +p { padding: 0 0.5em; } +pre { padding: 0 1em; } ''' STYLESHEET = os.path.join(os.path.expanduser('~/.mutt'), @@ -87,21 +103,16 @@ STYLESHEET = os.path.join(os.path.expanduser('~/.mutt'), if os.path.exists(STYLESHEET): DEFAULT_CSS += open(STYLESHEET).read() -HTML_DOCUMENT = ''' - - - - -HTML E-Mail - -{htmlbody} -''' - - SIGNATURE_HTML = \ '
-- {sig}
' +def _preprocess_signature(sig): + ''' + Preprocess the signature before markdown processing. + ''' + return sig + def _preprocess_markdown(mdwn): ''' Preprocess Markdown for handling by the converter. @@ -119,6 +130,13 @@ def _preprocess_markdown(mdwn): # text-mode HTML2text converters, and so it's left commented for now. #ret = re.sub(r'\n>', r' \n>[>]{.quotechar}', ret, flags=re.MULTILINE) + # With the autolink_bare_uris extension, we do not need to put links into + # angle brackets to have them converted, so let's conserve the brackets + # when used around email addresses. Note that this needs a postprocessing + # hack because the pandoc autolink converted includes the ambersand + # (https://github.com/jgm/pandoc/issues/7398). + ret = re.sub(r'<([^@]+@.+\.[^>]+)>', r'<\g<1> -PANDOC_BUG_7398->', ret) + return ret @@ -160,7 +178,7 @@ def _identify_quotes_for_later(mdwn): # The lead-in to a quote is a single line immediately preceding the # quote, and ending with ':'. Note that there could be multiple of # these: - if re.match(r'^.+:\s*$', cur) and nxt.startswith('>'): + if re.match(r'^[^>]+.*:\s*$', cur) and nxt.startswith('>'): ret.append(f'{{.quotelead}}{cur.strip()}') # pandoc needs an empty line before the blockquote, so # we enter one for the purpose of HTML rendition: @@ -169,13 +187,13 @@ def _identify_quotes_for_later(mdwn): # The first blockquote after such a lead-in gets marked as the # "initial" quote: - elif prev and re.match(r'^.+:\s*$', prev) and cur.startswith('>'): + elif prev and re.match(r'^[^>]+.*:\s*$', prev) and cur.startswith('>'): ret.append(re.sub(r'^(\s*>\s*)+(.+)', r'\g<1>{.quoteinitial}\g<2>', cur, flags=re.MULTILINE)) # All other occurrences of blockquotes get the "subsequent" marker: - elif cur.startswith('>') and prev and not prev.startswith('>'): + elif cur.startswith('>') and prev is not None and not prev.startswith('>'): ret.append(re.sub(r'^((?:\s*>\s*)+)(.+)', r'\g<1>{.quotesubsequent}\g<2>', cur, flags=re.MULTILINE)) @@ -200,7 +218,7 @@ def _reformat_quotes(html): def _convert_with_pandoc(mdwn, inputfmt='markdown', outputfmt='html5', ext_enabled=None, ext_disabled=None, - standalone=True, title="HTML E-Mail"): + standalone=True, selfcontained=True, title=None): ''' Invoke pandoc to do the actual conversion of Markdown to HTML5. ''' @@ -227,6 +245,7 @@ def _convert_with_pandoc(mdwn, inputfmt='markdown', outputfmt='html5', 'inline_notes', 'emoji', 'tex_math_double_backslash', + 'autolink_bare_uris' ] if not ext_disabled: ext_disabled = [ 'tex_math_single_backslash', @@ -242,6 +261,8 @@ def _convert_with_pandoc(mdwn, inputfmt='markdown', outputfmt='html5', args = [] if standalone: args.append('--standalone') + if selfcontained: + args.append('--self-contained') if title: args.append(f'--metadata=pagetitle:"{title}"') @@ -260,6 +281,10 @@ def _postprocess_html(html): ''' Postprocess the generated and styled HTML. ''' + + # Preprocessing leaves a sentinel to work around + # https://github.com/jgm/pandoc/issues/7398, and so we need to remove it: + html = html.replace(' -PANDOC_BUG_7398->', '>') return html @@ -279,14 +304,19 @@ def convert_markdown_to_html(mdwn): if body: body = _preprocess_markdown(body) body = _identify_quotes_for_later(body) - html = _convert_with_pandoc(body, standalone=False) + html = _convert_with_pandoc(body, standalone=True, selfcontained=True, + title=None) + html = html.replace('Untitled\n','') html = _reformat_quotes(html) if sig: + sig = _preprocess_signature(sig) sig = _preprocess_markdown(sig) - html += SIGNATURE_HTML.format(sig='
'.join(sig.splitlines())) + sig = _convert_with_pandoc(sig, standalone=False, selfcontained=False) + sig = SIGNATURE_HTML.format(sig='
'.join(sig.splitlines())) + eob = html.find('') + html = f'{html[:eob]}{sig}\n{html[eob:]}' - html = HTML_DOCUMENT.format(htmlbody=html) html = _apply_styling(html) html = _postprocess_html(html)