Package: markdown-anki-decks
markdown-anki-decksMarkdown anki decks is a simple program to convert markdown files into anki decks.# The h1 tag is the deck title## The h2 tags are the questionsThe markdown content between h2 tags are the answers.Markdown anki decks uses the question to uniquely identify the card.
You can change the card contents without losing your progress on the card.
Markdown anki decks can be reimported without creating duplicates.InstallationMake sure you have a python version of 3.7 or greater installed.pip install markdown-anki-decksThis will install themdankideckcli tool.TutorialMarkdown anki decks converts all markdown files in an input directory toapkgfiles.
Theapkgfiles are stored in an output directory.Create the input directorymkdir input.Create the output directorymkdir output.Create a markdown file in the input directory.<!-- input/deck.md --># Deck Title## Card Titlecard contents.## Second Card Titlecard contents 2.Runmdankideck input outputto convert the markdown files in the input directory toapkgfiles in the output directory.Importapkgfiles as decks into anki.Usagemdankideckcomes with built in documentation. Runmdankideck --helpto see it.Usage: mdankideck [OPTIONS] INPUT_DIR OUTPUT_DIR

Arguments:
  INPUT_DIR   The input directory. Contains markdown files which will be
              converted to anki decks.  [required]

  OUTPUT_DIR  The output directory. Anki .apkg files will be written here.
              [required]


Options:
  --sync                Whether or not to synchronize the output with anki
                        using anki connect.  [default: False]

  --prefix TEXT         Can be used to make your markdown decks part of a
                        single subdeck. Anki uses `::` to indicate sub decks.
                        `markdown-decks::` could be used to make all generated
                        decks part of a single root deck `markdown-decks`
                        [default: ]

  --delete              Whether to delete cards from anki during sync. If sync
                        is false this has no effect.  [default: False]

  --cloze               Whether to support cloze syntax  [default: False]
  --version             Show version information  [default: False]
  --install-completion  Install completion for the current shell.
  --show-completion     Show completion for the current shell, to copy it or
                        customize the installation.

  --help                Show this message and exit.SyncingMarkdown anki decks can useAnkiConnectto sync the created decks immediately to anki.
