Skip to content

Instantly share code, notes, and snippets.

@snackfart
Last active April 2, 2023 20:26
Show Gist options
  • Save snackfart/3ef4430f520814b7440d950be95104b4 to your computer and use it in GitHub Desktop.
Save snackfart/3ef4430f520814b7440d950be95104b4 to your computer and use it in GitHub Desktop.
hedgeDocToAnkiConverter
import glob
from typing import Counter
# import urllib.request
# import os
import json
import genanki # https://pypi.org/project/genanki/
import warnings
import random
deckID = random.randint(1000000000, 2000000000)
selectionDelim = "####"
questionDelim = '- '
answerDelim = ' '
beginDelim = '## Anki'
# if not os.path.isdir("images"):
# os.makedirs("images")
normalModel = genanki.Model(
deckID,
'normalModel',
fields=[
{'name': 'Question'},
{'name': 'Answer'},
],
templates=[
{
'name': 'Card 1',
'qfmt': '{{Question}}',
'afmt': '{{FrontSide}}<hr id="answer">{{Answer}}',
},
]
)
# def saveImage(url, fileName):
# fullfilename = os.path.join("images/", fileName)
# urllib.request.urlretrieve(url, fullfilename)
formattedObject = {}
for file in glob.glob("*.md"):
print(f"current file: {file}")
deckID = random.randint(1000000000, 2000000000)
deckName = file.split(".")[0]
print(deckName)
currentDeck = genanki.Deck(deckID, deckName)
isForAnki = False
with open(file) as f:
lines = f.readlines()
currentSection = ""
currentCounter = 1
currentAnswer = ""
currentQuestion = ""
for line in lines:
if line.startswith(beginDelim):
isForAnki = True
if isForAnki:
if line.startswith(selectionDelim):
currentSection = line.split(selectionDelim)[1].split(" ")[
1].split("\n")[0]
currentCounter = 1
if line.startswith(questionDelim):
currentQuestion = line.split(questionDelim)[
1].split("\n")[0]
formattedObject[currentQuestion] = {
"answers": [],
"selection": currentSection,
}
if line.startswith(answerDelim):
if "![](" in line:
imageUrl = line.split("![](")[1].split(")")[0]
fileID = currentSection + str(currentCounter) + ".png"
# if not os.path.isfile(f"images/{fileID}"):
# print(f"Downloading {fileID}")
# saveImage(imageUrl, fileID)
formattedObject[currentQuestion]["answers"].append(
imageUrl)
currentCounter += 1
elif "</" in line:
formattedObject[currentQuestion]["answers"].append(
f"<html> {line} </html>")
else:
formattedObject[currentQuestion]["answers"].append(
line)
exportedQuestions = 0
# print(json.dumps(formattedObject, indent=4))
for question, answerDict in formattedObject.items():
completeAnswerString = ""
try:
for answer in answerDict["answers"]:
if ".png" in answer or ".jpg" in answer:
completeAnswerString += f'\n<img src="{answer}">\n'
else:
completeAnswerString += answer
my_note = genanki.Note(
model=normalModel,
fields=[question, "<pre>" + completeAnswerString + "</pre>"]
)
currentDeck.add_note(my_note)
exportedQuestions += 1
except Exception as e:
print(f"failed: {question}, {completeAnswerString}")
print(f"--> created {exportedQuestions}/{len(formattedObject)} anki cards")
warnings.filterwarnings('ignore', module='genanki',
message='^Field contained the following invalid HTML tags')
genanki.Package(currentDeck).write_to_file(f'{deckName}.apkg')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment