lepture/mistune

Markdown Renderer does not properly render Task Lists with task list plugin

WarpedPixel opened this issue · 2 comments

Create a Markdown object with a MarkdownRenderer and just the task_lists plugin.

        markdownparser = mistune.create_markdown(renderer=MarkdownRenderer(), plugins=[task_lists])

This properly parses Markdowns with task lists. However, they are not rendered correctly by the MarkdownRenderer (the [ ] or [x] is deleted).
Attempting to use the techniques that work with the HTMLRenderer like deriving a renderer class and overriding task_list_item() or registering a rendering function for the 'task_list_item' tags does not work. Basically MarkdownRenderer does not support plugins.
The following patch in _list.py solves the problem but is not a solution I would propose. The ideal solution would be for MarkdownRenderer to support plugins fully.

def _render_list_item(renderer, parent, item, state):
    leading = parent['leading']
    text = ''
    # support for task lists. plugins are not properly supported by markdown renderer
    if 'checked' in item['attrs']:
        leading += f"[{'x' if item['attrs']['checked'] else ' '}] "
    for tok in item['children']:

This properly renders task lists with the MarkdownRenderer if the task_lists plugin is used.

For the record, I have worked around this in two ways:

  1. forked the depot and added the above fix (which worked for one use case)
  2. wrote a separate task_lists plugin that does not mess with the existing list_item token content, just adds additional information in the attrs field that other code can use as it processes list items. This way Markdown rendering is not affected (it ignored the attrs)

I suggest (2) is probably a better solution for most use cases, barring proper plugin support in the Markdown renderer itself.

You can subclass MarkdownRenderer, and add a task_list_item method:

class MyMarkdownRenderer(MarkdownRenderer):
    def task_list_item(self, token, state):
        return '...'