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.
|
a clean way.
|
||||||
|
|
||||||
Consider a [total order](https://en.wikipedia.org/wiki/Total_order). What this
|
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
|
"total order", others call a "linear order". Though this example is simple, it
|
||||||
does highlight an issue - remembering the various synonyms used to describe
|
highlights an important issue - remembering the various synonyms used to
|
||||||
a concept is important for fluency.
|
describe a concept is necessary for fluency.
|
||||||
|
|
||||||
As of now, to handle this situation, it is probably best to use two flashcards,
|
As of now, to handle this situation, it is probably suggested to use two
|
||||||
one with prompt "Total Order" and another with prompt "Linear Order". In some
|
flashcards, one with prompt "Total Order" and another with prompt "Linear Order".
|
||||||
cases though, it'd be nice if the flashcard could *choose* which term it shows
|
In some cases though, it'd be nice if the flashcard could *choose* which term it
|
||||||
when it shows it. That is, it'd be nice to have a single card and allow Anki to
|
shows when it shows it. That is, it'd be nice to have a single card and allow
|
||||||
randomly choose to show "Total Order" *or* "Linear Order".
|
Anki to randomly choose to show "Total Order" *or* "Linear Order".
|
||||||
|
|
||||||
To do so, we can install this plugin and write the following:
|
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
|
end of the set. The result is either "Total Order" or "Linear Order" at time
|
||||||
of prompting.
|
of prompting.
|
||||||
|
|
||||||
|
You can also nest choices if need be:
|
||||||
|
|
||||||
|
```
|
||||||
|
'('(Logical|Valid) Consequence|Entailment)
|
||||||
|
```
|
||||||
|
|
||||||
|
will yield either "Logical Consequence", "Valid Consequence", or "Entailment".
|
||||||
|
|
||||||
## Configuration
|
## 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 copy
|
||||||
import enum
|
import enum
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Optional, Union
|
||||||
|
|
||||||
START_TAG = "'("
|
from anki import hooks
|
||||||
END_TAG = ")"
|
from anki.template import TemplateRenderContext, TemplateRenderOutput
|
||||||
CHOICE_TAG = "|"
|
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):
|
class Tag(enum.Enum):
|
||||||
|
@ -106,16 +118,32 @@ def run_parser(arg: str) -> str:
|
||||||
respectively, parsing "'(hello|world)" yields either "hello" or "world".
|
respectively, parsing "'(hello|world)" yields either "hello" or "world".
|
||||||
"""
|
"""
|
||||||
tokens = _tokenize(arg)
|
tokens = _tokenize(arg)
|
||||||
stack: list[list[str]] = [[]]
|
buffer: list[str] = [""]
|
||||||
|
stack: list[list[str]] = []
|
||||||
for token in tokens:
|
for token in tokens:
|
||||||
if token is Tag.START:
|
if token is Tag.START:
|
||||||
|
buffer.append("")
|
||||||
stack.append([])
|
stack.append([])
|
||||||
elif token is Tag.END:
|
elif token is Tag.END:
|
||||||
|
stack[-1].append(buffer.pop())
|
||||||
ts = stack.pop()
|
ts = stack.pop()
|
||||||
stack[-1].append(random.choice(ts))
|
buffer[-1] += random.choice(ts)
|
||||||
elif token is Tag.CHOICE:
|
elif token is Tag.CHOICE:
|
||||||
pass
|
stack[-1].append(buffer[-1])
|
||||||
|
buffer[-1] = ""
|
||||||
else:
|
else:
|
||||||
stack[-1].append(token)
|
buffer[-1] += token
|
||||||
assert len(stack) == 1, "Stack is larger than a single element"
|
assert not stack, "Stack should be empty"
|
||||||
return "".join(stack[0])
|
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