aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWaylan Limberg <waylan@gmail.com>2014-07-31 22:40:33 -0400
committerWaylan Limberg <waylan@gmail.com>2014-07-31 22:40:33 -0400
commit47372051cf9724f1355b1c07c63c4beff9a5f626 (patch)
tree82130393bfa7118cab45a80579fbed2eeed05261
parentaae373860b5c5cbb40f126bf5acb9693dc577c4a (diff)
downloadmarkdown-47372051cf9724f1355b1c07c63c4beff9a5f626.tar.gz
markdown-47372051cf9724f1355b1c07c63c4beff9a5f626.tar.bz2
markdown-47372051cf9724f1355b1c07c63c4beff9a5f626.zip
Update extensions for Extension.__init__ refactor
Fixes #325. All extensions can now accept a dict of configs or **kwargs, not just a list of tuples. Third party extensions may want to follow suite. Extensions may only accept keyword arguments in the future. These changes still need to be documented. A couple things of note: The CodeHilite extension previously issued a DeprecationWarning if the old config key `force_linenos` was used. With thins change, a KeyError will now be raised. The `markdown.util.parseBoolValue` function gained a new argument: `preserve_none` (defaults to False), which when set to True, will pass None through unaltered (will not convert it to False).
-rw-r--r--markdown/extensions/__init__.py5
-rw-r--r--markdown/extensions/abbr.py4
-rw-r--r--markdown/extensions/admonition.py5
-rw-r--r--markdown/extensions/attr_list.py4
-rw-r--r--markdown/extensions/codehilite.py23
-rw-r--r--markdown/extensions/def_list.py4
-rw-r--r--markdown/extensions/extra.py4
-rw-r--r--markdown/extensions/fenced_code.py5
-rw-r--r--markdown/extensions/footnotes.py34
-rw-r--r--markdown/extensions/headerid.py5
-rw-r--r--markdown/extensions/meta.py5
-rw-r--r--markdown/extensions/nl2br.py5
-rw-r--r--markdown/extensions/sane_lists.py4
-rw-r--r--markdown/extensions/smart_strong.py4
-rw-r--r--markdown/extensions/smarty.py9
-rw-r--r--markdown/extensions/tables.py5
-rw-r--r--markdown/extensions/toc.py44
-rw-r--r--markdown/extensions/wikilinks.py22
-rw-r--r--markdown/util.py11
-rw-r--r--tests/test_extensions.py37
20 files changed, 121 insertions, 118 deletions
diff --git a/markdown/extensions/__init__.py b/markdown/extensions/__init__.py
index 296ce0c..2751eef 100644
--- a/markdown/extensions/__init__.py
+++ b/markdown/extensions/__init__.py
@@ -4,6 +4,7 @@ Extensions
"""
from __future__ import unicode_literals
+from ..util import parseBoolValue
class Extension(object):
""" Base class for extensions to subclass. """
@@ -47,6 +48,10 @@ class Extension(object):
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
def setConfigs(self, items):
diff --git a/markdown/extensions/abbr.py b/markdown/extensions/abbr.py
index bed3bb4..7f2344a 100644
--- a/markdown/extensions/abbr.py
+++ b/markdown/extensions/abbr.py
@@ -92,5 +92,5 @@ class AbbrPattern(Pattern):
abbr.set('title', self.title)
return abbr
-def makeExtension(configs=None):
- return AbbrExtension(configs=configs)
+def makeExtension(*args, **kwargs):
+ return AbbrExtension(*args, **kwargs)
diff --git a/markdown/extensions/admonition.py b/markdown/extensions/admonition.py
index 9a45b92..7888d5e 100644
--- a/markdown/extensions/admonition.py
+++ b/markdown/extensions/admonition.py
@@ -114,5 +114,6 @@ class AdmonitionProcessor(BlockProcessor):
return klass, title
-def makeExtension(configs={}):
- return AdmonitionExtension(configs=configs)
+def makeExtension(*args, **kwargs):
+ return AdmonitionExtension(*args, **kwargs)
+
diff --git a/markdown/extensions/attr_list.py b/markdown/extensions/attr_list.py
index f0508cd..f725a17 100644
--- a/markdown/extensions/attr_list.py
+++ b/markdown/extensions/attr_list.py
@@ -164,5 +164,5 @@ class AttrListExtension(Extension):
md.treeprocessors.add('attr_list', AttrListTreeprocessor(md), '>prettify')
-def makeExtension(configs={}):
- return AttrListExtension(configs=configs)
+def makeExtension(*args, **kwargs):
+ return AttrListExtension(*args, **kwargs)
diff --git a/markdown/extensions/codehilite.py b/markdown/extensions/codehilite.py
index f379da7..e3c5b3d 100644
--- a/markdown/extensions/codehilite.py
+++ b/markdown/extensions/codehilite.py
@@ -225,7 +225,7 @@ class HiliteTreeprocessor(Treeprocessor):
class CodeHiliteExtension(Extension):
""" Add source code hilighting to markdown codeblocks. """
- def __init__(self, configs):
+ def __init__(self, *args, **kwargs):
# define default configs
self.config = {
'linenums': [None, "Use lines numbers. True=yes, False=no, None=auto"],
@@ -237,22 +237,7 @@ class CodeHiliteExtension(Extension):
'noclasses': [False, 'Use inline styles instead of CSS classes - Default false']
}
- # Override defaults with user settings
- for key, value in configs:
- # convert strings to booleans
- if value == 'True': value = True
- if value == 'False': value = False
- if value == 'None': value = None
-
- if key == 'force_linenos': #pragma: no cover
- warnings.warn('The "force_linenos" config setting'
- ' to the CodeHilite extension is deprecrecated.'
- ' Use "linenums" instead.', DeprecationWarning)
- if value:
- # Carry 'force_linenos' over to new 'linenos'.
- self.setConfig('linenums', True)
-
- self.setConfig(key, value)
+ super(CodeHiliteExtension, self).__init__(*args, **kwargs)
def extendMarkdown(self, md, md_globals):
""" Add HilitePostprocessor to Markdown instance. """
@@ -263,6 +248,6 @@ class CodeHiliteExtension(Extension):
md.registerExtension(self)
-def makeExtension(configs={}):
- return CodeHiliteExtension(configs=configs)
+def makeExtension(*args, **kwargs):
+ return CodeHiliteExtension(*args, **kwargs)
diff --git a/markdown/extensions/def_list.py b/markdown/extensions/def_list.py
index df639df..3511651 100644
--- a/markdown/extensions/def_list.py
+++ b/markdown/extensions/def_list.py
@@ -113,6 +113,6 @@ class DefListExtension(Extension):
'>ulist')
-def makeExtension(configs={}):
- return DefListExtension(configs=configs)
+def makeExtension(*args, **kwargs):
+ return DefListExtension(*args, **kwargs)
diff --git a/markdown/extensions/extra.py b/markdown/extensions/extra.py
index 8986ba6..6fba8db 100644
--- a/markdown/extensions/extra.py
+++ b/markdown/extensions/extra.py
@@ -60,8 +60,8 @@ class ExtraExtension(Extension):
r'^(p|h[1-6]|li|dd|dt|td|th|legend|address)$', re.IGNORECASE)
-def makeExtension(configs={}):
- return ExtraExtension(configs=dict(configs))
+def makeExtension(*args, **kwargs):
+ return ExtraExtension(*args, **kwargs)
class MarkdownInHtmlProcessor(BlockProcessor):
diff --git a/markdown/extensions/fenced_code.py b/markdown/extensions/fenced_code.py
index fe1559c..25163cf 100644
--- a/markdown/extensions/fenced_code.py
+++ b/markdown/extensions/fenced_code.py
@@ -175,5 +175,6 @@ class FencedBlockPreprocessor(Preprocessor):
return txt
-def makeExtension(configs=None):
- return FencedCodeExtension(configs=configs)
+def makeExtension(*args, **kwargs):
+ return FencedCodeExtension(*args, **kwargs)
+
diff --git a/markdown/extensions/footnotes.py b/markdown/extensions/footnotes.py
index 9f93ad1..cec0d71 100644
--- a/markdown/extensions/footnotes.py
+++ b/markdown/extensions/footnotes.py
@@ -42,23 +42,23 @@ TABBED_RE = re.compile(r'((\t)|( ))(.*)')
class FootnoteExtension(Extension):
""" Footnote Extension. """
- def __init__ (self, configs):
+ def __init__ (self, *args, **kwargs):
""" Setup configs. """
- self.config = {'PLACE_MARKER':
- ["///Footnotes Go Here///",
- "The text string that marks where the footnotes go"],
- 'UNIQUE_IDS':
- [False,
- "Avoid name collisions across "
- "multiple calls to reset()."],
- "BACKLINK_TEXT":
- ["&#8617;",
- "The text string that links from the footnote to the reader's place."]
- }
-
- for key, value in configs:
- self.config[key][0] = value
+ self.config = {
+ 'PLACE_MARKER':
+ ["///Footnotes Go Here///",
+ "The text string that marks where the footnotes go"],
+ 'UNIQUE_IDS':
+ [False,
+ "Avoid name collisions across "
+ "multiple calls to reset()."],
+ "BACKLINK_TEXT":
+ ["&#8617;",
+ "The text string that links from the footnote to the reader's place."]
+ }
+ super(FootnoteExtension, self).__init__(*args, **kwargs)
+
# In multiple invocations, emit links that don't get tangled.
self.unique_prefix = 0
@@ -309,7 +309,7 @@ class FootnotePostprocessor(Postprocessor):
text = text.replace(FN_BACKLINK_TEXT, self.footnotes.getConfig("BACKLINK_TEXT"))
return text.replace(NBSP_PLACEHOLDER, "&#160;")
-def makeExtension(configs=[]):
+def makeExtension(*args, **kwargs):
""" Return an instance of the FootnoteExtension """
- return FootnoteExtension(configs=configs)
+ return FootnoteExtension(*args, **kwargs)
diff --git a/markdown/extensions/headerid.py b/markdown/extensions/headerid.py
index 07351cc..55e09ce 100644
--- a/markdown/extensions/headerid.py
+++ b/markdown/extensions/headerid.py
@@ -204,5 +204,6 @@ class HeaderIdExtension(Extension):
self.processor.IDs = set()
-def makeExtension(configs=None):
- return HeaderIdExtension(configs=configs)
+def makeExtension(*args, **kwargs):
+ return HeaderIdExtension(*args, **kwargs)
+
diff --git a/markdown/extensions/meta.py b/markdown/extensions/meta.py
index 9063188..8de2646 100644
--- a/markdown/extensions/meta.py
+++ b/markdown/extensions/meta.py
@@ -89,5 +89,6 @@ class MetaPreprocessor(Preprocessor):
return lines
-def makeExtension(configs={}):
- return MetaExtension(configs=configs)
+def makeExtension(*args, **kwargs):
+ return MetaExtension(*args, **kwargs)
+
diff --git a/markdown/extensions/nl2br.py b/markdown/extensions/nl2br.py
index 028561c..c355c13 100644
--- a/markdown/extensions/nl2br.py
+++ b/markdown/extensions/nl2br.py
@@ -34,5 +34,6 @@ class Nl2BrExtension(Extension):
md.inlinePatterns.add('nl', br_tag, '_end')
-def makeExtension(configs=None):
- return Nl2BrExtension(configs)
+def makeExtension(*args, **kwargs):
+ return Nl2BrExtension(*args, **kwargs)
+
diff --git a/markdown/extensions/sane_lists.py b/markdown/extensions/sane_lists.py
index fda6638..22a4ff3 100644
--- a/markdown/extensions/sane_lists.py
+++ b/markdown/extensions/sane_lists.py
@@ -46,6 +46,6 @@ class SaneListExtension(Extension):
md.parser.blockprocessors['ulist'] = SaneUListProcessor(md.parser)
-def makeExtension(configs={}):
- return SaneListExtension(configs=configs)
+def makeExtension(*args, **kwargs):
+ return SaneListExtension(*args, **kwargs)
diff --git a/markdown/extensions/smart_strong.py b/markdown/extensions/smart_strong.py
index c7ac9f1..877b5a7 100644
--- a/markdown/extensions/smart_strong.py
+++ b/markdown/extensions/smart_strong.py
@@ -38,5 +38,5 @@ class SmartEmphasisExtension(Extension):
md.inlinePatterns['strong'] = SimpleTagPattern(STRONG_RE, 'strong')
md.inlinePatterns.add('strong2', SimpleTagPattern(SMART_STRONG_RE, 'strong'), '>emphasis2')
-def makeExtension(configs={}):
- return SmartEmphasisExtension(configs=dict(configs))
+def makeExtension(*args, **kwargs):
+ return SmartEmphasisExtension(*args, **kwargs)
diff --git a/markdown/extensions/smarty.py b/markdown/extensions/smarty.py
index 8131591..5a82dfd 100644
--- a/markdown/extensions/smarty.py
+++ b/markdown/extensions/smarty.py
@@ -134,15 +134,14 @@ class SubstituteTextPattern(HtmlPattern):
return result
class SmartyExtension(Extension):
- def __init__(self, configs):
+ def __init__(self, *args, **kwargs):
self.config = {
'smart_quotes': [True, 'Educate quotes'],
'smart_angled_quotes': [False, 'Educate angled quotes'],
'smart_dashes': [True, 'Educate dashes'],
'smart_ellipses': [True, 'Educate ellipses']
}
- for key, value in configs:
- self.setConfig(key, parseBoolValue(value))
+ super(SmartyExtension, self).__init__(*args, **kwargs)
def _addPatterns(self, md, patterns, serie):
for ind, pattern in enumerate(patterns):
@@ -204,5 +203,5 @@ class SmartyExtension(Extension):
md.treeprocessors.add('smarty', inlineProcessor, '_end')
md.ESCAPED_CHARS.extend(['"', "'"])
-def makeExtension(configs=None):
- return SmartyExtension(configs)
+def makeExtension(*args, **kwargs):
+ return SmartyExtension(*args, **kwargs)
diff --git a/markdown/extensions/tables.py b/markdown/extensions/tables.py
index cfac0bc..2977bd1 100644
--- a/markdown/extensions/tables.py
+++ b/markdown/extensions/tables.py
@@ -96,5 +96,6 @@ class TableExtension(Extension):
'<hashheader')
-def makeExtension(configs={}):
- return TableExtension(configs=configs)
+def makeExtension(*args, **kwargs):
+ return TableExtension(*args, **kwargs)
+
diff --git a/markdown/extensions/toc.py b/markdown/extensions/toc.py
index 89468d6..f1593b2 100644
--- a/markdown/extensions/toc.py
+++ b/markdown/extensions/toc.py
@@ -204,26 +204,26 @@ class TocExtension(Extension):
TreeProcessorClass = TocTreeprocessor
- def __init__(self, configs=[]):
- self.config = { "marker" : ["[TOC]",
- "Text to find and replace with Table of Contents -"
- "Defaults to \"[TOC]\""],
- "slugify" : [slugify,
- "Function to generate anchors based on header text-"
- "Defaults to the headerid ext's slugify function."],
- "title" : [None,
- "Title to insert into TOC <div> - "
- "Defaults to None"],
- "anchorlink" : [0,
- "1 if header should be a self link"
- "Defaults to 0"],
- "permalink" : [0,
- "1 or link text if a Sphinx-style permalink should be added",
- "Defaults to 0"]
- }
-
- for key, value in configs:
- self.setConfig(key, value)
+ def __init__(self, *args, **kwargs):
+ self.config = {
+ "marker" : ["[TOC]",
+ "Text to find and replace with Table of Contents - "
+ "Defaults to \"[TOC]\""],
+ "slugify" : [slugify,
+ "Function to generate anchors based on header text - "
+ "Defaults to the headerid ext's slugify function."],
+ "title" : [None,
+ "Title to insert into TOC <div> - "
+ "Defaults to None"],
+ "anchorlink" : [0,
+ "1 if header should be a self link - "
+ "Defaults to 0"],
+ "permalink" : [0,
+ "1 or link text if a Sphinx-style permalink should be added - "
+ "Defaults to 0"]
+ }
+
+ super(TocExtension, self).__init__(*args, **kwargs)
def extendMarkdown(self, md, md_globals):
tocext = self.TreeProcessorClass(md)
@@ -236,5 +236,5 @@ class TocExtension(Extension):
md.treeprocessors.add("toc", tocext, "_end")
-def makeExtension(configs={}):
- return TocExtension(configs=configs)
+def makeExtension(*args, **kwargs):
+ return TocExtension(*args, **kwargs)
diff --git a/markdown/extensions/wikilinks.py b/markdown/extensions/wikilinks.py
index 6d34173..c2aab8f 100644
--- a/markdown/extensions/wikilinks.py
+++ b/markdown/extensions/wikilinks.py
@@ -90,19 +90,17 @@ def build_url(label, base, end):
class WikiLinkExtension(Extension):
- def __init__(self, configs):
- # set extension defaults
+
+ def __init__ (self, *args, **kwargs):
self.config = {
- 'base_url' : ['/', 'String to append to beginning or URL.'],
- 'end_url' : ['/', 'String to append to end of URL.'],
- 'html_class' : ['wikilink', 'CSS hook. Leave blank for none.'],
- 'build_url' : [build_url, 'Callable formats URL from label.'],
+ 'base_url' : ['/', 'String to append to beginning or URL.'],
+ 'end_url' : ['/', 'String to append to end of URL.'],
+ 'html_class' : ['wikilink', 'CSS hook. Leave blank for none.'],
+ 'build_url' : [build_url, 'Callable formats URL from label.'],
}
- configs = dict(configs) or {}
- # Override defaults with user settings
- for key, value in configs.items():
- self.setConfig(key, value)
+ super(WikiLinkExtension, self).__init__(*args, **kwargs)
+
def extendMarkdown(self, md, md_globals):
self.md = md
@@ -147,5 +145,5 @@ class WikiLinks(Pattern):
return base_url, end_url, html_class
-def makeExtension(configs=None) :
- return WikiLinkExtension(configs=configs)
+def makeExtension(*args, **kwargs) :
+ return WikiLinkExtension(*args, **kwargs)
diff --git a/markdown/util.py b/markdown/util.py
index cdad775..d5deaba 100644
--- a/markdown/util.py
+++ b/markdown/util.py
@@ -86,16 +86,21 @@ def isBlockLevel(tag):
# Some ElementTree tags are not strings, so return False.
return False
-def parseBoolValue(value, fail_on_errors=True):
+def parseBoolValue(value, fail_on_errors=True, preserve_none=False):
"""Parses a string representing bool value. If parsing was successful,
- returns True or False. If parsing was not successful, raises
- ValueError, or, if fail_on_errors=False, returns None."""
+ returns True or False. If preserve_none=True, returns True, False,
+ or None. If parsing was not successful, raises ValueError, or, if
+ fail_on_errors=False, returns None."""
if not isinstance(value, string_type):
+ if preserve_none and value is None:
+ return value
return bool(value)
elif value.lower() in ('true', 'yes', 'y', 'on', '1'):
return True
elif value.lower() in ('false', 'no', 'n', 'off', '0'):
return False
+ elif preserve_none and value.lower() == 'none':
+ return None
elif fail_on_errors:
raise ValueError('Cannot parse bool value: %r' % value)
diff --git a/tests/test_extensions.py b/tests/test_extensions.py
index e763576..b98295c 100644
--- a/tests/test_extensions.py
+++ b/tests/test_extensions.py
@@ -16,7 +16,10 @@ class TestExtensionClass(unittest.TestCase):
def setUp(self):
class TestExtension(markdown.extensions.Extension):
- config = {'foo': ['bar', 'Description of foo']}
+ config = {
+ 'foo': ['bar', 'Description of foo'],
+ 'bar': ['baz', 'Description of bar']
+ }
self.ext = TestExtension()
self.ExtKlass = TestExtension
@@ -29,38 +32,39 @@ class TestExtensionClass(unittest.TestCase):
self.assertEqual(self.ext.getConfig('baz', default='missing'), 'missing')
def testGetConfigs(self):
- self.assertEqual(self.ext.getConfigs(), {'foo': 'bar'})
+ self.assertEqual(self.ext.getConfigs(), {'foo': 'bar', 'bar': 'baz'})
def testGetConfigInfo(self):
- self.assertEqual(self.ext.getConfigInfo(), [('foo', 'Description of foo')])
+ self.assertEqual(self.ext.getConfigInfo(), [('foo', 'Description of foo'),
+ ('bar', 'Description of bar')])
def testSetConfig(self):
self.ext.setConfig('foo', 'baz')
- self.assertEqual(self.ext.getConfigs(), {'foo': 'baz'})
+ self.assertEqual(self.ext.getConfigs(), {'foo': 'baz', 'bar': 'baz'})
def testSetConfigWithBadKey(self):
# self.ext.setConfig('bad', 'baz) ==> KeyError
self.assertRaises(KeyError, self.ext.setConfig, 'bad', 'baz')
def testConfigAsArgListOnInit(self):
- ext = self.ExtKlass([('foo', 'baz')])
- self.assertEqual(ext.getConfigs(), {'foo': 'baz'})
+ ext = self.ExtKlass([('foo', 'baz'), ('bar', 'blah')])
+ self.assertEqual(ext.getConfigs(), {'foo': 'baz', 'bar': 'blah'})
def testConfigAsArgDictOnInit(self):
- ext = self.ExtKlass({'foo': 'baz'})
- self.assertEqual(ext.getConfigs(), {'foo': 'baz'})
+ ext = self.ExtKlass({'foo': 'baz', 'bar': 'blah', 'bar': 'blah'})
+ self.assertEqual(ext.getConfigs(), {'foo': 'baz', 'bar': 'blah'})
def testConfigAsKwargListOnInit(self):
- ext = self.ExtKlass(configs=[('foo', 'baz')])
- self.assertEqual(ext.getConfigs(), {'foo': 'baz'})
+ ext = self.ExtKlass(configs=[('foo', 'baz'), ('bar', 'blah')])
+ self.assertEqual(ext.getConfigs(), {'foo': 'baz', 'bar': 'blah'})
def testConfigAsKwargDictOnInit(self):
- ext = self.ExtKlass(configs={'foo': 'baz'})
- self.assertEqual(ext.getConfigs(), {'foo': 'baz'})
+ ext = self.ExtKlass(configs={'foo': 'baz', 'bar': 'blah'})
+ self.assertEqual(ext.getConfigs(), {'foo': 'baz', 'bar': 'blah'})
def testConfigAsKwargsOnInit(self):
- ext = self.ExtKlass(foo='baz')
- self.assertEqual(ext.getConfigs(), {'foo': 'baz'})
+ ext = self.ExtKlass(foo='baz', bar='blah')
+ self.assertEqual(ext.getConfigs(), {'foo': 'baz', 'bar': 'blah'})
class TestAbbr(unittest.TestCase):
@@ -515,11 +519,12 @@ Some text with a [[WikiLink]]."""
def testURLCallback(self):
""" Test used of a custom URL builder. """
+
+ from markdown.extensions.wikilinks import WikiLinkExtension
def my_url_builder(label, base, end):
return '/bar/'
- md = markdown.Markdown(extensions=['wikilinks'],
- extension_configs={'wikilinks' : [('build_url', my_url_builder)]})
+ md = markdown.Markdown(extensions=[WikiLinkExtension(build_url=my_url_builder)])
self.assertEqual(md.convert('[[foo]]'),
'<p><a class="wikilink" href="/bar/">foo</a></p>')