--- a/eric6/QScintilla/Exporters/ExporterHTML.py Wed Oct 23 19:57:12 2019 +0200 +++ b/eric6/QScintilla/Exporters/ExporterHTML.py Wed Oct 23 19:57:49 2019 +0200 @@ -525,56 +525,116 @@ ) return "" - try: - import mdx_mathjax # __IGNORE_EXCEPTION__ __IGNORE_WARNING__ - except ImportError: - # mathjax doesn't require import statement if installed as - # extension - pass - - if Preferences.getEditor("PreviewMarkdownNLtoBR"): - extensions = ['fenced_code', 'nl2br', 'extra'] - else: - extensions = ['fenced_code', 'extra'] + extensions = [] + if Preferences.getEditor("PreviewMarkdownUsePyMdownExtensions"): + try: + import pymdownx # __IGNORE_EXCEPTION__ __IGNORE_WARNING__ + # PyPI package is 'pymdown-extensions' + + extensions = [ + 'pymdownx.extra', 'pymdownx.caret', 'pymdownx.emoji', + 'pymdownx.mark', 'pymdownx.tilde', 'pymdownx.keys', + 'pymdownx.tasklist', 'pymdownx.smartsymbols', + ] + if Preferences.getEditor("PreviewMarkdownNLtoBR"): + extensions.append('nl2br') + except ImportError: + pass + if not extensions: + if Preferences.getEditor("PreviewMarkdownNLtoBR"): + extensions = ['fenced_code', 'nl2br', 'extra'] + else: + extensions = ['fenced_code', 'extra'] + + # version 2.0 supports only extension names, not instances + if ( + markdown.version_info[0] > 2 or + (markdown.version_info[0] == 2 and + markdown.version_info[1] > 0) + ): + class _TildeExtension(markdown.Extension): + """ + Class is placed here, because it depends on imported + markdown, and markdown import is lazy. + + (see https://pythonhosted.org/Markdown/extensions/api.html + this page for details) + """ + DEL_RE = r'(~~)(.+?)~~' + SUB_RE = r'(~)(.+?)~' + + def extendMarkdown(self, md, md_globals): + # Create the sub pattern and insert it into markdown + # parser + sub_tag = markdown.inlinepatterns.SimpleTagPattern( + self.SUB_RE, 'sub') + md.inlinePatterns.add('sub', sub_tag, '>not_strong') + + # Create the del pattern and insert it into markdown + # parser + del_tag = markdown.inlinepatterns.SimpleTagPattern( + self.DEL_RE, 'del') + md.inlinePatterns.add('del', del_tag, '>not_strong') + + class _CaretExtension(markdown.Extension): + """ + Class is placed here, because it depends on imported + markdown, and markdown import is lazy. + + (see https://pythonhosted.org/Markdown/extensions/api.html + this page for details) + """ + INS_RE = r'(\^\^)(.*?)\^\^' + SUP_RE = r'(\^)(.*?)\^' + + def extendMarkdown(self, md, md_globals): + # Create the sup pattern and insert it into markdown + # parser + sup_tag = markdown.inlinepatterns.SimpleTagPattern( + self.SUP_RE, 'sup') + md.inlinePatterns.add('sup', sup_tag, '>not_strong') + + # Create the ins pattern and insert it into markdown + # parser + ins_tag = markdown.inlinepatterns.SimpleTagPattern( + self.INS_RE, 'ins') + md.inlinePatterns.add('ins', ins_tag, '>not_strong') + + class _MarkExtension(markdown.Extension): + """ + Class is placed here, because it depends on imported + markdown, and markdown import is lazy. + + (see https://pythonhosted.org/Markdown/extensions/api.html + this page for details) + """ + MARK_RE = r'(==)(.*?)==' + + def extendMarkdown(self, md, md_globals): + # Create the mark pattern and insert it into markdown + # parser + mark_tag = markdown.inlinepatterns.SimpleTagPattern( + self.MARK_RE, 'mark') + md.inlinePatterns.add('mark', mark_tag, '>not_strong') + + extensions.extend([ + _TildeExtension(), _CaretExtension(), _MarkExtension() + ]) - # version 2.0 supports only extension names, not instances - if ( - markdown.version_info[0] > 2 or - (markdown.version_info[0] == 2 and - markdown.version_info[1] > 0) - ): - class _StrikeThroughExtension(markdown.Extension): - """ - Class is placed here, because it depends on imported markdown, - and markdown import is lazy. - - (see http://achinghead.com/ - python-markdown-adding-insert-delete.html this page for - details) - """ - DEL_RE = r'(~~)(.*?)~~' - - def extendMarkdown(self, md, md_globals): - # Create the del pattern - del_tag = markdown.inlinepatterns.SimpleTagPattern( - self.DEL_RE, 'del') - # Insert del pattern into markdown parser - md.inlinePatterns.add('del', del_tag, '>not_strong') - - extensions.append(_StrikeThroughExtension()) + if Preferences.getEditor("PreviewMarkdownMathJax"): + mathjax = ( + "<script type='text/javascript' id='MathJax-script' async" + " src='https://cdn.jsdelivr.net/npm/mathjax@3/es5/" + "tex-chtml.js'>\n" + "</script>\n" + ) + else: + mathjax = "" htmlFormat = Preferences.getEditor("PreviewMarkdownHTMLFormat").lower() - try: - body = markdown.markdown(self.editor.text(), - extensions=extensions + ['mathjax'], - output_format=htmlFormat) - except (ImportError, ValueError): - # markdown raises ValueError or ImportError, depends on version - # It is not clear, how to distinguish missing mathjax from other - # errors. So keep going without mathjax. - body = markdown.markdown(self.editor.text(), - extensions=extensions, - output_format=htmlFormat) + body = markdown.markdown(self.editor.text(), + extensions=extensions, + output_format=htmlFormat) if htmlFormat == "xhtml1": head = ( @@ -602,9 +662,10 @@ '''<meta name="Generator" content="eric6" />\n''' '''<meta http-equiv="Content-Type" ''' '''content="text/html; charset=utf-8" />\n''' + '''{0}''' '''</head>\n''' '''<body>\n''' - ) + ).format(mathjax) foot = '''\n</body>\n</html>\n'''