Block parse contents of a block plugin
hellocode808 opened this issue · comments
I'm trying to write a plugin that renders tabs:
{tabs}
{tab Title 1}
**Content 1**
- Eggs
- Carrots
- Milk
{/tab}
{/tabs}
The plugin code:
TABS_PATTERN = r'(?sm){tabs}(?P<tabs_content>.*?){/tabs}'
TAB_PATTERN = r'(?sm){tab\s+(?P<tab_title>.+?)}(?P<tab_content>.*?)\s*{/tab}'
def parse_block_tabs(block, m, state):
text = m.group('tabs_content')
state.append_token({'type': 'tabs', 'text': text})
return m.end() + 1
def parse_block_tab(block, m, state):
title = m.group("tab_title")
text = m.group('tab_content')
state.append_token(
{
'type': 'tab',
'text': text,
'attrs': {
'title': title
}
}
)
return m.end() + 1
def render_block_tabs(renderer, text):
return '<ul class="tabs">' + text + '</ul>'
def render_block_tab(renderer, text, title):
return '<li data-title="' + title + '">' + text + '</li>'
def tabs(md):
md.block.register(
'tabs', TABS_PATTERN, parse_block_tabs, before="paragraph"
)
if md.renderer and md.renderer.NAME == 'html':
md.renderer.register('tabs', render_block_tabs)
def tab(md):
md.block.register('tab', TAB_PATTERN, parse_block_tab, before="paragraph")
if md.renderer and md.renderer.NAME == 'html':
md.renderer.register('tab', render_block_tab)
Is there a way to employ the block parser after parsing with parse_block_tabs
? In the docs I only found the option 'text': text
to use the inline parser. I want all elements, inline and block, to be rendered - in my example the list and {tab}
is not parsed.
Why not use directives
? You can create a custom directive for tabs: https://mistune.lepture.com/en/latest/directives.html
That sounds like a good option! A syntax like this for example, inspired by PyMdown Extensions:
.. tab::
:title: Title 1
Content 1
.. tab::
:title: Title 2
Content 2
"Consecutive tabs will automatically be grouped. " - but how to implement this? I think in the parsing of the directive there needs to be a check if the preceding tokens are part of a tab set (or if not, start a new tab set). For that, access to the token tree would be needed. Any pointers on that or is there a simpler way I am not seeing?
@hellocode808 I suggest you to built it upon v3 (current master code). https://pypi.org/project/mistune/3.0.0rc4/
It supports RST-styled directives and fenced-styled directives. If you want to group your tabs, you can rerun the tokens in before_render_hooks
.
BTW, I do offer paid work to write plugins and directives: https://github.com/sponsors/lepture/sponsorships?tier_id=220664