Coloring all ALLCAPS words with JavaScript

Could someone help me with a JavaScript code to find all words written with capitalized letters and color them red, blue, or green alternatingly? I have asked this before and I couldn’t find a working solution :confused:

2 Likes

I am trying to reword this now: Is there a way to colorize all capital letters inside the text with red?

ChatGPT gave this but to no avail…

<script>
document.addEventListener("DOMContentLoaded", function() {
    // Select the main content area where your card text is located.
    const contentDiv = document.querySelector("#qa"); // Adjust the selector if needed

    if (contentDiv) {
        // Regular expression to match individual uppercase letters
        const regex = /[A-Z]/g;
        
        // Replace matches with span styled red
        const highlightedText = contentDiv.innerHTML.replace(regex, function(match) {
            return `<span style="color: red;">${match}</span>`;
        });
        
        // Set the modified content back to the div
        contentDiv.innerHTML = highlightedText;
    }
});
</script>

I noticed that you’ve brought up this topic a few times. I just wanted to make sure you didn’t miss my previous suggestion in Coloring ALL CAPS words - #15 by hkr. It worked on my end, so I thought it might help with your case as well. Or was it perhaps not working as you expected?

I did indeed try it. What it did is that it has indeed coloured allcaps words, but ones that are not a part of the card in itself, but rather it has coloured those words that are a part of the card template itself, which end up showing in the reviewer itself.

Here look at it:

BEFORE

AFTER ADDING


This makes me now think, is this because I have a radically different card template which conflicts with yours. I see that your card template is very simple.

I have found this code from Gemini, it works…but to some extent. It is coloring the words in the same way that I want, only that it causes Anki to reveal the answer and the […] box on the front side of the card simultaneously, so it messes up the revealing of the answer. The backside remains normal.

<script>
  function colorAllCapsWords(text) {
    // Regulärer Ausdruck, um Wörter in Großbuchstaben zu finden (mindestens 2 Buchstaben)
    const regex = /\b[A-Z]{2,}\b/g; 

    // Text mit rot gefärbten Wörtern ersetzen
    const result = text.replace(regex, '<span style="color: red;">$&</span>');

    return result;
  }

  function applyFormatting() {
    // Den Textinhalt des aktuellen Feldes abrufen
    const contentDiv = document.getElementById("content"); 
    let text = contentDiv.innerHTML;

    // Die Funktion aufrufen, um Wörter in Großbuchstaben einzufärben
    text = colorAllCapsWords(text);

    // Den geänderten Textinhalt wieder in das Feld einfügen
    contentDiv.innerHTML = text;
  }

  // Den Code zum Einfärben nach dem CLOZE MARKER Block ausführen
  setTimeout(applyFormatting, 10); 
</script>

Update: now here is a working code I found

<script>
    (function() {
        function colorCapsText() {
            const cardContent = document.getElementById("content");
            if (!cardContent) return;

            const regex = /\b[A-ZÄÖÜß]+\b/g;

            // Helper function to process text nodes, while avoiding any interference with cloze deletions
            function processTextNodes(element) {
                const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, null, false);
                let node;

                while ((node = walker.nextNode())) {
                    // Check if the text node is inside a cloze deletion and skip it
                    if (node.parentNode.closest('.cloze')) {
                        continue; // This avoids modifying cloze deletions
                    }

                    const text = node.textContent;
                    if (regex.test(text)) {
                        // We will not directly replace the node, to avoid breaking cloze
                        const newText = text.replace(regex, '<span class="all-caps">$&</span>');
                        
                        // Create a temporary wrapper to insert the modified content
                        const spanWrapper = document.createElement('span');
                        spanWrapper.innerHTML = newText;

                        // Insert each new node from the wrapper in place of the original text node
                        while (spanWrapper.firstChild) {
                            node.parentNode.insertBefore(spanWrapper.firstChild, node);
                        }
                        
                        // Remove the original text node after its content has been replaced
                        node.parentNode.removeChild(node);
                    }
                }
            }

            // Safely process text nodes after the DOM has rendered
            requestAnimationFrame(() => processTextNodes(cardContent));
        }

        // Run the function after the page loads
        requestAnimationFrame(colorCapsText);
    })();
</script>

The only problem with this is that it has a long loading time. I wonder if someone could help optimize it.

1 Like

Maybe instead of changing the templates you can ask chatGPT to simply wrap all cap words with <span> tags by sending it a text file? ChatGPT is bad with these kind of meta-language things though, but I hear o1 is pretty good with them (it can tell you number of a letter a word has which LLMs normally find hard to do).

Or maybe write you a script running which updates your actual notes with the tags. I think it’s doable with some regex. (maybe like //s[A-Z]+/s/ space+any number of capital letters+another space which is what you’re trying to find)

edit: Oh, wait… can you not do it with actual Anki feature “Find and replace”? I’m not sure what will you place in replace though. (I learned regex only yesterday)

I am revisiting this: This code is now not even working anymore, let alone work slowly :frowning:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.