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
[WIP] Implement inline-toc extra for TOC HTML insertion after first heading #280
Changes from 1 commit
a365aed
64cd722
c707ba2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -241,7 +241,7 @@ def __init__(self, html4tags=False, tab_width=4, safe_mode=None, | |
extras = dict([(e, None) for e in extras]) | ||
self.extras.update(extras) | ||
assert isinstance(self.extras, dict) | ||
if "toc" in self.extras and "header-ids" not in self.extras: | ||
if ("toc" in self.extras or "inline-toc" in self.extras) and "header-ids" not in self.extras: | ||
self.extras["header-ids"] = None # "toc" implies "header-ids" | ||
self._instance_extras = self.extras.copy() | ||
|
||
|
@@ -391,8 +391,20 @@ def convert(self, text): | |
text += "\n" | ||
|
||
rv = UnicodeWithAttrs(text) | ||
if "toc" in self.extras: | ||
if ("toc" in self.extras or "inline-toc" in self.extras): | ||
# Generate TOC HTML as a property to be able to hijack it in "inline-toc" for subsctitution | ||
# TODO (Tomas Hubelbauer): See about using that as a static method without a need for a throwaway instance. | ||
rv._toc = self._toc | ||
if "inline-toc" in self.extras: | ||
if self._toc[0] is None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we have no headings, there is no need to prepend anything (
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have changed this to only include the TOC HTML if any heading exist. |
||
rv = UnicodeWithAttrs(rv.toc_html + text) | ||
else: | ||
(level, id, name) = self._toc[0] | ||
# Need to use a regex and rely on the HTML structure, tracking the regex's `end()` across all the HTML transformations would be extremely unreliable | ||
# TODO (Tomas Hubelbauer): Consider looser regex which allows for more attributes in order to to find heading even when more extras add attributes to it (future-proof) | ||
pattern = r"\<h{} id=[\"\']{}[\"\']\>{}<\/h{}\>".format(level, id, re.escape(name), level) | ||
text = re.sub(pattern, "\g<0>" + rv.toc_html, text) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice to somehow check for the failure of the substitution and prepend the TOC HTML instead, but not sure what would be the best way to go about that. Oh and this probably doesn't deal well with multiple headings with the same text, I need to check for that.
|
||
rv = UnicodeWithAttrs(text) | ||
if "metadata" in self.extras: | ||
rv.metadata = self.metadata | ||
return rv | ||
|
@@ -1540,7 +1552,7 @@ def _h_sub(self, match): | |
if header_id: | ||
header_id_attr = ' id="%s"' % header_id | ||
html = self._run_span_gamut(header_group) | ||
if "toc" in self.extras and header_id: | ||
if ("toc" in self.extras or "inline-toc" in self.extras) and header_id: | ||
self._toc_add_entry(n, header_id, html) | ||
return "<h%d%s>%s</h%d>\n\n" % (n, header_id_attr, html, n) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is currently needlessly inefficient, here I just take advantage of the fact that the object with
toc_html
on it is already created and replace its reference with a new copy. I will investigate static methods in Python to see if I can runinline-toc
before line 393 and avoid having to create two objects.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not end up using
staticmethod
decorator because I wasn't sure if Python 2.2 and 2.3 are expected to be supported and even then it gave me a hard time with me calling it withinUnicodeWithAttrs
where it was defined but it reportingUnicodeWithAttrs.toc_html
not existing.