mirror of
https://github.com/Ascyii/typstar.git
synced 2026-01-01 13:34:24 -05:00
fix(anki): external resources in flashcards
This commit is contained in:
@@ -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")
|
||||
|
||||
|
||||
@@ -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})"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user