Git Product home page Git Product logo

ankdown's Introduction

Ankdown

A simple way to write Anki decks in Markdown.

What This Is

Anki is awesome, in many ways. However, its card editor is... a little bit uncomfortable. I really wanted to write Anki cards in Markdown. So I made a tool to convert Markdown (+ standard MathJAX math notation) into Anki decks that can be easily imported. This way, it's possible to use any fancy markdown (and MathJAX) tools to build your decks.

How to use it

NOTE This program requires Python 3, along with the packages in requirements.txt

Installing

Ankdown can be installed by doing pip3 install --user ankdown.

Writing Cards

Cards are written in the following format:

Expected Value of \(f(x)\)

%

\[\mathbb{E}[f(x)] = \sum_x p(x)f(x)\]

%

math, probability

---

Variance of \(f(x)\)

%

\[\text{Var}(f(x)) = \mathbb{E}[(f(x) - \mathbb{E}[f(x)])^2]\]

Each of the solitary % signs is a field separator: the first field is the front of the card, the second field is the back of the card, and subsequent fields can contain whatever you want them to (all fields after the second are optional).

--- markers represent a card boundary.

The tool needs these separators to be alone on their own lines, and most markdown editors will work better if you separate them from other text with empty lines, so that they're treated as their own paragraphs by the editor.

Running Ankdown

Method A: manually

To compile your cards, put them in markdown files with .md extensions, inside of a directory that has the name of the deck you'd like to put the cards into. Then, run ankdown -r [directory] -p [package filename]. The package filename should end in .apkg.

You can then import the package using the Anki import tool. To do this, go to File > Import, and then in the drop-down menu select "Packaged Anki Deck/Collection (*.apkg)".

Method B: via the add-on

Once you've installed ankdown, it can be a hassle to run it on all of your decks over and over again. There is an ankdown Anki add-on that you can use to make this process simpler: If you put all of your decks in one megadirectory (mine is in ~/Flashcards), you can re-import your decks in one swell foop by going to Tools > Reload Markdown Decks (or using the operating-system-dependent keybinding).

Gotchas

Ankdown has an unusually large number of known issues; my preferred method of discussing them is via github ticket.

Multiple Decks

Ankdown uses Genanki as a backend, which doesn't (as of this writing) handle multiple decks in a single package very well. If you point ankdown at a directory with multiple decks in subdirectories, it will do its best, and your cards will all be added to the package, but they won't be assigned to the correct decks. The ankdown plugin solves this problem by running the executable on each deck individually, and then importing all the resulting packages.

Intentional feature removals

There used to be other ways to run ankdown, but they were slowly making the code worse and worse as I tried to keep them all operational. If there's a particular method of operating ankdown that you used and miss, let me know in a github issue.

Math separators

Unfortunately, $ and $$ as math separators were not chosen by the anki developers for the desktop client's MathJax display, and so in order for math to work in both web and desktop, it became much simpler to use \(\) and \[\]. These separators should be configurable in most markdown editors (e.g. I use the VSCode Markdown+Math plugin). Older decks that were built for ankdown need to be modified to use the new separators.

Media references

Ankdown should work with media references that result in src="" appearing somewhere in the generated html (mainly images). If you need it to work with other media types (like sounds), let me know in a github issue and I may make time to fix this.

Updating Cards

When you want to modify a card, just run your deck through the above process after changing the markdown file. Anki should notice, and update the card. This is done by giving the cards in your deck unique IDs based on their filename and index in the file.

This is the most robust solution I could come up with, but it has some downsides:

  1. It's not possible to automatically remove cards from your anki decks, since the anki package importer never deletes cards.
  2. If you delete a card from a markdown file, ankdown will give all of its successors off-by-one ID numbers, and so if they were different in important ways (like how much you needed to study them), anki will get confused. The best way to deal with this is to give each card its own markdown file.

General code quality

