How to append item to the list with right formating

Hi everyone!

Below I have a script which does following:

I defined a draft UUID in the script. The script dynamically extracts markdown headings, prompts me to choose one to append the text to the selected heading. Then, the content of the editor gets appended to the selected heading as a markdown item list.

It works almost as I want. Below are examples of the content of the draft before and after running the script.

Before:

## Heading

some content

## Second Heading

* Item 1

## Third Heading

For example, I append text to second heading.

## Heading

some content

## Second Heading

* Item 1

* Item 2
* Item 3
## Third Heading

Example of wanted result:

## Heading

some content

## Second Heading

* Item 1
* Item 2
* Item 3

## Third Heading

Maybe someone knows what I need to modify in the script to get items listed one after the other and keep a newline separator before the heading below. I tried experimenting with placing “\n” in different parts at the bottom of the script, but without any success.

Here is the script:

// Helper function to extract markdown headings
function extractHeadings(content) {
    const headingRegex = /^#+\s+.+$/gm;
    return content.match(headingRegex) || [];
}

// Prompt the user to select a heading
function chooseHeading(headings) {
    let p = Prompt.create();
    p.title = "Select Heading";
    p.message = "Choose a heading to append the content to:";
    
    // Create a map of displayed headings to actual headings
    let headingMap = {};
    headings.forEach(heading => {
        let displayedHeading = heading.replace(/^#+\s*/, ''); // Remove the # symbols and leading space
        p.addButton(displayedHeading);
        headingMap[displayedHeading] = heading;
    });
    p.addButton("Append to End", null, true); // Add an option to append to the end
    p.isCancellable = true;

    let selectedHeading = null;
    if (p.show()) {
        let selectedDisplayHeading = p.buttonPressed;
        selectedHeading = headingMap[selectedDisplayHeading] || "Append to End";
    }
    return selectedHeading;
}

// Helper function to find the end of the current block
function findBlockEnd(content, startIndex) {
    const blockRegex = /^#+\s+.+$/gm;
    blockRegex.lastIndex = startIndex;
    const match = blockRegex.exec(content);
    return match ? match.index : content.length;
}

// Main script logic

let dateCreated = draft.processTemplate("[[created|%Y-%m-%d]]");
const currentContent = draft.content.trim();
const specificDraftUUID = 'B07F108C-1F61-4258-97F7-CB319392810A';
var specificDraft = Draft.find(specificDraftUUID);

if (specificDraft) {
    const specificContent = specificDraft.content;
    const headings = extractHeadings(specificContent);
    const selectedHeading = chooseHeading(headings);

    if (selectedHeading) {
        if (selectedHeading === "Append to End") {
            specificDraft.content = specificContent + "\n\n" + "* <!-- " + dateCreated + " --> " + currentContent;
        } else {
            const headingIndex = specificContent.indexOf(selectedHeading);
            const blockEndIndex = findBlockEnd(specificContent, headingIndex + selectedHeading.length);
            const beforeBlock = specificContent.substring(0, blockEndIndex);
            const afterBlock = specificContent.substring(blockEndIndex);
            specificDraft.content = beforeBlock + "* <!-- " + dateCreated + " --> " + currentContent + "\n" + afterBlock;
        }
        specificDraft.update();
    } else {
        console.log("Operation cancelled.");
    }
} else {
    console.log(`Draft with UUID ${specificDraftUUID} not found.`);
}

Your findBlockEnd function is finding the location of the next heading and you are inserting the new text directly before that next heading. I think you also want that function to consider the whitespace (line feeds or spaces) prior to the next heading…maybe a regex more like /\s*^#+\s+.+$/gm that also matches the preceding whitespace would get you closer.

2 Likes

Thank you Greg! It solved my issue.

I suspected it was something to do with regex of the blocks, but didn’t detected it on my own.

1 Like