Fix up with anki libraries.
parent
0b629044a8
commit
b716795d96
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
filesToFormat=$(
|
||||
git --no-pager diff --name-status --no-color --cached | \
|
||||
awk '$1 != "D" && $2 ~ /\.py/ {print $NF}'
|
||||
)
|
||||
|
||||
for path in $filesToFormat
|
||||
do
|
||||
black --quiet $path
|
||||
git add $path
|
||||
done
|
|
@ -0,0 +1,41 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
38
README.md
38
README.md
|
@ -5,16 +5,16 @@ different options for parts of prompts. This was designed to handle synonyms in
|
|||
a clean way.
|
||||
|
||||
Consider a [total order](https://en.wikipedia.org/wiki/Total_order). What this
|
||||
is does not matter; what it could also be called does. What some people call a
|
||||
is does not matter; other names it may have does. What some people call a
|
||||
"total order", others call a "linear order". Though this example is simple, it
|
||||
does highlight an issue - remembering the various synonyms used to describe
|
||||
a concept is important for fluency.
|
||||
highlights an important issue - remembering the various synonyms used to
|
||||
describe a concept is necessary for fluency.
|
||||
|
||||
As of now, to handle this situation, it is probably best to use two flashcards,
|
||||
one with prompt "Total Order" and another with prompt "Linear Order". In some
|
||||
cases though, it'd be nice if the flashcard could *choose* which term it shows
|
||||
when it shows it. That is, it'd be nice to have a single card and allow Anki to
|
||||
randomly choose to show "Total Order" *or* "Linear Order".
|
||||
As of now, to handle this situation, it is probably suggested to use two
|
||||
flashcards, one with prompt "Total Order" and another with prompt "Linear Order".
|
||||
In some cases though, it'd be nice if the flashcard could *choose* which term it
|
||||
shows when it shows it. That is, it'd be nice to have a single card and allow
|
||||
Anki to randomly choose to show "Total Order" *or* "Linear Order".
|
||||
|
||||
To do so, we can install this plugin and write the following:
|
||||
|
||||
|
@ -27,10 +27,26 @@ Here, `'(` is used to indicate the start of a set of choices Anki can display,
|
|||
end of the set. The result is either "Total Order" or "Linear Order" at time
|
||||
of prompting.
|
||||
|
||||
You can also nest choices if need be:
|
||||
|
||||
```
|
||||
'('(Logical|Valid) Consequence|Entailment)
|
||||
```
|
||||
|
||||
will yield either "Logical Consequence", "Valid Consequence", or "Entailment".
|
||||
|
||||
## Configuration
|
||||
|
||||
TODO
|
||||
From "Tools > Add-ons", select the `anki-synonyms` entry and select "Config"
|
||||
to reveal a dialog with contents:
|
||||
|
||||
## Nesting
|
||||
```json
|
||||
{
|
||||
"CHOICE_TAG": "|",
|
||||
"END_TAG": ")",
|
||||
"START_TAG": "'("
|
||||
}
|
||||
```
|
||||
|
||||
TODO
|
||||
Update these accordingly if the default `'(|)` set of operators do not mesh with
|
||||
the text in your questions and answers.
|
||||
|
|
|
@ -1,14 +1,26 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import Optional, Union
|
||||
|
||||
import copy
|
||||
import enum
|
||||
import random
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional, Union
|
||||
|
||||
START_TAG = "'("
|
||||
END_TAG = ")"
|
||||
CHOICE_TAG = "|"
|
||||
from anki import hooks
|
||||
from anki.template import TemplateRenderContext, TemplateRenderOutput
|
||||
from aqt import mw
|
||||
|
||||
|
||||
config = mw.addonManager.getConfig(__name__)
|
||||
|
||||
|
||||
START_TAG: str = config["START_TAG"]
|
||||
END_TAG: str = config["END_TAG"]
|
||||
CHOICE_TAG: str = config["CHOICE_TAG"]
|
||||
|
||||
|
||||
assert (
|
||||
len(set([START_TAG, END_TAG, CHOICE_TAG])) == 3
|
||||
), "Must have unique start, end, and choice operators."
|
||||
|
||||
|
||||
class Tag(enum.Enum):
|
||||
|
@ -106,16 +118,32 @@ def run_parser(arg: str) -> str:
|
|||
respectively, parsing "'(hello|world)" yields either "hello" or "world".
|
||||
"""
|
||||
tokens = _tokenize(arg)
|
||||
stack: list[list[str]] = [[]]
|
||||
buffer: list[str] = [""]
|
||||
stack: list[list[str]] = []
|
||||
for token in tokens:
|
||||
if token is Tag.START:
|
||||
buffer.append("")
|
||||
stack.append([])
|
||||
elif token is Tag.END:
|
||||
stack[-1].append(buffer.pop())
|
||||
ts = stack.pop()
|
||||
stack[-1].append(random.choice(ts))
|
||||
buffer[-1] += random.choice(ts)
|
||||
elif token is Tag.CHOICE:
|
||||
pass
|
||||
stack[-1].append(buffer[-1])
|
||||
buffer[-1] = ""
|
||||
else:
|
||||
stack[-1].append(token)
|
||||
assert len(stack) == 1, "Stack is larger than a single element"
|
||||
return "".join(stack[0])
|
||||
buffer[-1] += token
|
||||
assert not stack, "Stack should be empty"
|
||||
assert len(buffer) == 1, "Buffer should only have one element."
|
||||
return buffer[0]
|
||||
|
||||
|
||||
def on_card_render(
|
||||
output: TemplateRenderOutput,
|
||||
_unused_context: TemplateRenderContext,
|
||||
):
|
||||
output.question_text = run_parser(output.question_text)
|
||||
output.answer_text = run_parser(output.answer_text)
|
||||
|
||||
|
||||
hooks.card_did_render.append(on_card_render)
|
|
@ -0,0 +1 @@
|
|||
{"START_TAG": "'(", "END_TAG": ")", "CHOICE_TAG": "|"}
|
Loading…
Reference in New Issue