List of all references so far

Is there a way to get a list of all the references/tags I’ve created so far? Using a Search would presume I vaguely know what I’m looking for. But I might have created references or taken notes on a topic that I’d since moved on from. How do I find those abandoned references and notes, if I don’t remember they exist (if I haven’t made them into flashcards or organized them into folders to find later)?

I hope to create a wall of references I’ve created (akin to a tag database I’ve created in Notion).

Kind regards,
Brindha

1 Like

So you want to find either all top-level rems or reference targets.

The closes thing you can do is have a look at the #stub tag which gets assigned to a rem when you create it by using it as a reference or tag.

Other than that, there is not built-in method so far. Even the Tag Power-Up only starts collecting tags after the you enable it in the options.

It is not too difficult to query the IndexedDB with a user script. Create the following in Chrome DevTools (F12) > Sources > Snippets > New Snippet and run it on any page. Then click one of the buttons at the bottom to list all references.

function getRemText(remId, remStore, exploredRem=[]) {
    let rem = remStore[remId];
    if (!rem) return;

    const richTextElementsText = rem.key.map((richTextElement)=>{
        // If the element is a string, juts return it
        if (typeof richTextElement == 'string') {
            return richTextElement;
            // If the element is a Rem Reference (i == "q"), then recursively get that Rem Reference's text.
        } else if (richTextElement.i == 'q' && !exploredRem.includes(richTextElement._id)) {
            return getRemText(richTextElement._id, remStore, exploredRem.concat([richTextElement._id]));
        } else {
            // If the Rem is some other rich text element, just take its .text property.
            return richTextElement.text;
        }
    }
    );
    return richTextElementsText.join('');
}

(function() {
    let test = true;
    let targetContainerId = 'ReferenceLinks';
    let buttonId = 'list-reference-button';
    let listId = 'reference-list';

    let linksContainer = document.getElementById(targetContainerId);

    if (!test && document.getElementById(buttonId))
        return;

    function compareUsage(map) {
        return (aId, bId) => {
            const a = map[aId];
            const b = map[bId];
            return a.usageCount > b.usageCount ? -1 : 1;
        }
    }

    function compareText(map) {
        return (aId, bId) => {
            if (aId == bId) return 0;
            const ta = map[aId].text;
            const tb = map[bId].text;
            if (ta === undefined) return 1;
            if (tb === undefined) return -1;
            return ta.toLowerCase() < tb.toLowerCase() ? -1 : 1;
        }
    }

    let button = document.createElement('input');
    button.type = 'button';
    button.value = "List referenced Rem alphabetically";
    button.onclick = () => listRem(compareText);
    linksContainer.appendChild(button);

    let button2 = document.createElement('input');
    button2.type = 'button';
    button2.value = "List referenced Rem by most used";
    button2.onclick = () => listRem(compareUsage);
    linksContainer.appendChild(button2);
    

    function listRem(compare) {
        if (!test && document.getElementById(listId))
            return;

        query((rems)=>{
            let remStore = Object.fromEntries(rems.map(rem => [rem._id, rem]));
            let references = [];

            for (let rem of rems) {
                rem.key.forEach((richTextElement) => {
                    if (richTextElement.i === 'q') {
                        references.push(richTextElement._id);
                    }
                })
            }
            let referenceMap = [...references].reduce((map, rem) => {
                if (!map[rem]) {
                    map[rem] = { id: rem, text: getRemText(rem, remStore), usageCount: 0 };
                }
                map[rem].usageCount++;
                return map;
             }, {});
            console.warn(referenceMap);
            let list = document.getElementById(listId) || document.createElement('ul');
            list.id = listId;
            list.innerHTML = '';

            for (let rem of Object.keys(referenceMap).sort(compare(referenceMap))) {
                let link = document.createElement('a');
                link.href = `https://www.remnote.io/document/${rem}`;
                link.appendChild(document.createTextNode(`${referenceMap[rem].text} (${referenceMap[rem].usageCount})`));
                let li = document.createElement('li');
                li.appendChild(link);
                list.appendChild(li);
            }

            linksContainer.appendChild(list);
        }
        );
    }


    function query(handler) {
        let openRequest = indexedDB.open('lnotes', 21)

        openRequest.onsuccess = ()=>{
            console.info('Connected to database.')
            let db = openRequest.result;
            let t = db.transaction('quanta');
            let quanta = t.objectStore('quanta');
            let request = quanta.getAll();
            request.onsuccess = ()=>{
                console.info('Loaded Rems');
                handler(request.result);
            }
        }
        openRequest.onerror = ()=>{
            console.warn('There was an error:', openRequest.error);
        }
        openRequest.onupgradeneeded = ()=>{
            console.warn('The database version has got an upgrade. Update this script!');
        }
    }
}
)();

I did something similar a while ago when I listed all Power-Ups:

1 Like

Thank you the detailed explanation and sharing the code. Can we also get a list of power-ups with a possible shortcut, without using the code?

As for tags, you can go to your settings → experimental and activate the tag collaction:

Afterwards you can open the tag power-up with CTRL+P and you have a list of all tags:

(Just noticed, Hannes also mentioned it. I didn’t know that it starts collecting after you activate it! So it’s good to activate it early.)

Didn’t know about the Ctrl+P command. That’s awesome. Clicking on Tag there gives a list of just what I wanted. Thank you.