diff --git a/anki/exporting.py b/anki/exporting.py index b72694a90..f4f3ec4d3 100644 --- a/anki/exporting.py +++ b/anki/exporting.py @@ -11,23 +11,26 @@ from anki.hooks import runHook from anki.storage import Collection from typing import Any, Dict, List, Tuple +from io import BufferedWriter +from anki.collection import _Collection +from zipfile import ZipFile class Exporter: includeHTML: typing.Union[bool, None] = None - def __init__(self, col, did=None) -> None: + def __init__(self, col: _Collection, did: None = None) -> None: self.col = col self.did = did def doExport(self, path) -> None: raise Exception("not implemented") - def exportInto(self, path) -> None: + def exportInto(self, path: str) -> None: self._escapeCount = 0 file = open(path, "wb") self.doExport(file) file.close() - def processText(self, text) -> str: + def processText(self, text: str) -> str: if self.includeHTML is False: text = self.stripHTML(text) @@ -35,7 +38,7 @@ class Exporter: return text - def escapeText(self, text) -> str: + def escapeText(self, text: str) -> str: "Escape newlines, tabs, CSS and quotechar." # fixme: we should probably quote fields with newlines # instead of converting them to spaces @@ -47,7 +50,7 @@ class Exporter: text = "\"" + text.replace("\"", "\"\"") + "\"" return text - def stripHTML(self, text) -> str: + def stripHTML(self, text: str) -> str: # very basic conversion to text s = text s = re.sub(r"(?i)<(br ?/?|div|p)>", " ", s) @@ -101,11 +104,11 @@ class TextNoteExporter(Exporter): includeTags = True includeHTML = True - def __init__(self, col) -> None: + def __init__(self, col: _Collection) -> None: Exporter.__init__(self, col) self.includeID = False - def doExport(self, file) -> None: + def doExport(self, file: BufferedWriter) -> None: cardIds = self.cardIds() data = [] for id, flds, tags in self.col.db.execute(""" @@ -138,10 +141,10 @@ class AnkiExporter(Exporter): includeSched: typing.Union[bool, None] = False includeMedia = True - def __init__(self, col) -> None: + def __init__(self, col: _Collection) -> None: Exporter.__init__(self, col) - def exportInto(self, path) -> None: + def exportInto(self, path: str) -> None: # sched info+v2 scheduler not compatible w/ older clients self._v2sched = self.col.schedVer() != 1 and self.includeSched @@ -259,7 +262,7 @@ class AnkiExporter(Exporter): # such as update the deck description pass - def removeSystemTags(self, tags) -> Any: + def removeSystemTags(self, tags: str) -> Any: return self.src.tags.remFromStr("marked leech", tags) def _modelHasMedia(self, model, fname) -> bool: @@ -280,10 +283,10 @@ class AnkiPackageExporter(AnkiExporter): key = _("Anki Deck Package") ext = ".apkg" - def __init__(self, col): + def __init__(self, col: _Collection) -> None: AnkiExporter.__init__(self, col) - def exportInto(self, path): + def exportInto(self, path: str) -> None: # open a zip file z = zipfile.ZipFile(path, "w", zipfile.ZIP_DEFLATED, allowZip64=True) media = self.doExport(z, path) @@ -291,7 +294,7 @@ class AnkiPackageExporter(AnkiExporter): z.writestr("media", json.dumps(media)) z.close() - def doExport(self, z, path) -> Dict[str, str]: + def doExport(self, z: ZipFile, path: str) -> Dict[str, str]: # export into the anki2 file colfile = path.replace(".apkg", ".anki2") AnkiExporter.exportInto(self, colfile) @@ -315,7 +318,7 @@ class AnkiPackageExporter(AnkiExporter): shutil.rmtree(path.replace(".apkg", ".media")) return media - def _exportMedia(self, z, files, fdir) -> Dict[str, str]: + def _exportMedia(self, z: ZipFile, files: List[str], fdir: str) -> Dict[str, str]: media = {} for c, file in enumerate(files): cStr = str(c) diff --git a/anki/latex.py b/anki/latex.py index 2a5b001ff..46a283955 100644 --- a/anki/latex.py +++ b/anki/latex.py @@ -8,6 +8,8 @@ from anki.hooks import addHook from anki.lang import _ from typing import Any + +from typing import Any, Dict, List, Optional, Union pngCommands = [ ["latex", "-interaction=nonstopmode", "tmp.tex"], ["dvipng", "-D", "200", "-T", "tight", "tmp.dvi", "-o", "tmp.png"] @@ -38,7 +40,7 @@ def stripLatex(text) -> Any: text = text.replace(match.group(), "") return text -def mungeQA(html, type, fields, model, data, col) -> Any: +def mungeQA(html: str, type: Optional[str], fields: Optional[Dict[str, str]], model: Dict[str, Any], data: Optional[List[Union[int, str]]], col) -> Any: "Convert TEXT with embedded latex tags to image links." for match in regexps['standard'].finditer(html): html = html.replace(match.group(), _imgLink(col, match.group(1), model)) @@ -51,7 +53,7 @@ def mungeQA(html, type, fields, model, data, col) -> Any: "\\begin{displaymath}" + match.group(1) + "\\end{displaymath}", model)) return html -def _imgLink(col, latex, model) -> Any: +def _imgLink(col, latex: str, model: Dict[str, Any]) -> Any: "Return an img link for LATEX, creating if necesssary." txt = _latexFromHtml(col, latex) @@ -76,13 +78,13 @@ def _imgLink(col, latex, model) -> Any: else: return link -def _latexFromHtml(col, latex) -> Any: +def _latexFromHtml(col, latex: str) -> Any: "Convert entities and fix newlines." latex = re.sub("|
", "\n", latex) latex = stripHTML(latex) return latex -def _buildImg(col, latex, fname, model) -> Any: +def _buildImg(col, latex: str, fname: str, model: Dict[str, Any]) -> Any: # add header/footer latex = (model["latexPre"] + "\n" + latex + "\n" + @@ -130,7 +132,7 @@ package in the LaTeX header instead.""") % bad os.chdir(oldcwd) log.close() -def _errMsg(type, texpath) -> Any: +def _errMsg(type: str, texpath: str) -> Any: msg = (_("Error executing %s.") % type) + "
" msg += (_("Generated file: %s") % texpath) + "
" try: