Skip to content
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

Callout is being displayed twice after pageToMarkdown and toMarkdownString #118

Open
Mikescops opened this issue Jan 6, 2025 · 8 comments · Fixed by #119
Open

Callout is being displayed twice after pageToMarkdown and toMarkdownString #118

Mikescops opened this issue Jan 6, 2025 · 8 comments · Fixed by #119
Labels
bug Something isn't working v4-candidate This issue / PR can be better handled in v4

Comments

@Mikescops
Copy link
Contributor

Mikescops commented Jan 6, 2025

My Notion page contains a Callout block, and when doing:

const mdblocks = await n2m.pageToMarkdown(id);
const mdString = n2m.toMarkdownString(mdblocks);

The blockquote is rendered twice because pageToMarkdown takes the child block and already make them as markdown in the parent when building MD blocks. This operation is done another time when toMarkdownString parses the blocks again.

Example of mdblocks:

 {
    "type": "callout",
    "blockId": "143eac7c-3bb3-801c-9f7e-e533b0665635",
    "parent": "> 📝 ### **A Simplified Analogy**  \n>   \n> Think of confidential computing as an ultra-secure vault:  \n>   \n> 1. **The Vault (Trusted Execution Environment or TEE):** This is a locked room where only specific operations can take place, shielded from everything outside. Even if a hacker (or a curious system admin) tried to gain entry to the vault, they’d see only encrypted gibberish.  \n>   \n> 2. **The Key (Encryption):** Only you—and those you trust—can unlock what’s inside. Even the company hosting the vault doesn’t have a spare key.",
    "children": [
      {
        "type": "heading_3",
        "blockId": "143eac7c-3bb3-8031-9fc2-ceb8475d347b",
        "parent": "### **A Simplified Analogy**",
        "children": []
      },
      {
        "type": "paragraph",
        "blockId": "143eac7c-3bb3-80cd-9f39-e031f41b5786",
        "parent": "Think of confidential computing as an ultra-secure vault:",
        "children": []
      },
      {
        "type": "numbered_list_item",
        "blockId": "143eac7c-3bb3-8050-901b-d988226c5beb",
        "parent": "1. **The Vault (Trusted Execution Environment or TEE):** This is a locked room where only specific operations can take place, shielded from everything outside. Even if a hacker (or a curious system admin) tried to gain entry to the vault, they’d see only encrypted gibberish.",
        "children": []
      },
      {
        "type": "numbered_list_item",
        "blockId": "143eac7c-3bb3-8007-9f42-e41c95fe37e9",
        "parent": "2. **The Key (Encryption):** Only you—and those you trust—can unlock what’s inside. Even the company hosting the vault doesn’t have a spare key.",
        "children": []
      }
    ]
  },

This can be easily solved by adding conditions in notion-to-md.ts file, I'll open a PR and let you look if it's the best solution.

@souvikinator
Copy link
Owner

Oh I see where I messed up. Appreciate the PR I'll merge it and push a new release. Thanks :)

@Mikescops
Copy link
Contributor Author

Here it is #119

@souvikinator
Copy link
Owner

Thank you, @Mikescops, for your contribution, truly appreciate it! 😊
v3.1.3 is now live.

I’d love to hear your feedback or see your input on the development of v4. Let me know how it addresses your use case or if you have any other use cases to share.
Join the discussion on GitHub: #112

@Mikescops
Copy link
Contributor Author

I think we missed something, if there are other blocks after the title in the callout they are not displayed

image

I think it's a matter of regex, maybe we could do something simpler to understand like this

    const formattedText = text.replace(/\n/g, "  \n> ");
    const formattedEmoji = emoji ? emoji + " " : "";
    const headingMatch = text.match(/^(#{1,6})\s/);
    if (headingMatch) {
        const headingLevel = headingMatch[1].length;
        return `> ${"#".repeat(headingLevel) + " "}${formattedEmoji}${formattedText.replace(headingMatch[0], "")}`;
    }
    return `> ${formattedEmoji}${formattedText}`;

@Mikescops
Copy link
Contributor Author

PR here: #120

@souvikinator
Copy link
Owner

Good catch, Tested it, look good. Will create a new release thank you :)

This solves the issue however there are a lot of edge cases that still needs to be handled and one of them being:

image

which ignores the child elements of the toggle and there are many such cases where a type of block can be accommodated inside another block.


The real issue is how inconsistently blocks are handled during rendering, especially the ones with child blocks. Honestly, the code I wrote here is a mess, and that's on me. Going forward, We need to make sure we clean this up in v4 and have a consistent block processing method that fits well with the renderer plugin and also gives enough flexibility to users to customize without much hassle.

@souvikinator souvikinator reopened this Jan 7, 2025
@souvikinator
Copy link
Owner

Since this is not completely solved I'll mark it as candidate of v4 and probably plan out the development of v4.

@souvikinator souvikinator added bug Something isn't working v4-candidate This issue / PR can be better handled in v4 labels Jan 7, 2025
@souvikinator
Copy link
Owner

It's live now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working v4-candidate This issue / PR can be better handled in v4
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants