From 36ab0c387f84485444e60480382caafb7a807fd6 Mon Sep 17 00:00:00 2001 From: Waylan Limberg Date: Thu, 14 Feb 2013 16:04:24 -0500 Subject: Allow better linenum override in CodeHilite Fixes #148. The "force_linenos" config setting of the CodeHilite extension has been marked as Pending Deprecation and a new setting "linenums" has been added to replace it. See documentation for the [CodeHilite Extension] for an explaination of the new "linenums" setting. The new setting will honor the old "force_linenos" if it is set, but it will raise a PendingDeprecationWarning and will likely be removed in a future version of Python-Markdown. [CodeHilite Extension]: extensions/codehilite.html --- docs/extensions/code_hilite.txt | 25 ++++++++++--- docs/release-2.3.txt | 9 +++++ markdown/extensions/codehilite.py | 33 ++++++++++++----- tests/test_extensions.py | 78 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 125 insertions(+), 20 deletions(-) diff --git a/docs/extensions/code_hilite.txt b/docs/extensions/code_hilite.txt index fbf05b3..31ecfbb 100644 --- a/docs/extensions/code_hilite.txt +++ b/docs/extensions/code_hilite.txt @@ -41,6 +41,13 @@ blocks, with one exception. The hiliter needs to know what language to use for the code block. There are three ways to tell the hiliter what language the code block contains and each one has a different result. +!!! Note +The format of the language identifier only effects the display of line numbers +if `linenums` is set to `None` (the default). If set to `True` or `False` +(see [Usage](#usage) below) the format of the identifier has no effect on the +display of line numbers -- it only serves as a means to define the language +of the code block. + [syntax]: http://daringfireball.net/projects/markdown/syntax#precode ###SheBang (with path) @@ -107,19 +114,25 @@ Usage From the Python interpreter: - >>> html = markdown.markdown(text, ['codehilite']) + >>> html = markdown.markdown(text, extensions=['codehilite']) + +If you want to force every code block to have line numbers, even when using +colons (`:::`) for language identification, set `linenums` to `True`. + + >>> html = markdown.markdown(text, + ... extensions=['codehilite(linenums=True)'] + ... ) -If you want every code block to have line numbers, even when using colons -(`:::`) for language identification, the setting `force_linenos` is available -to do so. +If you do **not** want any code block to have line numbers, even when using +SheBangs (`#!`) for language identification, set `linenums` to `False`. >>> html = markdown.markdown(text, - ... ['codehilite(force_linenos=True)'] + ... extensions=['codehilite(linenums=False)'] ... ) If you want to prevent Pygments from guessing the language, only highlighting blocks when you explicitly request it, set the `guess_lang` setting to 'False'. >>> html = markdown.markdown(text, - ... ['codehilite(guess_lang=False)'] + ... extensions=['codehilite(guess_lang=False)'] ... ) diff --git a/docs/release-2.3.txt b/docs/release-2.3.txt index e7a6414..e8a6257 100644 --- a/docs/release-2.3.txt +++ b/docs/release-2.3.txt @@ -29,6 +29,15 @@ reference to those ids in your JavaScript or CSS and using the HTML5 output, you will need to update your code accordingly. No changes are necessary if you are outputing XHTML (the default) or HTML4. +* The "force_linenos" config setting of the CodeHilite extension has been +marked as Pending Deprecation and a new setting "linenums" has been added to +replace it. See documentation for the [CodeHilite Extension] for an explaination +of the new "linenums" setting. The new setting will honor the old "force_linenos" +if it is set, but it will raise a PendingDeprecationWarning and will likely be +removed in a future version of Python-Markdown. + +[CodeHilite Extension]: extensions/codehilite.html + * The "RSS" extension has been removed and no longer ships with Python-Markdown. If you would like to continue using the extension (not recomended), it is archived on [Github](https://gist.github.com/waylan/4773365). diff --git a/markdown/extensions/codehilite.py b/markdown/extensions/codehilite.py index bab8c6f..fd8e2f4 100644 --- a/markdown/extensions/codehilite.py +++ b/markdown/extensions/codehilite.py @@ -21,6 +21,7 @@ Dependencies: """ import markdown +import warnings try: from pygments import highlight from pygments.lexers import get_lexer_by_name, guess_lexer, TextLexer @@ -40,7 +41,8 @@ class CodeHilite: * src: Source string or any object with a .readline attribute. - * linenos: (Boolean) Turn line numbering 'on' or 'off' (off by default). + * 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). @@ -54,12 +56,12 @@ class CodeHilite: """ - def __init__(self, src=None, linenos=False, guess_lang=True, + def __init__(self, src=None, linenums=None, guess_lang=True, css_class="codehilite", lang=None, style='default', noclasses=False, tab_length=4): self.src = src self.lang = lang - self.linenos = linenos + self.linenums = linenums self.guess_lang = guess_lang self.css_class = css_class self.style = style @@ -93,7 +95,7 @@ class CodeHilite: lexer = TextLexer() except ValueError: lexer = TextLexer() - formatter = HtmlFormatter(linenos=self.linenos, + formatter = HtmlFormatter(linenos=self.linenums, cssclass=self.css_class, style=self.style, noclasses=self.noclasses) @@ -107,7 +109,7 @@ class CodeHilite: classes = [] if self.lang: classes.append('language-%s' % self.lang) - if self.linenos: + if self.linenums: classes.append('linenums') class_str = '' if classes: @@ -153,9 +155,9 @@ class CodeHilite: if m.group('path'): # path exists - restore first line lines.insert(0, fl) - if m.group('shebang'): - # shebang exists - use line numbers - self.linenos = True + if self.linenums is None and m.group('shebang'): + # Overridable and Shebang exists - use line numbers + self.linenums = True else: # No match lines.insert(0, fl) @@ -175,7 +177,7 @@ class HiliteTreeprocessor(markdown.treeprocessors.Treeprocessor): children = block.getchildren() if len(children) == 1 and children[0].tag == 'code': code = CodeHilite(children[0].text, - linenos=self.config['force_linenos'], + linenums=self.config['linenums'], guess_lang=self.config['guess_lang'], css_class=self.config['css_class'], style=self.config['pygments_style'], @@ -197,7 +199,8 @@ class CodeHiliteExtension(markdown.Extension): def __init__(self, configs): # define default configs self.config = { - 'force_linenos' : [False, "Force line numbers - Default: False"], + 'linenums': [None, "Use lines numbers. True=yes, False=no, None=auto"], + 'force_linenos' : [False, "Depreciated! Use 'linenums' instead. Force line numbers - Default: False"], 'guess_lang' : [True, "Automatic language detection - Default: True"], 'css_class' : ["codehilite", "Set class name for wrapper
- Default: codehilite"], @@ -210,6 +213,16 @@ class CodeHiliteExtension(markdown.Extension): # convert strings to booleans if value == 'True': value = True if value == 'False': value = False + if value == 'None': value = None + + if key == 'force_linenos': + warnings.warn('The "force_linenos" config setting' + ' to the CodeHilite extension is deprecrecated.' + ' Use "linenums" instead.', PendingDeprecationWarning) + if value: + # Carry 'force_linenos' over to new 'linenos'. + self.setConfig('linenums', True) + self.setConfig(key, value) def extendMarkdown(self, md, md_globals): diff --git a/tests/test_extensions.py b/tests/test_extensions.py index fd77e5e..bee270a 100644 --- a/tests/test_extensions.py +++ b/tests/test_extensions.py @@ -31,8 +31,6 @@ class TestCodeHilite(unittest.TestCase): """ Test codehilite extension. """ def setUp(self): - self.md = markdown.Markdown(extensions=['codehilite']) - self.has_pygments = True try: import pygments @@ -41,16 +39,88 @@ class TestCodeHilite(unittest.TestCase): def testBasicCodeHilite(self): text = '\t# A Code Comment' + md = markdown.Markdown(extensions=['codehilite']) + if self.has_pygments: + self.assertEqual(md.convert(text), + '
' + '
# A Code Comment\n'
+                '
') + else: + self.assertEqual(md.convert(text), + '
# A Code Comment'
+                '
') + + def testLinenumsTrue(self): + text = '\t# A Code Comment' + md = markdown.Markdown(extensions=['codehilite(linenums=True)']) + if self.has_pygments: + self.assertEqual(md.convert(text), + '' + '' + '' + '
1
' + '
# A Code Comment\n
' + '
\n
') + else: + self.assertEqual(md.convert(text), + '
# A Code Comment'
+                '
') + + def testLinenumsFalse(self): + text = '\t#!Python\n\t# A Code Comment' + md = markdown.Markdown(extensions=['codehilite(linenums=False)']) + if self.has_pygments: + self.assertEqual(md.convert(text), + '
' + '
# A Code Comment\n'
+                '
') + else: + self.assertEqual(md.convert(text), + '
# A Code Comment'
+                '
') + + def testLinenumsNone(self): + text = '\t# A Code Comment' + md = markdown.Markdown(extensions=['codehilite(linenums=None)']) if self.has_pygments: - self.assertEqual(self.md.convert(text), + self.assertEqual(md.convert(text), '
' '
# A Code Comment\n'
                 '
') else: - self.assertEqual(self.md.convert(text), + self.assertEqual(md.convert(text), '
# A Code Comment'
                 '
') + def testLinenumsNoneWithShebang(self): + text = '\t#!Python\n\t# A Code Comment' + md = markdown.Markdown(extensions=['codehilite(linenums=None)']) + if self.has_pygments: + self.assertEqual(md.convert(text), + '' + '' + '' + '
1
' + '
# A Code Comment\n
' + '
\n
') + else: + self.assertEqual(md.convert(text), + '
# A Code Comment'
+                '
') + + def testLinenumsNoneWithColon(self): + text = '\t:::Python\n\t# A Code Comment' + md = markdown.Markdown(extensions=['codehilite(linenums=None)']) + if self.has_pygments: + self.assertEqual(md.convert(text), + '
' + '
# A Code Comment\n'
+                '
') + else: + self.assertEqual(md.convert(text), + '
# A Code Comment'
+                '
') + class TestFencedCode(unittest.TestCase): """ Test fenced_code extension. """ -- cgit v1.2.3