Add hooks for comparing answers (#3855)

* Add hooks associated to compare answer feature

* Update CONTRIBUTORS

* Add type pattern to compare answer related hooks
This commit is contained in:
chel-ou 2025-03-15 06:12:01 +01:00 committed by GitHub
parent 33b8235186
commit 122980e06b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 58 additions and 7 deletions

View file

@ -217,6 +217,7 @@ Mumtaz Hajjo Alrifai <mumtazrifai@protonmail.com>
Thomas Graves <fate@hey.com> Thomas Graves <fate@hey.com>
Jakub Fidler <jakub.fidler@protonmail.com> Jakub Fidler <jakub.fidler@protonmail.com>
Valerie Enfys <val@unidentified.systems> Valerie Enfys <val@unidentified.systems>
Julien Chol <https://github.com/chel-ou>
******************** ********************

View file

@ -749,13 +749,25 @@ class Reviewer:
def typeAnsAnswerFilter(self, buf: str) -> str: def typeAnsAnswerFilter(self, buf: str) -> str:
if not self.typeCorrect: if not self.typeCorrect:
return re.sub(self.typeAnsPat, "", buf) return re.sub(self.typeAnsPat, "", buf)
m = re.search(self.typeAnsPat, buf)
type_pattern = m.group(1) if m else ""
orig = buf orig = buf
origSize = len(buf) origSize = len(buf)
buf = buf.replace("<hr id=answer>", "") buf = buf.replace("<hr id=answer>", "")
hadHR = len(buf) != origSize hadHR = len(buf) != origSize
expected = self.typeCorrect initial_expected = self.typeCorrect
provided = self.typedAnswer initial_provided = self.typedAnswer
expected, provided = gui_hooks.reviewer_will_compare_answer(
(initial_expected, initial_provided), type_pattern
)
output = self.mw.col.compare_answer(expected, provided, self._combining) output = self.mw.col.compare_answer(expected, provided, self._combining)
output = gui_hooks.reviewer_will_render_compared_answer(
output,
initial_expected,
initial_provided,
type_pattern,
)
# and update the type answer area # and update the type answer area
def repl(match: Match) -> str: def repl(match: Match) -> str:

View file

@ -100,6 +100,44 @@ hooks = [
legacy_hook="showQuestion", legacy_hook="showQuestion",
legacy_no_args=True, legacy_no_args=True,
), ),
Hook(
name="reviewer_will_compare_answer",
args=[
"expected_provided_tuple: tuple[str, str]",
"type_pattern: str",
],
return_type="tuple[str, str]",
doc="""Modify expected answer and provided answer before comparing
expected_provided_tuple is a tuple composed of:
- expected answer
- provided answer
type_pattern is the detail of the type tag on the card
Return a tuple composed of:
- modified expected answer
- modified provided answer
""",
),
Hook(
name="reviewer_will_render_compared_answer",
args=[
"output: str",
"initial_expected: str",
"initial_provided: str",
"type_pattern: str",
],
return_type="str",
doc="""Modify the output of default compare answer feature
output is the result of default compare answer function
initial_expected is the expected answer from the card
initial_provided is the answer provided during review
type_pattern is the detail of the type tag on the card
Return a string comparing expected and provided answers
""",
),
Hook( Hook(
name="reviewer_did_show_answer", name="reviewer_did_show_answer",
args=["card: Card"], args=["card: Card"],
@ -846,7 +884,7 @@ gui_hooks.webview_did_inject_style_into_page.append(mytest)
'content' is a list of HTML strings added by add-ons which you can append your 'content' is a list of HTML strings added by add-ons which you can append your
own components or elements to. To equip your components with logic and styling own components or elements to. To equip your components with logic and styling
please see `webview_will_set_content` and `webview_did_receive_js_message`. please see `webview_will_set_content` and `webview_did_receive_js_message`.
Please note that Anki's main screen is due to undergo a significant refactor Please note that Anki's main screen is due to undergo a significant refactor
in the future and, as a result, add-ons subscribing to this hook will likely in the future and, as a result, add-ons subscribing to this hook will likely
require changes to continue working. require changes to continue working.
@ -861,7 +899,7 @@ gui_hooks.webview_did_inject_style_into_page.append(mytest)
'content' is a list of HTML strings added by add-ons which you can append your 'content' is a list of HTML strings added by add-ons which you can append your
own components or elements to. To equip your components with logic and styling own components or elements to. To equip your components with logic and styling
please see `webview_will_set_content` and `webview_did_receive_js_message`. please see `webview_will_set_content` and `webview_did_receive_js_message`.
Please note that Anki's main screen is due to undergo a significant refactor Please note that Anki's main screen is due to undergo a significant refactor
in the future and, as a result, add-ons subscribing to this hook will likely in the future and, as a result, add-ons subscribing to this hook will likely
require changes to continue working. require changes to continue working.
@ -1161,7 +1199,7 @@ gui_hooks.webview_did_inject_style_into_page.append(mytest)
args=["editor: aqt.editor.Editor", "path_or_nid: str | anki.notes.NoteId"], args=["editor: aqt.editor.Editor", "path_or_nid: str | anki.notes.NoteId"],
doc="""Called when the image occlusion mask editor has completed doc="""Called when the image occlusion mask editor has completed
loading an image. loading an image.
When adding new notes `path_or_nid` will be the path to the image file. When adding new notes `path_or_nid` will be the path to the image file.
When editing existing notes `path_or_nid` will be the note id.""", When editing existing notes `path_or_nid` will be the note id.""",
), ),
@ -1250,7 +1288,7 @@ gui_hooks.webview_did_inject_style_into_page.append(mytest)
name="addon_manager_will_install_addon", name="addon_manager_will_install_addon",
args=["manager: aqt.addons.AddonManager", "module: str"], args=["manager: aqt.addons.AddonManager", "module: str"],
doc="""Called before installing or updating an addon. doc="""Called before installing or updating an addon.
Can be used to release DB connections or open files that Can be used to release DB connections or open files that
would prevent an update from succeeding.""", would prevent an update from succeeding.""",
), ),
@ -1258,7 +1296,7 @@ gui_hooks.webview_did_inject_style_into_page.append(mytest)
name="addon_manager_did_install_addon", name="addon_manager_did_install_addon",
args=["manager: aqt.addons.AddonManager", "module: str"], args=["manager: aqt.addons.AddonManager", "module: str"],
doc="""Called after installing or updating an addon. doc="""Called after installing or updating an addon.
Can be used to restore DB connections or open files after Can be used to restore DB connections or open files after
an add-on has been updated.""", an add-on has been updated.""",
), ),