diff options
author | A. Jesse Jiryu Davis <jesse@10gen.com> | 2014-01-03 18:03:15 -0500 |
---|---|---|
committer | A. Jesse Jiryu Davis <jesse@10gen.com> | 2014-01-03 18:03:15 -0500 |
commit | c18ce238e39c2ccac92da25a6429bdade0db4dff (patch) | |
tree | 6f0caa4392c98dc9e10824bb0d1e8530310548d2 /markdown/extensions/codehilite.py | |
parent | b6ed501695ea5f8029a228686f84c163c0cdc50b (diff) | |
download | markdown-c18ce238e39c2ccac92da25a6429bdade0db4dff.tar.gz markdown-c18ce238e39c2ccac92da25a6429bdade0db4dff.tar.bz2 markdown-c18ce238e39c2ccac92da25a6429bdade0db4dff.zip |
Add feature for emphasizing some lines in a code block.
A code blocked headed by “:::python{1,3}” now emphasizes the first and third lines. With fences enabled, ```python{1,3} has the same effect.
Diffstat (limited to 'markdown/extensions/codehilite.py')
-rw-r--r-- | markdown/extensions/codehilite.py | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/markdown/extensions/codehilite.py b/markdown/extensions/codehilite.py index 7a3676b..d05d495 100644 --- a/markdown/extensions/codehilite.py +++ b/markdown/extensions/codehilite.py @@ -31,6 +31,22 @@ try: except ImportError: pygments = False + +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 map(int, expr.strip('{}').split(',')) + except ValueError: + return [] + + # ------------------ The Main CodeHilite Class ---------------------- class CodeHilite(object): """ @@ -49,6 +65,8 @@ class CodeHilite(object): * 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. @@ -59,7 +77,7 @@ class CodeHilite(object): def __init__(self, src=None, linenums=None, guess_lang=True, css_class="codehilite", lang=None, style='default', - noclasses=False, tab_length=4): + noclasses=False, tab_length=4, hl_lines=None): self.src = src self.lang = lang self.linenums = linenums @@ -68,6 +86,7 @@ class CodeHilite(object): self.style = style self.noclasses = noclasses self.tab_length = tab_length + self.hl_lines = hl_lines or [] def hilite(self): """ @@ -83,7 +102,7 @@ class CodeHilite(object): self.src = self.src.strip('\n') if self.lang is None: - self._getLang() + self._parseHeader() if pygments: try: @@ -99,7 +118,8 @@ class CodeHilite(object): formatter = HtmlFormatter(linenos=self.linenums, cssclass=self.css_class, style=self.style, - noclasses=self.noclasses) + 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 @@ -118,7 +138,7 @@ class CodeHilite(object): return '<pre class="%s"><code%s>%s</code></pre>\n'% \ (self.css_class, class_str, txt) - def _getLang(self): + def _parseHeader(self): """ Determines language of a code block from shebang line and whether said line should be removed or left in place. If the sheband line contains a @@ -131,6 +151,7 @@ class CodeHilite(object): (e.i.: :::python), line numbering is left in the current state - off by default. + Also parses optional list of highlight lines, like :::python{1,3} """ import re @@ -141,9 +162,10 @@ class CodeHilite(object): fl = lines.pop(0) c = re.compile(r''' - (?:(?:^::+)|(?P<shebang>^[#]!)) # Shebang or 2 or more colons. + (?:(?:^::+)|(?P<shebang>^[#]!)) # Shebang or 2 or more colons (?P<path>(?:/\w+)*[/ ])? # Zero or 1 path (?P<lang>[\w+-]*) # The language + (?P<hl_lines>\{.*?})? # Maybe hl_lines ''', re.VERBOSE) # search first line for shebang m = c.search(fl) @@ -159,6 +181,8 @@ class CodeHilite(object): if self.linenums is None and m.group('shebang'): # Overridable and Shebang exists - use line numbers self.linenums = True + + self.hl_lines = parse_hl_lines(m.group('hl_lines')) else: # No match lines.insert(0, fl) |