Prototype: 'Block Promotion' - Conversion from text to entity

This is actually a fibery feature request because I see myself and others use it so often.
The idea is to mimick what Obsidian and Logseq do regarding the refactoring of a paragraph into a new page, and replacing that paragraph with a link to that new page.

Prototype

For the time being I solved it using an automation script, which converts all quoted parts in the Description text and converts them to entities, using the first line of the quote as title and the remaining lines as Description text.

I used the quotation feature, but there are different ways to accomplish the same, for example making the script recognize headings of paragraphs.

I am now also working on a new version that recognizes text tokens that users can insert in text to perform operations on the text and convert it to entities of a particular database the token symbols are referring to. This can be combined with select fields that set the configuration of operations, like target database, relationships etc.

But to start, here is the relatively simple version that assumes one specific database ‘Page’.
The prototype works as follows:

chrome_iSucNvrcCd

Here is the script:

const fibery = context.getService('fibery');
const yNoteType = 'Yuri/Y Note';
const pageType = 'CCE Root/Page';
const databaseId = '8ff09230-0883-11ee-a2e3-qd72er7a05a2'; // Provided database ID for 'CCE Root/Page'

async function processYNoteTokens() {
    try {
        const currentEntity = args.currentEntities[0];
        console.log('Processing Y Note with ID:', currentEntity.id);

        // Fetch the Y Note entity with 'Description' field
        const yNoteEntity = await fibery.getEntityById(yNoteType, currentEntity.id, ['Description']);
        console.log('Y Note entity fetched:', yNoteEntity);

        if (yNoteEntity.Description && yNoteEntity.Description.Secret) {
            console.log('Fetching Y Note Description content...');
            let descriptionContent = await fibery.getDocumentContent(yNoteEntity.Description.Secret, 'md');
            console.log('Y Note Description content fetched:', descriptionContent);

            // Process the Description content to identify and replace quoted sections
            descriptionContent = await processQuotedSectionsAndReplace(descriptionContent);

            // Update the Y Note Description with replaced content
            console.log('Updating Y Note Description content...');
            await fibery.setDocumentContent(yNoteEntity.Description.Secret, descriptionContent, 'md');
            console.log('Y Note Description content updated.');
        } else {
            console.log('No Description or Secret found for the current Y Note entity.');
        }
    } catch (error) {
        console.error('Error in script:', error);
    }
}

async function processQuotedSectionsAndReplace(descriptionContent) {
    // Regex to match markdown quoted sections
    const regex = />(.*?)\n(?:>(.*?)\n)*/gs;
    let match;
    while ((match = regex.exec(descriptionContent)) !== null) {
        // The first line is the entity name, the rest is the description
        const lines = match[0].split('\n').filter(line => line.trim()).map(line => line.trim().substring(1).trim());
        if (lines.length > 0) {
            const entityName = lines[0];
            const entityDescription = lines.slice(1).join('\n');

            // Create a new Page entity with the extracted name and description
            const newEntityId = await createPageEntity(entityName, entityDescription);

            // Replace quoted section in the Y Note Description content with the reference link
            descriptionContent = descriptionContent.replace(match[0], `[[#^${databaseId}/${newEntityId}]]`);
        }
    }
    return descriptionContent;
}

async function createPageEntity(name, description) {
    try {
        console.log(`Creating entity in Database 'CCE Root/Page' with Name "${name}" and Description...`);
        // Create a new Page entity
        const newEntity = await fibery.createEntity(pageType, { 'Name': name });
        console.log(`Entity created with ID: ${newEntity.id}`);

        // Update the Description field of the newly created entity
        // Fetch the newly created entity to get the Description Document ID
        const createdEntity = await fibery.getEntityById(pageType, newEntity.id, ['Description']);
        if (createdEntity.Description && createdEntity.Description.Secret) {
            await fibery.setDocumentContent(createdEntity.Description.Secret, description, 'md');
            console.log(`Description for entity "${name}" updated.`);
        } else {
            console.log(`Description field not found or inaccessible for entity "${name}".`);
        }
        return newEntity.id; // Return the ID of the newly created entity
    } catch (error) {
        console.error(`Error creating entity with Name "${name}" and Description:`, error);
    }
}

await processYNoteTokens();

Explanation

  1. The script starts by initializing the Fibery service and defining some constants like the types of entities it will be working with and the database ID.
  2. The processYNoteTokens function is the main function in the script. It fetches a specific ‘Y Note’ entity using its ID and the ‘Description’ field.
  3. If the ‘Description’ field exists and has a ‘Secret’, it fetches the content of the ‘Description’ using the ‘Secret’ and the format ‘md’ (markdown).
  4. The content of the ‘Description’ is then processed to identify and replace quoted sections using the processQuotedSectionsAndReplace function.
  5. The ‘Description’ field of the ‘Y Note’ entity is then updated with the replaced content.
  6. If no ‘Description’ or ‘Secret’ is found for the ‘Y Note’ entity, it logs a message.
  7. The processQuotedSectionsAndReplace function uses a regex to match markdown quoted sections in the ‘Description’ content.
  8. For each matched quoted section, it creates a new ‘Page’ entity with the extracted name and description using the createPageEntity function and replaces the quoted section in the ‘Description’ content with a reference link to the new entity.
  9. The createPageEntity function creates a new ‘Page’ entity with the provided name and updates the ‘Description’ field of the created entity with the provided description.
  10. The script ends by calling the processYNoteTokens function.

If you have any comments or suggestions, feel free.