Cobertos / md2notion

A better Notion.so Markdown importer
MIT License
654 stars 65 forks source link

Support for checkbox. #18

Closed mshiyaf closed 4 years ago

mshiyaf commented 4 years ago

I cannot find conversion for a checkbox block. It renders as a normal bulleted list.

Cobertos commented 4 years ago

md2notion uses mistletoe for Markdown processing which is based on CommonMark which doesn't support GitHub Markdown Flavor (GFM) checkboxes.

I originally looked at adding it as a new token...

As a new token...

`mistletoe` makes it [super easy to add new tokens](https://github.com/miyuchina/mistletoe#a-new-token). We should be able to add a new block token to the renderer that handles this. Something like the following: ``` from md2notion.NotionPyRenderer import NotionPyRenderer from notion.block import TodoBlock class GFMCheckbox(BlockToken): """ Similar to ListItemBlock but has an extra /\[(x )\]/i Attributes: children (list): a list of TODO, use the pattern = from ListItemBlock but with the extra regex above """ pass class NotionPyWithTodoBlockRenderer(NotionPyRenderer): def __init__(self): super().__init__(GFMCheckbox) ```

... but then realized this can just be handled in the ListItem handling directly

import re
from md2notion.NotionPyRenderer import NotionPyRenderer
from notion.block import TodoBlock

class NotionPyWithTodoBlockRenderer(NotionPyRenderer):
    def render_list_item(self, token):
        # Lists can have "children" (nested lists, nested images...), so we need
        # to render out all the nodes and sort through them to find the string
        # for this item and any children
        rendered = self.renderMultiple(token.children)
        children = [b for b in rendered if b['type'] != TextBlock]
        strings = [s['title'] for s in rendered if s['type'] == TextBlock]

        # Figure out which type of block we need to render
        leaderContainsNumber = re.match(r'\d', token.leader) #Contains a number
        renderType = None
        if leaderContainsNumber:
            renderType = NumberedListBlock
        else if re.match(r"^\[[x ]\]", strings, re.I):
            renderType = TodoBlock
        else:
            renderType = BulletedListBlock

        return {
            'type': renderType,
            'title': "".join(strings),
            'children': children
        }

If you use this renderer with the notionPyRendererCls kwarg it should handle it.

Still trying to decide if I should add as a feature, I'd rather not continue to add random Markdown features that Mistletoe doesn't have extensions for.

Cobertos commented 4 years ago

image Ended up adding it, should be in the next version

ghost commented 4 years ago

That's great to hear, since personally I use a lot of TODO items not finding checkbox conversion made me feel incomplete. Hoping to see the new version released soon.

Cobertos commented 4 years ago

Added in v2.1.1