First you need to install AnkiConnect as an add on in Anki.
Then you need to callmdankideckwith the--syncflag.
By default if you delete a question in markdown we do not delete the question in Anki during sync.
However you can delete missing questions in Anki during sync by callingmdankideckwith the--deleteflag.If you see an error messageUnable to reach anki connect. Make sure anki is running and the Anki Connect addon is installed., make sure you have installed anki connect and that you are running anki.# convert markdown file in the input directory to apkg files in the output# directory and sync the decks to anki using anki connectmdankideckinputoutput--sync# convert input to output with an empty deck prefix (default)# and delete cards from anki if the question is deleted or changed in markdownmdankideckinputoutput--sync--deleteSubdecksYou can use the Deck title prefix option to make all your markdown decks part of a single subdeck.
Anki automatically creates subdecks based on deck names.Decks can contain other decks, which allows you to organize decks into a tree. Anki uses “::” to show different levels. A deck called “Chinese::Hanzi” refers to a “Hanzi” deck, which is part of a “Chinese” deck. If you select “Hanzi” then only the Hanzi cards will be shown; if you select “Chinese” then all Chinese cards, including Hanzi cards, will be shown.SourceI use a prefixmd::to store all my markdown decks in a subdeck calledmd.# sync all cards to anki with a root deck `md`mdankideckinputoutputTrue"md::"TrueImagesMarkdown anki decks support images which are stored in the same folder as the markdown file they are referenced by.![my-image](image.jpg)will work because it is in the same folder as the markdown file.![my-image](./images/image.jpg)will not work because it is in a different folder than the markdown file.All images must have unique filenames even if they are stored in different folders.These are limitations of anki not Markdown anki decks.SoundsUse the syntax[sound:sound-file.mp3]to add a sound to your card.Markdown anki decks support sounds which are stored in the same folder as the markdown file they are referenced by.[sound:sound-file.mp3]will work because it is in the same folder as the markdown file.[sound:./sounds/sound-file.mp3]will not work because it is in a different folder than the markdown file.All sounds must have unique filenames even if they are stored in different folders.These are limitations of anki not Markdown anki decks.Styling CardsThe cards are styled with minimal cssmarkdown.css.
Syntax highlighting is provided viapygments.
The syntax highlighting uses the pygments default theme.Clozes (experimental)mdankideck supports close syntax in questions if you callmdankideckwith the--clozeflag. Clozes can be specified in the question using the template{{c#::answer::hint}}where#is a number and answer and hint are words or multiple words. The hint is optional so you can also write{{c#::answer}}. Clozes with the samec#will be hidden together.The following markdown would create two cloze cards.## The alphabet starts with {{c1::a}} {{c2::b}} {{c1::a}}The alphabet starts with [...] b [...]andThe alphabet starts with a [...] cThec1clozes are blocked out together.Custom StylingYou can add custom styling using yaml frontmatter. The css key takes a path to a css file as a string or an array of paths to multiple css files.---css:custom-styles.css------css:["one.css","two.css","three.css","four.css"]---The paths to the css files are assumed to be relative to the markdown file.
Cards have the following html structure. During processing markdown anki decks wraps your answer in a section tag. So the answer will be<section>{{Answer}}</section>. This extra wrapping step is performed because answers can consist of multiple sibling html elements and we need to provide a single element to Anki.<!-- the question card --><divclass="card"><divclass="question">{{Question}}</div></div><!-- the answer card --><divclass="card"><divclass="question">{{Question}}</div><hr/><divclass="answer">{{Answer}}</div></div>You can style cards in general using the.cardselector and you can style questions and answers using the.questionand.answerselector./* apply red background to all cards */.card{background:red;}MathjaxAnki supports mathjax out of the box. However you need to be careful with how markdown escapes characters. The following code snippet will not render as mathjax when you convert it because markdown will assume you are trying to escape the parentheses and will render the text(\sqrt{x})\(\sqrt{x}\)You need to escape the backslashes by using double backslashes.
The following snippet will work to render math using mathjax.<!-- this will render inline math -->

\\(\sqrt{x}\\)

<!-- this will render block math -->

\\[\sqrt{x}\\]Markdown FeaturesMost commonly used markdown features should work without any issues.
If there is a Markdown feature you want to use and it is supported by one of theofficial extensions for python-markdownthere is good chance it can be added to the project.
Check outcli.pyto see the list of currently enabled extensions. (Search forextensions=)Multiline questionsYou may want to render complex questions which span multiple lines.
You can use the fact that anyh2element is assumed to be a question combined with the fact that the markdown converter supports embedding markdown in html if you use the special attributemarkdown="block"on the html element. It's much easier to see with an example.<h2 markdown="block">-this question-is actually-a markdown list

You can even add math to your questions \\(\sqrt{2}\\)

</h2>Additionally you may not wanth2styling for your multiline question. In that case you can add thedata-questionattribute to any tag to make it a question.<div data-question markdown="block">

This is a question which does not have h2 formatting!-it can contain nested markdown such as`code`</div>For more informationsee themd_in_htmldocumentationLimitationsMarkdown anki decks makes some assumptions to enable syncing.
Cards are uniquely identified by their deck name and question.
If you change the deck name or the question you will lose the card history.
All deck names must be unique.
All questions in a single deck must be unique.
Identical questions in separate decks are ok.DesignThe markdown files are parsed withpython-markdown. The resulting html is then parsed withbeautifulsoup.
Finally the cards are created withgenanki.
The cli is implemented usingtyperand the program is packaged usingpoetry.ContributingHappy to discuss additional features if you open up an issue.We use commitizen for commits.
Runpoetry run cz committo make a commit.Runpoetry run mdankideck --prefix "test::" --sync --cloze testData/input testData/outputto convert the test data into decks.Runpoetry run pygmentize -S default -f html -a .codehilite > ./markdown_anki_decks/styles/pygments.cssto create a pygments stylesheet.
Runpoetry run pygmentize -S monokai -f html -a ".nightMode .codehilite" > ./markdown_anki_decks/styles/pygments-dark.cssto create the dark mode stylesheet.
The-Sflag is used to specify the style. Runpoetry run pygmentize -L styleto list the styles pygmentize can use. Replacedefaultwith any of the styles to use a different style.Currently usedefaultfor light mode andmonokaifor dark mode.ReleasesRunpoetry run cz bump --check-consistencyto update the changelog and create a tag.Runpoetry publish --buildto publish the pack to pypi.git push --tags && git pushto update github.