diff --git a/lib/markdown2.py b/lib/markdown2.py index 43596ddf..be5a8110 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -184,13 +184,13 @@ def markdown_path(path, encoding="utf-8", def markdown(text, html4tags=False, tab_width=DEFAULT_TAB_WIDTH, safe_mode=None, extras=None, link_patterns=None, footnote_title=None, footnote_return_symbol=None, - use_file_vars=False): + use_file_vars=False, cli=False): return Markdown(html4tags=html4tags, tab_width=tab_width, safe_mode=safe_mode, extras=extras, link_patterns=link_patterns, footnote_title=footnote_title, footnote_return_symbol=footnote_return_symbol, - use_file_vars=use_file_vars).convert(text) + use_file_vars=use_file_vars, cli=cli).convert(text) class Markdown(object): @@ -217,7 +217,7 @@ class Markdown(object): def __init__(self, html4tags=False, tab_width=4, safe_mode=None, extras=None, link_patterns=None, footnote_title=None, footnote_return_symbol=None, - use_file_vars=False): + use_file_vars=False, cli=False): if html4tags: self.empty_element_suffix = ">" else: @@ -255,6 +255,7 @@ def __init__(self, html4tags=False, tab_width=4, safe_mode=None, self.footnote_return_symbol = footnote_return_symbol self.use_file_vars = use_file_vars self._outdent_re = re.compile(r'^(\t|[ ]{1,%d})' % tab_width, re.M) + self.cli = cli self._escape_table = g_escape_table.copy() if "smarty-pants" in self.extras: @@ -393,11 +394,21 @@ def convert(self, text): if "target-blank-links" in self.extras: text = self._a_blank.sub(r'<\1 target="_blank"\2', text) + if "toc" in self.extras and self._toc: + self._toc_html = calculate_toc_html(self._toc) + + # Prepend toc html to output + if self.cli: + text = '{}\n{}'.format(self._toc_html, text) + text += "\n" + # Attach attrs to output rv = UnicodeWithAttrs(text) - if "toc" in self.extras: - rv._toc = self._toc + + if "toc" in self.extras and self._toc: + rv.toc_html = self._toc_html + if "metadata" in self.extras: rv.metadata = self.metadata return rv @@ -2229,46 +2240,48 @@ class MarkdownWithExtras(Markdown): # ---- internal support functions + +def calculate_toc_html(toc): + """Return the HTML for the current TOC. + + This expects the `_toc` attribute to have been set on this instance. + """ + if toc is None: + return None + + def indent(): + return ' ' * (len(h_stack) - 1) + lines = [] + h_stack = [0] # stack of header-level numbers + for level, id, name in toc: + if level > h_stack[-1]: + lines.append("%s" % indent()) + lines.append('%s
  • %s' % ( + indent(), id, name)) + while len(h_stack) > 1: + h_stack.pop() + if not lines[-1].endswith("
  • "): + lines[-1] += "" + lines.append("%s" % indent()) + return '\n'.join(lines) + '\n' + + class UnicodeWithAttrs(unicode): """A subclass of unicode used for the return value of conversion to possibly attach some attributes. E.g. the "toc_html" attribute when the "toc" extra is used. """ metadata = None - _toc = None - def toc_html(self): - """Return the HTML for the current TOC. - - This expects the `_toc` attribute to have been set on this instance. - """ - if self._toc is None: - return None - - def indent(): - return ' ' * (len(h_stack) - 1) - lines = [] - h_stack = [0] # stack of header-level numbers - for level, id, name in self._toc: - if level > h_stack[-1]: - lines.append("%s" % indent()) - lines.append('%s
  • %s' % ( - indent(), id, name)) - while len(h_stack) > 1: - h_stack.pop() - if not lines[-1].endswith("
  • "): - lines[-1] += "" - lines.append("%s" % indent()) - return '\n'.join(lines) + '\n' - toc_html = property(toc_html) + toc_html = None ## {{{ http://code.activestate.com/recipes/577257/ (r1) _slugify_strip_re = re.compile(r'[^\w\s-]') @@ -2647,7 +2660,8 @@ def main(argv=None): html4tags=opts.html4tags, safe_mode=opts.safe_mode, extras=extras, link_patterns=link_patterns, - use_file_vars=opts.use_file_vars) + use_file_vars=opts.use_file_vars, + cli=True) if py3: sys.stdout.write(html) else: