aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--markdown/__init__.py61
-rw-r--r--markdown/extensions/__init__.py51
-rw-r--r--markdown/preprocessors.py24
-rw-r--r--tests/misc/block_html_attr.html27
-rw-r--r--tests/misc/block_html_attr.txt24
-rw-r--r--tests/misc/block_html_simple.html10
-rw-r--r--tests/misc/block_html_simple.txt9
-rw-r--r--tests/test_apis.py4
8 files changed, 140 insertions, 70 deletions
diff --git a/markdown/__init__.py b/markdown/__init__.py
index 5375b7d..1375523 100644
--- a/markdown/__init__.py
+++ b/markdown/__init__.py
@@ -43,7 +43,7 @@ from blockprocessors import build_block_parser
from treeprocessors import build_treeprocessors
from inlinepatterns import build_inlinepatterns
from postprocessors import build_postprocessors
-from extensions import Extension, load_extension, load_extensions
+from extensions import Extension
import html4
# For backwards compatibility in the 2.0.x series
@@ -136,7 +136,7 @@ class Markdown:
"""
for ext in extensions:
if isinstance(ext, basestring):
- ext = load_extension(ext, configs.get(ext, []))
+ ext = self.build_extension(ext, configs.get(ext, []))
if isinstance(ext, Extension):
try:
ext.extendMarkdown(self, globals())
@@ -147,6 +147,47 @@ class Markdown:
'Extension "%s.%s" must be of type: "markdown.Extension".' \
% (ext.__class__.__module__, ext.__class__.__name__))
+ def build_extension(self, ext_name, configs = []):
+ """Build extension by name, then return the module.
+
+ The extension name may contain arguments as part of the string in the
+ following format: "extname(key1=value1,key2=value2)"
+
+ """
+
+ # Parse extensions config params (ignore the order)
+ configs = dict(configs)
+ pos = ext_name.find("(") # find the first "("
+ if pos > 0:
+ ext_args = ext_name[pos+1:-1]
+ ext_name = ext_name[:pos]
+ pairs = [x.split("=") for x in ext_args.split(",")]
+ configs.update([(x.strip(), y.strip()) for (x, y) in pairs])
+
+ # Setup the module names
+ ext_module = 'markdown.extensions'
+ module_name_new_style = '.'.join([ext_module, ext_name])
+ module_name_old_style = '_'.join(['mdx', ext_name])
+
+ # Try loading the extention first from one place, then another
+ try: # New style (markdown.extensons.<extension>)
+ module = __import__(module_name_new_style, {}, {}, [ext_module])
+ except ImportError:
+ try: # Old style (mdx_<extension>)
+ module = __import__(module_name_old_style)
+ except ImportError:
+ message(WARN, "Failed loading extension '%s' from '%s' or '%s'"
+ % (ext_name, module_name_new_style, module_name_old_style))
+ # Return None so we don't try to initiate none-existant extension
+ return None
+
+ # If the module is loaded successfully, we expect it to define a
+ # function called makeExtension()
+ try:
+ return module.makeExtension(configs.items())
+ except AttributeError, e:
+ message(CRITICAL, "Failed to initiate extension '%s': %s" % (ext_name, e))
+
def registerExtension(self, extension):
""" This gets called by the extension """
self.registeredExtensions.append(extension)
@@ -294,10 +335,7 @@ Those are the two functions we really mean to export: markdown() and
markdownFromFile().
"""
-def markdown(text,
- extensions = [],
- safe_mode = False,
- output_format = 'xhtml1'):
+def markdown(text, *args, **kwargs):
"""Convert a markdown string to HTML and return HTML as a unicode string.
This is a shortcut function for `Markdown` class to cover the most
@@ -321,9 +359,7 @@ def markdown(text,
Returns: An HTML document as a string.
"""
- md = Markdown(extensions=load_extensions(extensions),
- safe_mode=safe_mode,
- output_format=output_format)
+ md = Markdown(*args, **kwargs)
return md.convert(text)
@@ -331,12 +367,9 @@ def markdownFromFile(input = None,
output = None,
extensions = [],
encoding = None,
- safe_mode = False,
- output_format = 'xhtml1'):
+ *args, **kwargs):
"""Read markdown code from a file and write it to a file or a stream."""
- md = Markdown(extensions=load_extensions(extensions),
- safe_mode=safe_mode,
- output_format=output_format)
+ md = Markdown(extensions=extensions, *args, **kwargs)
md.convertFile(input, output, encoding)
diff --git a/markdown/extensions/__init__.py b/markdown/extensions/__init__.py
index 14e0911..1cc4762 100644
--- a/markdown/extensions/__init__.py
+++ b/markdown/extensions/__init__.py
@@ -48,54 +48,3 @@ class Extension:
raise NotImplementedError, 'Extension "%s.%s" must define an "extendMarkdown"' \
'method.' % (self.__class__.__module__, self.__class__.__name__)
-
-def load_extension(ext_name, configs = []):
- """Load extension by name, then return the module.
-
- The extension name may contain arguments as part of the string in the
- following format: "extname(key1=value1,key2=value2)"
-
- """
-
- # Parse extensions config params (ignore the order)
- configs = dict(configs)
- pos = ext_name.find("(") # find the first "("
- if pos > 0:
- ext_args = ext_name[pos+1:-1]
- ext_name = ext_name[:pos]
- pairs = [x.split("=") for x in ext_args.split(",")]
- configs.update([(x.strip(), y.strip()) for (x, y) in pairs])
-
- # Setup the module names
- ext_module = 'markdown.extensions'
- module_name_new_style = '.'.join([ext_module, ext_name])
- module_name_old_style = '_'.join(['mdx', ext_name])
-
- # Try loading the extention first from one place, then another
- try: # New style (markdown.extensons.<extension>)
- module = __import__(module_name_new_style, {}, {}, [ext_module])
- except ImportError:
- try: # Old style (mdx.<extension>)
- module = __import__(module_name_old_style)
- except ImportError:
- message(WARN, "Failed loading extension '%s' from '%s' or '%s'"
- % (ext_name, module_name_new_style, module_name_old_style))
- # Return None so we don't try to initiate none-existant extension
- return None
-
- # If the module is loaded successfully, we expect it to define a
- # function called makeExtension()
- try:
- return module.makeExtension(configs.items())
- except AttributeError, e:
- message(CRITICAL, "Failed to initiate extension '%s': %s" % (ext_name, e))
-
-
-def load_extensions(ext_names):
- """Loads multiple extensions"""
- extensions = []
- for ext_name in ext_names:
- extension = load_extension(ext_name)
- if extension:
- extensions.append(extension)
- return extensions
diff --git a/markdown/preprocessors.py b/markdown/preprocessors.py
index ab44f96..2bd85b0 100644
--- a/markdown/preprocessors.py
+++ b/markdown/preprocessors.py
@@ -81,14 +81,32 @@ class HtmlBlockPreprocessor(Preprocessor):
tag = block[1:].replace(">", " ", 1).split()[0].lower()
return tag, len(tag)+2, {}
+ def _recursive_tagfind(self, ltag, rtag, start_index, block):
+ while 1:
+ i = block.find(rtag, start_index)
+ if i == -1:
+ return -1
+ j = block.find(ltag, start_index)
+ # if no ltag, or rtag found before another ltag, return index
+ if (j > i or j == -1):
+ return i + len(rtag)
+ # another ltag found before rtag, use end of ltag as starting
+ # point and search again
+ j = block.find('>', j)
+ start_index = self._recursive_tagfind(ltag, rtag, j + 1, block)
+ if start_index == -1:
+ # HTML potentially malformed- ltag has no corresponding
+ # rtag
+ return -1
+
def _get_right_tag(self, left_tag, left_index, block):
for p in self.right_tag_patterns:
tag = p % left_tag
- i = block.rfind(tag)
+ i = self._recursive_tagfind("<%s" % left_tag, tag, left_index, block)
if i > 2:
- return tag.lstrip("<").rstrip(">"), i + len(p)-2 + left_index-2
+ return tag.lstrip("<").rstrip(">"), i
return block.rstrip()[-left_index:-1].lower(), len(block)
-
+
def _equal_tags(self, left_tag, right_tag):
if left_tag[0] in ['?', '@', '%']: # handle PHP, etc.
return True
diff --git a/tests/misc/block_html_attr.html b/tests/misc/block_html_attr.html
new file mode 100644
index 0000000..d1c9efc
--- /dev/null
+++ b/tests/misc/block_html_attr.html
@@ -0,0 +1,27 @@
+<blockquote>
+Raw HTML processing should not confuse this with the blockquote below
+</blockquote>
+
+<div id="current-content">
+ <div id="primarycontent" class="hfeed">
+ <div id="post-">
+ <div class="page-head">
+ <h2>Header2</h2>
+ </div>
+ <div class="entry-content">
+ <h3>Header3</h3>
+ <p>Paragraph</p>
+ <h3>Header3</h3>
+ <p>Paragraph</p>
+ <blockquote>
+ <p>Paragraph</p>
+ </blockquote>
+ <p>Paragraph</p>
+ <p><a href="/somelink">linktext</a></p>
+ </div>
+ </div><!-- #post-ID -->
+ <!-- add contact form here -->
+ </div><!-- #primarycontent -->
+</div>
+
+<!-- #current-content --> \ No newline at end of file
diff --git a/tests/misc/block_html_attr.txt b/tests/misc/block_html_attr.txt
new file mode 100644
index 0000000..b2603cc
--- /dev/null
+++ b/tests/misc/block_html_attr.txt
@@ -0,0 +1,24 @@
+<blockquote>
+Raw HTML processing should not confuse this with the blockquote below
+</blockquote>
+<div id="current-content">
+ <div id="primarycontent" class="hfeed">
+ <div id="post-">
+ <div class="page-head">
+ <h2>Header2</h2>
+ </div>
+ <div class="entry-content">
+ <h3>Header3</h3>
+ <p>Paragraph</p>
+ <h3>Header3</h3>
+ <p>Paragraph</p>
+ <blockquote>
+ <p>Paragraph</p>
+ </blockquote>
+ <p>Paragraph</p>
+ <p><a href="/somelink">linktext</a></p>
+ </div>
+ </div><!-- #post-ID -->
+ <!-- add contact form here -->
+ </div><!-- #primarycontent -->
+</div><!-- #current-content -->
diff --git a/tests/misc/block_html_simple.html b/tests/misc/block_html_simple.html
new file mode 100644
index 0000000..dce68bc
--- /dev/null
+++ b/tests/misc/block_html_simple.html
@@ -0,0 +1,10 @@
+<p>foo</p>
+
+<ul>
+<li>
+<p>bar</p>
+</li>
+<li>
+<p>baz</p>
+</li>
+</ul> \ No newline at end of file
diff --git a/tests/misc/block_html_simple.txt b/tests/misc/block_html_simple.txt
new file mode 100644
index 0000000..d108c50
--- /dev/null
+++ b/tests/misc/block_html_simple.txt
@@ -0,0 +1,9 @@
+<p>foo</p>
+<ul>
+<li>
+<p>bar</p>
+</li>
+<li>
+<p>baz</p>
+</li>
+</ul>
diff --git a/tests/test_apis.py b/tests/test_apis.py
index e420c2a..51f4e73 100644
--- a/tests/test_apis.py
+++ b/tests/test_apis.py
@@ -249,13 +249,13 @@ class TestErrors(unittest.TestCase):
def testLoadExtensionFailure(self):
""" Test failure of an extension to load. """
self.assertRaises(MarkdownWarning,
- markdown.extensions.load_extension, 'non_existant_ext')
+ markdown.Markdown, extensions=['non_existant_ext'])
def testLoadBadExtension(self):
""" Test loading of an Extension with no makeExtension function. """
_create_fake_extension(name='fake', has_factory_func=False)
self.assertRaises(MarkdownException,
- markdown.extensions.load_extension, 'fake')
+ markdown.Markdown, extensions=['fake'])
def testNonExtension(self):
""" Test loading a non Extension object as an extension. """