pymdown-extensions
pymdown-extensions copied to clipboard
Snippets - Inserting markdown, is it possible to custom the level for inherited headers?
When embedding a markdown file into another one, is there a way to control how headers are transformed? As performed in the markdown-include extension : https://github.com/cmacmackin/markdown-include#configuration.
If not, could it be a future feature?
I can already think of multiple corner cases that would break markdown-include
's implementation. I can see it parsing headers in fences when you don't want it to. I can see this not playing well with other of our features...since it runs as a preprocessor, it has no context of other files. It may work in certain scenarios, but it will not work in all, at least the way markdown-include
implements it.
You would be better off implementing something like a relative header feature. I could see a Tree processor looking for any headers that have data-header-rel="1"
where the value instructs the processor how much to increase the header level by. These would stack of course. When done, I imagine you could reset it data-header-rel="-1"
. This would have to run before the toc
extension processes the headers.
# Header Level 1
# Header Level 3 {: data-header-rel="2"}
# Header Level 4 {: data-header-rel="1"}
# Header Level 5 {: data-header-rel="1 -4"}
# Header Level 1
<h1>Header Level 1</h1>
<h3>Header Level 3</h3>
<h4>Header Level 4</h4>
<h5>Header Level 5</h5>
<h1>Header Level 1</h1>
This would seem to avoid the pitfalls of markdown-include
by not relying on the processor that has no context to make context decisions.
@gir-bot remove S: triage @gir-bot add T: feature, S: maybe, C: snippets
Nice! Where could it be implemented in the source code? By there maybe:
https://github.com/facelessuser/pymdown-extensions/blob/f121e0816571ef2eadfa8cc6ba87fe169736a6e1/pymdownx/snippets.py#L62
Most likely, the best approach would be to create a separate TreeProcessor. It would run at a later time than the Snippet preprocessor.
The snippet creator would need to doctor the headers as I mentioned earlier (and also enable the attr_list
extension from Python Markdown).
The TreeProcessor would execute right before toc
and would walk the tree changing the header levels as dictated by the data-header-rel
(or whatever we call it). Those attributes would then get stripped out. Then toc
could do its thing on the headers as desired.
When you write:
the best approach would be to create a separate TreeProcessor
You mean, creating something like that somewhere in snippets.py
:
from markdown.treeprocessors import Treeprocessor
[...]
class SnippetTreeprocessor(Treeprocessor):
"""Snippet Treeprocessor."""
or inheriting directly from attr_list
?
https://github.com/Python-Markdown/markdown/blob/370e17b3923d7d8f4709652bc24b695271a0210d/markdown/extensions/attr_list.py#L65
I'm asking a lot but it to determine if I'm feelling able to psuh a PR or not.
Yes, in snippets. When called, it would probably exit immediately if attr_list is not enabled.
Well, I take that back. It probably shouldn't care if attr_list
is enabled. But attr_list
would be the way to set those.
I say this because you could probably do manual headers and it would work as well:
<h2 data-header-rel="2">Header text</h2>
I'm not positive I'm totally following the proposed solution, so please forgive the noise if what I'm saying doesn't make sense. But—looking at the implementation in markdown-include
, there's also support for headingOffset
, where you pass in a specific header offset. Would something like that work here? As in, along with the snippet filename, pass in an optional offset by which snippets
should bump any Markdown headers it finds in the included content?
(This is a great tool, thanks!)
Currently, there is no support for special header logic. Snippets, in its current form, simply inserts the content where you reference it (indented appropriately).
There has been no real decision yet on what the final solution will look like, assuming we implement it.