Lastly, the catch-all disclaimer: this is, as they say, alpha-quality software. I wrote this program (and the add-on) to work for me; it's pretty likely that you'll hit bugs in proportion to how different your desires are from mine. That said, I want it to be useful for other people as well; please submit github tickets if you do run into problems!

ankdown's People

Contributors

benwr avatar dzackgarza avatar jay-pee avatar kadaliao avatar p1tt1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ankdown's Issues

Cloze support

Hi Ben:

I just added cloze feature, would you like to add into your project?

Thank you
Houcheng Lin

Cannot import the package in Anki after running Ankdown with method A

I follow the method A to create a package.

An error occurs when importing the package with the Anki import tool:

Selected file was not in UTF-8 format. Please see the importing section of the manual.

The directory specified after -r has only one file which is a copy-paste of the cards example from README.

Tried out on Anki 2.1.11-1 and Anki 2.1.13 (dev).

Is ankdown supposed to produce files in UTF-8 format? When I run file -i package I can see charset=binary, so the output I get from ankdown isn't UTF-8.

Improvement: Text after % field seperator

Hi there,

I've modified your code to allow for 11 fields, this is my basic card type (I don't have that many fields which I actually use for text, some work as toggles). Since it's quite hard to see which of the 11 % symbols belongs to which of the 11 fields it would be nice to put some text after the % symbol.

For instance:

Front

% Back:

Back

% Field 3:

Content of field 3.

etc.

Would there be a simple way to implement this?

README clarification

#20 pointed out that the README doesn't mention that this tool creates .apkg files; this should be fixed.

Feature Request: Github flavored markdown

I made a test deck to look if ankdown is converting everything properly.
After fixing the error in issue #24 and #7 it did work! :)

Actually not fully :P

My last card is about github flavored markdown:

# Github Flavored

%

**Syntax Higlighting**

```javascript
function fancyAlert(arg) {
  if(arg) {
    $.facebox({div:'#foo'})
  }
}
```


**Task List**

- [x] @mentions, #refs, [links](), **formatting**, and <del>tags</del> supported
- [x] list syntax required (any unordered or ordered list supported)
- [x] this is a complete item
- [ ] this is an incomplete item

**Tables**

| test | test2 | test3 | test4 | test5 |
|------|-------|-------|-------|-------|
| test | test2 | test3 | test4 | test5 |
| test | test2 | test3 | test4 | test5 |
| test | test2 | test3 | test4 | test5 |

**Strike through**

~~this~~

Ankdown doesn't support this fully. Her is a picture of the rendered version:

Capture

Would be nice to have this feature :)

Option to change math separators

I can't change my vscode plugin (Markdown All in One) to work with the Math separator syntax which the script is using. In my opinion it should be possible to have a option that ankdown also works with $ and $$ by substitute it later in the process to \( \) and \[ \] with a regular expression.

When I have the time I would do a pull request. Would be nice to get your opinion about it.

Thank you for your work.

Tests

I should write some tests or something if I want anyone else to use this ever.

Image import is broken

Somehow we're now creating invalid apkgs when there are images. One problem is the relative paths change, but there's some deeper problem, because even when that's fixed we produce invalid archives.

Images

I am using a lot of mnemonics for my flash cards and audio files. Does ankdown support them? And if yes, how would I add them to my flash cards?

Images in Subfolders

From @jay-pee in #7 , copying here as it's a slightly different issue

When putting images in subfolders an error occurs:

Traceback (most recent call last):
  File "c:\Users\Philip\Documents\GitHub\ankdown\ankdown\ankdown.py", line 389, in main
    cards_to_apkg(card_iterator, pkg_arg)
  File "c:\Users\Philip\Documents\GitHub\ankdown\ankdown\ankdown.py", line 343, in cards_to_apkg
    copyfile(abspath, newpath) # This is inefficient but definitely works on all platforms.
  File "C:\Python36\lib\shutil.py", line 121, in copyfile
    with open(dst, 'wb') as fdst:
