fix(anki): external resources in flashcards

This commit is contained in:
arne314
2024-12-23 20:22:56 +01:00
parent 1124181f59
commit b0d8031a8e
6 changed files with 41 additions and 102 deletions

View File

@@ -1,3 +1,4 @@
import os.path
from typing import List
import tree_sitter
@@ -11,6 +12,10 @@ class FileHandler:
self.file_path = path
self.read()
@property
def directory_path(self) -> str:
return os.path.dirname(self.file_path)
def get_bytes(self) -> bytes:
return bytes("".join(self.file_content), encoding="utf-8")

View File

@@ -1,5 +1,7 @@
import tree_sitter
from .file_handler import FileHandler
class Flashcard:
note_id: int
@@ -8,6 +10,8 @@ class Flashcard:
deck: str
id_updated: bool
file_handler: FileHandler
note_id_node: tree_sitter.Node
front_node: tree_sitter.Node
back_node: tree_sitter.Node
@@ -15,8 +19,8 @@ class Flashcard:
svg_front: bytes
svg_back: bytes
def __init__(self, front: str, back: str, deck: str = None, note_id: int = None):
if not deck:
def __init__(self, front: str, back: str, deck: str | None, note_id: int, file_handler: FileHandler):
if deck is None:
deck = "Default"
if not note_id:
note_id = 0
@@ -25,6 +29,7 @@ class Flashcard:
self.deck = deck
self.note_id = note_id
self.id_updated = False
self.file_handler = file_handler
def __str__(self):
return f"Flashcard(id={self.note_id}, front={self.front})"

View File

@@ -41,16 +41,23 @@ class FlashcardParser:
cards = []
tree = self.typst_parser.parse(file.get_bytes(), encoding="utf8")
captures = self.flashcard_query.captures(tree.root_node)
if not captures:
return cards
n = len(captures["flashcard"]) if captures else 0
for idx in range(n):
note_id = captures["id"][idx]
front = captures["front"][idx]
back = captures["back"][idx]
def row_compare(node):
return node.start_point.row
captures["id"].sort(key=row_compare)
captures["front"].sort(key=row_compare)
captures["back"].sort(key=row_compare)
for note_id, front, back in zip(captures["id"], captures["front"], captures["back"]):
card = Flashcard(
file.get_node_content(front, True),
file.get_node_content(back, True),
note_id=int(file.get_node_content(note_id))
None,
int(file.get_node_content(note_id)),
file,
)
card.set_ts_nodes(front, back, note_id)
cards.append(card)

View File

@@ -1,5 +1,6 @@
import asyncio
import os
import random
from typing import List
from .flashcard import Flashcard
@@ -33,21 +34,24 @@ class TypstCompiler:
self.preamble = preamble
self.max_processes = round(os.cpu_count() * 1.5)
async def _compile(self, src: str) -> bytes:
async def _compile(self, src: str, directory: str) -> bytes:
tmp_path = f"{directory}/tmp_{random.randint(1, 1000000000)}.typ"
with open(tmp_path, "w") as f:
f.write(src)
proc = await asyncio.create_subprocess_shell(
f"{self.typst_cmd} compile - - --root {self.typst_root_dir} --format svg",
stdin=asyncio.subprocess.PIPE,
f"{self.typst_cmd} compile {tmp_path} - --root {self.typst_root_dir} --format svg",
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await proc.communicate(bytes(src, encoding="utf-8"))
stdout, stderr = await proc.communicate()
os.remove(tmp_path)
if stderr:
raise TypstCompilationError(bytes.decode(stderr, encoding="utf-8"))
return stdout
async def _compile_flashcard(self, card: Flashcard):
front = await self._compile(self.preamble + "\n" + card.as_typst(True))
back = await self._compile(self.preamble + "\n" + card.as_typst(False))
front = await self._compile(self.preamble + "\n" + card.as_typst(True), card.file_handler.directory_path)
back = await self._compile(self.preamble + "\n" + card.as_typst(False), card.file_handler.directory_path)
card.set_svgs(front, back)
async def compile_flashcards(self, cards: List[Flashcard]):
@@ -58,4 +62,7 @@ class TypstCompiler:
async with semaphore:
return await self._compile_flashcard(card)
return await asyncio.gather(*(compile_coro(card) for card in cards))
results = await asyncio.gather(*(compile_coro(card) for card in cards), return_exceptions=True)
for result in results:
if isinstance(result, Exception):
raise result