Refactor fence block code to never infinite loop

(imported from commit f72cb182e4fc9c4e8003853276d8aa40b454d08f)
This commit is contained in:
Leo Franchi 2013-01-29 10:14:30 -05:00
parent 56e29ba11c
commit c6f73f7697
1 changed files with 43 additions and 34 deletions

View File

@ -95,6 +95,30 @@ class FencedBlockPreprocessor(markdown.preprocessors.Preprocessor):
self.checked_for_codehilite = False
self.codehilite_conf = {}
def process_fence(self, m, text):
lang = ''
if m.group('lang'):
lang = LANG_TAG % m.group('lang')
# If config is not empty, then the codehighlite extension
# is enabled, so we call it to highlite the code
if self.codehilite_conf:
highliter = CodeHilite(m.group('code'),
force_linenos=self.codehilite_conf['force_linenos'][0],
guess_lang=self.codehilite_conf['guess_lang'][0],
css_class=self.codehilite_conf['css_class'][0],
style=self.codehilite_conf['pygments_style'][0],
lang=(m.group('lang') or None),
noclasses=self.codehilite_conf['noclasses'][0])
code = highliter.hilite()
else:
code = CODE_WRAP % (lang, self._escape(m.group('code')))
placeholder = self.markdown.htmlStash.store(code, safe=True)
return '%s\n%s\n%s'% (text[:m.start()], placeholder, text[m.end():])
def run(self, lines):
""" Match and store Fenced Code Blocks in the HtmlStash. """
@ -108,44 +132,29 @@ class FencedBlockPreprocessor(markdown.preprocessors.Preprocessor):
self.checked_for_codehilite = True
text = "\n".join(lines)
end = 0
while 1:
m = FENCED_BLOCK_RE.search(text)
if not m:
fence = FENCE_RE.search(text)
if fence:
# If we found a starting fence but no ending fence,
# then we add a closing fence before the two newlines that
# markdown automatically inserts
if text[-2:] == '\n\n':
text = text[:-2] + '\n' + fence.group('fence') + text[-2:]
else:
text += fence.group('fence')
continue
else:
break
lang = ''
if m.group('lang'):
lang = LANG_TAG % m.group('lang')
# If config is not empty, then the codehighlite extension
# is enabled, so we call it to highlite the code
if self.codehilite_conf:
highliter = CodeHilite(m.group('code'),
force_linenos=self.codehilite_conf['force_linenos'][0],
guess_lang=self.codehilite_conf['guess_lang'][0],
css_class=self.codehilite_conf['css_class'][0],
style=self.codehilite_conf['pygments_style'][0],
lang=(m.group('lang') or None),
noclasses=self.codehilite_conf['noclasses'][0])
code = highliter.hilite()
if m:
end = m.end()
text = self.process_fence(m, text)
else:
code = CODE_WRAP % (lang, self._escape(m.group('code')))
break
fence = FENCE_RE.search(text, end)
if fence:
# If we found a starting fence but no ending fence,
# then we add a closing fence before the two newlines that
# markdown automatically inserts
if text[-2:] == '\n\n':
text = text[:-2] + '\n' + fence.group('fence') + text[-2:]
else:
text += fence.group('fence')
m = FENCED_BLOCK_RE.search(text)
if m:
text = self.process_fence(m, text)
placeholder = self.markdown.htmlStash.store(code, safe=True)
text = '%s\n%s\n%s'% (text[:m.start()], placeholder, text[m.end():])
return text.split("\n")
def _escape(self, txt):