FileNotFoundError: [Errno 2] No such file or directory: 'assets/images/philly-magic-garden.jpg'

Maybe we have to create the folder before putting the image there with copyfile(abspath, newpath).
Or change the newpath variable.

Reloading decks overwrites css changes

First of all, thanks for this addon and your help with my image issue. PDF -> Markdown -> Anki is sooo much more fun to work with.

As I am often iterating on my cards, I have to reimport the decks multiple times (because I want to keep all the cards managed by ankdown and not risk overwriting changes done in anki itself).
However, everytime I reimport the decks, it overwrites my CSS changes to the Ankdown Card Type (I changed the font-size and the font itself as it was not really readable on my computer).

Is this a known issue?

Currently I just copy the affected CSS back into the card template once I reloaded the decks.

UnicodeDecodeError

When importing the some flashcards with utf8 formatting this error occurs:

Traceback (most recent call last):
  File "c:\Users\Philip\Documents\GitHub\ankdown\ankdown\ankdown.py", line 389, in main
    cards_to_apkg(card_iterator, pkg_arg)
  File "c:\Users\Philip\Documents\GitHub\ankdown\ankdown\ankdown.py", line 340, in cards_to_apkg
    for card in cards:
  File "c:\Users\Philip\Documents\GitHub\ankdown\ankdown\ankdown.py", line 328, in cards_from_dir
    for card in produce_cards(os.path.join(parent_dir, fn)):
  File "c:\Users\Philip\Documents\GitHub\ankdown\ankdown\ankdown.py", line 301, in produce_cards
    for line in f:
  File "C:\Python36\lib\encodings\cp1252.py", line 23, in decode
    return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 3504: character maps to <undefined>

Changing line 297 in ankdown.py to

    with open(filename, "r", encoding="utf8") as f:

helps.

I thought though, that the default import in python is utf8. Should I do a pull request for this little bug?

PyYAML warnings are annoying

This project uses a PyYAML version that has a code execution vulnerability. Since the user is here assumed to be in complete control of any yaml input, I don't actually consider this a vulnerability in the project, but it should probably be dealt with anyway.

Order of processed markdown files seems random

Is there a way to control the order of cards that are added?
I currently use Markdown to write my lecture notes and then arrange them for the import. However, especially in math-heavy courses the ordering of the cards is quite important.

I just tested two md files with 2 cards each (1Test.md and 2Test.md). The order that the cards were added was random, first one card of md file 1, then two cards of file 2 and then the second card of file 1.
My Anki Setup is configured to ask the cards in the order they were added.

Merge Ankidown and Ankdown

Hi,

it's a little bit unusual request but I recently found the project ankidown. It can work with more difficult templates but has maybe some problems in parsing the markdown that ankdown doesn't have. Would be great if we could join forces between all who want to have a great tool for importing markdown into Anki. Please check it out. Hope you don't take it offensive.

Installation instructions failing

Hi,

I've followed the instructions

but i still see:

MacBook-Pro:~ Documents$ ankdown
-bash: ankdown: command not found

after running the pip3 install...

The anki addon also won't work

Configuration file

There are a bunch of things that one might want to configure about this tool: custom CSS and math separators are two that have gotten pull requests recently, but I suspect there are others.

It would probably be nice if these options could be placed into configuration files. But I think you might also want to have different configurations for different decks, or even different files. So it might also be nice if all the configuration options could be passed as command line flags. I don't want to overengineer this, but there's probably a reasonably nice, future-proof solution in design space somewhere.

Methods of correctly preserving card identity

Preserving card identity across edits is difficult: You can force the user to give each card a unique ID, or you can try to infer one, based either on card position, or on card contents. I wonder if you could do better by incorporating information from your existing anki decks (e.g. by interfacing with an anki plugin, or by reading the database directly). This is one of my major pain points with ankdown at the moment.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.