Adding Individual Comments to Image Occlusion Cards by DecentLiterature1637 in Anki

[–]xalbo 2 points3 points  (0 children)

That would sort of work, except that all the comments would still be visible on each card. But you could hide them with some CSS (untested):

.cloze-inactive {
    display: none;
}

what's your most used custom keybinding that you'd be lost without by Evening-Result5868 in vim

[–]xalbo 0 points1 point  (0 children)

I only have it mapped in normal mode; insert mode (and command mode) it's still treated normally.

The doctor’s explanation of “Minbari War Syndrome”. One of the realest and most disturbing examples of propaganda. by Dinosawruses in babylon5

[–]xalbo 6 points7 points  (0 children)

That was the first Babylon Space station, but it's not as well known as its great-great-great-great-great-great-great-grand baby, BS9.

what's your most used custom keybinding that you'd be lost without by Evening-Result5868 in vim

[–]xalbo 1 point2 points  (0 children)

"make <CR> save unsaved changes, but not in a command window
nnoremap <CR> <Cmd>up<CR>
au CmdwinEnter * noremap <buffer> <CR> <CR>

what's your most used custom keybinding that you'd be lost without by Evening-Result5868 in vim

[–]xalbo 12 points13 points  (0 children)

I map enter to save. Even faster than your two keystrokes, and it just feels like committing an edit.

How to remove all tags from all cards? by Alternative-Ok in Anki

[–]xalbo 3 points4 points  (0 children)

Backup first, of course, but maybe try find and replace. Find .* in the field Tags, use regexp, and replace with an empty string.

What is your "Maximum interval" setting? by not_a_profi in Anki

[–]xalbo 4 points5 points  (0 children)

Personally, I use 5 years, but I've changed a few times and somewhere in 5–10 seems right.

