A notes format that I can automatically convert to flashcards?

_playground
Published

October 4, 2023

My goal is to have a notes format that I can automatically convert to flashcards, for studying.

So quarto has support for a format called revealjs.

Revealjs is basically presentations, like powerpoint or google slides, but in your browser. Although you can also print them to pdf.

Anyway, I was in need of some flashcards for my class and I wanted to see if I could use revealjs for this.

to create slides, just use a second level header:

## Getting up

- Turn off alarm
- Get out of bed

## Going to sleep

- Get in bed
- Count sheep

However, I don’t really want a title, so I can simply have the second level header (##), without a title, and it still creates another slide.

By default, lists are revealed all at once. To change this, in your quarto heading options:

format: 
    revealjs:
        incremental: true

Actually, I like content pauses better.

## Slide with a pause

content before the pause

. . .

content after the pause

Now, how can I randomize slide orders?

According to the revealjs pull where this feature was implemented:

I can have a range of slides, something like:

// for everything
// Reveal.configure({ random: true });

Reveal.configure({
                random: {
                    rangeStart: 5,
                    rangeEnd: 8
                }
            });

No wait, quarto has an option to shuffle the slides.

shuffle: true

Now, is there a way to randomize the the list? I want the list options to sometimes have the name, and sometimes have the content, and you have to match which with which.

chatgpt gave me this:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Randomized List on Page Load</title>
</head>
<body>
    <h1>Randomized List</h1>
    <ul id="randomList">
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4</li>
        <li>Item 5</li>
    </ul>

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            const list = document.getElementById("randomList");
            for (let i = list.children.length; i >= 0; i--) {
                list.appendChild(list.children[Math.random() * i | 0]);
            }
        });
    </script>
</body>
</html>

But does it work? :

Randomized List on Page Load

Randomized List

But it doesn’t work in revealjs, as revealjs won’t run show thing incrementally.

Rather than lists, can I just have javascript manipulate classes and divs created by pandoc?

::: {#myCustomBlock .custom-class}
This is a custom block that can be manipulated by JavaScript.
:::

This should be able to be changed by pandoc.

And then I can shuffle them with something like:

    function shuffleBlocks() {
    const container = document.getElementById("blocksContainer");
    const blocks = Array.from(container.children);
    for (let i = blocks.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [blocks[i], blocks[j]] = [blocks[j], blocks[i]];
    }
    container.innerHTML = "";
    blocks.forEach(block => container.appendChild(block));
}

// Shuffle the blocks when the page loads
window.addEventListener("DOMContentLoaded", shuffleBlocks);

So to test:

Shuffle blocks:

This is Block 1.

This is Block 2.

This is Block 3.

<script>
    function shuffleBlocks() {
        const container = document.querySelector("#blockContainer");
        const blockDivs = Array.from(container.querySelectorAll(".block"));
        
        // Shuffle the order of the block divs
        for (let i = blockDivs.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            const temp = blockDivs[i];
            blockDivs[i] = blockDivs[j];
            blockDivs[j] = temp;
        }
        
        // Append shuffled block divs back to the container
        blockDivs.forEach(blockDiv => {
            container.appendChild(blockDiv);
        });
    }

    // Shuffle the blocks when the page loads
    window.addEventListener("DOMContentLoaded", shuffleBlocks);
</script>

After many iterations with chatgpt, I finally got it to shuffle content.

Now is there a way to scale this across multiple slides? I don’t want to have to copy and paste this for the every single block. In fact, can I just make a custom html element that shuffles them?

So chatgpt gave me a custom html element class. It gave me a lot, actually, and none of them worked. So I’m giving up on that for now.

However, revealjs does support a grid slide layout, and it groups vertical slides together while randomizing their order, but it also randomizes the horizontal slides as well.

format: 
    revealjs:
        incremental: true
        theme: dark
        shuffle: true
        navigation-mode: grid

Eventually, I gave up on the revealjs format, after I found out that this flashcards app, anki

In my research, I found some tools which can convert other formats to anki:

Software Last update? Packaged?
md2anki 4 years ago pypi
markdown2anki 2 weeks ago pypi
markdown-anki-decks 1 year ago pypi, but also in nixpkgs

I did some testing. markdown-anki-decks is exceedingly simply, with something like:

# Deck title

## card front

card back

to create a deck.

I also experimented with markdown2anki. It’s way, way more complex. Unlike the previous option, it has many, many options.

To create a simple flashcard:

```{.markdown}