test bkp
This commit is contained in:
1 parent
6ccab0347b
commit
954a2fd6d6
18684 files changed
+601012
-190
No files matched your search
@@ -0,0 +1,228 @@
|
||||
"""
|
||||
Inline Highlighting.
|
||||
|
||||
pymdownx.inlinehilite
|
||||
|
||||
An alternative inline code extension that highlights code. Can
|
||||
use CodeHilite to source its settings or pymdownx.highlight.
|
||||
|
||||
`:::javascript var test = 0;`
|
||||
|
||||
- or -
|
||||
|
||||
`#!javascript var test = 0;`
|
||||
|
||||
Copyright 2014 - 2017 Isaac Muse <isaacmuse@gmail.com>
|
||||
"""
|
||||
|
||||
from markdown import Extension
|
||||
from markdown.inlinepatterns import InlineProcessor
|
||||
from markdown import util as md_util
|
||||
import xml.etree.ElementTree as etree
|
||||
import functools
|
||||
|
||||
ESCAPED_BSLASH = '{}{}{}'.format(md_util.STX, ord('\\'), md_util.ETX)
|
||||
DOUBLE_BSLASH = '\\\\'
|
||||
BACKTICK_CODE_RE = r'''(?x)
|
||||
(?:
|
||||
(?<!\\)(?P<escapes>(?:\\{2})+)(?=`+) | # Process code escapes before code
|
||||
(?<!\\)(?P<tic>`+)
|
||||
((?:\:{3,}|\#!)(?P<lang>[\w#.+-]*)\s+)? # Optional language
|
||||
(?P<code>.+?) # Code
|
||||
(?<!`)(?P=tic)(?!`) # Closing
|
||||
)
|
||||
'''
|
||||
|
||||
|
||||
class InlineHiliteException(Exception):
|
||||
"""InlineHilite exception."""
|
||||
|
||||
|
||||
def _escape(txt):
|
||||
"""Basic html escaping."""
|
||||
|
||||
txt = txt.replace('&', '&')
|
||||
txt = txt.replace('<', '<')
|
||||
txt = txt.replace('>', '>')
|
||||
return txt
|
||||
|
||||
|
||||
def _test(language, test_language=None):
|
||||
"""Test language."""
|
||||
|
||||
return test_language is None or test_language == '*' or language == test_language
|
||||
|
||||
|
||||
def _formatter(src="", language="", md=None, class_name="", fmt=None):
|
||||
"""Formatter wrapper."""
|
||||
|
||||
return fmt(src, language, class_name, md)
|
||||
|
||||
|
||||
class InlineHilitePattern(InlineProcessor):
|
||||
"""Handle the inline code patterns."""
|
||||
|
||||
def __init__(self, pattern, config, md):
|
||||
"""Initialize."""
|
||||
|
||||
self.config = config
|
||||
InlineProcessor.__init__(self, pattern, md)
|
||||
self.md = md
|
||||
|
||||
self.formatters = [
|
||||
{
|
||||
"name": "inlinehilite",
|
||||
"test": _test,
|
||||
"formatter": self.highlight_code
|
||||
}
|
||||
]
|
||||
|
||||
# Custom Fences
|
||||
custom_inline = self.config.get('custom_inline', [])
|
||||
for custom in custom_inline:
|
||||
name = custom.get('name')
|
||||
class_name = custom.get('class')
|
||||
inline_format = custom.get('format', self.highlight_code)
|
||||
if name is not None and class_name is not None:
|
||||
self.extend_custom_inline(
|
||||
name,
|
||||
functools.partial(_formatter, class_name=class_name, fmt=inline_format)
|
||||
)
|
||||
|
||||
self.get_hl_settings = False
|
||||
|
||||
def extend_custom_inline(self, name, formatter):
|
||||
"""Extend SuperFences with the given name, language, and formatter."""
|
||||
|
||||
obj = {
|
||||
"name": name,
|
||||
"test": functools.partial(_test, test_language=name),
|
||||
"formatter": formatter
|
||||
}
|
||||
|
||||
if name == '*':
|
||||
self.formatters[0] = obj
|
||||
else:
|
||||
self.formatters.append(obj)
|
||||
|
||||
def get_settings(self):
|
||||
"""Check for Highlight extension settings."""
|
||||
|
||||
if not self.get_hl_settings:
|
||||
self.get_hl_settings = True
|
||||
self.style_plain_text = self.config['style_plain_text']
|
||||
|
||||
config = None
|
||||
self.highlighter = None
|
||||
for ext in self.md.registeredExtensions:
|
||||
try:
|
||||
config = ext.get_pymdownx_highlight_settings()
|
||||
self.highlighter = ext.get_pymdownx_highlighter()
|
||||
break
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
css_class = self.config['css_class']
|
||||
self.css_class = css_class if css_class else config['css_class']
|
||||
|
||||
self.extend_pygments_lang = config.get('extend_pygments_lang', None)
|
||||
self.guess_lang = config['guess_lang']
|
||||
self.pygments_style = config['pygments_style']
|
||||
self.use_pygments = config['use_pygments']
|
||||
self.noclasses = config['noclasses']
|
||||
self.language_prefix = config['language_prefix']
|
||||
self.pygments_lang_class = config['pygments_lang_class']
|
||||
|
||||
def highlight_code(self, src='', language='', classname=None, md=None):
|
||||
"""Syntax highlight the inline code block."""
|
||||
|
||||
process_text = self.style_plain_text or language or self.guess_lang
|
||||
default_lang = self.style_plain_text if isinstance(self.style_plain_text, str) else ''
|
||||
|
||||
if process_text:
|
||||
el = self.highlighter(
|
||||
guess_lang=self.guess_lang,
|
||||
pygments_style=self.pygments_style,
|
||||
use_pygments=self.use_pygments,
|
||||
noclasses=self.noclasses,
|
||||
extend_pygments_lang=self.extend_pygments_lang,
|
||||
language_prefix=self.language_prefix,
|
||||
pygments_lang_class=self.pygments_lang_class,
|
||||
default_lang=default_lang
|
||||
).highlight(src, language, self.css_class, inline=True)
|
||||
el.text = self.md.htmlStash.store(el.text)
|
||||
else:
|
||||
el = etree.Element('code')
|
||||
el.text = self.md.htmlStash.store(_escape(src))
|
||||
return el
|
||||
|
||||
def handle_code(self, lang, src):
|
||||
"""Handle code block."""
|
||||
|
||||
for entry in reversed(self.formatters):
|
||||
if entry["test"](lang):
|
||||
value = entry["formatter"](
|
||||
src=src,
|
||||
language=lang,
|
||||
md=self.md
|
||||
)
|
||||
if isinstance(value, str):
|
||||
value = self.md.htmlStash.store(value)
|
||||
return value
|
||||
|
||||
def handleMatch(self, m, data):
|
||||
"""Handle the pattern match."""
|
||||
|
||||
if m.group('escapes'):
|
||||
return m.group('escapes').replace(DOUBLE_BSLASH, ESCAPED_BSLASH), m.start(0), m.end(0)
|
||||
else:
|
||||
lang = m.group('lang') if m.group('lang') else ''
|
||||
src = m.group('code').strip()
|
||||
self.get_settings()
|
||||
try:
|
||||
return self.handle_code(lang, src), m.start(0), m.end(0)
|
||||
except InlineHiliteException:
|
||||
raise
|
||||
except Exception:
|
||||
return m.group(0), None, None
|
||||
|
||||
|
||||
class InlineHiliteExtension(Extension):
|
||||
"""Add inline highlighting extension to Markdown class."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize."""
|
||||
|
||||
self.inlinehilite = []
|
||||
self.config = {
|
||||
'style_plain_text': [
|
||||
0,
|
||||
"Process inline code even when a language is not specified. "
|
||||
"When 'False', no classes will be added to code blocks without shebangs "
|
||||
"and no scoping will performed. The content will just be escaped."
|
||||
"If a language string is provided, then that language will be assumed "
|
||||
"for any inline code block without a shebang. "
|
||||
"- Default: False"
|
||||
],
|
||||
'css_class': [
|
||||
'',
|
||||
"Set class name for wrapper element. The default of Highlight will be used"
|
||||
"if nothing is set. - "
|
||||
"Default: ''"
|
||||
],
|
||||
'custom_inline': [[], "Custom inline - default []"]
|
||||
}
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def extendMarkdown(self, md):
|
||||
"""Add support for `:::language code` and `#!language code` highlighting."""
|
||||
|
||||
config = self.getConfigs()
|
||||
md.inlinePatterns.register(InlineHilitePattern(BACKTICK_CODE_RE, config, md), "backtick", 190)
|
||||
md.registerExtensions(["pymdownx.highlight"], {"pymdownx.highlight": {"_enabled": False}})
|
||||
|
||||
|
||||
def makeExtension(*args, **kwargs):
|
||||
"""Return extension."""
|
||||
|
||||
return InlineHiliteExtension(*args, **kwargs)
|
||||
Reference in new issue
Block a user