[^\s]+\.(%s)(?:/[^\s()\":]*?|([^\s()\":]*\([^\s()\":]*\)[^\s()\":]*))?)(?=([:;\?\),\.\'\"]\Z|[:;\?\),\.\'\"]\s|\Z|\s))" % (tlds,)
md.inlinePatterns.add('autolink', AutoLink(link_regex), '>http_autolink')
md.preprocessors.add('hanging_ulists',
BugdownUListPreprocessor(md),
"_begin")
md.treeprocessors.add("inline_images", InlineImagePreviewProcessor(md), "_end")
md.treeprocessors.add("inline_interesting_links", InlineInterestingLinkProcessor(md), "_end")
_md_engine = markdown.Markdown(
safe_mode = 'escape',
output_format = 'html',
extensions = ['nl2br',
codehilite.makeExtension(configs=[
('force_linenos', False),
('guess_lang', False)]),
fenced_code.makeExtension(),
Bugdown()])
# We want to log Markdown parser failures, but shouldn't log the actual input
# message for privacy reasons. The compromise is to replace all alphanumeric
# characters with 'x'.
#
# We also use repr() to improve reproducibility, and to escape terminal control
# codes, which can do surprisingly nasty things.
_privacy_re = re.compile(r'\w', flags=re.UNICODE)
def _sanitize_for_log(md):
return repr(_privacy_re.sub('x', md))
def convert(md):
"""Convert Markdown to HTML, with Humbug-specific settings and hacks."""
# Reset the parser; otherwise it will get slower over time.
_md_engine.reset()
try:
# Spend at most 5 seconds rendering.
# Sometimes Python-Markdown is really slow; see
# https://trac.humbughq.com/ticket/345
html = timeout(5, _md_engine.convert, md)
except:
from zephyr.models import Recipient
from zephyr.lib.actions import internal_send_message
cleaned = _sanitize_for_log(md)
html = '[Humbug note: Sorry, we could not understand the formatting of your message]
'
# Output error to log as well as sending a humbug and email
logging.getLogger('').error('Exception in Markdown parser: %sInput (sanitized) was: %s'
% (traceback.format_exc(), cleaned))
subject = "Markdown parser failure"
internal_send_message("humbug+errors@humbughq.com",
Recipient.STREAM, "devel", subject,
"Markdown parser failed, message sent to devel@")
mail.mail_admins(subject, "Failed message: %s\n\n%s\n\n" % (
cleaned, traceback.format_exc()),
fail_silently=False)
return html