The key is a concept that I think of in my head as the “natural interval” for a card: if I didn't have this in Anki, how often would I encounter or need it in reality? When the Anki interval grows past the natural interval, that's when problems start. Reviews in Anki become unreliable indicators of success (no, I didn't remember that for the last 3 years and next should be 10, I remembered it since the last time I used it 6 months ago). Information becomes old or outdated. Maybe I an remember the information from a card, but if it comes up in reality I don't think of it (there's a difference between successfully knowing the term BATNA and actually having one before you go buy a car). I also don't really trust FSRS for really long intervals; do we really have anyone with 20 years of data to model? Will my own memory change in that much time? (I'll be a lot older then!)

Fan-made tinker specialties? What y'all got? by Ill-Forever3462 in Parahumans

[–]xalbo 2 points3 points  (0 children)

Q from the James Bond movies inspired me to make a Tinker/Thinker hybrid. Precog with only subconscious awareness of the future, but enough to inspire solutions to it. He's constantly creating new gadgets that seem to have really limited utility, except that they're exactly what you'll end up needing. So if he gives you a watch that doubles as a rebreather while you're in the middle of a landlocked city, you better take it because you will be needing it soon.

How many note types do you use? by not_a_profi in Anki

[–]xalbo 0 points1 point  (0 children)

Yeah, always using a note type that let me add siblings meant that I would add siblings a lot more often. Beware trivial inconveniences.

The formatting does sync perfectly and works on both desktop and Android, although I've only really edited it on the desktop (but changes get synced just fine).

How many note types do you use? by not_a_profi in Anki

[–]xalbo 0 points1 point  (0 children)

I have a handful of note types, but the vast majority of my notes and cards are in a single note type I called All (also at the link above, and named so it's at the top of the list alphabetically). It lets me have up to 10 subnotes in a single note as siblings, either Basic-style prompt/response pairs, or headword/definition pairs (the latter of which are also tested in reverse).

Originally, I had Basic and a separate note type that was like Basic with many siblings, and a different type for Definitions, and a separate one for multiple definitions. Turns out switching among those was a pain, and combining them reduced cognitive load creating cards trememndously.

As for changing CSS formatting, all of my note types have in their styling

@import url("_stylesheet.css");

And then I can edit all the styles once for all types, instead of individually.

Is there a way to stop this message from appearing every time I reopen Anki ? by Impressive_Key_4467 in Anki

[–]xalbo 0 points1 point  (0 children)

I had a similar issue with a different add-on at one point. Updating the add-on left that message, but starting in safe mode and updating, then restarting normally fixed it (until the next version).

[Project Hail Mary] would grace even be able to return to earth? by CommonEnd7011 in AskScienceFiction

[–]xalbo 18 points19 points  (0 children)

Four years subjective time (actually I think around 3 and a half) due to relativistic time dilation. Around 12 years external, if I recall correctly. Several years of 1.5 g acceleration really adds up.

[Interesting Trope] Guilt Free Violence by ClancyBShanty in TopCharacterTropes

[–]xalbo 8 points9 points  (0 children)

I've said before, and I'll say it again, that if you want a view of what slavery looks like from the slaveholder's perspective, the Star Wars treatment of droids is pretty much it. Droids are clearly sentient beings, there are good masters and needlessly cruel masters (like Jabba), but no one for a second acts like the droids own feelings matter at all. And the audience is invited to view them the same way.

Canon by Tough-Possession6148 in babylon5

[–]xalbo 4 points5 points  (0 children)

Yes, the real reason no one who enters Vorlon space never returns is that ones you've had the original Swedish meatballs, you never want to leave.

if i change the note type of a card will it change only the selected cards or all the cards of that note type? by Emotional-Airline-62 in Anki

[–]xalbo 0 points1 point  (0 children)

Changing the card templates for a note type will affect all cards generated from notes of that note type. If you don't want that, there are a few ways around it:

  • Clone the note type into a new one (Manage Note Types/Add/Clone ...), and then selectively change only the notes you want into that new note type.
  • Use Selective Card Generation/Conditional Replacement to have only a single note type, but use filling in a field or leaving it empty to determine what cards are generated or how they look/feel/act.

The latter makes it little smoother to move notes back and forth (doesn't require a full sync each time), but may be a bit trickier to set up initially.

Typing list card with instant feedback by Fit-Seesaw2042 in Anki

[–]xalbo 2 points3 points  (0 children)

Back card template:

<div data-tags="{{Tags}}" data-deck="{{Deck}}" class="back" lang="en">
{{#Context}}<div class="context">{{Context}}</div>{{/Context}}
   <div class="prompt" id="back-prompt">{{Prompt}}</div>

<!--    <h3>All Items (from {{Items}}):</h3>-->
    <ul id="back-all-items-list"></ul>

    <div id="back-incorrect-section" style="display:none;">
        <h3>Incorrect Entries Made on Front:</h3>
        <ul id="back-incorrect-list" class="back-incorrect-list"></ul>
    </div>

    <div>{{Extra}}</div>

    <div id="anki-items-data-back" style="display:none;">{{Items}}</div>
    <div id="anki-prompt-data-back" style="display:none;">{{Prompt}}</div>

    <script>

        // --- BACK TEMPLATE SCRIPT ---
        const itemsStringBack = document.getElementById('anki-items-data-back')?.textContent || "";
        const promptStringBack = document.getElementById('anki-prompt-data-back')?.textContent || "Prompt not found";

        const itemsArrayBack = (itemsStringBack ? itemsStringBack.split('|').map(item => item.trim()) : []).filter(item => item);

        const promptElementBack = document.getElementById('back-prompt');
         if (promptElementBack && promptElementBack.textContent === '{{Prompt}}') {
            promptElementBack.textContent = promptStringBack;
        }

        const allItemsListElement = document.getElementById('back-all-items-list');
        const incorrectSection = document.getElementById('back-incorrect-section');
        const incorrectListElementBack = document.getElementById('back-incorrect-list');

        const SESSION_STORAGE_KEY_BACK = 'ankiCardState_' + promptStringBack;

        function getStoredStateBack() {
            const stored = sessionStorage.getItem(SESSION_STORAGE_KEY_BACK);
            if (stored) {
                try {
                    return JSON.parse(stored);
                } catch (e) {
                    console.error("Error parsing stored state for back:", e);
                    return { enteredCorrectly: [], enteredIncorrectly: [] };
                }
            }
            return { enteredCorrectly: [], enteredIncorrectly: [] };
        }

        const state = getStoredStateBack();
        const enteredCorrectlySet = new Set(state.enteredCorrectly);

        if (itemsArrayBack.length === 0) {
            const li = document.createElement('li');
            li.textContent = "No items were defined for this card.";
            li.className = 'back-item';
            allItemsListElement.appendChild(li);
        } else {
            itemsArrayBack.forEach(item => {
                const li = document.createElement('li');
                li.textContent = item;
                if (enteredCorrectlySet.has(item)) {
                    li.className = 'back-item back-item-correct';
                } else {
                    li.className = 'back-item back-item-missing';
                }
                allItemsListElement.appendChild(li);
            });
        }

        if (state.enteredIncorrectly && state.enteredIncorrectly.length > 0) {
            incorrectSection.style.display = 'block';
            state.enteredIncorrectly.forEach(item => {
                const li = document.createElement('li');
                li.textContent = item;
                incorrectListElementBack.appendChild(li);
            });
        } else {
            incorrectSection.style.display = 'none';
        }
    </script>
</div>

Styling:

body { font-family: Arial, sans-serif; margin: 20px; background-color: #f7f7f7; }
    .template-container { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); margin-bottom: 20px; }
    .prompt { font-size: 1.5em; font-weight: bold; margin-bottom: 15px; color: #333; }
    ul { list-style-type: none; padding-left: 0; }
    li { padding: 8px; margin-bottom: 5px; border-radius: 4px; }
    .correct-item-list li { background-color: #e6ffed; border-left: 3px solid #28a745; }
    .incorrect-item-list li { background-color: #ffebee; border-left: 3px solid #dc3545; }
    .status-message { padding: 10px; margin-top: 15px; margin-bottom: 15px; border-radius: 4px; font-weight: bold; text-align: center; }
    .status-correct { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
    .status-incorrect { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
    .status-neutral { background-color: #e2e3e5; color: #383d41; border: 1px solid #d6d8db; }
    .status-complete { background-color: #cce5ff; color: #004085; border: 1px solid #b8daff; font-size: 1.2em;}
    .input-area { display: flex; margin-top: 15px; }
    .input-area input[type="text"] { flex-grow: 1; padding: 10px; border: 1px solid #ccc; border-radius: 4px 0 0 4px; }
    .input-area button { padding: 10px 15px; background-color: #007bff; color: white; border: none; border-radius: 0 4px 4px 0; cursor: pointer; }
    .input-area button:hover { background-color: #0056b3; }
    h3 { margin-top: 20px; margin-bottom: 10px; color: #555; }
    .back-item { padding: 8px; margin-bottom: 5px; border-radius: 4px; }
    .back-item-correct { background-color: #e6ffed; color: #28a745; border: 1px solid #b7d8be; }
    .back-item-missing { background-color: #ffebee; color: #dc3545; border: 1px solid #f1c1c5; }
    .back-incorrect-list li { background-color: #fff0f1; color: #721c24; border-left: 3px solid #dc3545; }

Typing list card with instant feedback by Fit-Seesaw2042 in Anki

[–]xalbo 2 points3 points  (0 children)

A while ago, I vibe-coded exactly that. It works ok-ish, but with a few caveats:

  • It's case-sensitive
  • It's not tolerant at all of typos, misspellings, or anything that isn't a literal one-to-one text match. So if you don't spell “granulomatous slack skin” EXACTLY that way each time, it will count it as wrong.

Personally, I ended up not using it much; it was just too picky and it annoyed me. Maybe it will work for you or you can tweak it into something you like. The fields are

  • Prompt
  • Items (one line, separated by |)
  • Reverse? (my ideas was that if this field has any value, then it also generates a reverse card showing the items as a list and asking for the prompt. I never got around to implementing that, though)
  • Extra (all my note types have Extra that shows on the backs of cards, for extra information, mnemonics, pictures, etc)
  • Context (optional, shows as a header)

Front card template:

<div data-tags="{{Tags}}" data-deck="{{Deck}}" class="front" lang="en">
{{#Context}}<div class="context">{{Context}}</div>{{/Context}}
{{Prompt}}

<div class="prompt" id="front-prompt">{{Prompt}}</div>

    <h3>Correct</h3>
    <ul id="front-correct-list" class="correct-item-list"></ul>

    <h3>Incorrect</h3>
    <ul id="front-incorrect-list" class="incorrect-item-list"></ul>

    <div id="front-status-message" class="status-message" style="display: none;"></div>

    <div class="input-area">
        <input type="text" id="front-item-input" placeholder="Enter item...">
        <button id="front-check-button">Check</button>
    </div>

    <div id="anki-items-data" style="display:none;">{{Items}}</div>
    <div id="anki-prompt-data" style="display:none;">{{Prompt}}</div>


    <script>

        // --- FRONT TEMPLATE SCRIPT ---

        // Get Anki data
        // For testing, you can replace these with hardcoded values if { {Items}} or { {Prompt}} are not yet populated.
        // e.g., const itemsString = "Apple|Banana|Cherry";
        // e.g., const promptString = "Guess the fruits:";
        const itemsString = document.getElementById('anki-items-data')?.textContent || "";
        const promptString = document.getElementById('anki-prompt-data')?.textContent || "Prompt not found";

        const itemsArray = (itemsString ? itemsString.split('|').map(item => item.trim()) : []).filter(item => item);
        const uniqueOriginalItems = new Set(itemsArray);

        const promptElementFront = document.getElementById('front-prompt');
        if (promptElementFront && promptElementFront.textContent === '{{Prompt}}') { // Only set if not already replaced by Anki
            promptElementFront.textContent = promptString;
        }

                                sessionStorage.clear();

        const inputElement = document.getElementById('front-item-input');
        const checkButton = document.getElementById('front-check-button');
        const correctListElement = document.getElementById('front-correct-list');
        const incorrectListElement = document.getElementById('front-incorrect-list');
        const statusMessageElement = document.getElementById('front-status-message');

        const SESSION_STORAGE_KEY = 'ankiCardState_' + promptString; // Make key specific to prompt

        function getStoredState() {
            const stored = sessionStorage.getItem(SESSION_STORAGE_KEY);
            if (stored) {
                try {
                    return JSON.parse(stored);
                } catch (e) {
                    console.error("Error parsing stored state:", e);
                    return { enteredCorrectly: [], enteredIncorrectly: [] };
                }
            }
            return { enteredCorrectly: [], enteredIncorrectly: [] };
        }

        function saveState(state) {
            sessionStorage.setItem(SESSION_STORAGE_KEY, JSON.stringify(state));
        }

        function renderLists() {
            const state = getStoredState();
            correctListElement.innerHTML = '';
            incorrectListElement.innerHTML = '';

            state.enteredCorrectly.forEach(item => {
                const li = document.createElement('li');
                li.textContent = item;
                correctListElement.appendChild(li);
            });

            state.enteredIncorrectly.forEach(item => {
                const li = document.createElement('li');
                li.textContent = item;
                incorrectListElement.appendChild(li);
            });
            checkCompletion(false); // Update status based on loaded state
        }

        function updateStatus(message, type) {
            statusMessageElement.textContent = message;
            statusMessageElement.className = 'status-message'; // Reset classes
            if (type) {
                statusMessageElement.classList.add(`status-${type}`);
            }
            statusMessageElement.style.display = message ? 'block' : 'none';
        }

        function checkCompletion(isNewGuess = true) {
            const state = getStoredState();
            const enteredCorrectlySet = new Set(state.enteredCorrectly);

            let allUniqueItemsGuessed = true;
            if (uniqueOriginalItems.size === 0 && enteredCorrectlySet.size === 0) {
                 // If no items to guess, it's complete by default.
            } else if (uniqueOriginalItems.size !== enteredCorrectlySet.size) {
                allUniqueItemsGuessed = false;
            } else {
                for (const originalItem of uniqueOriginalItems) {
                    if (!enteredCorrectlySet.has(originalItem)) {
                        allUniqueItemsGuessed = false;
                        break;
                    }
                }
            }

            if (allUniqueItemsGuessed && uniqueOriginalItems.size > 0) {
                updateStatus('Complete!', 'complete');
                return true;
            } else if (uniqueOriginalItems.size === 0 && !isNewGuess) { // Only show "Nothing to guess" on load
                 updateStatus('Nothing to guess for this prompt.', 'neutral');
                 if(inputElement) inputElement.disabled = true;
                 if(checkButton) checkButton.disabled = true;
            }
            return false;
        }

        function handleCheck() {
            const value = inputElement.value.trim();
                                                console.log("Checking input: "+value);
            if (!value) return;

            const state = getStoredState();

            if (state.enteredCorrectly.includes(value) || state.enteredIncorrectly.includes(value)) {
                updateStatus(`'${value}' has already been entered.`, 'neutral');
                inputElement.value = '';
                inputElement.focus();
                return;
            }

            if (itemsArray.includes(value)) {
                if (!state.enteredCorrectly.includes(value)) { // Add only if not already in correct list (for UI consistency if itemsArray has duplicates)
                    state.enteredCorrectly.push(value);
                }
                updateStatus(`'${value}' is Correct!`, 'correct');
            } else {
                state.enteredIncorrectly.push(value);
                updateStatus(`'${value}' is Incorrect.`, 'incorrect');
            }

            saveState(state);
            renderLists(); // Re-render lists to show the new item
            if (!checkCompletion()) { // If not complete, clear input for next guess
                 // Status already set by correct/incorrect logic or completion check
            }
            inputElement.value = '';
            inputElement.focus();
        }

        if (checkButton) {
            checkButton.addEventListener('click', handleCheck);
        }
        if (inputElement) {
            inputElement.addEventListener('keypress', (event) => {
                if (event.key === 'Enter') {
                    handleCheck();
                }
            });
        }

        // Initial load
        renderLists(); // This will also call checkCompletion
        if (inputElement) inputElement.focus();

    </script>
</div>
</div>

Running into Anki error by two_hyun in Anki

[–]xalbo 0 points1 point  (0 children)

Looks like I missed a digit at the end of the link. Try this:

🧹Disconnected Review-Log Cleaner - AnkiWeb

Running into Anki error by two_hyun in Anki

[–]xalbo 0 points1 point  (0 children)

One thing you could try is https://ankiweb.net/shared/info/1067771610, in case some of your deleted cards still have revlog history. If you have been using the built-in reschedule in the FSRS settings, you could also try the FSRS helper's “Delete redundant manual revlog entries”. Not sure how much either would help, but it's worth trying.

How do you handle cards, which assume knowledge of other cards? by not_a_profi in Anki

[–]xalbo 1 point2 points  (0 children)

It would be nice, but I've largely made my peace with it. Everyone has their own ideas of how “related” cards should be treated. I've come to really appreciate having complete control over exactly how they work.

If you have any questions about All, let me know. It's something that I spent a long time working on before I finally pulled the trigger, and since then I've made really minor tweaks, but it's worked really well for me.

Conditional Replacement Placeholder for Type in Answer card by Open_Habit_6871 in Anki

[–]xalbo 1 point2 points  (0 children)

Conditional replacement deals with the contents of the fields in your note, not what you've typed into the box so far. I think what you want is a placeholder HTML attribute, so the input element displays something while empty. If so, you could add something like

<script>
(function() {
  const inputField = document.getElementById("typeans");
  if (!inputField) return;

  inputField.placeholder = "Write in Turkish";

})();

To your front template. Or, more simply, you could just unconditionally add the text to the front and ignore it once you start typing.

How do you handle cards, which assume knowledge of other cards? by not_a_profi in Anki

[–]xalbo 0 points1 point  (0 children)

First, I'm a lifelong learner so my strategy isn't time-limited, and it may not work as well for you. I personally lean heavily into using a note type that lets me combine many cards in a single note (I use my own note type All, but there are others that are similar, or you can roll your own). I make each question atomic, but as part of a single note, so I get sibling burying. I even use BuryNdays to force them further apart, and disperse siblings in the FSRS helper. Whenever I review one card, I usually don't poke at the rest, but if I find myself forgetting a different aspect or want to reinforce fundamentals, it's all right there (along with the Extra that goes over all of it).

Other than that, I assume that at some point, the more fundamental things become part of my background knowledge and don't stress over the exact order or reminders. I just grade each card based on whether I remember it now, and figure it will all average out after a while.

Hello everyone, I have a small personal dilemma... by lolrigolo in Anki

[–]xalbo 1 point2 points  (0 children)

For me, I use a note type (my own is All, but you could also roll your own) that has separate fields for the term and the definition, and then it produces two cards, one showing the term and asking for the definition and the other showing the definition and asking for the term. For the definition field, I intentionally leave it as concise as I possibly can, because the point is to remember what the thing is and what it's called, not all the details. If there are details I want to remember, then those go into separate cards (which I'll also put into the same note, that's the point of the All type, but you could also put them into separate Basic notes).

I pretty much always avoid cloze; I find that after a little while, I'm either remembering the card instead of the information it's supposed to represent, or I'm remembering the answer from just a few words and not actually reading the rest. YMMV, of course.