A simple script to convert Markdown to rich text?

I tried creating a button script that converts the Description field text from markdown to formatted text, but it returns HTML. Can anyone give some pointers how to do this? The operations like fetching and replacing text I know, just the part about using formatted text I don’t yet see.

Do you mean that you have raw markdown in the rich text field, and you want to convert it into interpreted markdown?


Yes exactly.

If you have some text on the UI that looks like raw markdown, e.g.

then if you were to examine the markdown for this, it would look like this on the ‘backend’:

i.e. the symbols used in raw markdown are ‘escaped’.

If you want to convert the raw markdown into interpreted markdown, you would need to take this backend text, and pass it through a converting function.

In the above example, the converting function that simply removes the backslashes would do the trick, since it would convert the backend to this:


which looks like this on the UI:



I suggest giving this a go, although I don’t know if this ‘converting function’ is robust enough to work for all possible markdown syntax


it worked. This is pretty amazing, thank you!

Most of the relevant Markdown is converted to rich text, but the code blocks have some issues:

BEFORE execution of the script:

AFTER execution of the script:

What is wrong

The result in the code block contains extra empty lines added, which were not present in the original code.
These extra empty lines are above and under the code lines in the code block.

Here is the used script

const fibery = context.getService('fibery');
const yNoteDB = 'Yuri/Y Note';

async function unescapeMarkdownInYNoteDescription(currentEntityId) {
    try {
        // Get the current Y Note entity with its Description field
        const yNoteEntity = await fibery.getEntityById(yNoteDB, currentEntityId, ['Description']);
        let descriptionField = yNoteEntity['Description'];

        if (descriptionField && descriptionField.Secret) {
            // Get the Markdown content from the Description field
            let markdownContent = await fibery.getDocumentContent(descriptionField.Secret, 'md');

            // Unescape Markdown by removing backslashes before Markdown syntax, including code blocks
            let unescapedMarkdown = markdownContent.replace(/\\([#*`_~>\[\]])/g, '$1');

            // Update the Description field with the unescaped Markdown
            await fibery.setDocumentContent(descriptionField.Secret, unescapedMarkdown, 'md');

            console.log('Description field of Y Note has been updated.');
        } else {
            console.log('No Description field or content found for the Y Note entity.');
    } catch (error) {
        console.error('Error in script:', error);

// This unction is called with the current entity ID
await unescapeMarkdownInYNoteDescription(args.currentEntities[0].id);

If you want to reverse engineer it, add some content to a rich text field and then use the export to markdown function to see what it looks like. Then replace the rich text contents with this ‘raw’ markdown and repeat the export. You can now see what the difference is and determine what the ‘converting function’ needs to be.

I did now the following:


In order to text a code block, I manually created the code block throug typing the ``` and inserting a code snippet, including an intentional white line in the code snippet:



When exporting that, I see in the export file:



I Ctrl-V paste that directly in the Description field (without manually creating a code block) which shows as:


After exporting the entity as Markdown, the export file shows:


During step 3, the pasting of the correct markdown into the Description field results in intentional empty lines in the code snippet to be DELETED.
This is confirmed by the second export in step 4, which shows that the empty line is also deleted, but also extra white lines are added. This is basically data corruption/loss.

So I guess this is a bug?

Anyhow, the script that removes the escape backslashes actually works correctly but returns something that happened before the script, which was what the ProseMirror editor modified about the pasted text. So the problem can only be fixed by fixing this bug in how ProseMirror handles pasted text.