Skip to content

codehilite

CodeHilite Extension for Python-Markdown.

Adds code/syntax highlighting to standard Python-Markdown code blocks.

See https://pythonhosted.org/Markdown/extensions/code_hilite.html for documentation.

Original code Copyright 2006-2008 Waylan Limberg.

All changes Copyright 2008-2014 The Python Markdown Project

License: BSD

Attributes

pygments = True module-attribute

Classes

CodeHilite(src=None, linenums=None, guess_lang=True, css_class='codehilite', lang=None, style='default', noclasses=False, tab_length=4, hl_lines=None, use_pygments=True)

Bases: object

Determine language of source code, and pass it into pygments hilighter.

Basic Usage
code = CodeHilite(src = 'some text')
html = code.hilite()
  • src: Source string or any object with a .readline attribute.

  • linenums: (Boolean) Set line numbering to 'on' (True), 'off' (False) or 'auto'(None). Set to 'auto' by default.

  • guess_lang: (Boolean) Turn language auto-detection 'on' or 'off' (on by default).

  • css_class: Set class name of wrapper div ('codehilite' by default).

  • hl_lines: (List of integers) Lines to emphasize, 1-indexed.

Low Level Usage
code = CodeHilite()
code.src = 'some text' # String or anything with a .readline attr.
code.linenos = True  # Turns line numbering on or of.
html = code.hilite()
Source code in pyrevitlib/pyrevit/coreutils/markdown/extensions/codehilite.py
def __init__(self, src=None, linenums=None, guess_lang=True,
             css_class="codehilite", lang=None, style='default',
             noclasses=False, tab_length=4, hl_lines=None, use_pygments=True):
    self.src = src
    self.lang = lang
    self.linenums = linenums
    self.guess_lang = guess_lang
    self.css_class = css_class
    self.style = style
    self.noclasses = noclasses
    self.tab_length = tab_length
    self.hl_lines = hl_lines or []
    self.use_pygments = use_pygments

Attributes

src = src instance-attribute
lang = lang instance-attribute
linenums = linenums instance-attribute
guess_lang = guess_lang instance-attribute
css_class = css_class instance-attribute
style = style instance-attribute
noclasses = noclasses instance-attribute
tab_length = tab_length instance-attribute
hl_lines = hl_lines or [] instance-attribute
use_pygments = use_pygments instance-attribute

Methods:

hilite()

Highlites the code.

Pass code to the Pygments highliter with optional line numbers. The output should then be styled with css to your liking. No styles are applied by default - only styling hooks (i.e.: ).

Returns:

Type Description
str

html text of the highlighted code.

Source code in pyrevitlib/pyrevit/coreutils/markdown/extensions/codehilite.py
def hilite(self):
    """Highlites the code.

    Pass code to the [Pygments](http://pygments.pocoo.org/) highliter with
    optional line numbers. The output should then be styled with css to
    your liking. No styles are applied by default - only styling hooks
    (i.e.: <span class="k">).

    Returns:
        (str): html text of the highlighted code.
    """
    self.src = self.src.strip('\n')

    if self.lang is None:
        self._parseHeader()

    if pygments and self.use_pygments:
        try:
            lexer = get_lexer_by_name(self.lang)
        except ValueError:
            try:
                if self.guess_lang:
                    lexer = guess_lexer(self.src)
                else:
                    lexer = get_lexer_by_name('text')
            except ValueError:
                lexer = get_lexer_by_name('text')
        formatter = get_formatter_by_name('html',
                                          linenos=self.linenums,
                                          cssclass=self.css_class,
                                          style=self.style,
                                          noclasses=self.noclasses,
                                          hl_lines=self.hl_lines)
        return highlight(self.src, lexer, formatter)
    else:
        # just escape and build markup usable by JS highlighting libs
        txt = self.src.replace('&', '&amp;')
        txt = txt.replace('<', '&lt;')
        txt = txt.replace('>', '&gt;')
        txt = txt.replace('"', '&quot;')
        classes = []
        if self.lang:
            classes.append('language-%s' % self.lang)
        if self.linenums:
            classes.append('linenums')
        class_str = ''
        if classes:
            class_str = ' class="%s"' % ' '.join(classes)
        return '<pre class="%s"><code%s>%s</code></pre>\n' % \
               (self.css_class, class_str, txt)

HiliteTreeprocessor(markdown_instance=None)

Bases: Treeprocessor

Hilight source code in code blocks.

Source code in pyrevitlib/pyrevit/coreutils/markdown/util.py
def __init__(self, markdown_instance=None):
    if markdown_instance:
        self.markdown = markdown_instance

Attributes

markdown = markdown_instance instance-attribute

Methods:

run(root)

Find code blocks and store in htmlStash.

Source code in pyrevitlib/pyrevit/coreutils/markdown/extensions/codehilite.py
def run(self, root):
    """Find code blocks and store in htmlStash."""
    blocks = root.iter('pre')
    for block in blocks:
        if len(block) == 1 and block[0].tag == 'code':
            code = CodeHilite(
                block[0].text,
                linenums=self.config['linenums'],
                guess_lang=self.config['guess_lang'],
                css_class=self.config['css_class'],
                style=self.config['pygments_style'],
                noclasses=self.config['noclasses'],
                tab_length=self.markdown.tab_length,
                use_pygments=self.config['use_pygments']
            )
            placeholder = self.markdown.htmlStash.store(code.hilite(),
                                                        safe=True)
            # Clear codeblock in etree instance
            block.clear()
            # Change to p element which will later
            # be removed when inserting raw html
            block.tag = 'p'
            block.text = placeholder

CodeHiliteExtension(*args, **kwargs)

Bases: Extension

Add source code hilighting to markdown codeblocks.

Source code in pyrevitlib/pyrevit/coreutils/markdown/extensions/codehilite.py
def __init__(self, *args, **kwargs):
    # define default configs
    self.config = {
        'linenums': [None,
                     "Use lines numbers. True=yes, False=no, None=auto"],
        'guess_lang': [True,
                       "Automatic language detection - Default: True"],
        'css_class': ["codehilite",
                      "Set class name for wrapper <div> - "
                      "Default: codehilite"],
        'pygments_style': ['default',
                           'Pygments HTML Formatter Style '
                           '(Colorscheme) - Default: default'],
        'noclasses': [False,
                      'Use inline styles instead of CSS classes - '
                      'Default false'],
        'use_pygments': [True,
                         'Use Pygments to Highlight code blocks. '
                         'Disable if using a JavaScript library. '
                         'Default: True']
        }

    super(CodeHiliteExtension, self).__init__(*args, **kwargs)

Attributes

config = {'linenums': [None, 'Use lines numbers. True=yes, False=no, None=auto'], 'guess_lang': [True, 'Automatic language detection - Default: True'], 'css_class': ['codehilite', 'Set class name for wrapper <div> - Default: codehilite'], 'pygments_style': ['default', 'Pygments HTML Formatter Style (Colorscheme) - Default: default'], 'noclasses': [False, 'Use inline styles instead of CSS classes - Default false'], 'use_pygments': [True, 'Use Pygments to Highlight code blocks. Disable if using a JavaScript library. Default: True']} instance-attribute

Methods:

extendMarkdown(md, md_globals)

Add HilitePostprocessor to Markdown instance.

Source code in pyrevitlib/pyrevit/coreutils/markdown/extensions/codehilite.py
def extendMarkdown(self, md, md_globals):
    """Add HilitePostprocessor to Markdown instance."""
    hiliter = HiliteTreeprocessor(md)
    hiliter.config = self.getConfigs()
    md.treeprocessors.add("hilite", hiliter, "<inline")

    md.registerExtension(self)
getConfig(key, default='')

Return a setting for the given key or an empty string.

Source code in pyrevitlib/pyrevit/coreutils/markdown/extensions/__init__.py
def getConfig(self, key, default=''):
    """Return a setting for the given key or an empty string."""
    if key in self.config:
        return self.config[key][0]
    else:
        return default
getConfigs()

Return all configs settings as a dict.

Source code in pyrevitlib/pyrevit/coreutils/markdown/extensions/__init__.py
def getConfigs(self):
    """Return all configs settings as a dict."""
    return dict([(key, self.getConfig(key)) for key in self.config.keys()])
getConfigInfo()

Return all config descriptions as a list of tuples.

Source code in pyrevitlib/pyrevit/coreutils/markdown/extensions/__init__.py
def getConfigInfo(self):
    """Return all config descriptions as a list of tuples."""
    return [(key, self.config[key][1]) for key in self.config.keys()]
setConfig(key, value)

Set a config setting for key with the given value.

Source code in pyrevitlib/pyrevit/coreutils/markdown/extensions/__init__.py
def setConfig(self, key, value):
    """Set a config setting for `key` with the given `value`."""
    if isinstance(self.config[key][0], bool):
        value = parseBoolValue(value)
    if self.config[key][0] is None:
        value = parseBoolValue(value, preserve_none=True)
    self.config[key][0] = value
setConfigs(items)

Set multiple config settings given a dict or list of tuples.

Source code in pyrevitlib/pyrevit/coreutils/markdown/extensions/__init__.py
def setConfigs(self, items):
    """Set multiple config settings given a dict or list of tuples."""
    if hasattr(items, 'items'):
        # it's a dict
        items = items.items()
    for key, value in items:
        self.setConfig(key, value)

Functions:

parse_hl_lines(expr)

Support our syntax for emphasizing certain lines of code.

expr should be like '1 2' to emphasize lines 1 and 2 of a code block. Returns a list of ints, the line numbers to emphasize.

Source code in pyrevitlib/pyrevit/coreutils/markdown/extensions/codehilite.py
def parse_hl_lines(expr):
    """Support our syntax for emphasizing certain lines of code.

    expr should be like '1 2' to emphasize lines 1 and 2 of a code block.
    Returns a list of ints, the line numbers to emphasize.
    """
    if not expr:
        return []

    try:
        return list(map(int, expr.split()))
    except ValueError:
        return []

makeExtension(*args, **kwargs)

Source code in pyrevitlib/pyrevit/coreutils/markdown/extensions/codehilite.py
def makeExtension(*args, **kwargs):
    return CodeHiliteExtension(*args, **kwargs)