Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TOC via CLI toc_html prepended to output #283

Merged
merged 1 commit into from Dec 1, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
94 changes: 54 additions & 40 deletions lib/markdown2.py
Expand Up @@ -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):
Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<ul>" % indent())
h_stack.append(level)
elif level == h_stack[-1]:
lines[-1] += "</li>"
else:
while level < h_stack[-1]:
h_stack.pop()
if not lines[-1].endswith("</li>"):
lines[-1] += "</li>"
lines.append("%s</ul></li>" % indent())
lines.append('%s<li><a href="#%s">%s</a>' % (
indent(), id, name))
while len(h_stack) > 1:
h_stack.pop()
if not lines[-1].endswith("</li>"):
lines[-1] += "</li>"
lines.append("%s</ul>" % 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<ul>" % indent())
h_stack.append(level)
elif level == h_stack[-1]:
lines[-1] += "</li>"
else:
while level < h_stack[-1]:
h_stack.pop()
if not lines[-1].endswith("</li>"):
lines[-1] += "</li>"
lines.append("%s</ul></li>" % indent())
lines.append('%s<li><a href="#%s">%s</a>' % (
indent(), id, name))
while len(h_stack) > 1:
h_stack.pop()
if not lines[-1].endswith("</li>"):
lines[-1] += "</li>"
lines.append("%s</ul>" % 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-]')
Expand Down Expand Up @@ -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:
Expand Down